Ir al contenido
CoinsSendDesarrolladores
Guías prácticas

Create reusable crypto deposit addresses for customers

Ver MarkdownConfigurar agente

Esta página aún no está disponible en tu idioma.

Use a reusable address when a customer needs to top up an account more than once, without opening a new fixed-price checkout for every deposit. CoinsSend static wallets provide a receiving address and deposit notifications; your application owns the mapping between that address, the customer, and the customer’s balance.

For a specific order with an amount and an expiry, use the invoice checkout recipe.

Before creating an address, choose whether your customer ledger is denominated in cryptocurrency or a fiat unit. A USDT amount and a USD amount are distinct fields even when their numerical values are close.

Keep these records in your application:

RecordPurpose
Customer ID + coin + networkIdentify whose top-up this address represents.
Returned address + QR URLDisplay the correct receiving details again on the next visit.
Deposit transaction IDDeduplicate notifications for one deposit.
Gross amount, net amount, fees, and currencyExplain the credit and reconcile it with the merchant balance.
Deposit and ledger statesSeparate an observed deposit from funds available for spending or withdrawal.

Choose a currently available pair using the public coin catalog. Show both the asset and the network to the customer.

Send this body from your server to POST /v1/wallet-address with the signed Merchant and Sign headers:

{
"network": "tron",
"coin": "usdt",
"type": "static",
"label": "Customer 1042 top-ups",
"webhook_url": "https://merchant.example/coinssend/deposits"
}

See Authentication for body serialization and signing. Complete signed examples are available in PHP, Node.js, and Python.

The response contains data.address and data.qr_code_url. Store them with your customer mapping before displaying them. The QR URL contains a wallet record ID, not the blockchain address.

label is a human-readable annotation, not a unique customer identifier enforced by CoinsSend. Multiple static addresses can exist for the same pair. Serve the address you already stored when the customer opens the top-up screen again.

Address creation has no request idempotency-key contract. If a create request times out, reconcile it through merchant tooling or support before retrying: another request can create another address.

3. Process deposits without crediting twice

Section titled “3. Process deposits without crediting twice”

The successful-deposit event is wallet.transaction. Verify X-Signature against the exact raw body before trusting its contents.

After verification:

  1. Match data.wallet.address, data.wallet.coin, and data.wallet.network to your stored customer mapping.
  2. Use data.transaction.id as a stable business identifier for the deposit.
  3. Store the signed gross, net, fee, and status fields.
  4. Insert the deposit and its ledger entry atomically, with a uniqueness constraint that prevents the same deposit from crediting the customer twice.
  5. Acknowledge a duplicate that has already been recorded successfully.

The signed payload supplies data.transaction.amounts.gross and data.transaction.amounts.net, each with fiat and crypto values. Base a net-credit policy on the appropriate signed net field; do not subtract fees from an already net amount.

The callback uses the address-specific webhook_url when provided, otherwise the merchant’s default callback. Handle aml.rejected.static_wallet as a separate rejection event rather than a successful credit. The webhook reference defines the exact schemas and delivery rules.

For type: "static", deposits incur the configured merchant and network fees, and the merchant’s credited funds have a 24-hour hold. Receipt of a deposit event is not a promise that those funds are immediately withdrawable.

Your customer spending policy must account for that hold. Do not display “available to withdraw” solely because a successful deposit webhook arrived. Use merchant balances to reconcile available funds and merchant fees for the current merchant-specific settings.

type: "merchant" has different crediting semantics and permits only one wallet per merchant and pair. It is not an interchangeable setting for customer-specific static addresses.

MistakeWhat to do instead
Creating an address every time the screen loadsPersist and reuse the customer’s address mapping.
Matching a deposit using the label aloneMatch the stored address and coin/network pair.
Crediting the amount on every callbackDeduplicate and update the ledger atomically.
Crediting USD as though it were the token amountUse the explicit currency and crypto fields.
Treating a deposit as immediately withdrawableModel the static-wallet hold and available balance separately.