Skip to main content

Payin Integration Guide

This guide explains how merchants create a Payin acquiring order, redirect the user to pay, handle order webhooks, and query the final result.

Payin is a three-step flow:

  1. Create the order: call POST /payment/acquiring/orders.
  2. Let the user pay: redirect the user to checkout_url, where the user selects a currency and network.
  3. Confirm the result: receive acquiring.order.updated webhooks and query order detail for fallback confirmation and reconciliation.

One-Page Summary

Minimum API set:

  1. POST /payment/acquiring/orders
  2. GET /payment/acquiring/orders/{order_id}

Supplementary APIs:

  1. GET /payment/acquiring/orders/{order_id}/payments: list payment records under the order
  2. POST /payment/acquiring/orders/{order_id}/close: close an unfinished order early

Minimum webhook:

  1. acquiring.order.updated: order status changed

To receive webhooks, pass a valid notify_webhook_id when creating the order. The webhook must be active and subscribed to acquiring.order.updated, acquiring.payment.updated, or acquiring.*.

Before Integration

Confirm these items before creating live orders:

ItemWhy it matters
API key permissionsCreating orders requires acquiring create permission. Querying orders requires acquiring read permission. Closing orders requires acquiring close permission.
Payment optionsConfirm the pay tokens enabled for the account, such as TRON_USDT or BSC_USDT.
Merchant order numberSend out_trade_no for every order and keep it unique in the merchant system.
Webhook configurationCreate and enable the webhook first, then pass its webhook_id as notify_webhook_id for every order.
Merchant storageStore at least out_trade_no, order_id, status, checkout_url, and expire_time.

Confirm Payment Methods

Before the first integration, or before adding a new payment route, the merchant needs to know which currencies and networks users can pay with.

A pay token ID represents a network and a currency. The usual format is:

<NETWORK>_<CURRENCY>

Examples:

Pay token IDMeaningUser pays with
TRON_USDTUSDT on TRONUSDT transfer on TRON
ETH_USDTUSDT on EthereumUSDT transfer on Ethereum
BSC_USDTUSDT on BNB Smart ChainUSDT transfer on BSC
ETH_USDCUSDC on EthereumUSDC transfer on Ethereum
BASE_USDCUSDC on BaseUSDC transfer on Base

Confirm these values:

Value neededExampleUsed in request
Pricing currencyUSDorder_currency
Pay token IDTRON_USDT, BSC_USDTallowed_pay_currencies; when omitted, system default tokens are used
Webhook IDwebhook_xxxnotify_webhook_id

These values are usually confirmed through Beyounger or the merchant dashboard. When creating an order, the merchant can send token IDs in allowed_pay_currencies to restrict payment methods. When omitted, the system uses the default tokens enabled for the account.

Common token IDs:

CurrencyAvailable token IDs
USDTTRON_USDT, ETH_USDT, BSC_USDT, MATIC_USDT, ARBITRUM_USDT, SOL_USDT
USDCETH_USDC, BASE_USDC, BSC_USDC, MATIC_USDC, ARBITRUM_USDC, SOL_USDC

Recommendations:

  1. Only include token IDs that the merchant wants to allow for the user.
  2. To allow only TRON USDT, send ["TRON_USDT"].
  3. To allow USDT on multiple networks, send ["TRON_USDT", "ETH_USDT", "BSC_USDT"].
  4. Do not send only USDT or USDC; send the full token ID.
  5. Do not include token IDs that are not enabled or not supported for the merchant.

Core Sequence

Step 1: Create The Order

Endpoint

POST /payment/acquiring/orders

Use this endpoint to create a Payin order. After the order is created, Beyounger returns checkout_url; the merchant frontend should redirect the user to that URL to complete payment.

Headers

Authorization: Bearer <api_key_jwt>
Content-Type: application/json
Accept: application/json

Request Fields

