Appearance
Payins
Merchants call this endpoint to request a payin. The portal forwards the request to the configured payin backend to generate the QR code or payment flow, then returns the backend’s response.
Endpoint
http
POST /api/v1/payins1
All payin traffic flows through this unified endpoint. The application forwards every request to the remote server configured via PAYIN_SERVER_* environment variables, using the exact JSON payload supplied by the client.
Authentication
Requires API key authentication via the X-API-Key (or Api-Key) header.
Request Body
json
{
"amount": 100.50,
"currency": "USDT",
"memo": "Payment for invoice #123",
"out_trade_no": "MERCHANT-ORDER-001"
}1
2
3
4
5
6
2
3
4
5
6
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Amount in USDT (min 0.01, up to 6 decimal places). |
currency | string | No | Defaults to USDT. Supported: USDT. |
memo | string | No | Optional reference or note (max 255 characters). |
out_trade_no | string | Yes | Merchant order identifier (max 255 characters). Must be unique per merchant. |
The payload is forwarded as-is to the configured payin server. Set
PAYIN_SERVER_ENDPOINTandPAYIN_SERVER_API_KEYin your environment to enable forwarding.
Response
json
{
"success": true,
"code": 200,
"data": {
"invoice_reference": "PAYIN-202511A1B2C3D4E5F6G7H",
"amount": 100.5,
"currency": "USDT",
"fee": 2.50,
"qrcode": {
"content": "00020101021229...",
"image": "iVBORw0KGgoAAAANSUhEUgAAAyoAAANmCAIAAACaMeiHAADFN0lEQVR4nOzdd..."
},
"out_trade_no": "MERCHANT-ORDER-001"
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| Field | Description |
|---|---|
invoice_reference | System-generated unique invoice reference (format: PAYIN-XXXXXXXXXXXXXXXXXX). |
amount | The requested amount. |
currency | Currency code (defaults to USDT). |
fee | Processing fee charged for this transaction (in same currency as amount). |
qrcode | Object containing the QR code data. |
qrcode.content | Decoded QR code data (e.g., payment URI for deep linking). |
qrcode.image | Base64-encoded PNG image of the QR code. |
out_trade_no | Merchant's order identifier. |
Example Request (cURL)
bash
#!/bin/bash
API_KEY="your_api_key"
curl -X POST "https://dev-crypto-portal.kesspay.io/api/v1/payins" \
-H "Content-Type: application/json" \
-H "X-Api-Key: ${API_KEY}" \
-d '{
"amount": 100,
"memo": "POS-INV-9231",
"out_trade_no": "ORDER-2025-001"
}'1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
How it works
- Merchant calls
/api/v1/payinswith amount,out_trade_no, and optional memo. - Portal validates uniqueness of
out_trade_no(must be unique per merchant). - Portal creates a TopUp record and forwards the JSON payload to your configured payin server.
- The payin server generates the QR code/payment payload and returns JSON.
- Portal returns the TopUp details, fee information, and QR code to the merchant.
- When the payment is settled, the webhook callback includes the
out_trade_nofor merchant reconciliation.
Error Responses
| Status | Message | When it occurs |
|---|---|---|
| 422 | Validation errors for fields or duplicate out_trade_no. | Missing/invalid fields or out_trade_no already exists for this merchant. |
| 502 | Payin service is unavailable. Please try again later. | The upstream payin server responded with a 4xx/5xx or could not be reached. |
| 500 | Unable to process payin request. Please contact support. | Unexpected exception while forwarding the request. |
Query Payment Status
Query the status of a payment using your merchant order reference.
Endpoint
http
POST /api/v1/payins/status1
Authentication
Requires API key authentication via the X-API-Key header.
Request Body
json
{
"out_trade_no": "MERCHANT-ORDER-001"
}1
2
3
2
3
| Field | Type | Required | Description |
|---|---|---|---|
out_trade_no | string | Yes | Your merchant order identifier used when creating the payin. |
Response
json
{
"success": true,
"code": 200,
"data": {
"trx_ref": "TRX-PROVIDER-123",
"amount": 100.5,
"fee": 2.5,
"invoice_reference": "PAYIN-202511A1B2C3D4E5F6G7H",
"out_trade_no": "MERCHANT-ORDER-001",
"status": "success"
}
}1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
| Field | Type | Description |
|---|---|---|
trx_ref | string | Provider transaction reference. |
amount | number | Payment amount (same as input). |
fee | number | Fee amount. |
invoice_reference | string | System-generated invoice reference. |
out_trade_no | string | Your merchant order identifier. |
status | string | Current payment status. |
Status Values
| Status | Description |
|---|---|
waiting | Payment pending, awaiting user payment. |
success | Payment confirmed and wallet credited. |
expired | Payment expired without completion. |
close | Payment closed/cancelled. |
Example Request (cURL)
bash
#!/bin/bash
API_KEY="your_api_key"
curl -X POST "https://dev-crypto-portal.kesspay.io/api/v1/payins/status" \
-H "Content-Type: application/json" \
-H "X-Api-Key: ${API_KEY}" \
-d '{
"out_trade_no": "MERCHANT-ORDER-001"
}'1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Error Responses
| Status | Message | When it occurs |
|---|---|---|
| 401 | Unauthorized | Invalid or missing API key. |
| 404 | Top-up not found. | No payment found for the given out_trade_no. |
| 422 | Validation error | Missing out_trade_no field. |
Implementation Notes
- The request payload is never mutated. If you include optional fields, they are forwarded to the upstream server.
- Payin server configuration lives in
config/services.php(PAYIN_SERVER_ENDPOINT,PAYIN_SERVER_API_KEY,PAYIN_SERVER_TIMEOUT). - If
PAYIN_SERVER_ENDPOINTis not set, payin requests will fail validation. Configure your own provider endpoint and API key before enabling payins.
Next Steps
- Learn about Webhooks to receive payment notifications from the portal.
- Review Rate Limiting to understand API throttling rules.