post
https://sandbox.paystrator.com/v1/checkout
Recent Requests
Log in to see full request history
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||
Loading…
Headers
| Key | Value |
|---|---|
| Authorization | Bearer <publicAccessToken> |
| Idempotency-Key | [uuid] (recommended) |
Notes on headers:
- Same key + same request body → returns the same checkout session (no duplicates).
- Different body with the same key →
409 Idempotency Mismatch.
Request Body
{
"externalId": "ORD-2025-0001",
"currency": "IDR",
"amount": 125000,
"description": "Top up Premium Plan",
"successUrl": "https://merchant.com/thank-you?o=ORD-2025-0001",
"cancelUrl": "https://merchant.com/cancel?o=ORD-2025-0001",
"metadata": "{ \"note\": \"optional\" }",
"type": "virtual_account"
}Field Reference
| Field | Required | Type | Notes |
|---|---|---|---|
externalId | ✅ | string | Unique per client. If duplicate return 409 DUPLICATE_EXTERNAL_ID. |
currency | ✅ | string | IDR (more in future). |
amount | integer | Smallest unit (Rupiah). Omit to ask end-user on page. | |
description | string | Shown on checkout page. | |
successUrl | string | Redirect user to this URL if payment success. Overrides dashboard default. Required here or in dashboard. | |
failedUrl | string | Redirect user to this URL if payment failed. Overrides dashboard default. Required here or in dashboard. | |
metadata | string | Custom key-value pairs. Stored in Paystrator and returned in API/webhook, but never sent to providers. Read more about metadata here. | |
type | enum | Preselect flow: virtual_account / ewallet / qrcode / credit_card. If omitted: end-user will chooses. |
End-User Page Flow Guide**
- If
amountif empty, end-user will be prompted to input payment amount. - If type:
- is empty, end-user can choose the available payment method
- is filled (with
ewallet/qrcode/virtual_account/credit_card), end-user will be directed to respective payment type. So, end-user can't choose the payment method available.
Responses
201 Created
{
"id": "co_01JABCXYZ",
"externalId": "ORD-2025-0001",
"status": "PENDING",
"checkoutUrl": "https://checkout.paystrator.com/co_01JABCXYZ",
"currency": "IDR",
"amount": 125000,
"type": "qrcode",
"createdAt": "2025-08-23T03:50:00Z"
}Field Notes
| Field | Description |
|---|---|
| id | Checkout session ID (prefix co_). |
| checkoutUrl | Send your customer here (redirect or link). |
| status | PENDING on create |
| amount | null if omitted in request |
Error Payload (standard)
{
"error": {
"code": "INVALID_TYPE_FOR_TENANT",
"message": "The selected type is not enabled for this tenant.",
"requestId": "req_abc123"
}
}Error Codes
| HTTP | Code | Description |
|---|---|---|
| 400 | INVALID_AMOUNT | Amount invalid/missing for fixed flows. |
| 400 | MISSING_REDIRECT_URLS | Neither API nor dashboard provided success/cancel. |
| 400 | INVALID_TYPE_FOR_TENANT | Type not enabled for this tenant. |
| 400 | NO_AVAILABLE_PAYMENT_TYPE | Tenant has no payment methods enabled. |
| 403 | PERMISSION_DENIED | API key lacks required permissions. |
| 409 | DUPLICATE_EXTERNAL_ID | externalId already used. |
| 409 | IDEMPOTENCY_CONFLICT | Same Idempotency-Key with different body. |
| 422 | INVALID_PROVIDER_MAPPING | Provider not mapped in production. |
Status and Expiration Rules
| Status | Description | Expiry Rules |
|---|---|---|
| Created | Checkout created | 24h |
| Opened | End-user opened link | 15 mins from first open |
| Completed | Paid | |
| Expired | Not paid before expiry |
For UI purposes:
- Any status other than Completed is displayed as UNPAID.
- Completed is displayed as PAID.
200