Documentation Index
Fetch the complete documentation index at: https://docs.grain.inc/llms.txt
Use this file to discover all available pages before exploring further.
Base URL
| Environment | Base URL |
|---|
| Production | https://api.pay.grain.inc |
| Sandbox | https://api.sandbox.pay.grain.inc |
Payment Sessions
Create Payment Session
Create a new payment session. Returns a session ID and token for the client-side SDK.
Headers:
| Header | Value |
|---|
Authorization | Bearer {CUBEPAY_API_KEY} |
Content-Type | application/json |
Request Body:
| Parameter | Type | Required | Description |
|---|
amount | string | Yes | Payment amount as a decimal string (e.g., "50.00") |
currency | string | Yes | Currency code (e.g., "USD") |
requestId | string | No | Idempotency key — your own UUID to prevent duplicate sessions |
Example:
curl -X POST https://api.pay.grain.inc/payment-sessions \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{"amount": "50.00", "currency": "USD", "requestId": "ord_12345"}'
Response 200 OK:
{
"paymentSessionId": "ps_abc123def456",
"paymentSessionToken": "eyJhbGciOiJIUzI1NiIs...",
"amount": "50.00",
"currency": "USD",
"network": "ETHEREUM",
"tokenSymbol": "USDC",
"oneTimeWalletAddress": "0x1234...abcd",
"userAddress": null,
"fundingTransactionHash": null,
"status": "PENDING",
"createdAt": "2026-03-20T12:00:00Z"
}
Get Payment Session
GET /payment-sessions/{paymentSessionId}
Retrieve the current state of a payment session.
Headers:
| Header | Value |
|---|
Authorization | Bearer {paymentSessionToken} |
Example:
curl https://api.pay.grain.inc/payment-sessions/ps_abc123def456 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
Response 200 OK:
{
"paymentSessionId": "ps_abc123def456",
"status": "FUNDED",
"amount": "50.00",
"currency": "USD",
"network": "ETHEREUM",
"tokenSymbol": "USDC",
"userAddress": "0xCustomerWallet...",
"oneTimeWalletAddress": "0xOTW...",
"fundingTransactionHash": "0xabc123...",
"userSubmittedTransactionHash": "0xdef456...",
"createdAt": "2026-03-20T12:00:00Z"
}
Captures
Create Capture
POST /api/v1/payment-sessions/{paymentSessionId}/captures
Transfer funds from the one-time wallet (OTW) to your treasury wallet. Supports partial and final captures. Only available when the session status is FUNDED.
Headers:
| Header | Value |
|---|
Authorization | Bearer {CUBEPAY_API_KEY} |
Content-Type | application/json |
Request Body:
| Parameter | Type | Required | Description |
|---|
requestId | string | Yes | Idempotency key to prevent duplicate captures |
captureAmount | string | Yes | Amount to capture (e.g., "50.00") |
isFinalCapture | boolean | No | Default false. When true, remaining balance is refunded to the customer and session moves to SUCCEEDED |
Example:
curl -X POST https://api.pay.grain.inc/api/v1/payment-sessions/ps_abc123def456/captures \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{"requestId": "cap_ord_12345", "captureAmount": "50.00", "isFinalCapture": true}'
Response 202 Accepted:
{
"captureId": "cap_xyz789",
"captureAmount": "50.00",
"refundAmount": "0.00",
"status": "CAPTURING"
}
Get Capture
GET /api/v1/payment-sessions/{paymentSessionId}/captures/{captureId}
Check the status of a capture operation.
Headers:
| Header | Value |
|---|
Authorization | Bearer {CUBEPAY_API_KEY} |
Example:
curl https://api.pay.grain.inc/api/v1/payment-sessions/ps_abc123def456/captures/cap_xyz789 \
-H "Authorization: Bearer your-api-key"
Response 200 OK:
{
"captureId": "cap_xyz789",
"status": "CAPTURED",
"captureAmount": "50.00",
"refundAmount": "0.00",
"captureTransferTransactionHash": "0xcapture123...",
"refundTransferTransactionHash": null
}
Capture Object
| Field | Type | Description |
|---|
captureId | string | Unique capture identifier |
status | string | CAPTURING (in progress) or CAPTURED (complete) |
captureAmount | string | Amount captured |
refundAmount | string | Amount refunded to customer (on final capture) |
captureTransferTransactionHash | string | null | On-chain hash of the capture transfer |
refundTransferTransactionHash | string | null | On-chain hash of the refund transfer (if applicable) |
Webhooks
Payment Status Update
Grain sends payment status updates to your registered webhook URL as JSON-RPC 2.0 requests.
Payload:
{
"jsonrpc": "2.0",
"id": "1770947403693",
"method": "cubepay_paymentStatusUpdate",
"params": [
{
"merchantId": "your-merchant-id",
"paymentSessionId": "ps_abc123def456",
"status": "FUNDED",
"updatedAt": "2026-03-20T12:05:00Z"
}
]
}
Status Values:
| Status | Description |
|---|
CREATED | Session created, customer has not connected a wallet yet |
PENDING | Wallet connected, awaiting funding transaction |
FUNDED | Funds received at the one-time wallet — ready to capture |
CAPTURING | Capture in progress (funds being transferred) |
SUCCEEDED | Final capture complete — funds settled to your treasury |
CANCELED | Session expired or was cancelled (not funded within 24 hours) |
ERROR | An error occurred during processing |
Expected Response:
Return 200 with a JSON-RPC acknowledgment:
{
"jsonrpc": "2.0",
"result": "ok"
}
Response Fields Reference
Payment Session Object
| Field | Type | Description |
|---|
paymentSessionId | string | Unique session identifier |
paymentSessionToken | string | Short-lived token for client-side operations |
amount | string | Payment amount |
currency | string | Currency code |
network | string | Blockchain network (e.g., ETHEREUM, SEPOLIA) |
tokenSymbol | string | Token used for payment (e.g., USDC) |
oneTimeWalletAddress | string | Unique receiving address for this session |
userAddress | string | null | Customer’s wallet address (populated after connection) |
fundingTransactionHash | string | null | Transaction hash of the funding transfer |
userSubmittedTransactionHash | string | null | Transaction hash as submitted by the user’s wallet |
capturableAmount | string | Remaining balance available for capture |
capturedAmount | string | Total amount captured so far |
captures | array | Array of capture operations with their statuses and transaction hashes |
status | string | Current session status |
createdAt | string | ISO 8601 creation timestamp |