Accept payments on the TRON network through a separate address for every invoice without giving the service private keys to the funds.
Core principle
The service monitors payments and coordinates processing, while smart contracts perform financial operations according to your factory rules.
What the project is for
A conventional cryptocurrency payment setup often requires many wallets and private keys. This makes the infrastructure harder to maintain and creates an additional security risk.
Merchant Receipt assigns a separate settlement address with no private key to every invoice. The service detects payments, maintains history, runs checks and automation, but does not store keys capable of withdrawing received funds.
What merchants gain
No private-key vault
A service compromise cannot expose invoice-address keys because those keys do not exist.
Predictable processing rules
The factory defines the key rules, and smart contracts execute fund transfers.
A separate address per invoice
Each payment is linked to its order without sharing one address or relying on a transfer memo.
Automation with control
Routine payments are processed automatically, while exceptions pause for a merchant decision.
What you need to begin
✓
A wallet on the TRON networkIt is used to sign in, prove ownership and manage factories.
Signing in requires a message signature. This is not a transaction: authentication does not transfer funds or grant spending permission.
When network costs apply
Viewing data, creating invoices, receiving notifications and routine service requests do not send a transaction from the merchant wallet.
A real transaction may be required to register a factory, change its on-chain parameters or resolve an exception manually, such as issuing a refund, selecting a custom recipient or managing the factory wallet.
A single workspace for configuring payment acceptance, monitoring invoices and resolving situations that require a merchant decision.
The dashboard manages the process but does not store private keys for payment addresses.
It combines service data and contract state in a clear interface, while the connected wallet proves the owner's authority.
What the dashboard is for
Merchant UI is designed for day-to-day control of payment infrastructure. Use it to prepare a factory, verify its readiness, monitor payments and make decisions when automatic processing has been paused by the configured rules.
Manage factoriesCreate projects and configure payment acceptance, recipients, AML and webhooks.
Work with invoicesFind invoices, track payments, inspect the journal and perform permitted manual actions.
Monitor eventsReceive notifications for important stages and review action history in one place.
Configure integrationsManage the interface, notifications, API keys and connections to external systems.
Main sections
Factories
The project's primary screen. It shows factory readiness, volume, payments, active invoices, TMR balance and processing settings.
Invoices
A combined list of invoices from every factory with search, filters, statuses and a detailed view for each payment.
Address check
A free preliminary assessment of a prospective payer based on known labels and direct connections.
Events
Notifications, service news and the operation journal. It helps reconstruct the event sequence and avoid missing an important action.
Settings
General dashboard preferences, interface customization, notification controls and server API keys.
Preliminary address check
This tool helps assess a prospective payer's address before accepting a payment. It looks for known labels on the address and analyzes its immediate incoming and outgoing interactions to a depth of one level.
Preliminary and full checks are counted separately
You receive 100 free preliminary requests per day. Full AML checks are kept in a separate cumulative balance and are spent only after your confirmation.
Risk levelAn assessment ranging from minimal to high risk and a brief forecast of whether the main AML check is likely to pass.
Known labelsCategories assigned to the address in the analytics database, such as service type, attribution or a known source of risk.
Risk indicatorsSpecific findings that affected the assessment, including sanctions exposure, dangerous categories, elevated jurisdiction risk or another detected risk.
Direct connections and operationsAddresses of immediate risky counterparties and the operations connected with them, when such data is found.
Wallet and action confirmation
The dashboard opens after connecting the owner's wallet. Signing a message is enough to sign in: authentication does not transfer funds or send a transaction to the network.
You will encounter two types of confirmation. A message signature sends an instruction to the service without a network fee. A real transaction changes state on the TRON network and may require TRX, Bandwidth or Energy. Before every confirmation, the dashboard clearly identifies the operation type and purpose.
Message signatureConfirms a service request. No transaction is sent from the wallet.
Network transactionRuns on behalf of the owner and consumes TRON network resources.
Dashboard for control, SDK for invoice flow
You can create an individual invoice manually in the dashboard. For an online store, application or another production service, we recommend creating invoices through the Node.js SDK on the merchant's own server.
1
Your server reserves a numberThe SDK obtains a safe sequence for a new factory record.
2
The address is calculated locallyThe future payment address is generated inside the SDK on the merchant side.
3
The result is verified independentlyThe SDK verifies the address through the TRON node selected by the merchant.
4
The service verifies it againThe invoice is accepted for monitoring and processing only after all parameters match.
Which devices to use
The interface adapts to different widths, but detailed tables, settings and manual operations are more convenient on a computer or tablet. Until a dedicated mobile application is available, we recommend at least a tablet-sized screen for full operation.
ComputerBest for configuration and analysis
TabletSuitable for monitoring and most operations
Mobile applicationPlanned for operational monitoring
Additional interface verification
We plan to release a Google Chrome extension as an additional security layer. It will not be required for signing in or routine use.
The extension will be able to monitor important dashboard processes, verify the sources of loaded content and warn when the interface version is unknown or modified. Independent comparison of payment addresses with on-chain factory data is also planned.
Planned featureExact capabilities and extension requirements will be published before release.
Recommended workflow
MERCHANT UIConfiguration, monitoring and manual decisions
SERVER SDKAutomated invoice creation and verification
API + WEBHOOKData exchange with the merchant system
A merchant's personal smart contract that defines invoice-processing rules and protects critical payment acceptance settings.
One factory means one project, one asset and its own rules.
Invoices receive separate payment addresses, but processing always follows the settings of their factory.
What a factory is
After an application is approved, a separate MerchantFactory contract is created on TRON. It is permanently linked to the owner's wallet and the selected asset. The factory calculates future invoice addresses, stores on-chain settings and pays processing fees from its own TMR balance.
A factory is not a shared customer wallet. In the normal flow, invoice funds are sent directly to the payout address selected by the merchant. Separate factories are useful for different projects, assets or payment models.
1OwnerControls critical settings
→
2FactoryStores rules and calculates invoices
→
3RecipientReceives normally processed payments
Factory settings
Settings are separated by purpose. On-chain parameters affect the movement of funds. The profile organizes work in the dashboard without changing contract logic.
On-chain parameters
Factory assetThe asset accepted by invoices. It is fixed when the factory is created and cannot later be substituted by the service.
FIXED
Payout addressThe recipient of normally processed payments. Only the factory owner can change it.
OWNER
Maximum feeThe maximum fee in TMR that the contract allows to be charged from the factory when one invoice is activated.
OWNER
Minimum invoice balanceThe minimum amount on an invoice address at which normal processing is allowed.
OWNER
AML checkDetermines whether invoice activation must consider a full source-of-funds check. When AML checks are enabled, the owner can also configure AMLback.
OWNER
Automatic TMR top-upAllows USDT received by the factory to be converted automatically into TMR at a 1:1 ratio.
OWNER
USDT retained by the factoryThe amount of USDT that remains at the factory address and is excluded from automatic conversion into TMR. A non-zero balance can reduce the sender's energy consumption on subsequent USDT transfers to the factory.
OWNER
AMLbackUses a suitable previous high-risk AML result during invoice activation. The new check that was not used is credited to the merchant balance.
OWNER
AMLback risk thresholdThe minimum risk of a previous result that may be reused: from 60% to 100%.
OWNER
AMLback result ageThe allowed age of a previous check: 7, 30 or 90 days, or no limit.
OWNER
10 full AML checks with every factory activation
This is a one-time credit, not a limit. Checks accumulate in the owner's balance and remain available for on-demand use.
Profile and integrations
Project nameA clear factory name used in the dashboard, journal, and notifications.
DescriptionAn internal note describing the factory and its payment flow.
Invoice prefixA short prefix for displayed invoice numbers, for example SHOP-0000000001.
Recipient on the invoice pageThe store, company, or recipient name shown to the customer. This is a label, not the payout address.
Logo on the invoice pageA JPEG, PNG, or WebP image up to 5 MB. The built-in editor saves the selected square area.
Administrator contactA service contact for questions related to the factory.
Webhook URL and eventsThe integration endpoint and events that Merchant Receipt sends to the merchant system.
The public invoice page uses the current recipient name and logo from the factory profile. This off-chain data cannot change the asset, payout address, invoice amount, or contract rules for moving funds.
Who controls what
Authority is deliberately separated. The service coordinates processing but cannot rewrite the merchant's financial terms.
OWNER ONLYCritical settings
payout address;
maximum permitted fee;
minimum invoice balance;
AML, automatic TMR top-up and the retained USDT amount;
manual decisions for invoices and factory assets.
SERVICEOperational parameters
the active and pending fee, with a mandatory delay for increases;
discount when AML checking is disabled;
active or paused factory status;
monitoring and initiation of normal invoice processing.
THE SERVICE CANNOTBypass restrictions
change the factory asset;
assign another payout address;
charge an activation fee above the approved maximum;
withdraw TMR backing to an arbitrary address.
How the fee is agreed
The fee is charged in TMR only when an invoice is activated. The factory contract stores active and scheduled terms separately: an increase cannot take effect earlier than 201,600 TRON blocks, approximately 7 days.
1
Initial termsWhen the factory is created, the proposed fee becomes both the active rate and the initial approvedMaxFee.
2
The owner sets the limitOnly the owner's wallet can change approvedMaxFee through an on-chain transaction. The new limit applies immediately.
3
Increases are announced in advanceThe service may reduce the rate immediately, but an increase takes effect only after 201,600 blocks. Until then, the contract keeps the previous rate.
4
The transition window protects invoicesIf the pending fee exceeds approvedMaxFee, new invoices cannot be created, while existing invoices can still be activated at the previous rate before the activation block.
The contract cannot charge above the approved maximumIf approvedMaxFee is still below the active fee when the tariff changes, activation pauses. It resumes after the owner raises the limit or the service lowers the tariff.
Discount when AML is disabled
If the merchant disables built-in AML screening, the effective invoice processing fee is reduced by the discount configured for the factory.
For the first 7 days after the factory starts, an introductory discount of 0.5 TMR per invoice applies. This grace period lets the merchant test the factory without built-in AML screening at a lower cost.
After the introductory period, the discount is 0.2 TMR per invoice. The base fee does not change; only the discount amount changes. Current terms are always displayed in the dashboard.
The service sets the discount, but the contract requires it to remain below the base fee. Only the owner decides whether AML is disabled. The lower cost means accepting additional risks, described separately in the AML section.
What TMR is
TMR is Merchant Receipt's service settlement token on TRON. It is used only to pay factory invoice-processing fees and keeps service expenses separate from customer funds.
The working supply is capped at 1,000,000,000 TMR with 6 decimals and is assigned in full to the main contract at launch. In the normal model, TMR moves only between the main contract and personal factories.
Top-upThe merchant sends USDT to their factory.
→
1:1 conversionThe factory receives the same amount of TMR, while the USDT forms the reserve.
→
Invoice processingThe fee is deducted from the factory's TMR balance.
→
Reverse conversionUnused TMR is returned to the owner as USDT.
How the backing is protected
TMR outside the main contract=reserved USDT
When TMR is transferred to a factory, an equal amount of USDT reaches the main contract in the same operation. If either side fails, the entire transaction is reverted.
Profit is separated from the reserveThe service's standard withdrawal can take only USDT above the obligations backing TMR.
USDT is blocked from the emergency mechanismThe main contract's universal emergency call is technically unable to call the USDT contract.
Returns go only to the ownerWhen TMR is converted back to USDT, the recipient comes from the factory registry and cannot be substituted by the service.
Conversion is atomicTMR and USDT cannot move on only one side of a failed operation.
Security of merchant funds
The factory smart contract cannot be upgraded by the service or receive new powers after publication. Financially significant restrictions can be verified directly on-chain.
The service can pause a factory to stop new processing, but it cannot redirect accepted funds to itself. The payout address and manual decisions remain under the owner's wallet control.
Merchant Receipt priorityThe security of merchant and customer funds takes priority over operational convenience for the service. Administrative powers are therefore limited by the contracts in advance.
When a factory is ready
A factory is active when the service has enabled it, its asset and payout address are valid, and the recipient is ready to accept the selected token. The dashboard shows readiness problems separately instead of hiding them behind a single status.
A warmed-up address is already activated on TRON and has a non-zero balance of the accepted TRC20 asset. When a token is sent to an empty balance, the token contract usually has to create a new state entry, so the operation consumes more Energy. A previously inactive address may also require additional network resources.
Keep the payout address warmed upActivate the address before launching the factory. For a factory accepting a TRC20 asset, receive a small amount of that token and do not withdraw it completely afterward: a non-zero balance reduces resource consumption for subsequent payouts and makes their cost more predictable.
The service may provide Energy and Bandwidth for an individual merchant network operation and count the actual usage against the merchant's daily limit.
The network cost payer is determined separately before every transaction.
The current result is always shown in the Network cost row before the wallet opens and the transaction is signed.
What the service covers
For selected merchants, the service may provide the resources required to execute transactions on TRON. In that case, the individual operation does not consume the owner's Energy and Bandwidth; actual usage is counted against the daily coverage limit.
Coverage may apply to factory setting changes, manual activation and invoice plan setup, factory and invoice wallet operations, and other actions that the owner confirms with an on-chain transaction.
Limits and resource availability
The daily limit is the maximum resource amount available to the account during the current accounting day. The remainder is shown in the account card and checked again before every operation.
The limit and the service's current resource capacity are different values. A positive limit remainder does not mean that the corresponding amount of Energy and Bandwidth is permanently reserved for the merchant.
1
Coverage is activeThe account is enrolled in the support program.
2
The limit is sufficientThe resource estimate fits within the available daily remainder.
3
Resources are availableThe service can provide the required Energy and Bandwidth at that time.
What to check before signing
Check the Network cost row in the confirmation dialog. It shows the decision for the current attempt, so do not rely only on the account's general status.
The payer is determined separately for every transaction. The presence of a general limit does not replace this check.
Covered by the serviceThe operation passed the preliminary checks. After execution, actual usage is deducted from the displayed daily remainder.
Paid by the factory ownerCoverage does not apply to this attempt. The transaction uses the connected wallet's resources or TRX in the standard way.
How a covered operation is performed
1
Resource estimateThe dashboard determines the required Energy and Bandwidth.
2
Eligibility checkThe service checks the limit and current resource availability.
3
Payer displayBefore signing, the interface shows who covers the network cost.
4
Owner signatureThe merchant reviews the purpose and confirms the transaction with the wallet.
5
Resource provisionThe service submits the transaction only after resources have been prepared successfully.
6
Usage accountingActual network consumption is deducted from the daily limit.
When coverage is unavailable
When the preliminary check finds insufficient limit or service resources, the dashboard does not block the action. The confirmation dialog states that the factory owner pays, and the standard TRON mechanism applies.
If resources cannot be prepared after a covered operation has been confirmed, the merchant transaction is not submitted. The dashboard reports an error; a retry performs a new estimate and determines the network payer again.
A preparation failure does not become an unexpected charge.The operation is not silently submitted at the owner's expense after the interface has shown service coverage.
Terms of availability
A displayed limit does not obligate the service to cover every subsequent operation and does not represent resources reserved in advance. For urgent operations, consider that your own wallet may need to cover the transaction when service coverage is temporarily unavailable.
A dedicated settlement address for every order. It accepts payment without a private key and becomes a smart-contract wallet only when activated.
Before activation, an invoice is a calculated address, not a pre-created wallet.
It is uniquely linked to a specific factory and invoice number, while no private key is ever created or stored for it.
The invoice before activation
When a merchant creates an invoice, Merchant Receipt reserves its sequential number and calculates its future payment address. No smart-contract code exists at that address yet. It is still a valid TRON address, and the customer can already send the selected asset to it.
The address is derived by fixed rules from the factory, invoice number, and future wallet code. The same inputs always produce the same result, and the invoice cannot belong to another factory.
1FactoryDefines the asset and rules
→
2Invoice numberUnique within the factory
→
3Payment addressCalculated in advance
Why there is no private key
An invoice address is not created from a new key pair. Merchant Receipt therefore has no database of payment-address private keys, the merchant has no separate secret for every order, and the customer does not have to trust a server wallet to hold the funds.
Even if the Merchant Receipt servers are compromised, an invoice key cannot be exposed because no such key exists. Before the contract is activated, funds cannot be moved from the address with an ordinary signature. During activation, the predetermined wallet code appears at the exact calculated address and executes the configured rules.
No key vaultThe service has nothing of this kind to lose or disclose to an attacker.
No merchant-held keyThere is no separate secret to create, archive, and protect for every invoice.
The address cannot be substitutedLocal calculation binds it to the selected factory and number.
The code is known in advanceActivation publishes a verifiable wallet with the expected behavior.
Local calculation in merchant infrastructure
When invoices are created through the Node.js SDK, the address is calculated inside the merchant's infrastructure and checked through the merchant's selected TRON node. Our server repeats the calculation before monitoring begins, but it cannot silently replace the result with an arbitrary address: a mismatch stops invoice creation.
A server breach cannot redirect payment to an attacker's addressThe SDK independently verifies the calculated address against the factory contract through the TRON network. For a production invoice flow, this is safer than unconditionally trusting an address returned by a single server.
Creating an invoice
An invoice can be created manually in the dashboard or automatically through the SDK. In both cases, its monitoring and processing parameters are recorded before monitoring starts.
FactoryDefines the accepted asset, payout address, and network restrictions.
AmountThe expected payment amount in the factory asset.
ExpirationThe period during which payment is considered timely.
PurposeA merchant-friendly description of the order or operation.
Activation modeAutomatic execution when all rules pass, or a manual merchant decision.
Stop rulesConditions that replace automatic processing with manual review.
From invoice to wallet
1
Address calculatedThe invoice is stored and placed under monitoring.
2
Payment detectedThe service confirms the transfer on-chain and updates the received amount.
3
Rules evaluatedAmount, senders, expiration, and AML are checked when applicable.
4
Scenario selectedNormal processing continues automatically or the invoice waits for the merchant.
5
Wallet activatedA contract is published at the address and immediately executes the selected plan.
6
Result recordedTransfers, remaining balance, and final status appear in the timeline.
Automatic and manual activation
With automatic activation, the service continues processing once the payment is confirmed and every configured condition has passed. In manual mode, the invoice still receives and records payments but does not become a contract until the merchant decides.
Auto-activation can be paused in the invoice card. If a protection rule stopped it, it cannot be resumed without reviewing the cause: the invoice remains in the attention queue.
AMOUNTAt least the invoice amount
an underpayment waits for an additional payment;
any positive payment can be accepted when that rule was selected in advance.
PAYMENTUnexpected payment conditions
stop on overpayment;
stop when there are multiple senders.
RISKAML threshold
a high or merchant-defined risk level;
wait for manual review instead of paying out automatically.
AML check before payout
When AML is enabled for the factory and invoice, the service checks the source of funds before the normal automatic payout. The result is compared with the selected risk threshold: an acceptable payment continues, while elevated risk moves the invoice to manual processing.
During manual activation, the dashboard specifically reminds the merchant to perform an AML check when the selected plan sends any funds to the factory's normal recipient. For a refund, another custom address, or keeping funds on the invoice, the decision remains with the merchant.
1
The check runs before activationPotentially risky funds therefore do not reach the main payout address automatically.
What happens during activation
The factory publishes a compact smart contract at the predetermined address. During creation it reads the authorized plan, checks the factory-asset balance, and immediately executes the transfers. If a required part fails, the entire activation is reverted.
Normally, the complete current balance of the factory asset is swept to the payout address. For an exception, the merchant selects one of the limited scenarios in advance; arbitrary executable code cannot be supplied as a plan.
Normal activation
The complete balance of the accepted asset is sent to the recipient configured in the factory.
Refund
Up to three recipients with exact amounts, including prepared payer-refund and overpayment-refund plans.
Custom recipient
The complete balance of the accepted asset is sent to one address confirmed by the owner.
Keep on invoice
Dry activation creates the contract wallet without transferring the factory asset. The owner handles the funds later.
After activation: the invoice wallet
After publication, the address becomes a smart-contract wallet. It can hold TRX, the factory asset, and other detected TRC20 assets. The dashboard shows balances and transfer history, and lets the merchant add a token for tracking, send an asset, or grant an allowance.
Manual actions are not executed as ordinary server commands. The factory owner's wallet submits a real network transaction, while the execution layer verifies that the invoice belongs to that factory and owner. Before signing, the dashboard separately shows whether the service covers the network cost or the owner's resources are used.
Send an assetTransfer TRX or a selected token from the invoice wallet.
Grant an allowanceAn on-chain allowance for a selected TRC20 token.
HistoryIncoming and outgoing movements shown separately for each asset.
Detected assetsBalances of the factory asset, TRX, and third-party tokens.
What the invoice card contains
The card header always shows the invoice number, current activation state, and complete address with a copy action. The remaining information is organized by task.
ActivationAuto-activation, four manual processing scenarios, and final recipients and amounts before confirmation.
WalletContract state, balances, sending, allowances, and asset history.
TimelineA chronology of creation, payments, warnings, AML, merchant decisions, and actual fund distribution.
AMLRun an available check and view the stored report for the selected address or payer.
InformationCore parameters, addresses, payment and activation states, stop rules, expiration, and purpose.
WarningsShown only for deviations such as multiple senders, an unrelated token, or other circumstances requiring attention.
Trust boundary
A dashboard session, API key, or webhook secret cannot replace the owner's wallet for manually moving funds. The interface shows in advance whether a transaction will be submitted, exactly what it will do, and who pays the network resources.
Core invoice guaranteeNo private key exists for the invoice address, either before or after activation. After activation, only the owner of the corresponding factory can control the invoice wallet and the funds it holds. The link to the ownership registry is permanent: the service cannot replace that registry or execute an operation in place of the owner.
This tool helps assess a prospective payer's address before accepting a payment. It looks for known labels on the address and analyzes its immediate incoming and outgoing interactions to a depth of one level.
Preliminary and full checks are counted separately
You receive 100 free preliminary requests per day. Full AML checks are kept in a separate cumulative balance and are spent only after your confirmation.
What the report includes
Risk levelAn assessment ranging from minimal to high risk and a brief forecast of whether the main AML check is likely to pass.
Known labelsCategories assigned to the address in the analytics database, such as service type, attribution or a known source of risk.
Risk indicatorsSpecific findings that affected the assessment, including sanctions exposure, dangerous categories, elevated jurisdiction risk or another detected risk.
Direct connections and operationsAddresses of immediate risky counterparties and the operations connected with them, when such data is found.
Full AML resultWhen a full check already exists for the address, the report shows its level, date, risk categories and final assessment without revealing who initiated the check.
Risk categoriesCategory shares and scales from the full AML check show which sources contributed to the risk.
How to read the indicators
Own risk
The finding applies directly to the checked address or to known information about its owner.
Direct-connection risk
The finding comes from a direct interaction between the checked address and a labeled counterparty. It does not mean that all of the address's transactions are risky.
No labels found
The available database contains no known labels. This reduces the number of detected signals but does not by itself prove that the address is clean.
How to enrich a report with a full AML check
If no full result exists yet, you can request one directly from the preliminary report. If a result is already shown, you can refresh it to receive current data. Either action spends one check from the cumulative balance.
1
Review the preliminary reportInspect the address labels, direct connections and operations before accepting payment.
2
Run or refresh AMLThe full-check action is available in the same report. A refresh also counts as a new check.
3
Confirm with your walletThe wallet signs a service message. No transaction is broadcast to the TRON network.
4
Receive the updated conclusionAfter the AML provider responds, the report adds risk categories and recalculates the final assessment using the stricter signal.
Where full checks come from
Factory activation
The owner receives 10 full AML checks once for every activated factory.
AMLback savings
When a suitable previous high-risk result is enough during invoice activation, the unused new check is credited to the balance.
Merchant-controlled use
Spend one check on a new or refreshed AML report for a payer address so you can decide before the invoice is paid.
How to use the result
Start with the free preliminary assessment. If it is not enough, enrich the report with a full AML check and decide whether to accept payment from this address or request another one. The enriched report, including its risk categories, can be saved as a PDF.
The dashboard preserves the operating history, highlights important events, and shows brief messages during an active session.
Important information does not depend on an open browserThe journal and important notifications are stored on the server for the authorized wallet. If an event occurs while the merchant is away from the dashboard, it will be available after the next sign-in.
Three levels of information
Each level has a distinct purpose. The journal provides a complete timeline, the notification center collects selected important events, and toasts show the immediate result of a current action.
Event journalA chronological history of factory, invoice, payment, AML, setting, and asset movement operations.
Important notificationsA separate list of events that require attention or were selected by the merchant in settings.
Toast messagesBrief pop-up messages about an action result or a new event while the dashboard is open.
NewsA separate tab for service announcements. News is not mixed with an individual merchant's operations.
Event journal
The journal helps reconstruct the sequence of actions. Events remain there regardless of important-notification settings: invoice creation and processing, incoming and outgoing transfers, warnings, AML results, factory changes, and confirmed settings.
Records are associated with the merchant wallet address and loaded from the server. The history therefore remains available after a browser restart and when signing in from another device with the same wallet. Changing the language retranslates loaded records without altering stored data.
Time and order
New records appear first, while the date and time help reconstruct the processing flow.
Context
When applicable, a record identifies the factory or invoice and provides a clear description of what happened.
Independent of subscriptions
Disabling a notification category does not remove the corresponding events from the journal.
Important notifications
The notification center is a focused selection from the journal. It avoids the need to search manually for events relevant to daily operations and shows the unread count next to the bell.
Required notifications
Insufficient TMRThe factory lacks the service balance required to complete an operation.
ALWAYS ENABLED
Invoice publication errorThe invoice was not published; the notification contains a safe description of the cause.
ALWAYS ENABLED
These categories protect the core payment flow and therefore cannot be disabled.
Configurable categories
Payments and overpaymentsInvoice statusAML checksFactories and requestsSetting changesTMR balance and operations
The merchant chooses which of these events should also appear in the important-notification list.
Managing subscriptions
1
Open settingsOpen the dashboard's general Settings section and find the notification settings.
2
Choose categoriesEnable the events that should appear in the notification center.
3
The preference is savedThe selection is stored on the server for the current wallet and applies across devices.
4
Watch the bellThe red badge shows unread records, while the compact panel opens the five latest notifications.
What works online and without an open dashboard
ALWAYSJournal
Events are recorded by the service and wait for the merchant's next sign-in.
ALWAYSImportant notifications
Selected and required categories are stored even while the dashboard is closed.
ONLINE ONLYToast messages
They appear over the current screen and make an operation result immediately visible.
A toast can be closed immediately or left to disappear automatically. It is a quick visual confirmation and does not replace the journal or notification center.
Working with unread notifications
Open the bell in the top bar to see the five latest notifications and the unread count. A record can be marked as read individually, or you can use Mark all as read. The complete paginated list is available in Events.
✓
A simple ruleThe journal answers “what happened,” notifications answer “what must not be missed,” and a toast answers “what happened just now.”
Receive factory event messages as soon as Merchant Receipt records them.
Webhooks notify, the API responds
With the API, the merchant server requests data from Merchant Receipt. A webhook works in the opposite direction: our server sends an HTTPS POST to the merchant when a selected event occurs.
When to use webhooks
Use webhooks to react to invoice creation, detected payments, AML results, invoice wallet publication and other changes without polling the API.
APIMerchant-initiated request
The application requests current data or performs an allowed operation.
WEBHOOKService-initiated message
Merchant Receipt delivers an event to a configured endpoint.
SDKReady-to-use API access
The Node.js SDK signs requests and exposes factory and invoice methods.
Connecting a factory
1
Prepare an HTTPS endpointIt must accept JSON POST requests and respond without lengthy processing.
2
Enable the webhookEnter the URL in factory parameters and select the required events.
3
Store the secretThe secret is generated on enable and lets the receiver verify HMAC.
4
Verify the connectionThe handshake confirms endpoint availability and the correct secret.
Endpoint requirements
✓
HTTPS and POSTThe service sends JSON with POST and does not follow redirects.
✓
Raw body accessVerify the signature against the original bytes before parsing JSON again.
✓
Fast 2xx responseQueue complex work after request verification.
✓
Event ID storageThe same event must not trigger a new business operation.
Delivery and retries
Any 2xx response completes delivery. A timeout, network failure or other HTTP status triggers retries with increasing delay, up to eight attempts. Delivery therefore follows an at-least-once model.
Timestamp is Unix time in seconds for this delivery attempt. The event occurrence time is stored in createdAt as ISO 8601 with milliseconds.
Signing string
HMAC-SHA256
{timestamp}.{eventId}.{rawRequestBody}
Safe processing order
1
Check the timestampReject a timestamp that is too old.
2
Verify HMACCompare signatures with a timing-safe operation.
3
Match the identifierWebhook-Id in the header must equal id in JSON.
4
Check for duplicatesReturn 2xx for a stored id without repeating the action.
Verification handshake
The verification button sends webhook.endpoint_verification with a random challenge. The receiver verifies the request and returns the same challenge with an HMAC proof. Success confirms both URL availability and possession of the correct secret.
Amounts in minimal units are decimal strings so JavaScript does not lose precision. Empty optional data fields are omitted.
Supported events
invoice.created
The invoice was created, verified and added to monitoring.
payment.detected
An incoming invoice payment was confirmed on TRON.
aml.pending
An AML check was created and is awaiting a result.
aml.approved
Risk did not reach the invoice threshold.
aml.rejected
Risk reached the threshold and automatic processing stopped.
invoice.published
Publication of the invoice wallet was confirmed on TRON.
settlement.sent
Actual recipient transfers during activation were recorded.
manual_review.required
The invoice awaits merchant action because of its mode or a safety rule.
Idempotent processing
Store id as the unique key for an incoming event. Different events such as invoice.published and settlement.sent can share one txId, so txId alone is not a valid deduplication key.
✓
A repeated id still gets a successful responseReturn 2xx without performing the business action again.
A minimal receiver verifies signatures, answers the handshake and handles invoice creation.
Verify first, process second
Do not trust the event type, challenge or any other JSON field until HMAC has been verified against the raw body bytes.
Preparation
Install Express
npm install express
Pass the secret from factory parameters in TMR_WEBHOOK_SECRET before starting.
Connecting HTTPS
Place a reverse proxy such as Nginx in front of Node.js. It accepts the secure request on a public domain and forwards it to the local receiver without changing the route:
Enter the public HTTPS URL in factory settingsFor the setup above, use https://hooks.example.com/webhook, not the internal http://127.0.0.1:3000/webhook address.
Merchant API lets a merchant server read factory and invoice data and create invoices through protected HTTP requests.
The merchant application calls the API
Your server decides when to send a request and what data to retrieve. Merchant Receipt uses webhooks for service-initiated messages.
Base URL
https://merchant.trc20.money/api/v1
Currently available
Access check
Validate key state, signature, time, nonce, IP and permissions.
Factories
List available factories and read profiles, aggregate statistics and webhook settings.
Invoices
Reserve a number, create invoices, list them and read detailed data.
Monitoring
Read state, payments, timeline, warnings, AML, assets and payment link.
Creating an API key
1
Open Settings → APIThe owner wallet confirms key creation.
2
Restrict accessChoose factories, scopes, expiration and optional IP addresses.
3
Store the private partThe tmrsk_v1 key is displayed once and is not stored by the service.
4
Check the integrationCall auth.check to validate the configuration.
Key restrictions
A key can be restricted to specific factories, minimum scopes, an expiration of up to 365 days and exact source IPs. Create separate keys for separate applications.
Merchant API boundary
Merchant API covers service data, invoices, webhooks, monitoring and explicitly scoped V3 service conversions. Network settings, arbitrary transfers and direct owner conversions use TRON API.
factoryAddress uses TRON Base58 format. A factory unavailable to the key returns FACTORY_NOT_FOUND without disclosing whether it exists.
Both conversion POST methods require an Idempotency-Key header and a JSON body containing { amountRaw }. The amount is a smallest-unit integer string that must fit uint88.
Saved configuration. secret appears only when credentials are created.
history page
history, summary/asset, nextCursor, hasMore
History page and continuation cursor.
History parameters
Property
Type
Description
period
today | 7d | 30d
Combined history period, 30d by default.
operationType
all | payout | tmr
Filters combined history by operation type.
search
string
Searches invoice, payout address or txId, up to 180 characters.
standard
TRX | TRC20 | TRC10
Asset standard for wallet history.
assetAddress
string
Contract address required for TRC20.
tokenId
string
TRC10 identifier, defaults to 1005181 for TMR.
limit
number
From 1 to 100 records.
cursor
string
nextCursor from the previous response.
Mutable data
Profile PATCH accepts any non-empty combination of displayName, description, invoicePrefix, notificationContact and paymentRecipientName. Omitted fields are preserved.
paymentLogoUrl is read-only. The logo POST endpoint accepts a binary PNG, JPEG or WebP body up to 5 MB.
Webhook PUT requires the full object and an Idempotency-Key header. The secret is returned only when new credentials are created and is not disclosed later.
invoiceId may be an internal numeric ID or the full Base58 invoice address. The invoice is additionally restricted to the selected factory in every case.
Page and size from 1 to 100, defaulting to 1 and 25.
search
string
Searches number, address, purpose and externalId.
externalId
string
Exact external identifier match.
status
string
Filters by current status.
requiresAttention
boolean
Returns only invoices requiring merchant action.
sort
created | updated | expires | amount | status | number
Sort field, created by default.
direction
asc | desc
Sort direction, desc by default.
Creating an invoice
The address must be calculated locally.
The prepare response contains the contract version and known hashes. The client selects invoice type, calculates addressCode, chainInvoiceId and invoiceAddress, optionally verifies the result through a TRON node, and only then sends create.
Property
Type
Description
reservationId
string
Identifier of an active prepare reservation.
sequenceNumber, addressCode, chainInvoiceId
integer string
Components of the local address calculation.
invoiceAddress
string
Calculated Base58 address of the future invoice.
invoiceKind, contractVersion
string, number
trc20 or trx type and template version from prepare.
amount
decimal string
Positive amount in regular asset units.
purpose, externalId
string
Purpose up to 220 characters and optional merchant ID up to 120.
expiresMinutes
number
Payment lifetime from 1 to 43200 minutes.
activationMode, settlementRule
auto | manual, at_least | any
Activation mode and payment sufficiency rule.
autoStopMultipleSenders, autoStopOverpayment
boolean
Conditions that stop automatic processing.
autoAmlRiskMode, autoAmlRiskThreshold
string, number
medium, high or custom mode and a threshold above 0 and at most 1.
Create requires an Idempotency-Key up to 128 characters. Repeating the same business request returns the created invoice, while changed parameters with the same key are rejected. A non-empty externalId is unique within the factory.
activation/process and payment-link require no body. Special payout plans and wallet operations are outside Merchant API and run directly through TRON.
The realtime channel delivers operational factory and invoice events without repeatedly polling Merchant API.
Socket.IO transport over WebSocket
This is not a raw WebSocket. The client must support the Socket.IO protocol and websocket transport.
Obtaining a token
Method
Endpoint
Scope
Result
Description
POST
/api/v1/realtime/token
—
token, expiresAt, socketPath
Issues a short-lived connection token.
The request is signed with the regular TMR1 key and has no body. The token is valid for five minutes; event access is then limited by each factory's scopes.
Pass the last processed event's lastEventId after reconnecting. The server replays missed events; an unknown cursor or excessive gap returns an explicit error.
Events
A single factory.event contains a unique id, API version, type, factory, createdAt and domain data in data. Invoice events require invoices:read; other factory events require factories:read.
To leave one factory, emit factory:unsubscribe with its factoryAddress. Realtime is intended for operational interfaces, while webhooks remain the reliable business-event delivery channel.
Retry only temporary network errors and safe idempotent operations. Nonce prevents signature replay, while Idempotency-Key protects the business operation during retry.
The SDK reduces integration code by building TMR1 signatures, mapping errors, creating factory and invoice contexts and reading on-chain data through TronWeb. Most importantly, new invoice addresses are calculated locally on the merchant server.
Requirements
Node.js 18+Merchant Receipt API keyHTTPS access to APITRON node or TronGrid
The constructor accepts one params object. The API key identifier and private part are required; other properties have defaults or enable additional verification.
Constructor parameters
Property
Type
Required
Description
apiUrl
string
No
Merchant API base URL. Defaults to https://merchant.trc20.money/api.
keyId
string
Yes
Public API key identifier in tmrk_... format.
privateKey
string
Yes
The private Ed25519 part shown once in tmrsk_v1_... format.
mainFactoryAddress
string
No
Main factory address used to verify MerchantFactory ownership.
factoryAddress
string
No
Default payment factory address for methods called without an explicit address.
timeoutMs
number
No
HTTP request timeout in milliseconds. Defaults to 15000.
tron
object
No
Node settings used by the SDK to create TronWeb.
tronWeb
TronWeb
No
An existing TronWeb instance. Takes priority over tron.
tron parameters
If tronWeb is not supplied, the SDK creates it from tron. If both are omitted, public TronGrid is used. The configured instance is always exposed as tmr.tronWeb.
Property
Type
Description
fullHost
string
HTTP API URL of the selected TRON node.
headers
object
Provider headers, such as TRON-PRO-API-KEY for TronGrid.
Configuration examples
Minimal configuration
Node.js
const tmr = new TmrMerchant({
keyId: process.env.TMR_KEY_ID,
privateKey: process.env.TMR_API_PRIVATE_KEY
});
The method returns an array of factories available to the current API key. It requires the factories:read scope. The order matches the factory order in the dashboard menu.
Property
Type
Description
id
number
Internal factory identifier.
address
string
TRON address of the factory smart contract.
displayName
string
Display name of the factory.
description
string
Factory profile description.
invoicePrefix
string
Prefix used in displayed invoice numbers.
receivedTotalRaw
string
Accepted volume in the asset's smallest units.
createdAt
string
Record creation time in ISO 8601 format.
updatedAt
string
Last update time in ISO 8601 format.
Selecting a factory
Find a record by profile data and pass its address to at(address). The method creates a local factory context with profile, webhook, statistics and invoice services ready to use.
Node.js
const factories = await tmr.factory.list();
const selected = factories.find(
({ displayName }) => displayName === "my_shop_1"
);
if (!selected) throw new Error("Factory my_shop_1 not found");
const factory = tmr.factory.at(selected.address);
const info = await factory.get();
console.log(info.asset.symbol, info.statistics.invoiceCount);
Factory methods
Method
Source
Result
Description
tmr.factory.list(apiOptions?)
API
FactorySummary[]
Returns factories permitted for the API key.
tmr.factory.at(address)
Local
FactoryService
Creates a context for one factory without a network request.
factory.get(readOptions?)
TronWeb + API
FactoryInfo
Reads the contract, asset and balances, then adds service statistics.
tmr.factory.get(address, readOptions?)
TronWeb + API
FactoryInfo
Performs the same read without first creating a context through at().
Returns indexed history for a selected factory-wallet asset.
factory.on(event, handler, realtimeOptions?)
Socket.IO
unsubscribe
Subscribes a handler to recurring factory events.
factory.once(event, handler, realtimeOptions?)
Socket.IO
unsubscribe
Removes the handler after the first matching event.
factory.off(event, handler?)
Local
boolean
Removes a selected handler or all handlers for an event.
factory.get() response
By default, get() reads on-chain state through the configured TronWeb and requests statistics in parallel. Pass includeStatistics: false to receive only the network snapshot without a Merchant API request.
Statistics API request timeout; it does not affect TronWeb reads.
The apiOptions parameter
Property
Type
Description
timeoutMs
number
Per-request timeout for the Merchant API HTTP request.
apiOptions is used by Merchant API methods, webhookOptions additionally accepts idempotencyKey, and transactionOptions is passed to TronWeb for on-chain changes.
FactoryInfo fields
Property
Type
Description
address
string
Normalized factory address.
mainFactoryAddress
string
Address of the main contract this factory belongs to.
merchantOwnerAddress
string
Factory owner address.
active
boolean
Current on-chain active state.
asset.address
string
Payment asset address.
asset.name
string
Payment asset name.
asset.symbol
string
Payment asset ticker.
asset.decimals
number
Number of decimal places used by the asset.
asset.standard
string
Asset standard: TRX or TRC20.
settings.feeRaw
string
Current fee in the smallest TMR units.
settings.approvedMaxFeeRaw
string
Maximum fee approved by the owner.
settings.feeSchedule
object
The active and pending V3 fee, effective values and activation block.
feeApproval
object
Fee readiness for activation and new invoice creation.
settings.payoutAddress
string
Recipient address for normal settlements.
settings.minimumInvoiceBalanceRaw
string
Minimum invoice balance required for processing.
settings.autoConvertUsdtToTmrEnabled
boolean
Whether automatic TMR funding is enabled.
settings.autoConvertUsdtRetainAmountRaw
string
USDT amount excluded from automatic conversion.
settings.amlEnabled
boolean
Whether factory AML checks are enabled.
settings.amlFeeRaw
string
Fee discount applied when AML checks are disabled.
balances.trxRaw
string
Factory TRX balance in sun.
balances.assetRaw
string
Payment asset balance.
balances.tmrRaw
string
Factory TMR balance.
balances.usdtRaw
string
Factory USDT balance.
balances.convertibleUsdtRaw
string
The portion of the USDT balance available for automatic conversion after the retained amount.
contracts.nativeTrxTokenAddress
string
Service address representing native TRX.
statistics
object
Service statistics; omitted when includeStatistics is false.
All monetary values ending in Raw are returned as strings in the asset's smallest units. This prevents JavaScript precision loss.
Factory profile
The profile is stored in the Merchant API and is not an on-chain contract setting. set() updates only the supplied fields and does not change the webhook.
Node.js
const profile = await factory.profile.get();
const updated = await factory.profile.set({
displayName: "My shop",
description: "Primary payment factory",
invoicePrefix: "SHOP",
notificationContact: "admin@example.com",
paymentRecipientName: "Example LLC"
});
// Set the logo displayed on the public invoice page.
await factory.profile.setPaymentLogo("./logo.png");
// Remove the logo from the public invoice page.
await factory.profile.removePaymentLogo();
In SDK v0.4.3, update the recipient through profile.set() and manage the logo through setPaymentLogo() and removePaymentLogo(). The SDK reads the file internally; PNG, JPEG and WebP files up to 5 MB are supported.
Invoice-page recipient
Pass only paymentRecipientName, up to 60 characters, to change the displayed recipient while keeping every other profile field unchanged. An empty string removes the recipient name.
setPaymentLogo() accepts a local file path. The SDK reads the file through fs.promises.readFile(), detects its MIME type from the extension and signs the exact image bytes. A relative path is resolved from the current Node.js working directory.
Administrator contact used for service communication.
paymentRecipientName
string
Recipient name displayed on the public invoice page; updated through profile.set().
paymentLogoUrl
string
URL of the configured invoice-page logo; this field is read-only.
createdAt
string
Record creation time in ISO 8601 format.
updatedAt
string
Last update time in ISO 8601 format.
Webhook configuration
A webhook informs the merchant server about events without continuous Merchant API polling. The configuration is replaced as a whole, so every set() call must include enabled, url, and the complete events list.
Node.js
const webhook = await factory.webhook.set({
enabled: true,
url: "https://shop.example/tmr/webhook",
events: ["invoice.created", "payment.detected"]
}, {
idempotencyKey: "webhook-my-shop-v1"
});
console.log(webhook.secret); // Available only when new credentials are issued
console.log(await factory.webhook.get());
console.log(await factory.webhook.test());
The webhookOptions parameter
Property
Type
Description
idempotencyKey
string
Stable key used to retry a configuration change safely.
timeoutMs
number
Per-request timeout for the Merchant API HTTP request.
FactoryWebhook fields
Property
Type
Description
enabled
boolean
Whether delivery of the selected events is enabled.
url
string
HTTPS endpoint of the merchant server.
events
string[]
Complete list of events subscribed to by the factory.
keyId
string
Public identifier of the webhook signing key.
secret
string?
Returned once on first enable or re-enable after disabling.
test() calls only the saved endpoint and requires an enabled configuration. Tests are rate limited to one per factory every 30 seconds, up to 10 per API key and 30 per source IP per minute.
history() returns the combined statement shown in the dashboard: invoice payouts, TMR funding, fees and TMR withdrawals. Totals cover the complete selected period regardless of the current page size.
All operations, payouts only or TMR movements only.
search
string
Search by invoice, payout address or txId; up to 180 characters.
limit
number
From 1 to 100 records; 50 by default.
cursor
string
nextCursor returned by the previous page.
FactoryHistory response
Property
Type
Description
history
FactoryHistoryItem[]
Operations ordered newest first.
summary.payoutRaw
string
Total payment-asset payouts during the period.
summary.tmrCreditRaw
string
Total TMR funding during the period.
summary.tmrDebitRaw
string
Total TMR spending during the period.
period
string
Applied statement period.
operationType
string
Applied operation type.
nextCursor
string
Cursor for the next page, or an empty string.
hasMore
boolean
Whether another page is available.
FactoryHistoryItem fields
Property
Type
Description
id / createdAt
string
Record cursor and operation time in ISO 8601 format.
operation
string
activation_payout, additional_payout, tmr_topup, tmr_fee or tmr_withdrawal.
invoiceDbId / invoiceId / invoiceAddress
string
Related invoice; empty strings for operations without an invoice.
payoutAddress / payoutAmountRaw
string
Payout recipient and amount in the payment asset.
tmrAmountRaw / tmrDirection
string
TMR amount and in/out direction.
txId / callId
string
Network transaction and call identifiers.
The method calls GET /api/v1/factories/{factoryAddress}/history and requires the View factory permission.
Factory wallet
A factory can hold TRX, TRC20 tokens, TMR and an operational USDT reserve. The wallet methods let the owner transfer TRX and TRC20, manually convert USDT to TMR, withdraw TMR back to USDT and read movements for a selected asset.
Transfers TRX from the factory address; the amount is specified in sun.
history(historyOptions, apiOptions?)
API
FactoryWalletHistory
Returns indexed movements for one selected asset with cursor pagination.
Balance methods use only the selected TRON node. They do not submit a transaction, require a signer or use the Merchant API. A token contract address is required for TRC20.
All amounts are positive integers in the asset's smallest units. The SDK validates their format but preserves network errors caused by insufficient balance, resources or a rejected transaction.
Manual convertUsdtToTmr() is independent of the automatic funding toggle. The SDK does not precheck the setting or balance; the smart contracts validate current state during execution.
The historyOptions parameter
Property
Type
Required
Description
standard
"TRX" | "TRC20" | "TRC10"
Yes
Asset standard whose history should be returned.
assetAddress
string
For TRC20
TRC20 token contract address.
tokenId
string
No
TRC10 identifier; TMR defaults to 1005181.
limit
number
No
From 1 to 100 records; 30 by default.
cursor
string
No
nextCursor from the previous response, used to load the next page.
Normalized standard, assetAddress and tokenId filter.
nextCursor
string
Cursor for the next page, or an empty string.
hasMore
boolean
Whether another page is available.
FactoryWalletMovement fields
Property
Type
Description
id
string
Cursor identifier of the record.
createdAt
string
Time the movement was detected, in ISO 8601 format.
eventType
string
Network event type that produced the record.
direction
string
Movement direction: inbound, outbound, fee or conversion.
amountRaw
string
Amount in the asset's smallest units.
assetStandard
string
TRX, TRC20 or TRC10.
assetAddress
string
TRC20 contract address or an empty string.
tokenId
string
TRC10 identifier or an empty string.
invoiceId
string
Related invoice when the movement belongs to an invoice.
invoiceAddress
string
Related invoice address or an empty string.
counterpartyAddress
string
Address of the other side of the movement.
payload
object
Additional indexed event data.
history() calls GET /api/v1/factories/{factoryAddress}/wallet/history and requires the View factory permission for the selected factory.
Smart contract interfaces
The SDK does not expose the universal executor as a standalone method. It builds only the supported TRX transfer or transfer() call for the selected TRC20 token.
Solidity
interface IMainFactoryWallet {
function convertFactoryUsdtToTmr(uint32 factoryId, uint256 amount) external;
function convertFactoryTmrToUsdt(uint32 factoryId, uint256 amount) external;
}
interface IMerchantFactoryWallet {
function executor(bytes calldata data) external;
}
interface ITrc20Transfer {
function transfer(address recipient, uint256 amount) external returns (bool);
}
Changing on-chain settings
These methods change the MerchantFactory smart contract state directly on the TRON network. Merchant API is not involved: TronWeb builds the transaction, and only the wallet that owns the selected factory can authorize it.
Sets the USDT amount that is excluded from automatic conversion.
setAmlEnabled(enabled, transactionOptions?)
bool
txId
Enables or disables AML checks for new invoices created by the factory.
valueRaw parameters are whole numbers in the asset's smallest units. Use a string for large values to prevent JavaScript precision loss.
Smart contract interface
Only the public interface of the available operations is shown below, without implementation source code.
Solidity
interface IMerchantFactorySettings {
function setApprovedMaxFee(uint32 newApprovedMaxFee) external;
function setPayoutAddress(address newPayoutAddress) external;
function setMinimumInvoiceBalance(uint256 newMinimumInvoiceBalance) external;
function setAutoConvertUsdtToTmrEnabled(bool enabled) external;
function setAutoConvertUsdtRetainAmount(uint256 value) external;
function setAmlEnabled(bool enabled) external;
}
The Solidity functions return no value. In JavaScript, txId is the result of submitting the transaction through TronWeb and can be used to check its network confirmation.
The transactionOptions parameter
Property
Type
Description
feeLimit
number
Maximum transaction execution cost in sun.
permissionId
number
Active TRON account permission identifier when permission management is used.
shouldPollResponse
boolean
Wait for execution result instead of returning txId immediately.
pollTimes
number
Number of result polling attempts when waiting is enabled.
rawResponse
boolean
Return the complete TronWeb response.
keepTxID
boolean
Preserve the transaction identifier in an extended TronWeb response.
Realtime events
A subscription receives events from the factory and its invoices without continuously polling the API. The SDK uses one Socket.IO connection per TmrMerchant instance even when several factories are selected.
Node.js
const unsubscribe = factory.on("payment.detected", (event) => {
console.log(event.data.invoiceAddress, event.data.amountRaw);
});
factory.once("invoice.published", (event) => {
console.log("Invoice activated:", event.data.invoiceAddress);
}, {
invoiceAddress,
timeoutMs: 300_000
});
// When the persistent subscription is no longer needed
unsubscribe();
Managing subscriptions
Method
Result
Description
on()
function
Calls the handler for every matching event. The returned function cancels this specific subscription.
once()
function
Waits for the first matching event and then removes the handler automatically.
off()
boolean
Returns true when at least one handler was removed.
tmr.close()
void
Closes the Socket.IO connection and removes every active subscription owned by this SDK instance.
The realtimeOptions parameter
Property
Type
Description
invoiceAddress
string
Passes only events belonging to the specified invoice address to the handler.
timeoutMs
number
For once(), stops waiting after this duration without calling the handler.
Supported events
Event
Description
factory.settings.changed
An on-chain factory setting change was confirmed.
factory.profile.changed
The descriptive factory profile changed.
factory.webhook.changed
The webhook configuration was replaced.
factory.asset.received
TRX, TRC20 or TMR from the normal conversion flow was received by the factory address. data contains the asset, raw amount, sender and transaction identifiers.
factory.balance.low
The factory does not have enough TMR to process an invoice normally.
factory.operation.failed
A background factory operation failed.
invoice.created
An invoice was created and accepted for monitoring.
payment.detected
A confirmed invoice payment was detected.
aml.pending / aml.approved / aml.rejected
The AML check state changed.
manual_review.required
An invoice requires a decision from the factory owner.
invoice.published
The invoice address was activated as a smart contract.
settlement.sent
A normal settlement was sent to the recipient.
invoice.expired
An unpaid invoice reached its expiry time.
invoice.failed
Background invoice processing was paused by an error.
invoice.*
All invoice events for the selected factory.
*
Every accessible event from the factory and its invoices.
The SDK obtains a short-lived realtime token through a signed HTTP request. Factory events require factories:read and invoice events require invoices:read. Webhook settings do not affect realtime subscriptions.
Common errors
Code
Description
FACTORY_ADDRESS_REQUIRED
No factory address was provided for the operation.
INVALID_FACTORY_ADDRESS
The supplied value is not a valid TRON address.
FACTORY_NOT_FOUND
The factory does not exist or is not available to the API key.
FACTORY_NODE_READ_FAILED
The selected TRON node could not read the contract.
MAIN_FACTORY_MISMATCH
The factory belongs to a different main contract.
API_SCOPE_REQUIRED
The API key lacks the scope required by the selected method.
INVALID_* / ZERO_PAYOUT_ADDRESS
The SDK rejected a setting value before building a transaction.
INVALID_*_AMOUNT / INVALID_*_ADDRESS
The SDK rejected an amount, token address or recipient before building a transaction.
FACTORY_WALLET_CONTEXT_FAILED
The factory, its owner and the MainFactory registry entry could not be reconciled.
FACTORY_BALANCE_READ_FAILED
The selected TRON node could not read the factory balance.
FACTORY_TRANSACTION_FAILED
TronWeb could not sign, submit, or execute the transaction.
For each direction, the SDK provides a service-paid operation and a direct factory-owner transaction.
Two execution modes
ViaService methods sign an HTTP request with the API key while the service General sends the transaction. OnChain methods call MainFactory V3 through the configured TronWeb, so the factory owner signs the transaction and pays its resources.
Method
Mode
Result
Description
getTmrToUsdtServiceQuota(apiOptions?)
API
ConversionQuota
Returns the limit, usage and remaining service-paid TMR-to-USDT operations for the current UTC month.
tmrToUsdtViaService(amountRaw, options)
API
ServiceConversionResult
Converts factory TMR to USDT using service resources; three successful calls are available per month.
tmrToUsdtOnChain(amountRaw, transactionOptions?)
TronWeb
OnChainConversionResult
Sends a direct owner transaction without consuming the service quota.
usdtToTmrViaService(amountRaw, options)
API
ServiceConversionResult
Converts factory USDT to TMR using service resources; the number of calls is currently unlimited.
usdtToTmrOnChain(amountRaw, transactionOptions?)
TronWeb
OnChainConversionResult
Sends a direct owner transaction to convert USDT to TMR.
amountRaw is an integer string in the asset's smallest units and must fit uint88. idempotencyKey is required: retrying an identical successful request returns the stored result and does not create another transaction.
Direct methods accept a positive uint256 and do not call the Merchant API. They use the signer and transactionOptions of the configured TronWeb. An API key cannot replace the wallet signature.
Results and retries
A service response contains operationId, executionMode, direction, factoryId, factoryAddress, amountRaw and result; TMR-to-USDT also contains quota. A direct response contains executionMode, direction, amountRaw, txId and the original TronWeb result.
One idempotencyKey cannot be reused for another amount, factory or direction. If the first attempt is recorded as failed, use a new operation key after correcting the cause.
Main errors
Code
Description
API_SCOPE_REQUIRED
The key does not allow the selected direction.
INVALID_IDEMPOTENCY_KEY
The service operation has no valid idempotencyKey.
IDEMPOTENCY_KEY_REUSED
The key is already associated with a different operation.
IDEMPOTENT_OPERATION_IN_PROGRESS / FAILED
The first request is still running or previously failed.
FREE_WITHDRAW_LIMIT_EXCEEDED
The monthly service-paid TMR-to-USDT quota is exhausted.
The factory context manages the invoice collection, while an individual invoice context combines its state, activation, wallet and events.
Two levels of operation
factory.invoice methods work with the selected factory's invoice collection. at(idOrAddress) creates a local object for one invoice without a network request. An integration can first find or create an invoice and then work only with its context.
Permanently reserves the next sequence for five minutes and calculates its future address locally.
factory.invoice.create(params, createOptions?)
Local + API + TronWeb
InvoiceData
Creates an invoice, verifies its address through the selected TRON node and returns a plain data object.
factory.invoice.list(filters?, apiOptions?)
API
InvoicePage
Returns a page of invoices with search, filtering and sorting.
factory.invoice.at(idOrAddress)
Local
InvoiceResource
Creates one invoice context from its internal id or complete TRON address.
The filters parameter
Property
Type
Description
page / pageSize
number
Page number and size from 1 to 100; the default size is 25.
search
string
Searches the number, address, purpose and external identifier.
externalId / status
string
An exact external identifier or invoice status.
requiresAttention
boolean
Keeps invoices requiring a manual owner decision.
sort / direction
string
Sort by created, updated, expires, amount, status or number in asc or desc direction.
One invoice context
The internal identifier is stored in invoice.invoiceDbId, the address in invoice.invoiceAddress and the on-chain number in invoice.chainInvoiceId. When selected by id, the address and on-chain number are remembered after the first get() or state() call.
Method
Source
Result
Description
invoice.get(apiOptions?)
API
InvoiceData
Returns the main invoice data and active warnings.
invoice.state(apiOptions?)
API
InvoiceState
Returns the invoice, payments, timeline, AML checks and detected assets in one request.
invoice.payments.list(apiOptions?)
API
Payment[]
Returns incoming and outgoing invoice movements.
invoice.timeline.list(apiOptions?)
API
TimelineEvent[]
Returns the ordered processing timeline.
invoice.warnings.list(apiOptions?)
API
Warning[]
Returns only active warnings.
invoice.aml.get(apiOptions?)
API
AmlCheck[]
Returns completed invoice AML checks.
invoice.paymentLink.get(apiOptions?)
API
PaymentLink
Returns the URL and token for the public payment page.
Activation and special payout plan
Normal processing can be requested through the Merchant API, automatic activation can be paused or resumed, and a manual AML check can be requested. A special payout plan is fixed by a separate factory owner transaction.
After activation, the address remains a complete invoice wallet. The factory owner can read balances and transfer TRX or TRC20. Sending funds is only available after activation and requires a real factory owner transaction.
Method
Source
Result
Description
invoice.wallet.assets(apiOptions?)
API
WalletAsset[]
Returns assets detected by the monitoring service.
invoice.wallet.getTrxBalance()
TronWeb
string
Reads the current TRX balance in sun from the selected node.
invoice.wallet.getTrc20Balance(tokenAddress)
TronWeb
string
Reads the current raw balance of the selected TRC20 token.
invoice.wallet.transferTrc20(token, to, amountRaw, transactionOptions?)
TronWeb
txId
Calls transfer on a selected TRC20 token from the invoice wallet.
✓
Arbitrary calls are not exposed.The SDK only exposes TRX and TRC20 transfers. The public invoice context has no approve, TRC10 or arbitrary code execution methods.
on receives every matching event, once receives only the first, and off removes handlers. The * wildcard inside an invoice context means only events for that invoice. If the context was created from an internal id, call get() or state() before subscribing so the SDK learns its address.
Available events are invoice.created, payment.detected, aml.pending, aml.approved, aml.rejected, manual_review.required, invoice.published, settlement.sent, invoice.expired and invoice.failed.
Access and signing
Operation
Permission
Description
Reading and events
invoices:read
A request signed by the API key; no TRON transaction is created.
Reservation and creation
invoices:create
The address is calculated locally and checked again by the service.
Normal processing
invoices:activate:standard
Process, pause, resume and manual AML checks through the Merchant API.
Plan and transfers
Owner signature
TronWeb signs a real network transaction. The SDK does not read or inspect the private key.
INDEPENDENT CONTROL
What happens to invoices if the service is unavailable
Funds held by factories and invoices remain under the merchant's full control. An unavailable dashboard, API or monitoring service does not transfer control to Merchant Receipt or block direct contract access.
The merchant retains full control
Merchant Receipt does not store invoice private keys and has no access to merchant funds. Management operations are approved by the factory owner's wallet, while execution rules are enforced by smart contracts.
What changes when the service stops
Service automation pauses temporarilyMonitoring new deposits, notifications, API, webhooks, automatic checks and invoice activation funded by the service wait for recovery.
Owner control remains availableFunds, on-chain factory settings, manual activation and permitted activated-invoice wallet operations remain available to the owner.
During normal operation Merchant Receipt monitors incoming funds and, once the conditions are met, activates an invoice using the service's network resources. If the service becomes unavailable, this automation waits for recovery. Funds are not transferred to the service and do not become accessible to it: the merchant can perform the required actions independently.
Rescue Merchant
rescue-merchant.trc20.moneyis a separate static page for direct factory and invoice management. It does not call the Merchant Receipt backend and reads state directly from the TRON network.
Factory settings, factory wallet and invoice search using on-chain data.
✓
Independent from the service backendThe selected TRON node is used to read state and prepare operations.
✓
A custom node can be selectedConnection settings accept any compatible FullNode API.
✓
The merchant retains signing controlTronLink displays every transaction before submission. The private key never leaves the wallet.
✓
Invoice data is cross-checkedSearch uses the on-chain Invoice ID and the required invoice address to prevent selecting the wrong invoice.
Available actions
Object
Available operations
Factory
Inspect and update on-chain settings, payout recipient and processing parameters.
Factory wallet
Inspect balances and send TRX, TMR and supported TRC20 tokens.
Inactive invoice
Choose a payout plan, confirm that it was recorded on-chain and then activate the invoice directly.
Activated invoice
Inspect balances and perform wallet operations permitted to the owner.
Merchant procedure
1
Check the TRON networkMake sure the selected node responds and TronLink is connected to the factory owner's address.
2
Open Rescue MerchantSelect the factory or open a link containing the previously supplied parameters.
3
Verify on-chain dataCheck the factory, Invoice ID, invoice address, working asset and current balances.
4
Approve only the required operationReview the parameters and estimated network costs in the confirmation dialog.
5
Verify the new stateAfter submission read the data again through the node and retain the txID in the incident log.
Direct access through TronWeb
Rescue Merchant is a convenient interface, but it is not the only access path. A merchant's technical team can read and call public contract methods directly through TronWeb and any compatible node.
An independent static interface for direct interaction with Merchant Receipt factories and invoices through the TRON network, without the dashboard, API or server-side monitoring.
Rescue Merchant reads data through the selected TRON node and prepares contract calls. Every transaction is approved separately by the factory owner's wallet.
What Rescue Merchant is for
Use the page when the main Merchant Receipt interface or server is temporarily unavailable and the merchant needs to inspect contract state or perform an operation authorized for the owner.
✓
Factory managementInspect and update on-chain settings, payout recipient and processing parameters.
✓
Factory walletInspect balances and send TRX, TMR and supported TRC20 tokens.
✓
Invoice search and activationCross-check the Invoice ID and address, select a plan and activate the invoice manually in sequence.
✓
Invoice walletInspect assets and perform owner-authorized operations after contract activation.
How independence is provided
1Browser and TronLinkThe interface loads as static files, while signing takes place in the merchant's wallet.
→
2Selected TRON nodeThe page reads state and prepares transactions through TronGrid or a compatible FullNode API.
→
3Smart contractsFactories and invoices enforce only the rules and authorities recorded directly on-chain.
Page interface
The factory list, on-chain settings, factory wallet and invoice search are available in one workspace.
Network connection
Default node
The public TronGrid endpoint configured in the application can be used for network reads.
Custom node
Connection settings accept the URL of any compatible FullNode API and route all requests through it.
Owner wallet
Once connected, Rescue Merchant shows only factories registered to the active address.
Preflight verification
Before each transaction the interface verifies the network, contract, owner and operation parameters.
Working with an invoice
1
Enter the identifier and addressAn on-chain Invoice ID or a UI number can be used, but the invoice address is always required for cross-checking.
2
Verify the resultCheck the on-chain Invoice ID, address, working asset, balance and activation state.
3
Choose an authorized actionActivation plans are available for an inactive invoice; wallet operations are available after activation.
4
Sign the transactionTronLink displays the actual contract call and network costs before submission.
Opening a protected link
The merchant can provide an operator with a deep link containing the factory, on-chain Invoice ID and expected invoice address.
A technical fallback path for reading state and performing owner-authorized operations directly through public contract interfaces.
Merchant code must not receive a private key
Any compatible TRON node can be used for reads. State-changing calls are signed by the connected factory owner wallet, and the contract address, network and parameters must be verified before submission.
Before you begin
MainFactory
TA8yRJ7bghwmMupPikN4xFYQhRqYVTVFssPermanent main registry for locating merchant factories and manually exchanging USDT and TMR.
MerchantFactory
The merchant's personal factory addressObtain the address from MainFactory and always verify its owner and factoryId.
EmergencyExecutor
TZAehzArybCEoQNQp1SUdZsggZWwJSx6kBPermanent contract for authorized operations with an activated invoice wallet.
Factory owner
The active TronLink address must match merchantOwner read from the network.
Raw values
Pass Invoice IDs and amounts as integer strings. For USDT and TMR, 1,000,000 represents one token.
Connection and context verification
A function signature, parameter types and contract address are sufficient for reads and submissions. No external interface file is required.
JavaScript · TronWeb
const readWeb = new TronWeb({ fullHost: nodeUrl });
const signer = window.tronWeb;
if (!signer?.ready) throw new Error("Connect TronLink");
const owner = signer.defaultAddress.base58;
async function constantCall(contract, selector, parameters = []) {
const response = await readWeb.transactionBuilder
.triggerConstantContract(contract, selector, {}, parameters, owner);
if (!response.result?.result) {
throw new Error(response.result?.message || "Constant call rejected");
}
return response.constant_result?.[0] || "";
}
async function sendCall(contract, selector, parameters, feeLimit) {
const prepared = await signer.transactionBuilder
.triggerSmartContract(contract, selector, { feeLimit }, parameters, owner);
if (!prepared.result?.result) {
throw new Error(prepared.result?.message || "Simulation rejected");
}
const signed = await signer.trx.sign(prepared.transaction);
return signer.trx.sendRawTransaction(signed);
}
Reading the factory and invoice
Read the network state first and calculate the expected invoice address independently. An address supplied by a user or deep link is used only for comparison.
JavaScript · read
const invoiceId = "10217324555";
const predictedWord = await constantCall(
factoryAddress,
"predictInvoice(uint40)",
[{ type: "uint40", value: invoiceId }]
);
const predictedAddress = readWeb.address.fromHex(
"41" + predictedWord.slice(-40)
);
if (normalize(predictedAddress) !== normalize(expectedInvoiceAddress)) {
throw new Error("Invoice ID does not match the expected address");
}
const payoutPlanHex = await constantCall(
factoryAddress,
"getInvoicePayoutPlan(address)",
[{ type: "address", value: expectedInvoiceAddress }]
);
Standard invoice activation
The primary workflow does not require a preliminary plan. First verify the calculated address, factory activity, payout address, minimum invoice balance and available TMR for the fee.
1
Verify the invoiceObtain the address through predictInvoice(uint40) and compare it with the expected address.
2
Check standard conditionsThe factory is active, a payout address is set, the plan is in default mode, the TMR fee is covered and the invoice balance meets the configured minimum.
3
Run a simulationCheck deployInvoice(uint40) through triggerConstantContract and stop if it is rejected.
4
Sign the activationPrepare a separate deployInvoice(uint40) transaction and verify the contract and Invoice ID in TronLink.
A different recipient, distribution or keeping funds on the invoice is represented by a separate plan. Save the plan first, wait until it appears in factory state, and only then prepare activation.
1
Build the planSpecify the mode, three-entry recipient and amount arrays, the number of used entries, and false for the activation request.
2
Save it in the first transactionCall setInvoicePayoutPlanById and sign only the plan-setting operation.
3
Wait for network statePoll getInvoicePayoutPlan(address) for up to 30 seconds and compare the complete plan with the expected values.
4
Activate in the second transactionOnly after the complete plan matches should deployInvoice(uint40) be simulated and submitted.
Checks before signing
✓
Network and contractsVerify mainnet, the fixed MainFactory and EmergencyExecutor addresses, and MerchantFactory registration.
✓
Owner authorityThe connected address must match merchantOwner for the selected factory.
✓
Call parametersVerify types, raw amounts, recipient addresses, the Invoice ID and the expected invoice address.
✓
Simulation resultDo not sign if the node rejects the call or returns an unexplained error.
Independent management functions
The methods below cover reads and operations available to the factory owner. Service-only administrative methods are intentionally omitted.
MainFactory (TA8yRJ7bghwmMupPikN4xFYQhRqYVTVFss): factory lookup and exchange
Function
Access
Parameters
Result
nativeTrxToken()
Read
No parameters.
Adapter address used to read native TRX balances.
usdtAccounting()
Read
No parameters.
USDT balance, TMR held by MainFactory, reserved USDT and available USDT.
getFactory(uint32)
Read
factoryIdis the on-chain identifier of a personal factory.
Owner, factory address, service proxy, fee and active state.
getFactoryFeeSchedule(uint32)
Read
factoryIdis the factory identifier.
Current and pending fees, AML discount and the activation block for new terms.
getFactoryByAddress(address)
Read
factoryAddressis the Base58 address of the personal factory.
factoryIdand the factory registration record.
getMerchantFactoryCount(address)
Read
merchantOwneris the merchant wallet address.
Number of factories registered to the owner.
getMerchantFactoryByIndex(address,uint32)
Read
merchantOwneris the owner;indexranges from 0 to count − 1.
factoryId, factory address, service proxy, fee and active state.
convertFactoryUsdtToTmr(uint32,uint256)
Owner
factoryId; amountis a positive USDT value in raw units.
Exchanges the specified personal-factory USDT amount for TMR.
convertFactoryTmrToUsdt(uint32,uint256)
Owner
factoryId; amountis a positive TMR value in raw units.
Exchanges personal-factory TMR for USDT.
MerchantFactory (the merchant's personal factory address): state and settings
Function
Access
Parameters
Result
merchantFactoryInfo()
Read
No parameters.
Core addresses, settings, balances, fees and factory state.
feeSchedule()
Read
No parameters.
Current and pending fee, AML discount and the terms activation block.
convertibleUsdtBalance()
Read
No parameters.
USDT in raw units available for exchange after subtracting the retained amount.
invoiceConfig()
Read
No parameters.
Working asset, payout address, minimum balance and current invoice payout parameters.
setApprovedMaxFee(uint32)
Owner
newApprovedMaxFeeis the maximum accepted TMR fee in raw units.
Changes the fee limit approved by the merchant.
setPayoutAddress(address)
Owner
newPayoutAddressis the new Base58 payout address.
Changes the standard recipient used during invoice activation.
setMinimumInvoiceBalance(uint256)
Owner
newMinimumInvoiceBalanceis the minimum invoice balance in raw units.
Sets the standard activation threshold.
setAutoConvertUsdtToTmrEnabled(bool)
Owner
enabled— true enables and false disables the feature.
Controls automatic exchange of factory USDT for TMR.
setAutoConvertUsdtRetainAmount(uint256)
Owner
newAmountis the USDT amount retained by the factory in raw units.
Changes the amount excluded from automatic exchange.
setAmlEnabled(bool)
Owner
enabledis the check state for future activations.
Enables or disables the check subject to current fee terms.
flagsis a bit sum:1 max fee, 2 payout address, 4 minimum balance, 8 auto-convert, 16 AML, 32 retain amount. Then pass, in order:newApprovedMaxFee, newPayoutAddress, newMinimumInvoiceBalance, newAutoConvertUsdtToTmrEnabled, newAmlEnabled, newAutoConvertUsdtRetainAmount. Fields without a set bit are ignored but must still have valid ABI types.
Applies selected settings atomically in one transaction.flags=63applies all six settings.
executor(bytes)
Owner
data: 20 bytes oftarget + 32 bytes of TRX amount in sun + calldata. For TRC20, target is the token, TRX amount is 0 and calldata is transfer(address,uint256).
Sends TRX directly or calls a supported TRC20 from the factory.
MerchantFactory (the merchant's personal factory address): invoices
Function
Access
Parameters
Result
predictInvoice(uint40)
Read
invoiceIdis the complete on-chain Invoice ID from 1 to 2⁴⁰ − 1.
Deterministically calculates the invoice address before deployment.
getInvoiceException(address)
Read
invoiceis the calculated Base58 invoice address.
Special recipient; the zero address means standard payout.
invoiceId; mode: 0standard, 1another recipient, 2keep on invoice, 3split; activateRequested=falsefor the manual sequence;recipientsandamountsare three-entry arrays;count — 0…3. Unused entries must be zero.
Stores the special plan. Mode 1 requires one recipient and a zero amount; mode 3 requires 1–3 nonzero recipients and amounts.
deployInvoice(uint40)
Public call
invoiceIdis the complete on-chain ID of the located and pre-verified invoice.
Deploys the invoice, applies the current plan and charges the effective TMR fee to the factory.
EmergencyExecutor (TZAehzArybCEoQNQp1SUdZsggZWwJSx6kB) and asset reads
Function
Access
Parameters
Result
mainFactory()
Read
No parameters.
Must return the fixed MainFactory address, verifying the executor's link to the main registry.
execute(uint32,uint40,address,bytes)
Owner
factoryIdis the factory ID;invoiceIdis the on-chain ID;expectedInvoiceis the expected address;invoiceFallbackDatais 20 bytes of target + 32 bytes of TRX amount in sun + calldata. For TRC20, target is the token and TRX amount is 0.
Rechecks the owner and calculated address, then performs the operation from the activated invoice wallet.
balanceOf(address)
Read
accountis a factory or invoice; call this on a TRC20 address or nativeTrxToken().
Asset balance in raw units. TRX is returned in sun.
decimals()
Read
No parameters; call this on the token address.
Decimal count used to convert a raw balance into a display value.
symbol()
Read
No parameters; call this on the token address.
Short asset symbol used for verification before sending.
Wallet operations
Source
Method
Purpose
Factory wallet
executor(bytes)
Direct TRX transfer or transfer(address,uint256) call on a supported TRC20 token.
Invoice wallet
execute(uint32,uint40,address,bytes)
EmergencyExecutor rechecks the owner, factory and calculated address of the activated invoice.
TMR exchange
convertFactoryTmrToUsdt(uint32,uint256)
The selected factory owner exchanges a raw TMR amount for USDT through MainFactory.
Errors and operation completion
Simulation rejected
Do not sign the transaction. Reread factory and invoice state and check the minimum balance, plan, fee and owner authority.
Broadcast rejected
Keep the node response, but do not automatically sign again. First verify that the original transaction was not accepted.
State confirmation
After submission, reread the contract through the selected node and retain the txID. For a plan, compare every field.
Short checklist
✓
Addresses, owner, network and parameters came from a verified source and were checked again on-chain.Every state-changing operation is simulated, approved separately by the owner and completed by reading the new state.
SECURITY
Recommendations
Merchant Receipt reduces the number of secrets and trusted parties, but secure integration also depends on how the merchant obtains invoice addresses, stores keys and verifies operations.
The service does not store private keys for payment addresses
An invoice address is created deterministically and has no private key either before or after activation. Once activated, it becomes a smart-contract wallet whose actions are restricted by contract rules and the factory owner's authority.
Merchant Receipt approach
✓
No custody of fund keysThe server monitors state and coordinates processing, but it does not store a key capable of signing a transfer from an invoice.
✓
Rules are enforced by contractsThe recipient, working asset, fee and authority cannot be arbitrarily replaced by changing a server record.
✓
API key is separate from the walletA tmrsk_v1 key signs Merchant API requests and cannot sign TRON transactions by itself.
✓
Results can be verified independentlyA merchant can calculate addresses in its own code and verify them through a selected TRON node without trusting the dashboard.
Obtaining an invoice address securely
For production integration, calculate addresses on your own server with the Node.js SDK or a compatible independent implementation. The address shown to a customer should come from the merchant's calculation, not from a dashboard response or an arbitrary string supplied by an external service.
1
A sequence is reservedMerchant API allocates an invoice number and returns the version of a known contract template.
2
The address is calculated locallyThe SDK performs the mathematical calculation inside the process running on the merchant server. The selected address has not yet been submitted to Merchant Receipt or placed under monitoring.
3
The calculation is verified through TRONThe SDK compares its local result with predictInvoice on the selected factory through a node trusted by the merchant.
4
The merchant registers the invoiceOnly after verification does the merchant submit the calculated address to the service, which then begins monitoring the payment.
✓
The merchant controls the payment address sourceEven if the dashboard has a problem, the customer address can be obtained and verified independently on the merchant backend. Merchant Receipt verifies the calculation again, but its server should not be the only source of truth.
What to verify
Template version
Compare the creation code hash from prepare with the known value in your SDK version. Do not accept an unfamiliar version automatically.
TRON node
Use TronGrid with your own key or your own Full Node for independent on-chain verification. Pin the expected network and factory address.
Order relationship
Store externalId, amount, asset, expiration, invoice address and factory identifier. Before displaying the address, make sure these values belong to the same order.
Events and statuses
Verify webhook signatures, process event.id idempotently and confirm critical state by reading the API or blockchain again.
Keys and access
API keyKeep tmrsk_v1 only in a backend secret store. Never place it in a frontend, mobile application, repository or log.
Owner wallet keyUse a hardware wallet where possible. If automation requires a signer, isolate it and never pass its private key as a Merchant API parameter.
Least privilegeCreate a separate key for each integration, select only required factories and scopes, and set an expiration and IP allowlist.
Revocation and replacementIf exposure is suspected, revoke the API key in the dashboard immediately and create a new one. A lost private part cannot be recovered.
Network transactions
Changing network settings, managing funds in a factory or activated invoice, and applying a special plan require a real TRON transaction. Before signing, the wallet should show the expected contract and action, while the application should verify the network, destination and call parameters.
When a problem is suspected
1
Stop issuing new invoicesPreserve addresses already issued and record the discovery time.
2
Revoke integration keysReplace API keys and webhook credentials that may have become available to another party.
3
Verify data independentlyCheck the factory, invoices and transactions through a trusted TRON node.
4
Preserve evidenceDo not delete logs, request IDs, event IDs, txIds or configuration snapshots until the investigation is complete.
Concise definitions, data formats, statuses, errors and public Merchant Receipt contract interfaces.
Core concepts
Factory
A merchant's personal smart contract that stores payment rules: the working asset, payout address, approved fee and invoice activation conditions. Each factory has one owner who confirms critical changes with their wallet.
Factory wallet
The factory address can also hold TRX, TRC20 and TMR. The owner can inspect balances and sign transfers of supported assets or conversions between TMR and USDT.
Invoice
A separately calculated address for one payment. No private key exists for this address either before or after activation. Before activation the contract has not yet been published; afterward the address becomes a smart-contract wallet.
Invoice activation
Publication of a known contract at the invoice address. In the standard flow, the contract immediately routes the received balance according to factory rules. A special plan can change the recipient, retain funds or split the amount.
Addresses, identifiers and amounts
Value
Format
Description
factoryAddress
Base58Check
The personal factory address, normally beginning with T. It defines the settings and address space of its invoices.
invoiceAddress
Base58Check
The calculated address of a specific invoice. It remains unchanged before and after contract publication.
tokenAddress
Base58Check
A TRC20 contract address. For native TRX, the system uses the address of a service adapter contract.
41...
hex
The network hex representation of the same TRON address: network byte 41 plus a 20-byte address. Use Base58Check in Merchant API unless a parameter explicitly requires hex.
id
integer
An internal Merchant API record identifier. It is neither an address nor a transaction number.
chainInvoiceId
uint40
An immutable on-chain invoice number within a factory, used to calculate its address.
txId
hex string
The identifier of a submitted TRON transaction.
amountRaw
decimal string
An amount in the smallest units without a decimal point. A string prevents JavaScript precision loss.
TMR asset
TMR, or Merchant Receipt, is the project's service TRC10 asset with token ID 1005181 and 6 decimal places. A factory spends TMR when publishing invoices, so a merchant can see the processing price and the maximum fee it has authorized in advance.
✓
Immutable USDT backingThe main factory contract permanently fixes the TRON USDT address and a one-to-one conversion in smallest units: 1 TMR corresponds to 1 USDT.
✓
USDT forms the reserveEvery unit of TMR outside the main factory has a corresponding reserved unit of USDT. The project owner can withdraw only USDT above the calculated reserve.
✓
Redemption belongs to the merchantA personal factory owner can convert its TMR back. TMR returns to the main factory and an equal USDT amount is sent directly to the owner's address.
✓
The reserve cannot be bypassedAdministrative withdrawal checks the available surplus, while the main factory's reserve call cannot target the USDT contract or a personal factory. These restrictions are enforced by the smart contract, not by a server promise.
Invoice statuses
Status
Description
created
The invoice record exists while initial monitoring setup is still finishing.
waiting_payment
The invoice is waiting for its first qualifying incoming payment.
partial_paid
Part of the expected amount was received; monitoring continues.
paid
The payment condition is met and the invoice is being prepared for activation.
overpaid
More than the expected amount was received; the next action depends on invoice rules.
awaiting_activation
A manual review or owner decision is required before activation.
fulfilled
The invoice contract was published and the selected processing plan completed.
activation_failed
An activation attempt did not complete; the reason is available in invoice state and timeline.
expired
The payment waiting period ended and ordinary monitoring stopped.
A status describes a processing stage; it does not replace checking balances and transactions. Use invoice state, payments and timeline together for financial decisions.
Error codes
Merchant API returns a machine-readable code in error. The SDK places it in TmrApiError.code, the HTTP status in status and supporting data in details. If no HTTP response was received, status is 0.
HTTP statuses
HTTP
Meaning
400
Invalid parameter format or value.
401
The request failed authentication or signature validation.
403
The key is recognized but lacks the required scope, factory or IP access.
404
A factory, invoice, key or reservation was not found in the accessible scope.
409
A state conflict, repeated nonce or incompatible idempotency-key reuse.
429
The request rate limit was exceeded.
500 / 503
An internal processing failure or temporary TRON provider outage.
Primary machine-readable codes
Code
Category
Description
INVALID_API_SIGNATURE API_REQUEST_REPLAYED
Authentication
The request signature is invalid or the nonce has already been used.
API_KEY_INACTIVE API_KEY_IP_DENIED
Access
The key expired or was revoked, or the request came from an unapproved IP.
API_SCOPE_REQUIRED API_FACTORY_ACCESS_DENIED
Access
The operation lacks the required permission or access to the selected factory.
FACTORY_NOT_FOUND FACTORY_NOT_READY
Factory
The factory is unavailable to this key or its on-chain conditions do not currently allow the action.
INVOICE_NOT_FOUND INVALID_INVOICE_IDENTIFIER
Invoice
The invoice was not found or the supplied id/address uses an unsupported format.
A factory transaction was not submitted or independent address verification through the selected node failed.
NativeTrxToken and native TRX
TRX has no TRC20 contract address, while an interface still needs consistent asset fields and balance reads. NativeTrxToken is a network adapter: it reports the name TRON, symbol TRX, 6 decimals and returns an address's native balance.
Solidity
interface INativeTrxToken {
// Returns the human-readable native asset name.
function name() external pure returns (string memory);
// Returns the native asset ticker.
function symbol() external pure returns (string memory);
// Returns TRX precision in decimal places.
function decimals() external pure returns (uint8);
// Reads the native TRX balance of an address in sun.
function balanceOf(address account) external view returns (uint256);
}
Public contract interfaces
These functions can be read or called through a compatible TRON node without the Merchant Receipt dashboard. State-changing functions create a transaction and must be signed by the address authorized by the contract.
Main factory: discovery and conversion
Solidity
interface IMainFactoryPublic {
// Returns the address used to represent native TRX.
function nativeTrxToken() external view returns (address);
// Returns USDT balance, TMR circulation reserve and withdrawable surplus.
function usdtAccounting() external view returns (
uint256 usdtBalance, uint256 tmrInMain, uint256 reservedUsdt, uint256 availableUsdt
);
// Creates an on-chain request for a personal merchant factory.
function requestMerchantFactory(uint32 fee, address token, bytes32 factorySalt)
external returns (uint40 requestId);
// Reads a factory publication request by its request ID.
function getFactoryRequest(uint40 requestId) external view returns (
address merchantOwner, uint32 fee, address token, bytes32 factorySalt, uint8 status
);
// Reads a registered personal factory by its numeric ID.
function getFactory(uint32 factoryId) external view returns (
address merchantOwner, address factory, address serviceProxy, uint32 fee, bool active
);
// Finds a registered factory record by its contract address.
function getFactoryByAddress(address factoryAddress) external view returns (
uint32 factoryId, address merchantOwner, address factory,
address serviceProxy, uint32 fee, bool active
);
// Returns the number of factories registered for an owner.
function getMerchantFactoryCount(address merchantOwner) external view returns (uint32);
// Reads one owner's factory by its position in the registry.
function getMerchantFactoryByIndex(address merchantOwner, uint32 index) external view returns (
uint32 factoryId, address factory, address serviceProxy, uint32 fee, bool active
);
// Exchanges a factory's USDT for the same raw amount of TMR.
function convertFactoryUsdtToTmr(uint32 factoryId, uint256 amount) external;
// Returns TMR and sends the same raw amount of USDT to the factory owner.
function convertFactoryTmrToUsdt(uint32 factoryId, uint256 amount) external;
}
The get... functions are available for reads. Converting funds belonging to a personal factory is restricted to that factory's registered owner. A new-factory request is only recorded on-chain and is not automatically accepted.
Personal factory: settings and invoices
Solidity
interface IMerchantFactoryPublic {
// Returns the factory's complete on-chain configuration and balances.
function merchantFactoryInfo() external view returns (
address mainFactory, address merchantOwner, uint32 fee, uint32 approvedMaxFee,
bool active, address token, address payoutAddress, uint256 minimumInvoiceBalance,
uint256 tmrBalance, uint256 usdtBalance, bool autoConvertUsdtToTmrEnabled,
bool amlEnabled, uint32 amlFee
);
// Returns the active and pending V3 fee and its activation block.
function feeSchedule() external view returns (
uint32 activeFee, uint32 activeAmlFee, uint32 pendingFee,
uint32 pendingAmlFee, uint64 activationBlock,
uint32 activeEffectiveFee, uint32 pendingEffectiveFee
);
// Returns the USDT balance available for automatic conversion.
function convertibleUsdtBalance() external view returns (uint256 amount);
// Sets the maximum invoice fee approved by the factory owner.
function setApprovedMaxFee(uint32 valueRaw) external;
// Changes the recipient of standard invoice payouts.
function setPayoutAddress(address payoutAddress) external;
// Sets the minimum balance required for standard activation.
function setMinimumInvoiceBalance(uint256 valueRaw) external;
// Enables or disables automatic USDT-to-TMR replenishment.
function setAutoConvertUsdtToTmrEnabled(bool enabled) external;
// Sets the USDT amount excluded from automatic conversion.
function setAutoConvertUsdtRetainAmount(uint256 valueRaw) external;
// Enables or disables AML processing for future invoices.
function setAmlEnabled(bool enabled) external;
// Calculates the deterministic address of a future invoice.
function predictInvoice(uint40 invoiceId) external view returns (address invoice);
// Publishes an invoice when the factory's conditions are satisfied.
function deployInvoice(uint40 invoiceId) external returns (address invoice);
// Reads the special recipient configured for an invoice.
function getInvoiceException(address invoice) external view returns (address);
// Reads the typed payout plan configured for an invoice.
function getInvoicePayoutPlan(address invoice) external view returns (
uint8 mode, bool activateRequested, uint8 count,
address[3] memory recipients, uint256[3] memory amounts
);
// Saves a payout plan and can request asynchronous invoice activation.
function setInvoicePayoutPlanById(
uint40 invoiceId, uint8 mode, bool activateRequested,
address[3] calldata recipients, uint256[3] calldata amounts, uint8 count
) external;
}
Reading information and predicting an address need no signature. Settings and special payout-plan changes are restricted to the factory owner. deployInvoice accepts any transaction sender, but publication succeeds only when the factory's enforced conditions are met.
Invoice wallet access proxy
After activation, an invoice remains a smart-contract wallet. The contract atTZAehzArybCEoQNQp1SUdZsggZWwJSx6kBacts as a verifying proxy: it locates the invoice through the immutable main/personal factory relationship, verifies the owner and only then forwards the selected operation to the invoice wallet.
✓
Factory owner onlyThe sender is compared with the owner recorded by the main factory. An API key or the Merchant Receipt server cannot replace this signature.
✓
Immutable relationshipThe main factory is bound to the proxy once, so the service cannot later replace the owner registry.
✓
Address is checked againThe proxy independently calculates the address from factoryId and invoiceId and can compare it with the expected invoice address.
User scenarios
Operation
Asset call
Description
TRX transfer
TRX transfer
The proxy instructs the activated invoice to send the specified number of sun to the recipient.
TRC20 transfer
transfer(to, amount)
The invoice calls the standard transfer function on the selected TRC20 contract.
TRC20 approval
approve(spender, amount)
The invoice can grant a specified contract a limited TRC20 allowance for a merchant's understood workflow.
Solidity
interface IInvoiceWalletExecutor {
// Executes a prepared operation after validating the factory owner and invoice address.
function execute(
uint32 factoryId,
uint40 invoiceId,
address expectedInvoice,
bytes calldata invoiceFallbackData
) external;
}
Parameter
Type
Description
factoryId
uint32
The on-chain identifier of the factory whose owner signs the operation.
invoiceId
uint40
The on-chain invoice number within the selected factory.
expectedInvoice
address
The expected invoice address used for an additional check before execution.
invoiceFallbackData
bytes
ABI-encoded data for the selected transfer or approval operation. The SDK can prepare it automatically.