POST - Create Invoice
Create a crypto payment invoice. Merchant sends the amount (USD), order information, and callback URL; the system returns trans_id and url_payment to redirect the customer to the checkout page.
Endpoint
POST https://api.payerscan.com/payment/crypto
Headers
| Header | Required | Description |
|---|---|---|
Content-Type | Yes | application/json |
x-api-key | Yes | Store's API Key |
Request Body (JSON)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
merchant_id | string | Yes | Non-empty | Store's merchant code (must match the API Key). |
amount | number | string | Yes | > 0 and ≤ 1,000,000 | Payment amount (USD). Example: 100, "100". |
callback_url | string | Recommended | Max 500 chars, valid URL | URL to receive webhook on completed or expired status. |
completed_url | string | No | Max 500 chars, valid URL | Redirect URL after successful payment. |
expired_url | string | No | Max 500 chars, valid URL | Redirect URL when the invoice expires. |
name | string | No | Max 255 chars | Invoice name/title. |
description | string | No | Max 1000 chars | Invoice description. |
request_id | string | No | Max 255 chars | Merchant's order ID for cross-reference (returned in response and webhook). Also used for idempotency — see notes below. |
Example Request
{
"merchant_id": "MID-XXXXXXXXXX",
"amount": 100,
"name": "Top-up balance",
"description": "Top-up the balance for username: [USERNAME]",
"callback_url": "https://your-server.com/webhook/payment",
"completed_url": "https://your-website.com/thank-you",
"expired_url": "https://your-website.com/",
"request_id": "ORDER_123456"
}
Response
Success (HTTP 200)
{
"status": "success",
"data": {
"request_id": "ORDER_123456",
"trans_id": "TID-ABC123DEF4567890",
"status": "waiting",
"amount": "100",
"url_payment": "https://app.payerscan.com/bill/TID-ABC123DEF4567890",
"expires_in_minutes": 15
}
}
| Field | Description |
|---|---|
request_id | The value you sent in the request. |
trans_id | Unique invoice code, used for lookup and webhook cross-reference. |
status | Always "waiting" when newly created. |
amount | USD amount (string). |
url_payment | Checkout page URL — redirect the customer here. |
expires_in_minutes | Invoice expiration time (minutes). |
Errors (4xx / 5xx)
All errors follow this format:
{
"status": "error",
"message": "Error description",
"error_code": "ERROR_CODE",
"request_id": "ORDER_123456",
"details": { }
}
| HTTP | error_code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid body (missing required fields, wrong type, exceeding constraints). details.errors has specifics. |
| 400 | INVALID_MERCHANT_ID | merchant_id doesn't match the Store's API Key. |
| 400 | NO_PAYMENT_METHOD | Store has no configured payment method. Add at least one wallet address or configure an exchange platform before creating invoices. |
| 401 | MISSING_API_KEY | No x-api-key header provided. |
| 401 | INVALID_API_KEY | The API key is invalid or does not exist. |
| 403 | ACCOUNT_INACTIVE | The account associated with this API key is disabled. |
| 403 | STORE_INACTIVE | The store associated with this API key is disabled. |
| 402 | INSUFFICIENT_BALANCE | Store balance insufficient for fees. details has current_balance, required_fee, shortage, fee_rate_percent, discount_percent, invoice_amount. |
| 429 | RATE_LIMIT_EXCEEDED | Exceeded request limit (burst or sustained). Has limit_type, retry_after_seconds. |
| 500 | INTERNAL_ERROR | Server error. |
Error code details: API Error Codes.
Rate Limit
- Burst: 5 requests/second (per API Key or IP).
- Sustained: 60 requests/minute (per API Key or IP).
Exceeding limit → HTTP 429, body has error_code: "RATE_LIMIT_EXCEEDED", retry_after_seconds.
Notes
- Payment method: Store must configure at least one wallet address or exchange platform (Binance Pay, OKX, Bybit, MEXC, Gate.io, Bitget, etc.) before creating invoices. If none configured, API returns
NO_PAYMENT_METHODerror. - Idempotency: If you send a
request_idthat already exists for the same store, API returns the existing invoice instead of creating a new one. The response will includeidempotent: trueto indicate this. This prevents duplicate invoices when retrying failed requests. - Fees: Fees are calculated on
amount(USD) and deducted from the Store's balance. Ensure sufficient balance before creating invoices. During the free trial period, fees are waived. - Callback: Always send
callback_urlto receive completed/expired webhooks; without it, you can only check viaGET https://api.payerscan.com/invoice/:trans_id. - request_id: Recommended to send for easy webhook-to-order matching and idempotency support.