Payment intents
Payment intents are the core collection resource. You create an intent, share checkout details, then consume lifecycle updates.
Lifecycle
- Create an intent with a token amount, chain, token, and optional metadata.
- Display the returned deposit address or hosted checkout URL to the payer.
- Track deposit progress with
deposit_status:none,detected,pending_confirmation, orconfirmed. - Use merchant-visible status values
PENDING,EXPIRED, andCOMPLETED. - Receive lifecycle updates via webhooks.
Create an intent
/v1/payment-intentsCreate payment intentRequired payload keys
| Field | Type | Description |
|---|---|---|
| amountrequired | string | Decimal amount in token units. Must be > 0 and within token precision. |
| chainrequired | string | Canonical deposit chain (for example ethereum). |
| tokenrequired | string | Canonical deposit token (for example USDC). |
Customer identity (`customer_id`)
Pass a stable merchant-defined customer key as the top-level customer_id field (not only inside metadata). The API echoes it on the payment intent and uses it for deposit routing and reporting.
- Required when your merchant
deposit_identity_modeisIDENTITY_BASED(all chains). - Tron: with
customer_idand modeIDENTITY_BASEDorHYBRID, deposits use a persistent per-customer address (samecustomer_idreuses the same Tron deposit address for that chain/token). Integrations collecting on Tron should always sendcustomer_idwhen using those modes. HYBRIDwithoutcustomer_idmay allocate a shared hot-wallet pool address (when enabled) instead of a dedicated customer wallet.- Max length 256 characters. Configure defaults via
GET|PUT /v1/merchant/deposit-rules-default.
Do not rely on metadata alone
customer_id only inside metadata does not drive deposit identity routing. Use the top-level field.Optional payload keys, enums, and defaults
| Field | Type | Description |
|---|---|---|
| customer_id | string | Stable merchant customer key. Required when deposit_identity_mode is IDENTITY_BASED; required for Tron persistent wallets in IDENTITY_BASED/HYBRID. |
| metadata | object | Default: {}. Merchant-defined non-financial metadata echoed in responses/webhooks. |
| purpose | merchant_payment | invoice_payment | Default: merchant_payment. Use invoice_payment for fixed invoices that must be paid in full before completion while the checkout window is open; partial confirmed inbound may settle after expiry. |
| funding_acceptance_mode | OPEN_AMOUNT | TARGET_WITH_TOLERANCE | EXACT | Default: EXACT. Controls how inbound deposit amounts are accepted. Ignored for invoice_payment (always EXACT). |
| target_settlement_amount | string | Default: amount. Settlement target in token units. |
| allowed_deviation_type | ABSOLUTE | PERCENTAGE | No default. Must be sent with allowed_deviation_value when using deviation. |
| allowed_deviation_value | string | No default. Positive decimal. Required when allowed_deviation_type is set. |
| allow_partial_funding | boolean | Default: false (true for invoice_payment). Allows multiple confirmed deposits to accumulate before routing. |
| allow_overpayment | boolean | Default: false. Whether inbound amount above maximum policy bound is accepted. |
| overpayment_handling | CREDIT_EXCESS | REJECT_EXCESS | Default: REJECT_EXCESS. Controls behavior when overpayment is accepted. |
| settlement_recipient_type | MERCHANT | CUSTOMER | Optional override. Rejected when it conflicts with merchant type policy. |
| beneficiary_details | object | Required when settlement_recipient_type resolves to CUSTOMER; must be provider-resolved before create. |
Funding acceptance mode rules
EXACT(default): fixed amount acceptance behavior.TARGET_WITH_TOLERANCE: requires bothallowed_deviation_typeandallowed_deviation_value.OPEN_AMOUNT: variable amount flow, commonly paired with partial/overpayment allowances.
Invoice payments (invoice_payment)
Set purpose to invoice_payment when collecting a fixed invoice amount. Xpend applies stricter rules than a generic merchant_payment with manual funding flags.
- While open: cumulative confirmed inbound must reach the exact quoted amount (no downward tolerance). Multiple deposits are allowed and sum toward the target.
- Before full payment: status stays
PENDING,payment_intent.completeddoes not fire, and routing is blocked (funding_status.acceptance_statemay showSHORTFALL). - After expiry: if the customer paid only part of the invoice, Xpend settles the confirmed partial amount and the intent can complete with whatever was received.
Policy locked at create
invoice_payment, Xpend sets funding_acceptance_mode to EXACT, enables allow_partial_funding, and uses zero downward deviation regardless of other funding fields you send.Validation coupling
allowed_deviation_type or allowed_deviation_value is provided, the other must also be provided.curl "$XPEND_BASE_URL/v1/payment-intents" \
-H "Authorization: Bearer $XPEND_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order_8421" \
-d '{
"amount": "150.00",
"chain": "ethereum",
"token": "USDC",
"metadata": {
"order_id": "order_8421"
}
}'Important response fields
| Field | Type | Description |
|---|---|---|
| payment_intent_idrequired | string | Xpend payment intent identifier. Store this on your order. |
| customer_id | string | Echoed when set at creation (top-level field). |
| deposit_addressrequired | string | Address the payer should fund on the requested chain/token route. |
| statusrequired | PENDING | EXPIRED | COMPLETED | Merchant-visible lifecycle state. |
| deposit_statusrequired | none | detected | pending_confirmation | confirmed | On-chain deposit progress. |
| transaction_hash | string | Best-known funding/settlement transaction hash or signature when available. |
| checkout_url | string | Hosted checkout URL when available. |
| metadatarequired | object | Merchant metadata echoed from creation. |
Read/list intents
/v1/payment-intentsList payment intents/v1/payment-intents/{id}Get payment intent by ID/v1/payment-intents/settlement-summarySummarized settlement totalsFunding status on GET
GET /v1/payment-intents/{id} may include funding_status with cumulative funded_amount, acceptance_state (SHORTFALL, WITHIN_POLICY, COMPLETED, etc.), and policy hints. For invoice payments, poll this field or use webhooks while waiting for the customer to finish paying.
Recommended integration pattern
- Persist the returned payment intent ID in your order record.
- Redirect users to hosted checkout when
checkout_urlis present, or render the returned deposit address. - Use
payment_intent.completedfor fulfillment decisions. - Use list/get endpoints for operator dashboards and support tooling.
Avoid polling loops
/v1/payment-intents/{id} aggressively is unnecessary. Use webhooks for state transitions and occasional reads for UI refresh.See full endpoint details in /business/reference/payment-intents.