Immediate Charge
Immediate charge combines authorization and capture into a single API call. Use it when you know the exact payment amount upfront and don't need a separate hold step.
Prerequisite: a paymentToken obtained from Account Linking.
Flow overview
sequenceDiagram
autonumber
participant ME as Merchant
participant SB as ShopBack API
ME->>SB: POST /tokenized-payment/v1/charge
Note over ME,SB: paymentToken, amount, currency, merchantRef, callbackUrl
Note over ME,SB: Header — X-ShopBack-Idempotent-Id: <uuid>
SB-->>ME: 201 { uuid, orderUuid, status }
SB-)ME: POST callbackUrl (async webhook)
Note over ME,SB: { order_uuid, order_status: "SUCCESS" }
Step-by-step
1. Charge the user
Request
POST /tokenized-payment/v1/charge
Authorization: Bearer <merchant_jwt>
Content-Type: application/json
X-ShopBack-Idempotent-Id: 1f4a8b22-9d37-4c11-8e20-bc91d73a4421
{
"paymentToken": "pt_sg_7829_a1b2c3d4e5f6...",
"merchantUserId": "usr_7829",
"amount": 18.90,
"currency": "SGD",
"merchantRef": "order-9017",
"useCashback": true,
"callbackUrl": "https://your-app.com/shopback/webhook"
}| Field | Required | Description |
|---|---|---|
paymentToken | Yes | Token from account linking, scoped to this user and your channel. |
merchantUserId | Yes | Must match the merchantUserId used during account linking. |
amount | Yes | Charge amount in major units (e.g. 18.90 for SGD 18.90). Must be > 0. |
currency | Yes | 3-letter ISO 4217 code. Must match your merchant channel's configured currency. |
merchantRef | Yes | Your stable, unique reference for this charge (e.g. order ID). Used for idempotency. |
useCashback | No | Apply the user's available ShopBack cashback to this payment. Defaults to true. |
callbackUrl | Recommended | HTTPS URL that ShopBack POSTs the order outcome to. |
X-ShopBack-Idempotent-Id | Yes (header) | UUID unique to this logical charge attempt. See Idempotency. |
2. Handle the response
Success response (201)
{
"uuid": "a3b1c7f2-8d42-4e19-b123-dd901e72a445",
"orderUuid": "61cf9737-5cc3-421a-84c1-ba554c0674ba",
"status": "APPROVED",
"orderType": "ONLINE",
"merchantRef": "order-9017",
"merchantOrderId": "SB-20260624-002",
"consumerEmail": "u***@example.com",
"failureReason": null,
"createdAt": "2026-06-24T11:30:00.000Z"
}A status of APPROVED means payment was successful and an order has been created.
Declined response (201 with failure)
{
"uuid": "a3b1c7f2-8d42-4e19-b123-dd901e72a445",
"orderUuid": "...",
"status": "REJECTED",
"failureReason": "INSUFFICIENT_FUNDS",
"createdAt": "2026-06-24T11:30:00.000Z"
}
Rejected charges still return 201The HTTP status code reflects a successful API call, not a successful payment. Always check
statusandfailureReasonin the response body.
3. Receive the webhook
If you provided a callbackUrl, ShopBack POSTs the final outcome once the PSP confirms:
{
"order_uuid": "61cf9737-5cc3-421a-84c1-ba554c0674ba",
"order_status": "SUCCESS",
"order_context_token": "c9393a19-00b0-48cd-9a9e-fdcf0b3cdbb5",
"cart_id": null,
"webhook_url": "https://your-app.com/shopback/webhook"
}
Treat the synchronous response as the source of truthThe webhook is best-effort. Use the
statusfield in the 201 response to determine payment outcome for your user.
Error responses
| HTTP status | Error code | Meaning |
|---|---|---|
400 | bad-request | Missing required field, amount ≤ 0, or currency mismatch |
401 | payment-token.invalid | Token not found, unlinked, or belongs to a different merchant |
Pre-auth vs immediate charge: which to use
| Pre-auth | Immediate charge | |
|---|---|---|
| Final amount known at start | Not required | Required |
| Separate capture step | Yes | No |
| Can void if service doesn't proceed | Yes | No |
| Time between auth and settlement | Up to pre-auth TTL | Immediate |
| Use case examples | Rides, hotels, metered services | Food delivery, top-ups, fixed-price orders |
Next step
- Key Concepts — idempotency, cashback, retries, and error codes