Pay In integration
A Pay In is a payment from your customer to you. You create it from your server, the customer pays on the provider's checkout, and your balance is credited with the amount received minus our service fee once the provider confirms it.
Create a payment
POST /payments · scope payments:write · requires an Idempotency-Key header
| Field | Type | Description |
|---|---|---|
amount required | string | Positive decimal with up to 8 decimals, for example "49.90". |
currency required | string | Currency code such as USDT. See GET /currencies. |
reference required | string | Your order ID. 1–64 characters: letters, digits, _ and -. Must be unique per mode. |
network | string | Blockchain network, if you want to fix it (for example tron). Omit to let the payer choose. |
provider | string | cryptomus or binance_pay. Omit to use the first enabled provider that supports the currency. |
description | string | Up to 255 characters. |
customer_email | string | Customer's email, if you have it. |
success_url, cancel_url | string | Where to send the customer after checkout. Never treat a visit to these URLs as proof of payment. |
lifetime | integer | Seconds before the payment expires, between 300 and 43200. Default 3600. |
metadata | object | Up to 20 keys with string values (max 500 characters). Returned unchanged on the payment and in webhooks. |
You cannot send fee, service_fee, network_fee, net_amount or total_debit. Fees are always calculated by the platform, and sending them returns a validation error.
Response 201
{
"data": {
"id": "pay_01j9x4...",
"object": "payment",
"mode": "test",
"status": "pending",
"provider": "cryptomus",
"reference": "order-1001",
"amount": "49.90000000",
"currency": "USDT",
"network": null,
"received_amount": null,
"service_fee": "0.49900000",
"net_amount": null,
"checkout_url": "https://...",
"pay_address": null,
"tx_hash": null,
"metadata": {},
"callback_verified": false,
"expires_at": "2026-10-16T13:00:00+00:00",
"completed_at": null,
"created_at": "2026-10-16T12:00:00+00:00"
}
}service_fee is an estimate at creation. When the payment settles, it is recalculated on the amount actually received and net_amount is set.
Payment statuses
| Status | Meaning | Final? |
|---|---|---|
created | Recorded, not yet created at the provider. | No |
pending | Waiting for the customer to pay. | No |
processing | Payment detected by the provider. | No |
confirming | Waiting for blockchain confirmations. | No |
completed | Paid and confirmed. Your balance has been credited. | Yes* |
underpaid | Less than requested was received. Only the received amount, minus fees, is credited. | Yes |
failed | The provider reported a failure. | Yes |
expired | Not paid before expires_at. | Yes |
cancelled | Cancelled at the provider. | Yes |
on_hold | Held for compliance review by us or the provider. | No |
refund_pending / refunded | A refund was started by our support team, or has completed. | * |
A payment becomes completed only from a provider callback with a valid signature, confirmed by an authenticated status query to the provider. Redirects and browser responses never change a payment's status.
Fees
Pay In fees are deducted from the amount received. With a 1% fee on a 10,000 USDT payment, the service fee is 100 and your net amount is 9,900. Call GET /fees for the rules that apply to your account, or GET /fees/quote to calculate a specific amount.
Common errors
| Status | Code | When |
|---|---|---|
| 409 | duplicate_reference | The reference was already used. details.existing_id has that payment's ID. |
| 422 | currency_not_supported, network_not_supported | The provider does not accept that currency or network. |
| 422 | amount_out_of_range | Below the provider minimum or above its maximum. |
| 422 | limit_exceeded | Over a per-transaction or daily limit set on your account. |
| 403 | account_not_allowed | Live payments are not enabled for your account yet. |
| 503 | service_unavailable | New payments are temporarily paused for maintenance. |
See Error codes for the full list.