---
updatedAt: 2026-06-24T04:54:53.000Z
agentTools:
  projectIndex: https://docs.shopback.com/llms.txt
---

# Immediate Charge

# 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](./02-account-linking.md).

***

## Flow overview

```mermaid
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**

```http
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](./05-key-concepts.md#idempotency). |

***

### 2. Handle the response

**Success response (201)**

```json
{
  "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)**

```json
{
  "uuid": "a3b1c7f2-8d42-4e19-b123-dd901e72a445",
  "orderUuid": "...",
  "status": "REJECTED",
  "failureReason": "INSUFFICIENT_FUNDS",
  "createdAt": "2026-06-24T11:30:00.000Z"
}
```

> 📘 **Rejected charges still return 201**
>
> The HTTP status code reflects a successful API call, not a successful payment. Always check `status` and `failureReason` in the response body.

***

### 3. Receive the webhook

If you provided a `callbackUrl`, ShopBack POSTs the final outcome once the PSP confirms:

```json
{
  "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 truth**
>
> The webhook is best-effort. Use the `status` field 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](./05-key-concepts.md) — idempotency, cashback, retries, and error codes