FieldRequiredDescription
out_trade_noYesMerchant order number. Must be unique for each order.
order_currencyYesPricing currency. Currently supports USD.
order_amountYesOrder amount. Must be greater than 0.
allowed_pay_currenciesOptionalToken IDs the user is allowed to pay with, for example ["TRON_USDT", "BSC_USDT"]. When omitted, system default tokens are used.
expire_secondsYesOrder validity window, from 60 to 10800 seconds.
underpay_toleranceYesUnderpayment tolerance. Must be greater than or equal to 0.
notify_webhook_idYesWebhook ID used for order status notifications.
redirect_urlOptionalWhere the user returns after checkout. Must be an HTTPS absolute URL or same-origin relative path.
logo_urlOptionalMerchant logo shown on checkout. Must be HTTPS.
remarkOptionalMerchant note.

Create Order Example

{
"out_trade_no": "payin_202606190001",
"order_currency": "USD",
"order_amount": "20.00",
"allowed_pay_currencies": ["TRON_USDT", "BSC_USDT"],
"expire_seconds": 1800,
"underpay_tolerance": "0",
"notify_webhook_id": "webhook_xxx",
"redirect_url": "https://merchant.example.com/payment/result",
"remark": "Order payin_202606190001"
}

Successful Response

{
"code": 0,
"message": "OK",
"data": {
"order": {
"order_id": "acq_order_xxx",
"platform_order_no": "P202606190001",
"out_trade_no": "payin_202606190001",
"status": "pending",
"checkout_type": "default",
"order_currency": "USD",
"order_amount": "20.00",
"allowed_pay_currencies": ["TRON_USDT", "BSC_USDT"],
"pay_amount": "20.00",
"paid_amount_total": "0",
"remaining_amount": "20.00",
"underpay_tolerance": "0",
"checkout_url": "https://api.example.com/payment/checkout/acq_order_xxx",
"notify_webhook_id": "webhook_xxx",
"expire_time": 1781789497,
"created_at": 1781787697,
"updated_at": 1781787697
}
}
}

A successful create response means the Payin order exists. It does not mean the user has paid.

Store these fields:

  1. out_trade_no
  2. order_id
  3. status
  4. checkout_url
  5. allowed_pay_currencies, if provided in the request
  6. pay_amount
  7. expire_time

Step 2: User Payment And Webhook

The merchant frontend redirects the user to checkout_url or displays it inside the merchant experience. After the user pays, Beyounger updates the order based on provider or on-chain results.

If the order was created with a valid notify_webhook_id, Beyounger sends:

acquiring.order.updated

The merchant webhook endpoint should:

  1. Verify the webhook signature.
  2. Process repeated events idempotently by event_id or business_id.
  3. Read data.order_id, data.out_trade_no, and data.status.
  4. Query GET /payment/acquiring/orders/{order_id} when confirmation is needed.
  5. Update the merchant order state.

Webhook Payload Example

{
"event_id": "acqevt_acq_order_xxx",
"event_type": "acquiring.order.updated",
"business_type": "acquiring",
"business_id": "acq_order_xxx",
"occurred_at": 1781789497,
"version": "v1",
"data": {
"provider_event": "transaction_confirmed",
"anomaly_tag": "",
"order_id": "acq_order_xxx",
"platform_order_no": "P202606190001",
"out_trade_no": "payin_202606190001",
"previous_status": "pending",
"status": "completed",
"status_changed": true,
"amount_changed": true,
"order_currency": "USD",
"pay_amount": "20.00",
"paid_amount_total": "20.00",
"remaining_amount": "0",
"overpaid_amount": "0",
"underpay_tolerance": "0",
"expire_time": 1781789497,
"updated_at": 1781789497
}
}

Important fields:

FieldDescription
event_idWebhook event ID.
event_typeacquiring.order.updated.
business_typeAlways acquiring.
business_idSame as order_id.
data.out_trade_noMerchant order number.
data.statusLatest order status.
data.paid_amount_totalTotal paid amount.
data.remaining_amountRemaining amount.
data.anomaly_tagAnomaly marker, such as late payment after expiry.

Crypto Payin Status Notes

Crypto Payin is not a simple success/failure model. The order status is aggregated from the payment records under the order. The key inputs are confirmed paid amount, expected order amount, underpayment tolerance, and whether the order has expired.

