# Buying eSIMs

## Checkout

`POST /checkout` charges your balance and **waits until the eSIMs are provisioned**, usually a
few seconds. Set your HTTP client timeout to at least 60 seconds.

| Response | Meaning | What to do |
| --- | --- | --- |
| `200` | eSIMs are ready | `POST /myesim` with the `transaction_id` |
| `400` | Insufficient balance, or the `transaction_id` belongs to an unpaid transaction | Top up your balance, or use another `transaction_id` |
| `409` | Another request with this `transaction_id` is still running | Wait, then check `/myesim` |
| `422` | Invalid body | Fix the request |
| `500` | Provisioning failed. Your balance was **refunded** | Retry with the same `transaction_id` |

### `transaction_id`

- Generate it yourself, for example `order-<your-order-id>`. It's your reference for the purchase.
- Use the same value on every item in one checkout.
- Retrying a completed purchase with the same `transaction_id` returns `200` without charging
  again. That makes it safe to retry after a timeout.

### Several packages at once

```json
[
  { "packageCode": "JC016", "count": 2, "transaction_id": "order-1001" },
  { "packageCode": "KR005", "count": 1, "transaction_id": "order-1001" }
]
```

## Top-ups

Top-ups are **asynchronous**.

1. `GET /list-topupdataplan?iccid=...` lists the plans that fit this eSIM.
2. `POST /topup-esim`:

   ```json
   {
     "packageCodeTopup": "<packageCode from step 1>",
     "iccid": "8985200012345678901",
     "transaction_id": "order-1001",
     "external_id": "renew-7781"
   }
   ```

   - `transaction_id` is the **original purchase** this eSIM came from, not a new value.
   - `external_id` is your own unique key for this top-up. Always send it: a retry with the
     same `external_id` is never charged twice.

3. You get `202` with a new `transaction_id` (`topup-<external_id>`). Check it with
   `POST /check-status-payment` until it's **`Success`**. On `FAILED`, your balance was refunded.

Only eSIMs whose `supportTopUpType` is `2` or `3` can be topped up, and only before they expire.
An expired eSIM returns `422` with `error_type: ESIM_EXPIRED`.
