Developer guide
VEXPay siteAPI reference
Browse documentation

Accept USDT and USDC

Take stablecoin payments on the hosted checkout or with a permanent deposit address per customer, and credit your customer once per payment.

What you will do

Buyers pay 1 USDT or 1 USDC per US dollar. The coin lands in your USDT or USDC balance (each is separate), net of your stablecoin fee, which you pay — the buyer sees no fee. Pick the hosted checkout for orders, or a deposit address for top-ups.

  • USDT (and USDC, separately) enabled on your account by VEXPay.
  • A webhook endpoint subscribed to payment.completed and payment.canceled.

Steps: hosted checkout

  1. Create a session

    POST /v1/checkout/sessions with amountUsd and methods containing usdt and/or usdc (or no methods to offer everything).

  2. The buyer picks coin and network

    The checkout shows the networks enabled for that coin. TON payments need the tag/memo shown.

  3. The buyer sends the coin

    A payment page shows the address and exact amount. The status page moves from started to network confirmation to completed; the buyer may close it.

  4. Fulfil from the webhook

    payment.completed carries currency, amount, fee, network, txHashes and your checkoutSession reference.

Steps: deposit address per customer

  1. List the networks

    GET /v1/crypto/networks?currency=USDT (or USDC) shows the networks enabled for you.

  2. Get the address

    POST /v1/crypto/deposit-addresses with customerRef (your customer id: 1–128 characters of letters, digits and _ . : @ -), network and optionally currency. Calling it again for the same customer, coin and network returns the same address.

  3. Show it to your customer

    Show the address, and the tag whenever tagRequired is true. The customer can send any amount, any time.

  4. Credit your customer

    Each deposit fires payment.completed with customerRef. Credit amount − fee once per paymentId.

curlbash
curl --request POST "${API_URL}/v1/crypto/deposit-addresses" \
  --header "content-type: application/json" \
  --header "x-api-key: ${VEXPAY_API_KEY}" \
  --data '{ "customerRef": "user_123", "network": "TRC20", "currency": "USDT" }'

Check that it worked

  • In Test, use the test buttons on the payment page to confirm, cancel or send short; each outcome sends its webhook with livemode: false.
  • A Test deposit address cannot receive a simulated deposit yet. Test your crediting code with the hosted checkout, which sends the same payment.completed.
  • GET /v1/crypto/balances shows the credit as held until nextReleaseAt on Live, then available.

If something goes wrong

SymptomLikely causeWhat to do
403 method_not_allowedUSDT or USDC not enabled on your accountAsk VEXPay to enable it.
400 unsupported_networkThat network is not enabled for that coinPick one from GET /v1/crypto/networks.
payment.completed with underpaid: trueThe buyer sent less than the amountWhat arrived is credited, net of the fee; the checkout is not marked paid. Settle the difference with the buyer.
TON deposit not matched to the customerTag/memo missingAlways show tag when tagRequired is true. Contact VEXPay support with the transaction hash.
payment.completed for more than the amountThe buyer sent too muchEverything that arrived is credited, net of the fee, and the checkout is marked paid. To give the extra back, ask the buyer for an address and send it with POST /v1/crypto/payouts (the payout fee applies). Never send it back to the address it came from: that is often an exchange that will not credit it.
A deposit arrived but no webhookA coin or network that is not enabled for youContact VEXPay support with the transaction hash.
502/503 processor_unavailableTemporary outageRetry later; other currencies still work at checkout.

Fees: Pricing. Getting coins out: Withdraw your balance. Related: USDT & USDC