API Reference
Base URL
All API requests should be made to the following base URL:
Production Environment:
https://api.paystablecoin.globalComplete endpoint example:
https://api.paystablecoin.global/api/v1/merchants/{merchantId}/ordersAPI ENVIRONMENT
A Sandbox environment is available for development and testing:
https://api.sandbox.paystablecoin.globalUse the Production environment when you are ready to go live:
https://api.paystablecoin.globalOrder API
The Order API allows merchants to create and query payment orders. Orders support both fiat (USD) and stablecoin (USDT) pricing, and can be configured to restrict available payment methods per transaction.
1. Create Order
Function Description
Enables merchants to create payment orders, supporting both fiat currency and stablecoin pricing.
Endpoint Information
- Method:
POST - Path:
/api/v1/merchants/{merchantId}/orders - Content-Type:
application/json - Authentication:
Base64(HMAC-SHA256(timestamp + "\n" + method + "\n" + path + "\n" + SHA256(body), API_SECRET))
Request Headers
| Header | Type | Required | Description | Example |
|---|---|---|---|---|
X-Api-Key | String | Yes | Merchant API key | PSTG6ELOB2YXKO4ZHRQ6NKTSBY |
X-Timestamp | Long | Yes | Request timestamp (milliseconds) | 1738112345000 |
X-Signature | String | Yes | Request signature | base64-hmac-sha256 |
Content-Type | String | Yes | Fixed value | application/json |
Path Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
merchantId | String | Yes | Merchant ID (assigned by platform) | 1000 |
Request Body Parameters
Required Parameters
| Parameter | Type | Description | Example |
|---|---|---|---|
merchantOrderId | String | Merchant order ID (16-64 chars, alphanumeric + - _) | your-order-123456789 |
orderAmount | Object | Order amount (see structure below ↓) | {"value":"99.99","currency":"USD"} |
expiresAt | String | Order expiration time (UTC, ISO 8601) | 2025-10-01T12:00:00Z |
returnUrl | String | Customer browser redirect URL after payment (max 2048 chars) | https://merchant.com/success |
OrderAmount Object Structure:
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
value | String | Yes | Amount value (supports up to 18 decimal places) | 99.99 |
currency | String | Yes | Currency code (3-16 uppercase alphanumeric) | USD / USDT |
Notes:
- Fiat pricing:
{"value": "99.99", "currency": "USD"}- Converted to equivalent USDT at payment time - Stablecoin pricing:
{"value": "100.00", "currency": "USDT"}- Direct USDT payment
Optional Parameters - Payment Configuration
| Parameter | Type | Description | Example |
|---|---|---|---|
paymentMethodConfig | Object | Payment method configuration (see structure below ↓) | See below |
callbackUrl | String | Server-to-server webhook URL for order status updates (HTTPS, max 2048 chars) | https://merchant.com/webhook |
PaymentMethodConfig Object Structure:
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
allowedPaymentMethodTypes | Array | No | Allowed payment types: ON_CHAIN_TRANSFER (wallet), EXCHANGE_TRANSFER (exchange). Empty/null = no restriction | ["EXCHANGE_TRANSFER"] |
allowedPaymentMethods | Array | No | Specific payment methods (applies only to EXCHANGE_TRANSFER): BINANCE, KUCOIN. Empty/null = no restriction | ["BINANCE", "KUCOIN"] |
Configuration Priority:
- If
allowedPaymentMethodsis specified, only these payment methods are shown - If
allowedPaymentMethodTypesis specified, only these types are shown - If both are unspecified (null or empty), all available payment methods are shown
IMPORTANT
If you specify allowedPaymentMethods (e.g., ["BINANCE"]), you MUST also specify allowedPaymentMethodTypes that includes EXCHANGE_TRANSFER. Otherwise, the checkout may show unintended payment methods.
Recommended: Always specify both fields together when restricting to specific exchanges.
CONFIGURATION EXAMPLES
Example 1: Binance Pay Only
{
"allowedPaymentMethodTypes": ["EXCHANGE_TRANSFER"],
"allowedPaymentMethods": ["BINANCE"]
}Example 2: On-Chain Payments Only
{
"allowedPaymentMethodTypes": ["ON_CHAIN_TRANSFER"]
}Example 3: Binance + Kucoin
{
"allowedPaymentMethodTypes": ["EXCHANGE_TRANSFER"],
"allowedPaymentMethods": ["BINANCE", "KUCOIN"]
}Example 4: No Restrictions (Default)
{
"paymentMethodConfig": null
}or omit the field entirely.
Example 5: Mixed - Binance + On-Chain
{
"allowedPaymentMethodTypes": ["ON_CHAIN_TRANSFER", "EXCHANGE_TRANSFER"],
"allowedPaymentMethods": ["BINANCE"]
}This allows all on-chain payment methods plus Binance Pay.
Understanding callbackUrl vs returnUrl:
These two URL parameters serve different purposes in the payment flow:
callbackUrl(Server-to-Server Webhook)- Purpose: Receives real-time payment status notifications from PayStablecoin servers
- When triggered: Automatically called when order status changes
- Usage: Your backend server processes these notifications to update order status
- Optional but recommended for reliable payment confirmation
returnUrl(Browser Redirect)- Purpose: Redirects the customer's browser back to your website after payment
- When triggered: After customer completes or cancels payment on the checkout page
- Usage: Display order confirmation or thank you page to the customer
- Required for good user experience
BEST PRACTICE
Always use both URLs:
callbackUrlfor reliable backend order processing (even if user closes browser)returnUrlfor smooth user experience (customer sees confirmation page)
Optional Parameters - Customer Information
| Parameter | Type | Description | Example |
|---|---|---|---|
customer | Object | Customer information for risk control (see structure below ↓) | See below |
customerIp | String | Customer IP address (IPv4/IPv6) | 203.0.113.10 |
userAgent | String | Customer User-Agent (0-512 characters) | Mozilla/5.0... |
Customer Object Structure:
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
customerId | String | No | Customer ID (from merchant system) | u1001 |
email | String | No | Email address (for notifications) | user@example.com |
name | String | No | Customer name | John Doe |
phone | String | No | Phone number | 1234567890 |
Optional Parameters - Order Details
| Parameter | Type | Description | Example |
|---|---|---|---|
description | String | Order description (0-512 characters) | Monthly membership recharge |
items | Array | Line item details (see structure below ↓) | See below |
metadata | String | Merchant custom metadata (JSON format, max 4096 chars) | {"customerId":"u1001"} |
LineItem Object Structure:
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
name | String | Yes | Item name | Diamond Pack x10 |
quantity | Integer | Yes | Quantity (must be > 0) | 1 |
amount | Object | Yes | Unit price (same as OrderAmount structure) | {"value":"99.99","currency":"USD"} |
description | String | No | Item description | In-game virtual currency |
imageUrl | String | No | Item image URL | https://example.com/img.jpg |
Optional Parameters - Platform Merchants Only
| Parameter | Type | Description | Example |
|---|---|---|---|
subMerchants | Array | Sub-merchant information list (see structure below ↓) | See below |
SubMerchant Object Structure:
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
subMerchantId | String | Yes | Sub-merchant ID (1-32 characters) | SUB_001 |
name | String | Yes | Sub-merchant name (1-256 characters) | Apple Store |
amount | String | Yes | Split amount (must be > 0.01) | 500.00 |
mcc | String | No | Merchant Category Code (4 digits, ISO 18245) | 5732 |
settlementRatio | String | No | Settlement ratio (0-1, e.g., 0.95 = 95%) | 0.95 |
IMPORTANT
The sum of all sub-merchant amounts must equal the total order amount.
Complete Request Example
CURL Example:
curl -X POST https://api.paystablecoin.global/api/v1/merchants/1000/orders \
-H "X-Api-Key: PSTG6ELOB2YXKO4ZHRQ6NKTSBY" \
-H "X-Timestamp: 1738112345000" \
-H "X-Signature: <base64-hmac-sha256>" \
-H "Content-Type: application/json" \
-d '{
"merchantOrderId": "your-order-123456789",
"orderAmount": {
"value": "99.99",
"currency": "USD"
},
"expiresAt": "2025-10-01T12:00:00Z",
"paymentMethodConfig": {
"allowedPaymentMethodTypes": ["ON_CHAIN_TRANSFER", "EXCHANGE_TRANSFER"],
"allowedPaymentMethods": ["BINANCE"]
},
"description": "Monthly membership recharge",
"customer": {
"customerId": "u1001",
"email": "user@example.com",
"name": "John Doe"
},
"items": [
{
"name": "Diamond Pack x10",
"quantity": 1,
"amount": {
"value": "99.99",
"currency": "USD"
},
"description": "In-game virtual currency"
}
],
"customerIp": "203.0.113.10",
"userAgent": "Mozilla/5.0...",
"callbackUrl": "https://merchant.com/webhook",
"returnUrl": "https://merchant.com/success",
"metadata": "{\"customerId\":\"u1001\",\"source\":\"web\"}"
}'Response
All responses return HTTP Code 200, with business results expressed through status + code + message.
Response Field Descriptions
AcquiringOrderView (Order View)
| Field | Type | Description | Example |
|---|---|---|---|
orderId | String | Platform order ID | ord_8fcb2a2e5b |
merchantId | String | Merchant ID | M0001 |
merchantOrderId | String | Merchant order ID | your-order-123456789 |
status | String | Order status | INIT / PROCESSING / SUCCEEDED / FAILED / CLOSED |
checkoutUrl | String | Checkout page URL | https://checkout.paystablecoin.global/... |
createdAt | String | Creation time (UTC, ISO 8601) | 2025-09-28T12:00:00Z |
expiresAt | String | Expiration time (UTC) | 2025-10-01T12:00:00Z |
paidAt | String | Payment time (UTC, returned only after payment) | 2025-09-29T10:30:00Z |
orderAmount | Object | Order amount | See OrderAmount definition |
cryptoPaidAmount | Object | Actual stablecoin payment amount | See OrderAmount definition |
cryptoPaymentDetail | Object | Cryptocurrency payment details | See CryptoPaymentDetail definition |
standardResponseCode | String | Standard response code | 00000 |
standardResponseMessage | String | Response code description | Success |
CryptoPaymentDetail (Cryptocurrency Payment Details - Returned Only After Successful Payment)
| Field | Type | Description | Example |
|---|---|---|---|
txHash | String | Transaction hash | 0x1234...abcd |
network | String | Blockchain network | TRON / ETHEREUM |
fromAddress | String | Payer address | TXYz...4567 |
toAddress | String | Payee address | TQRs...8901 |
confirmations | Integer | Number of confirmations | 21 |
blockNumber | Long | Block height | 12345678 |
Response Examples
Success Response (status=INIT):
{
"code": "00000",
"message": "Success",
"data": {
"orderId": "ord_8fcb2a2e5b",
"merchantId": "M0001",
"merchantOrderId": "your-order-123456789",
"status": "INIT",
"checkoutUrl": "https://checkout.paystablecoin.global/ord_8fcb2a2e5b",
"createdAt": "2025-09-28T12:00:00Z",
"expiresAt": "2025-10-01T12:00:00Z",
"orderAmount": {
"value": "99.99",
"currency": "USD"
},
"cryptoPaidAmount": null,
"cryptoPaymentDetail": null,
"standardResponseCode": "00000",
"standardResponseMessage": "Success"
}
}Failure Response (status=FAILED):
{
"code": "10001",
"message": "Invalid parameter: orderAmount.currency must be ISO 4217",
"data": {
"orderId": null,
"merchantId": "M0001",
"merchantOrderId": "your-order-123456789",
"status": "FAILED",
"standardResponseCode": "10001",
"standardResponseMessage": "Invalid parameter"
}
}2. Query Order
Function Description
Enables merchants to query detailed information about a single order, supporting queries by either merchant order ID or platform order ID.
Endpoint Information
- Method:
GET - Path:
/api/v1/merchants/{merchantId}/orders/{merchantOrderId} - Signature Note: GET requests have no Body, signature content is
timestamp + "\n" + method + "\n" + path - Authentication: Same as Create Order endpoint
Request Headers
| Header | Type | Required | Description | Example |
|---|---|---|---|---|
X-Api-Key | String | Yes | Merchant API key | PSTG6ELOB2YXKO4ZHRQ6NKTSBY |
X-Timestamp | Long | Yes | Request timestamp (milliseconds) | 1738112345000 |
X-Signature | String | Yes | Request signature (no Body, sign path) | base64-hmac-sha256 |
Content-Type | String | Yes | Fixed value | application/json |
Path Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
merchantId | String | Yes | Merchant ID | 1000 |
merchantOrderId | String | Yes | Merchant order ID | your-order-123456789 |
Example Request:
curl -X GET "https://api.paystablecoin.global/api/v1/merchants/1000/orders/your-order-123456789" \
-H "X-Api-Key: PSTG6ELOB2YXKO4ZHRQ6NKTSBY" \
-H "X-Timestamp: 1738112345000" \
-H "X-Signature: <base64-hmac-sha256>" \
-H "Content-Type: application/json"Signature String: 1738112345000\nGET\n/api/v1/merchants/1000/orders/your-order-123456789
Response
All responses return HTTP Code 200, with business results expressed through status + code + message.
Response Field Descriptions
AcquiringOrderView (Order Details)
| Field | Type | Description | Example |
|---|---|---|---|
orderId | String | Platform order ID | ord_8fcb2a2e5b |
merchantId | String | Merchant ID | M0001 |
merchantOrderId | String | Merchant order ID | your-order-123456789 |
status | String | Order status (see status descriptions) | INIT / SUCCEEDED / FAILED / CLOSED |
checkoutUrl | String | Checkout page URL | https://checkout.exsatpay.com/... |
createdAt | String | Order creation time (UTC, ISO 8601) | 2025-09-28T12:00:00Z |
expiresAt | String | Order expiration time (UTC) | 2025-10-01T12:00:00Z |
paidAt | String | Payment success time (UTC, returned only after payment) | 2025-09-28T12:05:10Z |
orderAmount | Object | Order amount (merchant pricing) | See OrderAmount definition |
cryptoPaidAmount | Object | Actual payment amount (cryptocurrency) | See OrderAmount definition |
cryptoPaymentDetail | Object | On-chain payment details (returned only after payment) | See CryptoPaymentDetail definition |
standardResponseCode | String | Standard response code | 00000 |
standardResponseMessage | String | Response code description | Success |
CryptoPaymentDetail (On-Chain Payment Details - Returned Only After Successful Payment)
| Field | Type | Description | Example |
|---|---|---|---|
txHash | String | Transaction hash (viewable on blockchain explorer) | 0xabcf2a2e5b8fcb... |
network | String | Blockchain network | TRON / ETHEREUM / BSC |
fromAddress | String | Payer address (customer wallet address) | TKeoD2qV8HR4sfm4b9a3e2g1jCD7fDCZuv |
toAddress | String | Payee address (platform receiving address) | TPoD2qV8HR4sfm4b9a3e2g1jCD7fDAZaa |
confirmations | Integer | Number of block confirmations | 25 |
blockNumber | Long | Block height of transaction | 45678901 |
Order Status Descriptions
| Status | Description | Is Final? | Possible Next States |
|---|---|---|---|
INIT | Order created, awaiting payment | No | PROCESSING / CLOSED |
PROCESSING | Payment processing (on-chain transaction detected) | No | SUCCEEDED / FAILED |
SUCCEEDED | Payment successful (received and confirmed) | Yes | - |
FAILED | Payment failed (insufficient amount/timeout/error) | Yes | - |
CLOSED | Order closed (merchant cancelled/auto-expired) | Yes | - |
State Transition Diagram:
INIT ──┬──> PROCESSING ──┬──> SUCCEEDED (final)
│ └──> FAILED (final)
└──> CLOSED (final, cancelled or expired)Response Examples
Successful Query - Paid Order
{
"code": "00000",
"message": "Success",
"data": {
"orderId": "ord_8fcb2a2e5b",
"merchantId": "M0001",
"merchantOrderId": "your-order-123456789",
"status": "SUCCEEDED",
"checkoutUrl": "https://checkout.paystablecoin.global/ord_8fcb2a2e5b",
"createdAt": "2025-09-28T12:00:00Z",
"expiresAt": "2025-10-01T12:00:00Z",
"paidAt": "2025-09-28T12:05:10Z",
"orderAmount": {
"value": "99.99",
"currency": "USD"
},
"cryptoPaidAmount": {
"value": "100.02",
"currency": "USDT"
},
"cryptoPaymentDetail": {
"txHash": "0xabcf2a2e5b8fcb2a2e5b8fcb2a2e5b8fcb2a2e5b8fcb2a2e5b8fcb2a2e5b8f",
"network": "TRON",
"fromAddress": "TKeoD2qV8HR4sfm4b9a3e2g1jCD7fDCZuv",
"toAddress": "TPoD2qV8HR4sfm4b9a3e2g1jCD7fDAZaa",
"confirmations": 25,
"blockNumber": 45678901
},
"standardResponseCode": "00000",
"standardResponseMessage": "Success"
}
}Successful Query - Pending Order
When order is awaiting payment, paidAt, cryptoPaidAmount, and cryptoPaymentDetail will be null:
{
"code": "00000",
"message": "Success",
"data": {
"orderId": "ord_9def3c5e7d",
"merchantId": "M0001",
"merchantOrderId": "pending-order-456",
"status": "INIT",
"checkoutUrl": "https://checkout.paystablecoin.global/ord_9def3c5e7d",
"createdAt": "2025-09-29T10:00:00Z",
"expiresAt": "2025-10-02T10:00:00Z",
"paidAt": null,
"orderAmount": {
"value": "199.99",
"currency": "USD"
},
"cryptoPaidAmount": null,
"cryptoPaymentDetail": null,
"standardResponseCode": "00000",
"standardResponseMessage": "Success"
}
}Failed Query - Order Not Found
{
"code": "40001",
"message": "Order not found",
"data": {
"orderId": null,
"merchantId": "M0001",
"merchantOrderId": "your-order-not-exist",
"status": "FAILED",
"standardResponseCode": "40001",
"standardResponseMessage": "Order not found"
}
}Important Notes
Field Availability:
paidAt: Returned only when order payment is successful (status=SUCCEEDED)cryptoPaidAmount: Returned only when order payment is successfulcryptoPaymentDetail: Returned only when order payment is successful, contains on-chain transaction details
Amount Differences:
orderAmount: Pricing amount when merchant creates order (may be fiat or stablecoin)cryptoPaidAmount: Actual cryptocurrency amount paid by customer (may differ slightly due to exchange rate conversion)- Example: Order amount 99.99 USD, actual payment 100.02 USDT (due to exchange rate fluctuation)
Confirmation Count Explanation:
confirmations: Blockchain confirmation count, higher value = more secure- Different network confirmation requirements:
- TRON: Typically requires 19 confirmations
- ETHEREUM: Typically requires 12 confirmations
- BSC: Typically requires 15 confirmations
Query Frequency Recommendations:
- After order creation, recommend querying status every 5-10 seconds
- After order payment success, no need to continue querying
- Using Webhook callbacks can reduce active query frequency and improve efficiency
Refund API
The Refund API allows merchants to initiate refunds for completed payments. Refunds are always processed for the full original order amount. After submission, a refund request goes through immediate validation, fund reservation, asynchronous processing, and result notification stages.
3. Create Refund
Endpoint Information
- Method:
POST - Path:
/api/v1/merchants/{merchantId}/refunds - Content-Type:
application/json - Authentication: Required
Request Headers
| Header | Type | Required | Description | Example |
|---|---|---|---|---|
X-Api-Key | String | Yes | Merchant API key | PSTG6ELOB2YXKO4ZHRQ6NKTSBY |
X-Timestamp | Long | Yes | Request timestamp (milliseconds, 13 digits) | 1738112345000 |
X-Signature | String | Yes | Request signature (Base64-encoded). Algorithm: Base64(HMAC-SHA256(timestamp\nMETHOD\npath\nBase64(SHA256(body)), apiSecret)) | base64-hmac-sha256 |
Content-Type | String | Yes | Fixed value | application/json |
Path Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
merchantId | String | Yes | Merchant ID (assigned by platform) | 1000 |
Request Body Parameters
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
merchantRefundOrderId | String | Yes | Merchant refund order ID (globally unique, used for idempotency) | REFUND_20260128_001 |
acquiringOrderId | String | Yes | Original payment order ID (PSC order to refund) | ORDER_20260128_001 |
refundReason | String | Yes | Refund reason (English, for review and traceability) | Customer request full refund |
notifyUrl | String | No | Refund result notification URL. Uses merchant default config if omitted | https://merchant.example.com/webhook/refund |
extraData | String | No | Extra data in JSON format, returned as-is | {"orderId":"MERCHANT_ORDER_123"} |
Request Example
curl -X POST https://api.paystablecoin.global/api/v1/merchants/1000/refunds \
-H "X-Api-Key: PSTG6ELOB2YXKO4ZHRQ6NKTSBY" \
-H "X-Timestamp: 1738112345000" \
-H "X-Signature: <base64-hmac-sha256>" \
-H "Content-Type: application/json" \
-d '{
"merchantRefundOrderId": "REFUND_20260128_001",
"acquiringOrderId": "ORDER_20260128_001",
"refundReason": "Customer request full refund",
"notifyUrl": "https://merchant.example.com/webhook/refund",
"extraData": "{\"orderId\":\"MERCHANT_ORDER_123\",\"userId\":\"USER_456\"}"
}'Response Fields
| Field | Type | Description | Example |
|---|---|---|---|
code | String | Response code. 00000 indicates the refund application was accepted | 00000 |
message | String | Response message | Refund application accepted |
data | Object | Refund order data (see RefundOrderData below) | - |
requestId | String | Request ID for tracing | req_abc123xyz |
timestamp | Long | Response timestamp (milliseconds) | 1706428800000 |
RefundOrderData
| Field | Type | Description | Example |
|---|---|---|---|
refundOrderId | String | PSC refund order ID (globally unique) | REF_20260128120001 |
merchantRefundOrderId | String | Merchant refund order ID | REFUND_20260128_001 |
acquiringOrderId | String | Original payment order ID | ORDER_20260128_001 |
merchantOrderId | String | Merchant's original order ID | MERCHANT_ORDER_123 |
status | String | Refund status (see status table below) | PENDING |
refundAmount | String | Refund amount (user's actual payment amount) | 100.50 |
refundCurrency | String | Refund currency | USDT |
merchantDeductAmount | String | Amount deducted from merchant (net settlement amount) | 100.1985 |
paymentMethod | String | Original payment method | BINANCE_PAY |
createdTime | String (ISO 8601) | Creation time | 2026-01-28T12:00:00Z |
estimatedCompletionTime | String (ISO 8601) | Estimated completion time | 2026-01-28T12:15:00Z |
completedTime | String (ISO 8601) | Completion time (SUCCEEDED only) | 2026-01-28T12:05:30Z |
failedTime | String (ISO 8601) | Failure time (FAILED only) | 2026-01-28T12:03:15Z |
closedTime | String (ISO 8601) | Closed time (CLOSED only) | 2026-01-28T14:30:00Z |
errorCode | String | Error code (FAILED only) | EXCHANGE_BALANCE_INSUFFICIENT |
errorMessage | String | Error message (FAILED only) | Insufficient funds in Binance funding wallet |
extraData | String | Extra data, returned as-is | {"orderId":"MERCHANT_ORDER_123"} |
Refund Status Values
| Status | Description | Is Final? |
|---|---|---|
INIT | Refund record created | No |
PENDING | Application accepted, awaiting processing | No |
PROCESSING | Processing in progress | No |
SUCCEEDED | Refund completed successfully | Yes |
FAILED | Refund failed | Yes |
CLOSED | Refund closed | Yes |
Response Examples
Success — refund accepted:
{
"code": "00000",
"message": "Refund application accepted",
"data": {
"refundOrderId": "REF_20260128120001",
"merchantRefundOrderId": "REFUND_20260128_001",
"acquiringOrderId": "ORDER_20260128_001",
"merchantOrderId": "MERCHANT_ORDER_123",
"status": "PENDING",
"refundAmount": "100.50",
"refundCurrency": "USDT",
"merchantDeductAmount": "100.1985",
"paymentMethod": "BINANCE_PAY",
"createdTime": "2026-01-28T12:00:00Z",
"estimatedCompletionTime": "2026-01-28T12:15:00Z"
},
"requestId": "req_abc123xyz",
"timestamp": 1706428800000
}Error — insufficient balance:
{
"code": "INSUFFICIENT_BALANCE",
"message": "Merchant balance insufficient for refund",
"details": "Required: 100.00 USDT, Available: 50.00 USDT",
"requestId": "req_abc123xyz",
"timestamp": 1706428800000
}Error — refund period expired:
{
"code": "REFUND_PERIOD_EXPIRED",
"message": "Order refund period has expired",
"details": "Order paid at: 2025-12-15T10:00:00Z, Refund deadline: 2026-01-14T10:00:00Z (30 days)",
"requestId": "req_abc123xyz",
"timestamp": 1706428800000
}HTTP Status Codes
| HTTP Status | Meaning | Description |
|---|---|---|
200 | OK | Refund application accepted |
400 | Bad Request | Invalid parameters or business validation failed |
401 | Unauthorized | Signature verification failed |
404 | Not Found | Order not found |
429 | Too Many Requests | Rate limit exceeded |
4. Query Refund
Endpoint Information
- Method:
GET - Path:
/api/v1/merchants/{merchantId}/refunds - Authentication: Required
- Signature Note: GET requests have no body. Query parameters are hashed separately as the fourth component. Algorithm:
Base64(HMAC-SHA256(timestamp\nMETHOD\npath\nBase64(SHA256(queryString)), apiSecret))
TIP
At least one query parameter (refundOrderId, merchantRefundOrderId, or acquiringOrderId) must be provided.
Request Headers
| Header | Type | Required | Description | Example |
|---|---|---|---|---|
X-Api-Key | String | Yes | Merchant API key | PSTG6ELOB2YXKO4ZHRQ6NKTSBY |
X-Timestamp | Long | Yes | Request timestamp (milliseconds) | 1738112345000 |
X-Signature | String | Yes | Request signature (no body) | base64-hmac-sha256 |
Path Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
merchantId | String | Yes | Merchant ID | 1000 |
Query Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
refundOrderId | String | No | PSC refund order ID (highest priority) | REF_20260128120001 |
merchantRefundOrderId | String | No | Merchant refund order ID | REFUND_20260128_001 |
acquiringOrderId | String | No | Original payment order ID (returns the first refund for that order) | ORDER_20260128_001 |
Request Example
curl -X GET "https://api.paystablecoin.global/api/v1/merchants/1000/refunds?refundOrderId=REF_20260128120001" \
-H "X-Api-Key: PSTG6ELOB2YXKO4ZHRQ6NKTSBY" \
-H "X-Timestamp: 1738112345000" \
-H "X-Signature: <base64-hmac-sha256>"Signature string: 1738112345000\nGET\n/api/v1/merchants/1000/refunds\nBase64(SHA256("refundOrderId=REF_20260128120001"))
Response
Returns the same code / message / data / requestId / timestamp envelope, with data being a single RefundOrderData object (see RefundOrderData above).
Response Examples
Succeeded refund:
{
"code": "00000",
"message": "Query successful",
"data": {
"refundOrderId": "REF_20260128120001",
"merchantRefundOrderId": "REFUND_20260128_001",
"acquiringOrderId": "ORDER_20260128_001",
"merchantOrderId": "MERCHANT_ORDER_123",
"status": "SUCCEEDED",
"refundAmount": "100.50",
"refundCurrency": "USDT",
"merchantDeductAmount": "100.1985",
"paymentMethod": "BINANCE_PAY",
"createdTime": "2026-01-28T12:00:00Z",
"completedTime": "2026-01-28T12:05:30Z",
"extraData": "{\"orderId\":\"MERCHANT_ORDER_123\"}"
},
"requestId": "req_xyz789abc",
"timestamp": 1706428835000
}Failed refund:
{
"code": "00000",
"message": "Query successful",
"data": {
"refundOrderId": "REF_20260128120003",
"merchantRefundOrderId": "REFUND_20260128_003",
"acquiringOrderId": "ORDER_20260128_003",
"status": "FAILED",
"refundAmount": "75.00",
"refundCurrency": "USDT",
"paymentMethod": "BINANCE_PAY",
"createdTime": "2026-01-28T12:02:00Z",
"failedTime": "2026-01-28T12:03:15Z",
"errorCode": "EXCHANGE_BALANCE_INSUFFICIENT",
"errorMessage": "Insufficient funds in Binance funding wallet"
},
"requestId": "req_xyz789abc",
"timestamp": 1706428835000
}Not found:
{
"code": "REFUND_NOT_FOUND",
"message": "Refund order not found",
"details": "merchantRefundOrderId: REFUND_NONEXISTENT",
"requestId": "req_notfound123",
"timestamp": 1706428900000
}HTTP Status Codes
| HTTP Status | Meaning | Description |
|---|---|---|
200 | OK | Query successful |
404 | Not Found | Refund order not found |
5. Batch Query Refunds
Endpoint Information
- Method:
POST - Path:
/api/v1/merchants/{merchantId}/refunds/batch-query - Content-Type:
application/json - Authentication: Required
Use this endpoint for bulk reconciliation, report generation, or status sync. A single request supports up to 100 refund orders.
Request Headers
Same as Create Refund.
Path Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
merchantId | String | Yes | Merchant ID | 1000 |
Request Body Parameters
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
merchantRefundOrderIds | Array<String> | Yes | List of merchant refund order IDs (max 100) | ["REFUND_001", "REFUND_002"] |
Request Example
curl -X POST https://api.paystablecoin.global/api/v1/merchants/1000/refunds/batch-query \
-H "X-Api-Key: PSTG6ELOB2YXKO4ZHRQ6NKTSBY" \
-H "X-Timestamp: 1738112345000" \
-H "X-Signature: <base64-hmac-sha256>" \
-H "Content-Type: application/json" \
-d '{
"merchantRefundOrderIds": [
"REFUND_20260128_001",
"REFUND_20260128_002",
"REFUND_20260128_003"
]
}'Response Fields
| Field | Type | Description |
|---|---|---|
code | String | 00000 indicates success |
message | String | Response message |
data | Array | List of RefundOrderData objects (same structure as single query) |
requestId | String | Request ID |
timestamp | Long | Response timestamp (milliseconds) |
Response Example
{
"code": "00000",
"message": "Batch query successful",
"data": [
{
"refundOrderId": "REF_20260128120001",
"merchantRefundOrderId": "REFUND_20260128_001",
"status": "SUCCEEDED",
"refundAmount": "100.50",
"refundCurrency": "USDT"
},
{
"refundOrderId": "REF_20260128120002",
"merchantRefundOrderId": "REFUND_20260128_002",
"status": "PROCESSING",
"refundAmount": "50.00",
"refundCurrency": "USDC"
},
{
"refundOrderId": "REF_20260128120003",
"merchantRefundOrderId": "REFUND_20260128_003",
"status": "FAILED",
"refundAmount": "75.00",
"refundCurrency": "USDT",
"errorCode": "EXCHANGE_BALANCE_INSUFFICIENT"
}
],
"requestId": "req_batch123",
"timestamp": 1706428900000
}Refund Webhook
Refund webhook notifications are documented in the Webhook Notifications page.
Related Documentation
- Authentication Headers - Learn about request header setup
- Signature Algorithm - Learn signature calculation
- Webhook Notifications - Set up real-time payment status updates
- Error Codes and Solutions - Understand error codes and troubleshooting