When handling webhooks, use these rules:

data.status in webhookFinal?MeaningMerchant action
partial_paidNoSome amount has been confirmed, but confirmed amount has not reached pay_amount - underpay_tolerance.Do not mark the order paid. Wait for more payment or ask the user to top up according to merchant policy.
completedYesConfirmed amount plus underpayment tolerance satisfies the expected amount.Mark the merchant order as paid and continue fulfillment.
underpaidYesThe order expired with some confirmed amount, but it is still short beyond the tolerance.Mark as exception and handle manually, request top-up, or refund according to merchant policy.
expiredYesThe order expired with no confirmed paid amount.Mark the merchant order expired and stop using this order for payment.

Also note:

  1. pending, confirming, and processing are more common in query results or payment records. They usually mean waiting for user payment, broadcast, or confirmations.
  2. paid_amount_total is confirmed paid amount, not merely broadcast or unconfirmed amount.
  3. remaining_amount is calculated from confirmed paid amount.
  4. overpaid_amount greater than 0 means the user overpaid and the merchant should handle the extra amount by business policy.
  5. anomaly_tag=expired_paid means payment was detected after the order expired. Do not automatically treat it as a normal success; route it to exception handling.
  6. One order can have multiple payment records. Use the aggregated data.status as the order-level business result.

Step 3: Query Order Status

Endpoint

GET /payment/acquiring/orders/{order_id}

Use this endpoint:

  1. After create, to read the initial state.
  2. After receiving a webhook, to confirm the latest state.
  3. When a webhook times out or is missing.
  4. During finance or operations reconciliation.

State Guide

statusMeaningMerchant action
pendingWaiting for user payment.Keep the merchant order unpaid.
processingPayment detected and processing.Wait for the next status.
confirmingWaiting for confirmations.Wait for completion.
partial_paidPartially paid.Continue waiting or handle by merchant policy.
completedPayment completed.Mark the merchant order as paid.
underpaidUnderpaid beyond tolerance.Mark as exception and handle manually or refund.
expiredOrder expired.Mark as expired; if money arrives later, inspect anomaly_tag.

Final success should be based on status=completed. Do not mark the merchant order paid based only on frontend redirects or the create-order response.

Query Payment Records

Endpoint

GET /payment/acquiring/orders/{order_id}/payments

This API is for investigation and reconciliation. It is not required for the minimum integration.

Use it to:

  1. Inspect the user's selected currency and network.
  2. Inspect the receiving address.
  3. Read tx_hash.
  4. Investigate underpayment, overpayment, currency mismatch, or network mismatch.

Payment statuses:

payment.statusMeaning
pendingWaiting for payment.
processingPayment received and processing.
confirmingWaiting for confirmations.
completedThis payment completed.
failedPayment failed.
latePaid after expiry.
expiredPayment record expired.

Close An Order

Endpoint

POST /payment/acquiring/orders/{order_id}/close

Use this when the merchant order was cancelled, replaced, or should no longer accept payment.

{
"reason": "merchant_order_cancelled"
}

Use close only for unfinished orders. Do not use it to handle orders that have already completed.

Common Questions

Does a successful create response mean payment success?

No. It only means the Payin order was created. Final success is confirmed by webhook or query result.

Does Payin support per-order notify_url?

The current order creation API uses notify_webhook_id, not per-order notify_url. Create a webhook first, then pass its webhook_id in the order request.

How should allowed_pay_currencies be set?

Send allowed_pay_currencies when the merchant wants to restrict which tokens or networks the user can pay with. If omitted, the system uses the default tokens enabled for the account.

When provided, use the token IDs confirmed through Beyounger or the merchant dashboard. A token ID is network plus currency, such as TRON_USDT for USDT on TRON.

Example:

{
"allowed_pay_currencies": ["TRON_USDT", "BSC_USDT"]
}

Should the merchant rely on webhook or query?

Use both. Webhook gives real-time state changes; query is the fallback for timeout, missing notification, and reconciliation.

Developer Resources

  1. API Reference
  2. OpenAPI JSON
  3. Postman Collection
  4. Getting Started
  5. Authentication