{
  "info": {
    "_postman_id": "d384a7d8-43a4-5b66-a26d-645092361fea",
    "name": "PayGate.to — Reloadable Virtual Cards API",
    "description": "This is a different product from the one-time Virtual Credit Cards API. One-time cards are bought per order and redeemed once with a redeem_id. Reloadable cards live inside a lightweight anonymous account: you top the account up in crypto, mint one or more cards against that balance, then load, unload and reload those same cards for as long as you keep them. The two collections share nothing — different endpoints, different identifiers, different lifecycle.\n\nThis public API issues reloadable crypto-funded Visa and Mastercard virtual cards without KYC. There is no email, no password and no personal data: an account is a `session` string plus a recovery `token`, both generated in one call and both held only by you.\n\n**1. Create an account** — one browser-side call to `signup.php` returns a `token` and a `session`. Save both, they are the only way back in.\n\n**2. Top up in crypto** — `wallet.php` returns a deposit address, QR code, minimum amount and an expiry. The balance lands in USD cents.\n\n**3. Mint a card** — `issue-card.php` charges the tier price from the balance and returns a new card. Prices come live from `list-cards.php`.\n\n**4. Load, reveal, spend** — `load-card.php` moves balance onto the card, `reveal-card-number.php` shows the PAN behind TOTP.\n\n## Authentication\n\nThere are no API keys. Every endpoint except Sign Up takes a single `session` query parameter. A session is a bearer credential: anyone holding it controls the account and its cards, so treat it exactly as you would a password.\n\n- `session` — the working credential. Passed with every request. Store it in a cookie (or your own server-side store) and reuse it; it does not need to be re-issued for each call.\n- `token` — the recovery credential. It is returned once, at sign up, and is only used with `signin.php` to recover or rotate a session. It arrives **already percent-encoded**: store it and send it back byte-for-byte, without encoding it a second time.\n\n**There is no password reset.** Nothing about the account is recoverable from our side — no email, no support recovery, no identity check. If the customer loses both the token and the session, the balance and every card on the account are gone permanently. Any integration must force the customer to store the pair before letting them continue.\n\n## Rate limits and where to call from\n\n`signup.php` and `signin.php` are heavily rate limited and are intended to be called **client side, from the end customer's browser**, so the limit applies per customer rather than per server. Calling them from your backend puts every customer behind one shared limit and will start returning `400` quickly.\n\nSign up performs real key generation and provisioning work, so it is slow by design, commonly **20 to 60 seconds**. Show a spinner with reassuring copy for the whole wait, and on failure retry **once** only. Every other endpoint in this collection responds normally and may be called from either side.\n\n## Money is always in cents\n\nEvery monetary field in this collection is an integer number of **US cents**: `balanceCents`, `amountCents`, `tierPriceCents`, `priceCents`, and the `amount` parameter of `wallet.php`, `load-card.php` and `unload-card.php`. `601` is `$6.01`. Never send or render a decimal.\n\n## Base URL\n\n`https://api.paygate.to/crypto/cards/reloadable/`\n\nDeposit endpoints are the exception: they carry the coin ticker before the card path, matching the Crypto Payment Processor convention — `https://api.paygate.to/crypto/{ticker}/cards/reloadable/wallet.php`.\n\nHosted documentation: https://paygate.to/docs/virtual-credit-cards-api/reloadable/\n\nNo sign up, no API keys and no authentication headers are required. Every example value below is the one printed in the hosted docs — replace the placeholders in {curly braces} with your own values before sending.\n\nGenerated from the hosted documentation on 2026-09-07.\n\nReference material (not callable endpoints) is documented at https://paygate.to/docs/virtual-credit-cards-api/reloadable/",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "Account & Session",
      "description": "An account is created once and then addressed only by its session. These three endpoints cover the whole identity surface of the product: create the pair, recover the pair, and check that a session is still alive.",
      "item": [
        {
          "name": "Sign Up",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/signup.php",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "signup.php"
              ]
            },
            "description": "Creates a new anonymous reloadable card account. Takes no parameters. Returns the only two credentials that will ever exist for this account.\n\n Call this from the browser\n\n This endpoint is heavily rate limited and is designed to be requested client side, directly from the end customer's browser, so that the limit is scoped to that customer. A server-side proxy funnels every one of your customers through a single limit and will be throttled almost immediately.\n\n Expect it to be slow\n\n The account and its cryptographic material are provisioned during the request, so the response commonly takes 20 to 60 seconds. Do not set a short client timeout — allow at least 90 seconds. Render a spinner for the entire wait with copy that sets the expectation, for example: “Securely creating your account — this can take up to a minute. Please keep this page open.”\n\n Retry policy\n\n If the request fails or returns 400 Bad Request, retry exactly once, keeping the spinner on screen. Do not loop: repeated attempts will trip the rate limit and lock the customer out of signing up for a while. If the single retry also fails, tell the customer to try again in a few minutes.\n\n Response\n\n - token: the permanent recovery credential, URL-encoded. Used only with signin.php. Store it verbatim, including the %2B, %2F and %3D escapes.\n\n - session: the working credential. Pass it as the session parameter on every other endpoint in this collection."
          },
          "response": [
            {
              "name": "OK — Account created (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/signup.php",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "signup.php"
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"token\": \"NBcvfznMlfzL4ey%2BJmhdcdKVJpQBBqIxuOfZ2GFpbD0Orblz7zfywxXN4Te0Jheo%2F5vGoUuXwfrfxOd9zVOcTw%3D%3D\",\n    \"session\": \"JSgPHmS2RHUFoR5bsBDw2Gklw_NghKvZs0D9nn9AaiU\"\n}"
            }
          ]
        },
        {
          "name": "Sign In",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/signin.php?token={token}&session={session}",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "signin.php"
              ],
              "query": [
                {
                  "key": "token",
                  "value": "{token}"
                },
                {
                  "key": "session",
                  "value": "{session}"
                }
              ]
            },
            "description": "Recovers access when the working session has been lost, expired or invalidated. Both saved values must be supplied together — the token alone is not enough, and the session alone is not enough.\n\n If the pair is valid the account is returned. When the supplied session is still alive it comes back unchanged; when it has expired, a new session is issued in its place. Always overwrite your stored session with the value from this response rather than assuming it matched what you sent.\n\n The token is unchanged by this call and stays valid for the life of the account.\n\n Query Parameters\n\n - token: the recovery token exactly as returned by signup.php.\n\n - session: the last session the customer holds, valid or not.\n\n Do not URL-encode the token — it already is. The value returned by signup.php contains percent escapes such as %2B, %2F and %3D. Passing it through a generic query-string builder that calls encodeURIComponent (or PHP's urlencode, or requests' params=) encodes the % itself, so %3D becomes %253D and the sign-in is rejected. Concatenate the token into the URL verbatim.\n\n Copyconst token = \"…hSTupRqLCQfsJU70pDvFEgoeS5FcSFSVDMbE3ljTGCvjN3A%3D%3D\";\n\n// WRONG — the token is encoded a second time: %3D%3D becomes %253D%253D\n`${API}signin.php?${new URLSearchParams({ token, session })}`\n\n// RIGHT — the token goes in exactly as it was issued\n`${API}signin.php?token=${token}&session=${encodeURIComponent(session)}`\n\n The same applies in reverse: do not decode it before storing. Whatever you show the customer to save, and whatever they paste back, should be the same string the API issued.\n\n Rate limited like sign up. Call it from the browser, and only when a session has actually failed — never as a pre-flight check before ordinary requests. Use session.php for that.\n\nParameters:\n- `token` — Recovery token, URL-encoded (example: `NBcvfznMlfzL4ey%2BJmhdcdKVJpQBBqIxuOfZ2GFpbD0Orblz7zfywxXN4Te0Jheo%2F5vGoUuXwfrfxOd9zVOcTw%3D%3D`)\n- `session` — Last known session (example: `JSgPHmS2RHUFoR5bsBDw2Gklw_NghKvZs0D9nn9AaiU`)"
          },
          "response": [
            {
              "name": "OK — Signed in — session still valid (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/signin.php?token={token}&session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "signin.php"
                  ],
                  "query": [
                    {
                      "key": "token",
                      "value": "{token}"
                    },
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"token\": \"NBcvfznMlfzL4ey%2BJmhdcdKVJpQBBqIxuOfZ2GFpbD0Orblz7zfywxXN4Te0Jheo%2F5vGoUuXwfrfxOd9zVOcTw%3D%3D\",\n    \"session\": \"JSgPHmS2RHUFoR5bsBDw2Gklw_NghKvZs0D9nn9AaiU\"\n}"
            }
          ]
        },
        {
          "name": "Session & Balance",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/session.php?session={session}",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "session.php"
              ],
              "query": [
                {
                  "key": "session",
                  "value": "{session}"
                }
              ]
            },
            "description": "The cheap, unlimited way to answer two questions at once: is this session still signed in, and what is the account balance. Use it on page load, after a deposit confirms, and after any operation that moves money.\n\n A successful response means the session is live. A failure means the session is dead and the customer must recover it with signin.php using their saved token.\n\n Response\n\n - balanceCents: the spendable account balance in US cents. This is the pool that pays card issuing fees and card loads — it is not money on any card.\n\nParameters:\n- `session` — Active session (example: `JSgPHmS2RHUFoR5bsBDw2Gklw_NghKvZs0D9nn9AaiU`)"
          },
          "response": [
            {
              "name": "OK — Signed in · balance $6.01 (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/session.php?session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "session.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"balanceCents\": 601\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Funding the Account",
      "description": "Money enters the account as a crypto deposit. Each call creates a fresh, single-use deposit address with its own expiry — addresses are not reusable and must not be cached or shown again after they lapse.\n\n### Supported tickers\n\nThe ticker sits in the path, before the card segment: `https://api.paygate.to/crypto/{ticker}/cards/reloadable/wallet.php`\n\n| Ticker | Coin | Network |\n|---|---|---|\n| `btc` | Bitcoin | Bitcoin |\n| `xmr` | Monero | Monero |\n| `ltc` | Litecoin | Litecoin |\n| `eth` | Ethereum | Ethereum |\n| `erc20/usdc` | USD Coin | Ethereum (ERC-20) |\n| `erc20/usdt` | Tether | Ethereum (ERC-20) |\n\nFor coin logos, display names and live metadata, reuse the shared List all Coins & Minimums endpoint from the Crypto Payment Processor collection — `https://api.paygate.to/crypto/info.php` returns a `logo` URL per coin, keyed by network and symbol. That is the same source the PayGate.to deposit selectors use, so a ticker such as `erc20/usdc` resolves as `info[\"erc20\"][\"usdc\"].logo`, and a bare ticker such as `btc` as `info[\"btc\"].logo`.\n\n**Coin and network must match the ticker exactly, and the amount must be at or above `minimum_amount`.** A deposit of the wrong asset, on the wrong chain, or below the stated minimum is not recoverable and is not refundable. Surface the network name and the minimum prominently next to the address, not in fine print.\n\n**Deposit addresses expire.** `expiresAt` is an ISO-8601 UTC timestamp — in the example below the window is 60 minutes from `createdAt`. Drive a countdown from `expiresAt` rather than from a decrementing counter, so it stays honest when the tab is backgrounded. When it reaches zero, clear the QR and address from the page and offer to generate a new deposit.\n\n**One deposit at a time.** An account may hold only one deposit in `awaiting` at any moment. While one is outstanding, wallet.php, custom-affiliate.php and custom-sub-affiliate.php will not issue another address — for the same coin or any other — until the outstanding one expires or is cancelled. Call list-active-deposits.php before offering a deposit form, and give the customer cancel-deposit.php as the way out.",
      "item": [
        {
          "name": "Create Deposit",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/{ticker}/cards/reloadable/wallet.php?session={session}&amount={cents}",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "{ticker}",
                "cards",
                "reloadable",
                "wallet.php"
              ],
              "query": [
                {
                  "key": "session",
                  "value": "{session}"
                },
                {
                  "key": "amount",
                  "value": "{cents}"
                }
              ]
            },
            "description": "Creates a deposit intent for the signed-in account and returns the address, QR code, minimum and expiry. Once the deposit confirms on chain the account balance rises automatically — poll session.php or account-activity.php to detect it.\n\n**`amount` is required on every funding call, in integer US cents, and the minimum is `3000` — $30.00.** Send `3000` for $30.00, `3056` for $30.56, `5000` for $50.00. A decimal such as `30.56` is rejected, and so is anything below the floor, such as `2999` or `2500`. Multiply the dollar figure your customer sees by 100 and round to a whole number before sending it.\n\n Query Parameters\n\n - session: active session.\n\n - amount: the amount to fund, in integer US cents. Required, minimum 3000 ($30.00).\n\n Response\n\n - ok: true when the deposit intent was created.\n\n - id: the deposit intent identifier.\n\n - asset: uppercase asset symbol, e.g. BTC.\n\n - status: awaiting until the transaction is seen on chain.\n\n - confirmations: confirmations counted so far.\n\n - expiresAt: ISO-8601 UTC instant after which this address must not be used.\n\n - createdAt: ISO-8601 UTC creation instant.\n\n - minimum_amount: the smallest accepted deposit, denominated in the coin. Anything below this is lost.\n\n - network: human-readable chain name to display to the customer.\n\n - payCurrency: lowercase coin identifier.\n\n - address_in: the deposit address for this intent only.\n\n - qr_code: base64 PNG of the payment QR. Render it as <img src=\"data:image/png;base64,{qr_code}\" alt=\"Payment QR Code\"/>.\n\n - ipn_token: tracking token — quote it to support when asking about a deposit.\n\nParameters:\n- `session` — Active session (example: `3rzSe-1JuvDX5WdYIXBX7BbSaii8hHQiNSzit9mMGYc`)\n- `amount` — $50.00, in integer US cents. Required, minimum `3000` (example: `5000`)"
          },
          "response": [
            {
              "name": "OK — Deposit intent created (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/{ticker}/cards/reloadable/wallet.php?session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "{ticker}",
                    "cards",
                    "reloadable",
                    "wallet.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"id\": \"cmtnbkye5009jp207myrkr06t\",\n    \"asset\": \"BTC\",\n    \"status\": \"awaiting\",\n    \"confirmations\": 0,\n    \"expiresAt\": \"2026-09-04T20:01:13.669Z\",\n    \"payCurrency\": \"btc\",\n    \"createdAt\": \"2026-09-04T19:01:13.373Z\",\n    \"minimum_amount\": 0.00029,\n    \"network\": \"Bitcoin\",\n    \"address_in\": \"3AtsETkcLm3rbM3fL8bWYvF8SCP4tCUybu\",\n    \"qr_code\": \"iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAIAAAB7GkOtAAAyP0lEQVR4nO3deZQkR30n8O8vIuvsue8ZtUbn6BihE6EDCSQwSCADNseC8fLwsjZid23Ms/2wOWyvbfbhhefnNcb4eWVpfaxt1lw25jJCiAFJaHSgW2h0jDS3RnNf3XVkRvz2j6ye7pnRTFdOV1ZndXw/j380VGdGVWbltzIi4xeiqiAiovCY6W4AERFNDwYAEVGgGABERIFiABARBYoBQEQUKAYAEVGgGABERIFiABARBYoBQEQUKAYAEVGgGABERIFiABARBYoBQEQUKAYAEVGgokyvFpGc2jFTZaq23f3Hm18R72lvw8CdY4NVUD2/j5fnQ0FkOhC8AyAiChQDgIgoUAwAIqJAMQCIiALFACAiChQDgIgoUAwAIqJAMQCIiALFACAiChQDgIgoUAwAIqJAMQCIiALFACAiClS2aqDdG6wSiZkUoTzhwNV0LILu31p+H29OW57BRy2TGfw55HTm8A6AiChQDAAiokAxAIiIAsUAICIKFAOAiChQDAAiokAxAIiIAsUAICIKFAOAiChQDAAiokAxAIiIAsUAICIKFAOAiChQDAAiokDlVQ46kyIUWC5CIdmc2pDp4+3+xZlaO+2bLUgbupfTyVCEt1YERXhrRbjm8A6AiChQDAAiokAxAIiIAsUAICIKFAOAiChQDAAiokAxAIiIAsUAICIKFAOAiChQDAAiokAxAIiIAsUAICIKFAOAiChQDAAiokDlVQ56BteKzsnAfWKDVa84vza0P2Wi1CKuQglqXNShDYUAe8AiIgCxQAgIgoUA4CIKFAMACKiQDEAiIgCxQAgIgoUA4CIKFAMACKiQDEAiIgCxQAgIgoUA4CIKFAMACKiQDEAiIgClVc10CLUMqRUEcpVTvtms255sBTh4y2CGXyIc8I7ACKiQDEAiIgCxQAgIgoUA4CIKFAMACKiQDEAiIgCxQAgIgoUA4CIKFAMACKiQDEAiIgCxQAgIgoUA4CIKFAMACKiQDEAiIgCJQNX8ZUwgEV9B6tOb36fWPefw8BVui7CaUZZ8Q6AiChQDAAiokAxAIiIAsUAICIKFAOAiChQDAAiokAxAIiIAsUAICIKFAOAiChQDAAiokAxAIiIAsUAICIKFAOAiChQDAAiokANXjnonArq5tGA/NqQSRFqBRdB98di4D6xIpxmRTDtB64IRbwztYF3AEREgWIAEBEFigFARBQoBgARUaAYAEREgWIAEBEFigFARBQoBgARUaAYAEREgWIAEBEFigFARBQoBgARUaAYAEREgcqrGmh+JTOLUEIvJ4P11qa98iJyO3MG7oQsQhtyUoTiu0U41bvHaqBERDQ5BgARUaAYAEREgWIAEBEFigFARBQoBgARUaAYAEREgWIAEBEFigFARBQoBgARUaAYAEREgWIAEBEFigFARBQoBgARUaCi6W4AMGjVVovQ2vzq9A5WYeGcWpvfIe7+cxisA4FifC9yktNRK0LFb94BEBEFigFARBQoBgARUaAYAEREgWIAEBEFigFARBQoBgARUaAYAEREgWIAEBEFigFARBQoBgARUaAYAEREgWIAEBEFigFARBQoya88bE6mversPTQAAAAASUVORK5CYII=\",\n    \"ipn_token\": \"ZEE2cW8zb1N0N2o1WW1DNHd3RXpEaUlSbWxOWmJJby1VcU5KclplQmRGWGJWUnVqaUwtNFdmSmoxcUdJUVN3ZTZ1WjVkUWZTZHZPM1RjTERabnBiVGh2SGczN3M4ZlVXeWc%3D\"\n}"
            }
          ]
        },
        {
          "name": "Affiliate Deposit",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/{ticker}/cards/reloadable/custom-affiliate.php?session={session}&amount={cents}&affiliate={wallet}&affiliate_fee=0.075",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "{ticker}",
                "cards",
                "reloadable",
                "custom-affiliate.php"
              ],
              "query": [
                {
                  "key": "session",
                  "value": "{session}"
                },
                {
                  "key": "amount",
                  "value": "{cents}"
                },
                {
                  "key": "affiliate",
                  "value": "{wallet}"
                },
                {
                  "key": "affiliate_fee",
                  "value": "0.075"
                }
              ]
            },
            "description": "Identical to Create Deposit, plus an instant percentage commission paid to your own wallet on every top-up made through your integration. Use this when you are rebranding or white-labelling the reloadable card product.\n\n Query Parameters\n\n - session: active session.\n\n - amount: the amount to fund, in integer US cents. Required, minimum 3000 ($30.00).\n\n - affiliate: your payout wallet address.\n\n - affiliate_fee: your commission as a decimal fraction. 0.075 is 7.5%.\n\n The affiliate wallet must be on the same network as the selected ticker. A Bitcoin deposit pays a Bitcoin address; an eth or erc20/* deposit pays an EVM address. A mismatch loses the commission payout.\n\n Response\n\n Same shape as Create Deposit.\n\nParameters:\n- `session` — Active session (example: `3rzSe-1JuvDX5WdYIXBX7BbSaii8hHQiNSzit9mMGYc`)\n- `amount` — $50.00, in integer US cents. Required, minimum `3000` (example: `5000`)\n- `affiliate` — Your wallet, matching the ticker's network (example: `1FTpXfNvv1obYpLLFHHh8eEK2vaLwFTHQ2`)\n- `affiliate_fee` — 7.5% commission (example: `0.075`)"
          },
          "response": [
            {
              "name": "OK — Deposit intent created with affiliate split (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/{ticker}/cards/reloadable/custom-affiliate.php?session={session}&affiliate={wallet}&affiliate_fee=0.075",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "{ticker}",
                    "cards",
                    "reloadable",
                    "custom-affiliate.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "affiliate",
                      "value": "{wallet}"
                    },
                    {
                      "key": "affiliate_fee",
                      "value": "0.075"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"id\": \"cmtnbkye5009jp207myrkr06t\",\n    \"asset\": \"BTC\",\n    \"status\": \"awaiting\",\n    \"confirmations\": 0,\n    \"expiresAt\": \"2026-09-04T20:01:13.669Z\",\n    \"payCurrency\": \"btc\",\n    \"createdAt\": \"2026-09-04T19:01:13.373Z\",\n    \"minimum_amount\": 0.00029,\n    \"network\": \"Bitcoin\",\n    \"address_in\": \"3AtsETkcLm3rbM3fL8bWYvF8SCP4tCUybu\",\n    \"qr_code\": \"iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAIAAAB7GkOtAAAyP0lEQVR4nO3d…AAAASUVORK5CYII=\",\n    \"ipn_token\": \"ZEE2cW8zb1N0N2o1WW1DNHd3RXpEaUlSbWxOWmJJby1VcU5KclplQmRGWGJWUnVqaUwtNFdmSmoxcUdJUVN3ZTZ1WjVkUWZTZHZPM1RjTERabnBiVGh2SGczN3M4ZlVXeWc%3D\"\n}"
            }
          ]
        },
        {
          "name": "Sub-affiliate Deposit",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/{ticker}/cards/reloadable/custom-sub-affiliate.php?session={session}&amount={cents}&affiliate={wallet}&affiliate_fee=0.075&sub_affiliate={wallet}&sub_affiliate_fee=0.02",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "{ticker}",
                "cards",
                "reloadable",
                "custom-sub-affiliate.php"
              ],
              "query": [
                {
                  "key": "session",
                  "value": "{session}"
                },
                {
                  "key": "amount",
                  "value": "{cents}"
                },
                {
                  "key": "affiliate",
                  "value": "{wallet}"
                },
                {
                  "key": "affiliate_fee",
                  "value": "0.075"
                },
                {
                  "key": "sub_affiliate",
                  "value": "{wallet}"
                },
                {
                  "key": "sub_affiliate_fee",
                  "value": "0.02"
                }
              ]
            },
            "description": "Two-level commission on a single deposit: you take your cut, and your own downstream partner takes theirs, both paid instantly on confirmation. Use this to run an affiliate programme of your own on top of the reloadable card product.\n\n Query Parameters\n\n - session: active session.\n\n - amount: the amount to fund, in integer US cents. Required, minimum 3000 ($30.00).\n\n - affiliate: your payout wallet.\n\n - affiliate_fee: your commission as a decimal fraction — 0.075 is 7.5%.\n\n - sub_affiliate: your partner's payout wallet.\n\n - sub_affiliate_fee: their commission as a decimal fraction — 0.02 is 2%.\n\n Both wallets must match the network of the selected ticker. In the example below the ticker is eth, so both addresses are EVM addresses.\n\n Response\n\n Same shape as Create Deposit.\n\nParameters:\n- `session` — Active session (example: `3rzSe-1JuvDX5WdYIXBX7BbSaii8hHQiNSzit9mMGYc`)\n- `amount` — $50.00, in integer US cents. Required, minimum `3000` (example: `5000`)\n- `affiliate` — Your wallet (example: `0xBEf747A2FB84b6e5D4006B10a3f93cbd45B6E504`)\n- `affiliate_fee` — 7.5% (example: `0.075`)\n- `sub_affiliate` — Partner wallet (example: `0x260c3d5a94894b489EBC7912cB70DC5c89d31d97`)\n- `sub_affiliate_fee` — 2% (example: `0.02`)"
          },
          "response": [
            {
              "name": "OK — Deposit intent created with two-level split (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/{ticker}/cards/reloadable/custom-sub-affiliate.php?session={session}&affiliate={wallet}&affiliate_fee=0.075&sub_affiliate={wallet}&sub_affiliate_fee=0.02",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "{ticker}",
                    "cards",
                    "reloadable",
                    "custom-sub-affiliate.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "affiliate",
                      "value": "{wallet}"
                    },
                    {
                      "key": "affiliate_fee",
                      "value": "0.075"
                    },
                    {
                      "key": "sub_affiliate",
                      "value": "{wallet}"
                    },
                    {
                      "key": "sub_affiliate_fee",
                      "value": "0.02"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"id\": \"cmtnbkye5009jp207myrkr06t\",\n    \"asset\": \"ETH\",\n    \"status\": \"awaiting\",\n    \"confirmations\": 0,\n    \"expiresAt\": \"2026-09-04T20:01:13.669Z\",\n    \"payCurrency\": \"eth\",\n    \"createdAt\": \"2026-09-04T19:01:13.373Z\",\n    \"minimum_amount\": 0.0042,\n    \"network\": \"Ethereum\",\n    \"address_in\": \"0x2801651C19E3d55eB52145001e70c27B2Bbe1E22\",\n    \"qr_code\": \"iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAIAAAB7GkOtAAAyP0lEQVR4nO3d…AAAASUVORK5CYII=\",\n    \"ipn_token\": \"ZEE2cW8zb1N0N2o1WW1DNHd3RXpEaUlSbWxOWmJJby1VcU5KclplQmRGWGJWUnVqaUwtNFdmSmoxcUdJUVN3ZTZ1WjVkUWZTZHZPM1RjTERabnBiVGh2SGczN3M4ZlVXeWc%3D\"\n}"
            }
          ]
        },
        {
          "name": "List Active Deposits",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/list-active-deposits.php?session={session}",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "list-active-deposits.php"
              ],
              "query": [
                {
                  "key": "session",
                  "value": "{session}"
                }
              ]
            },
            "description": "Returns the deposits this account currently holds in awaiting. Call it before you show a deposit form: an account may hold only one awaiting deposit, so if this returns a non-empty array the funding endpoints will refuse to issue another address until that one expires or is cancelled.\n\n No address and no QR code are returned here. Those exist only in the response that created the deposit — deliberately, so a stale address can never be shown as if it were live. A customer who leaves the page and comes back can be told which coin is expected and when the window closes, but must cancel and start again to get an address.\n\n Query Parameters\n\n - session: active session.\n\n Response\n\n A JSON array. It is empty when the session is valid and nothing is awaiting.\n\n - id: the deposit identifier — pass it to cancel-deposit.php.\n\n - status: awaiting for as long as the deposit is outstanding.\n\n - expiresAt: ISO-8601 UTC instant after which the deposit lapses. Render it in the customer's own time zone.\n\n - payCurrency: the coin the deposit expects, in the flattened form usdterc20 rather than the path ticker erc20/usdt.\n\nParameters:\n- `session` — Active session (example: `RRpJdT9p74zDjsaux6UC_PT93inc1Ai6fVSajgqYL_0`)"
          },
          "response": [
            {
              "name": "OK — Nothing awaiting (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/list-active-deposits.php?session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "list-active-deposits.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "[]"
            },
            {
              "name": "OK — One deposit awaiting (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/list-active-deposits.php?session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "list-active-deposits.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "[\n  {\n    \"id\": \"cmtshqrb0000fqm07uv3p3d78\",\n    \"status\": \"awaiting\",\n    \"expiresAt\": \"2026-09-08T10:52:33.128Z\",\n    \"payCurrency\": \"usdterc20\"\n  }\n]"
            }
          ]
        },
        {
          "name": "Cancel Deposit",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/cancel-deposit.php?session={session}&id={depositId}",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "cancel-deposit.php"
              ],
              "query": [
                {
                  "key": "session",
                  "value": "{session}"
                },
                {
                  "key": "id",
                  "value": "{depositId}"
                }
              ]
            },
            "description": "Cancels an awaiting deposit and frees the account to create a new one. Pass the id reported by list-active-deposits.php, or the id returned when the deposit was created. Cancelling is the only way to change coin before the window closes on its own.\n\n Cancel closes the address for good. Anything sent to a cancelled deposit address afterwards is not credited and is not recoverable. Only cancel once the customer has confirmed they have not sent, and are not about to send, to that address.\n\n Query Parameters\n\n - session: active session.\n\n - id: the awaiting deposit's identifier.\n\n Response\n\n - ok: true when the deposit was cancelled. A following call to list-active-deposits.php returns [].\n\nParameters:\n- `session` — Active session (example: `RRpJdT9p74zDjsaux6UC_PT93inc1Ai6fVSajgqYL_0`)\n- `id` — The awaiting deposit to cancel (example: `cmtshqrb0000fqm07uv3p3d78`)"
          },
          "response": [
            {
              "name": "OK — Deposit cancelled (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/cancel-deposit.php?session={session}&id={depositId}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "cancel-deposit.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "id",
                      "value": "{depositId}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\"ok\":true}"
            }
          ]
        },
        {
          "name": "Account Activity",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/account-activity.php?session={session}",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "account-activity.php"
              ],
              "query": [
                {
                  "key": "session",
                  "value": "{session}"
                }
              ]
            },
            "description": "The full ledger for the account balance: deposits in, card purchases and card loads out. This is the statement view — for movements on an individual card use card-activity.php instead.\n\n Response\n\n - ok: true on success.\n\n - pending: array of movements not yet settled — typically deposits seen on chain but still confirming. Render these separately, greyed, and do not count them in the spendable balance.\n\n - entries: array of settled ledger entries, newest first.\n\n Entry fields\n\n - id: ledger entry identifier.\n\n - kind: deposit (crypto top-up in), card_purchase (a tier fee charged by issue-card.php), or card_load (balance moved onto a card by load-card.php).\n\n - amountCents: signed. Positive credits the account, negative debits it.\n\n - balanceAfter: account balance in cents immediately after this entry — useful for reconciling a statement without re-summing.\n\n - ref: related object id. For card_purchase and card_load this is the card id; for deposit it is the deposit intent id.\n\n - note: human-readable description already formatted for display, including the fee actually charged and the exchange rate used.\n\n - createdAt: ISO-8601 UTC timestamp.\n\n Reading the example below. A 1.016607 LTC deposit at $49.43 credited 7101 ($71.01). An Aurora card was then minted for 5000 ($50.00), leaving 2101. Finally 1500 ($15.00) was taken from the balance to load a card: the 5% load fee took $0.75 and $14.25 reached the card — the amount parameter of load-card.php is what leaves the account, not what arrives on the card.\n\nParameters:\n- `session` — Active session (example: `3rzSe-1JuvDX5WdYIXBX7BbSaii8hHQiNSzit9mMGYc`)"
          },
          "response": [
            {
              "name": "OK — Account ledger (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/account-activity.php?session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "account-activity.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"pending\": [],\n    \"entries\": [\n        {\n            \"id\": \"cmtkmoz7m00kdlp07oma95yja\",\n            \"kind\": \"card_load\",\n            \"amountCents\": -1500,\n            \"balanceAfter\": 601,\n            \"ref\": \"cmtkm8nk600j7lp07gv3lis6a\",\n            \"note\": \"Loaded $14.25 onto Primary ·· 2479 · 5% load fee $0.75\",\n            \"createdAt\": \"2026-09-02T21:48:58.307Z\"\n        },\n        {\n            \"id\": \"cmtkm8nkt00j9lp07kp918b7o\",\n            \"kind\": \"card_purchase\",\n            \"amountCents\": -5000,\n            \"balanceAfter\": 2101,\n            \"ref\": \"cmtkm8nk600j7lp07gv3lis6a\",\n            \"note\": \"Aurora creation — one time, per card\",\n            \"createdAt\": \"2026-09-02T21:36:16.733Z\"\n        },\n        {\n            \"id\": \"cmtk9lgti000kmy07nw5rxmaz\",\n            \"kind\": \"deposit\",\n            \"amountCents\": 7101,\n            \"balanceAfter\": 7101,\n            \"ref\": \"cmtk91jgc00hbp907i0d5hlb3\",\n            \"note\": \"LTC top-up · 1.016607 LTC @ $49.43\",\n            \"createdAt\": \"2026-09-02T15:42:19.494Z\"\n        }\n    ]\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Cards",
      "description": "Cards are minted against the account balance and stay on the account until they are retired. list-cards.php is the centre of gravity for the whole product: it returns every card, the live tier prices, the per-account caps and what may currently be minted. Treat it as the source of truth and re-fetch it after every mutating call — never hardcode a price, a cap or a capability.",
      "item": [
        {
          "name": "List Cards & Pricing",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/list-cards.php?session={session}",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "list-cards.php"
              ],
              "query": [
                {
                  "key": "session",
                  "value": "{session}"
                }
              ]
            },
            "description": "Returns every card on the account plus the live catalogue: tier prices, discounts, per-tier caps, the account-wide card limit and current availability. Almost every other endpoint in this collection needs a value that comes from here — above all the card id, which addresses a card in load, unload, reveal, activity and wallet provisioning.\n\n Prices are dynamic. tierPriceCents, discounts and eclipseDoor.priceCents move — Eclipse in particular is a repricing door that can close or ease. Always render the price from this response at the moment of display, and re-read it immediately before charging. A hardcoded price will eventually be wrong and the mint will fail with insufficient_funds.\n\n Top-level fields\n\n - ok: true on success.\n\n - cards: array of card objects — see the Card Object reference for every field.\n\n - tierPriceCents: the one-time minting fee per tier, in cents, before discounts.\n\n - discounts: per-tier discount in cents currently applied to that tier.\n\n - discountCents: account-wide discount in cents.\n\n - eclipseDoor: Eclipse availability window — baseCents (list price), priceCents (price right now), repriced (whether the current price differs from base), closes30d and easesAt (when the door next moves; null when it is not scheduled).\n\n - eclipseUkEdition: enabled, listed, and refundFeeBps — the refund fee in basis points (400 = 4%).\n\n - walletEdition.enabled: whether the wallet-provisioning edition is live on this account at all. Gate the Apple Pay and Google Pay UI on this and on the individual card's walletEligible.\n\n - maxLiveCards: total live cards allowed on the account across all tiers.\n\n - tierCaps: maximum live cards allowed per tier.\n\n - availability.canMint: whether any card may be minted right now.\n\n - availability.byTier: per-tier mintability. A tier is offerable only when this is true.\n\n - eclipseInterest: onList / dismissed — whether this account has registered interest in Eclipse while the door is closed.\n\n - eclipseRelaunch.pending: an Eclipse relaunch is scheduled.\n\n Deriving the UI from this response\n\n The correct way to build a tier selector:\n\n - Offer a tier only when availability.canMint and availability.byTier[tier] are both true.\n\n - Price it as tierPriceCents[tier] − discounts[tier] − discountCents, floored at zero, and label Eclipse from eclipseDoor.priceCents when that differs from tierPriceCents.eclipse.\n\n - Disable it when the count of live cards of that tier has reached tierCaps[tier], or when cards.length has reached maxLiveCards.\n\n - Disable it with a \"top up\" prompt when balanceCents is below the computed price.\n\nParameters:\n- `session` — Active session (example: `3rzSe-1JuvDX5WdYIXBX7BbSaii8hHQiNSzit9mMGYc`)"
          },
          "response": [
            {
              "name": "OK — Two cards — a funded Aurora and a fresh Eclipse (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/list-cards.php?session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "list-cards.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n  \"ok\": true,\n  \"cards\": [\n    {\n      \"id\": \"cmtkm8nk600j7lp07gv3lis6a\",\n      \"status\": \"active\",\n      \"network\": \"visa\",\n      \"tier\": \"aurora\",\n      \"balanceCents\": 897,\n      \"spendableCents\": 897,\n      \"pendingCents\": 0,\n      \"clearingCents\": 0,\n      \"pendingSpendCents\": 0,\n      \"reservedCents\": 0,\n      \"unloadableCents\": 897,\n      \"holderName\": \"Max Berg\",\n      \"nameChosenByHolder\": false,\n      \"checkoutFree\": false,\n      \"aiSubsNote\": false,\n      \"edition\": null,\n      \"feeLadder\": \"standard\",\n      \"billing\": {\n        \"address\": \"Flat E, 3/F, Manning House, 52 Argyle Street, North Point\",\n        \"city\": \"Hong Kong\",\n        \"zip\": \"999077\",\n        \"country\": \"Hong Kong\"\n      },\n      \"billingCountryOnly\": null,\n      \"billingEditable\": true,\n      \"unloadSupported\": true,\n      \"billingSource\": \"holder\",\n      \"last4\": \"2479\",\n      \"expMonth\": 1,\n      \"expYear\": 2031,\n      \"label\": \"Primary\",\n      \"createdAt\": \"2026-09-02T21:36:16.709Z\",\n      \"activatedAt\": \"2026-09-02T21:36:25.757Z\",\n      \"funded\": true,\n      \"provider\": \"managed\",\n      \"otpPush\": false,\n      \"bin\": \"446614\",\n      \"walletEligible\": true,\n      \"consecutiveDeclines\": 0,\n      \"nsfLockState\": \"none\",\n      \"mccLockState\": \"none\",\n      \"tapLockState\": \"none\",\n      \"abuseLockState\": \"none\"\n    },\n    {\n      \"id\": \"cmtnchwyd00aqp207mbotyouw\",\n      \"status\": \"active\",\n      \"network\": \"mastercard\",\n      \"tier\": \"eclipse\",\n      \"balanceCents\": 0,\n      \"spendableCents\": 0,\n      \"pendingCents\": 0,\n      \"clearingCents\": 0,\n      \"pendingSpendCents\": 0,\n      \"reservedCents\": 0,\n      \"unloadableCents\": 0,\n      \"nameChosenByHolder\": true,\n      \"checkoutFree\": true,\n      \"aiSubsNote\": true,\n      \"edition\": null,\n      \"feeLadder\": \"eclipse\",\n      \"mccMode\": \"deny\",\n      \"mccCount\": 12,\n      \"billingCountryOnly\": \"United Kingdom (GB)\",\n      \"billingEditable\": false,\n      \"unloadSupported\": true,\n      \"billingSource\": \"house\",\n      \"last4\": \"3340\",\n      \"expMonth\": 8,\n      \"expYear\": 2028,\n      \"label\": \"Card 2\",\n      \"createdAt\": \"2026-09-04T19:26:51.156Z\",\n      \"activatedAt\": \"2026-09-04T19:26:59.661Z\",\n      \"funded\": false,\n      \"provider\": \"managed\",\n      \"otpPush\": true,\n      \"bin\": \"525797\",\n      \"walletEligible\": false,\n      \"consecutiveDeclines\": 0,\n      \"nsfLockState\": \"none\",\n      \"mccLockState\": \"none\",\n      \"tapLockState\": \"none\",\n      \"abuseLockState\": \"none\"\n    }\n  ],\n  \"tierPriceCents\": { \"shadow\": 2500, \"aurora\": 4500, \"eclipse\": 500 },\n  \"eclipseDoor\": {\n    \"baseCents\": 500,\n    \"priceCents\": 500,\n    \"repriced\": false,\n    \"closes30d\": 0,\n    \"easesAt\": null\n  },\n  \"eclipseUkEdition\": { \"enabled\": false, \"listed\": false, \"refundFeeBps\": 400 },\n  \"walletEdition\": { \"enabled\": true },\n  \"discounts\": { \"shadow\": 0, \"aurora\": 0, \"eclipse\": 0 },\n  \"discountCents\": 0,\n  \"maxLiveCards\": 11,\n  \"tierCaps\": { \"shadow\": 3, \"aurora\": 3, \"eclipse\": 5 },\n  \"availability\": {\n    \"canMint\": true,\n    \"byTier\": { \"aurora\": true, \"shadow\": true, \"eclipse\": true }\n  },\n  \"eclipseInterest\": { \"onList\": false, \"dismissed\": false },\n  \"eclipseRelaunch\": { \"pending\": false }\n}"
            }
          ]
        },
        {
          "name": "Issue Card",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/issue-card.php?session={session}&type=aurora",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "issue-card.php"
              ],
              "query": [
                {
                  "key": "session",
                  "value": "{session}"
                },
                {
                  "key": "type",
                  "value": "aurora"
                }
              ]
            },
            "description": "Mints a new card of the requested tier and charges the tier fee to the account balance. The only requirement is balance — there is nothing to submit, verify or approve. The holder name and billing address are assigned by the issuer.\n\n Query Parameters\n\n - session: active session.\n\n - type: aurora, shadow or eclipse. Optional — omitting it mints an aurora, which is the most expensive tier, so always send it explicitly.\n\n Response\n\n - ok: true when the card was minted.\n\n - card: the new card object. See the Card Object reference.\n\n - priceCents: what was actually charged, in cents.\n\n - discountCents: discount applied to this mint, in cents.\n\n A new card arrives as status: \"issuing\" with no last4, bin, expMonth or expYear. Those appear once the issuer activates it, usually within seconds. Poll list-cards.php until status becomes active and activatedAt is set, rather than expecting the mint response to be complete.\n\n The card mints empty and funded is false. An unfunded card cannot be revealed, cannot be added to a wallet, and declines every charge. It must first be loaded with at least $15.00 — see Load Card.\n\nParameters:\n- `session` — Active session (example: `3rzSe-1JuvDX5WdYIXBX7BbSaii8hHQiNSzit9mMGYc`)\n- `type` — Optional. aurora · shadow · eclipse. Defaults to aurora (example: `aurora`)"
          },
          "response": [
            {
              "name": "OK — Card minted — status issuing (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/issue-card.php?session={session}&type=aurora",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "issue-card.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "type",
                      "value": "aurora"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n  \"ok\": true,\n  \"card\": {\n    \"id\": \"cmtnchwyd00aqp207mbotyouw\",\n    \"status\": \"issuing\",\n    \"network\": \"visa\",\n    \"tier\": \"eclipse\",\n    \"balanceCents\": 0,\n    \"spendableCents\": 0,\n    \"pendingCents\": 0,\n    \"clearingCents\": 0,\n    \"pendingSpendCents\": 0,\n    \"reservedCents\": 0,\n    \"unloadableCents\": 0,\n    \"nameChosenByHolder\": true,\n    \"checkoutFree\": true,\n    \"aiSubsNote\": true,\n    \"edition\": null,\n    \"feeLadder\": \"eclipse\",\n    \"mccMode\": \"deny\",\n    \"mccCount\": 12,\n    \"billingCountryOnly\": \"United Kingdom (GB)\",\n    \"billingEditable\": false,\n    \"unloadSupported\": true,\n    \"billingSource\": \"house\",\n    \"label\": \"Card 2\",\n    \"createdAt\": \"2026-09-04T19:26:51.156Z\",\n    \"funded\": false,\n    \"provider\": \"managed\",\n    \"otpPush\": false,\n    \"walletEligible\": false,\n    \"consecutiveDeclines\": 0,\n    \"nsfLockState\": \"none\",\n    \"mccLockState\": \"none\",\n    \"tapLockState\": \"none\",\n    \"abuseLockState\": \"none\"\n  },\n  \"priceCents\": 500,\n  \"discountCents\": 0\n}"
            },
            {
              "name": "Error — Balance below the tier price (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/issue-card.php?session={session}&type=aurora",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "issue-card.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "type",
                      "value": "aurora"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"error\": \"insufficient_funds\",\n    \"priceCents\": 4500\n}"
            }
          ]
        },
        {
          "name": "Load Card",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/load-card.php?amount=1500&id={cardId}&session={session}",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "load-card.php"
              ],
              "query": [
                {
                  "key": "amount",
                  "value": "1500"
                },
                {
                  "key": "id",
                  "value": "{cardId}"
                },
                {
                  "key": "session",
                  "value": "{session}"
                }
              ]
            },
            "description": "Moves money from the account balance onto a card. This is what activates a freshly minted card and what tops one up afterwards.\n\n Query Parameters\n\n - amount: cents taken from the account balance. Minimum 1500 ($15.00).\n\n - id: the card id from list-cards.php.\n\n - session: active session.\n\n amount is debited from the account, not credited to the card. The load fee comes out of that amount: at the standard 5% rate, amount=1500 debits $15.00 from the balance and puts $14.25 on the card. Show the customer both figures before they confirm. The rate eases from 5% toward 3.5% (Eclipse: 3.5% easing to 2.5%) as their trailing 30-day volume grows — the note on the resulting account activity entry states the rate that was actually charged.\n\n Response\n\n A bare success acknowledgement. Re-fetch list-cards.php and session.php afterwards to pick up the new card balance, the new account balance and the flip of funded to true.\n\nParameters:\n- `amount` — Cents debited from the account balance. Minimum 1500 (example: `1500`)\n- `id` — Card id (example: `cmtnchwyd00aqp207mbotyouw`)\n- `session` — Active session (example: `3rzSe-1JuvDX5WdYIXBX7BbSaii8hHQiNSzit9mMGYc`)"
          },
          "response": [
            {
              "name": "OK — Loaded (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/load-card.php?amount=1500&id={cardId}&session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "load-card.php"
                  ],
                  "query": [
                    {
                      "key": "amount",
                      "value": "1500"
                    },
                    {
                      "key": "id",
                      "value": "{cardId}"
                    },
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true\n}"
            },
            {
              "name": "Error — Balance below the requested amount (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/load-card.php?amount=1500&id={cardId}&session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "load-card.php"
                  ],
                  "query": [
                    {
                      "key": "amount",
                      "value": "1500"
                    },
                    {
                      "key": "id",
                      "value": "{cardId}"
                    },
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"error\": \"insufficient_funds\"\n}"
            }
          ]
        },
        {
          "name": "Unload Card",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/unload-card.php?id={cardId}&session={session}&amount=1500",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "unload-card.php"
              ],
              "query": [
                {
                  "key": "id",
                  "value": "{cardId}"
                },
                {
                  "key": "session",
                  "value": "{session}"
                },
                {
                  "key": "amount",
                  "value": "1500"
                }
              ]
            },
            "description": "The reverse of Load Card: pulls money off a card and returns it to the account balance, where it can be used to load another card or mint a new one.\n\n Query Parameters\n\n - id: the card id.\n\n - session: active session.\n\n - amount: cents to pull off the card. Minimum 1500 ($15.00), maximum the card's unloadableCents.\n\n The minimum unload is 1500 ($15.00) — the same floor as Load Card. A card holding less than that in unloadableCents cannot be unloaded at all yet, so do not offer the action for it; tell the customer how much is actually free to return instead of showing a control that can only fail.\n\n Bound the amount by unloadableCents, not by balanceCents. A card's balance can include money that is spoken for — authorisations still clearing (pendingSpendCents, clearingCents) or held (reservedCents). Only unloadableCents is actually free to leave. So the amount a customer may enter is bounded on both sides: at least 1500, at most unloadableCents. Offer the action only when unloadSupported is true and unloadableCents >= 1500.\n\n Response\n\n Same shape as Load Card. Re-fetch list-cards.php and session.php afterwards.\n\nParameters:\n- `id` — Card id (example: `cmtkm8nk600j7lp07gv3lis6a`)\n- `session` — Active session (example: `Z3EkzT4Y1LRdfWgdmKCsOdRAtQ_10K57mf32bSenAxE`)\n- `amount` — Cents returned to the account balance. Minimum 1500, capped at unloadableCents (example: `1500`)"
          },
          "response": [
            {
              "name": "OK — Unloaded back to balance (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/unload-card.php?id={cardId}&session={session}&amount=1500",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "unload-card.php"
                  ],
                  "query": [
                    {
                      "key": "id",
                      "value": "{cardId}"
                    },
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "amount",
                      "value": "1500"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true\n}"
            }
          ]
        },
        {
          "name": "Card Activity",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/card-activity.php?id={cardId}&session={session}",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "card-activity.php"
              ],
              "query": [
                {
                  "key": "id",
                  "value": "{cardId}"
                },
                {
                  "key": "session",
                  "value": "{session}"
                }
              ]
            },
            "description": "Transactions on a single card: authorisations, settlements, refunds, loads and unloads. This is the card statement, as opposed to the account ledger returned by account-activity.php.\n\n This response has a different shape from Account Activity. It returns a single transactions array — there is no entries and no pending. Rows are richer, carrying a merchant, a merchant category code, a status and fees. Do not reuse the account-ledger parser here.\n\n Query Parameters\n\n - id: the card id from list-cards.php.\n\n - session: active session.\n\n Response\n\n - ok: true on success.\n\n - transactions: array of transactions, newest first.\n\n Transaction fields\n\n - id: transaction identifier.\n\n - kind: what the movement is — purchase, refund, load, unload, reversal, fee.\n\n - source: where it came from — api for card-network activity, ledger for movements you initiated such as a load.\n\n - amountCents: the amount in US cents, as a magnitude. Direction comes from kind, not from the sign — see below.\n\n - feeCents: fee charged on this transaction, in US cents. On a load this is the load fee.\n\n - intlFeeCents: international fee, in US cents, present when the charge was in a foreign currency.\n\n - status: settled, pending, authorized, reversed, declined.\n\n - merchant: merchant name, when the network supplied one. Absent on ledger movements such as a load.\n\n - mcc: the merchant's category code as a string. Check it against the closed categories to explain a decline.\n\n - currency: the currency the merchant charged in.\n\n - fx: present on a non-USD charge — { amountCents, currency }, the original amount in the merchant's own currency and its minor units. In the example below the customer was charged 386 GBP pence (£3.86), which settled as 522 US cents ($5.22).\n\n - authorizedAt: ISO-8601 UTC instant the authorisation was taken.\n\n - createdAt: ISO-8601 UTC instant the transaction was recorded.\n\n - settledAt: ISO-8601 UTC settlement instant, once settled.\n\n Amounts are unsigned, so derive the direction from kind. load, refund and reversal put money on the card; purchase, unload and fee take it off. Rendering amountCents without that mapping shows a refund and a purchase identically.\n\nParameters:\n- `id` — Card id (example: `cmtkm8nk600j7lp07gv3lis6a`)\n- `session` — Active session (example: `Z3EkzT4Y1LRdfWgdmKCsOdRAtQ_10K57mf32bSenAxE`)"
          },
          "response": [
            {
              "name": "OK — A reversed foreign refund and a card load (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/card-activity.php?id={cardId}&session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "card-activity.php"
                  ],
                  "query": [
                    {
                      "key": "id",
                      "value": "{cardId}"
                    },
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"transactions\": [\n        {\n            \"id\": \"cmtkoorngw0tas307i8roock4\",\n            \"kind\": \"refund\",\n            \"source\": \"api\",\n            \"amountCents\": 522,\n            \"feeCents\": 0,\n            \"intlFeeCents\": 7,\n            \"status\": \"reversed\",\n            \"merchant\": \"SMSPOOL\",\n            \"mcc\": \"5734\",\n            \"currency\": \"GBP\",\n            \"fx\": {\n                \"amountCents\": 386,\n                \"currency\": \"GBP\"\n            },\n            \"authorizedAt\": \"2026-09-02T22:42:52.000Z\",\n            \"createdAt\": \"2026-09-02T22:44:47.740Z\"\n        },\n        {\n            \"id\": \"cmtkmoz7m00kdlp07oma95yja\",\n            \"kind\": \"load\",\n            \"source\": \"ledger\",\n            \"amountCents\": 1425,\n            \"feeCents\": 75,\n            \"status\": \"settled\",\n            \"createdAt\": \"2026-09-02T21:48:58.307Z\",\n            \"settledAt\": \"2026-09-02T21:48:58.307Z\"\n        }\n    ]\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Security & Reveal",
      "description": "Reading a card number, and provisioning a card into Apple Pay or Google Pay, are the two sensitive operations in this API. Both sit behind a TOTP step-up: a six-digit code from an authenticator app, submitted against the session before the sensitive call will answer.\n\nThe step-up is **per session**, not per request. Once a session has been stepped up it is `trusted` and further sensitive calls succeed without another code, until that trust lapses. The correct integration pattern is therefore *optimistic*: call the sensitive endpoint first, and only prompt for a code if it answers `step_up_required`.\n\n**1. Try the sensitive call** — reveal-card-number.php or arm-wallet-code.php. If it answers, the session was already trusted, and you are done.\n\n**2. Handle step_up_required** — on `{\"error\":\"step_up_required\",\"method\":\"totp\"}`, check totp-status.php to learn whether the account has TOTP yet.\n\n**3. Enrol, if needed** — `totp_setup_required` means first use: get a secret from totp-setup.php, show it as a QR and as text, confirm with totp-submit.php with `&setup=1`.\n\n**4. Submit and retry** — send the current code to totp-submit.php without `setup`, then repeat the original call, which now answers.",
      "item": [
        {
          "name": "TOTP Status",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/totp-status.php?session={session}",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "totp-status.php"
              ],
              "query": [
                {
                  "key": "session",
                  "value": "{session}"
                }
              ]
            },
            "description": "Tells you which branch of the step-up flow to run: prompt for a code, or walk the customer through first-time enrolment.\n\n Response\n\n - ok: true.\n\n - method: totp — an authenticator is already enrolled, so ask for a code. totp_setup_required — nothing is enrolled yet, so run totp-setup.php first.\n\nParameters:\n- `session` — Active session (example: `3rzSe-1JuvDX5WdYIXBX7BbSaii8hHQiNSzit9mMGYc`)"
          },
          "response": [
            {
              "name": "OK — Authenticator already enrolled (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/totp-status.php?session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "totp-status.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"method\": \"totp\"\n}"
            },
            {
              "name": "Setup needed No authenticator enrolled yet (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/totp-status.php?session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "totp-status.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"method\": \"totp_setup_required\"\n}"
            }
          ]
        },
        {
          "name": "TOTP Setup",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/totp-setup.php?session={session}",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "totp-setup.php"
              ],
              "query": [
                {
                  "key": "session",
                  "value": "{session}"
                }
              ]
            },
            "description": "Issues the shared secret for a new authenticator enrolment. Call it only when totp-status.php returned totp_setup_required. The enrolment is not live until it is confirmed with totp-submit.php and setup=1.\n\n Response\n\n - totp_secret: a base32 secret for any standard TOTP app — Google Authenticator, Aegis, 1Password, Bitwarden and so on. Standard parameters: SHA-1, 6 digits, 30-second period.\n\n Presenting the secret\n\n Show it both ways — as a scannable QR built from an otpauth:// URI, and as the plain base32 string for manual entry. Build the URI client side:\n\n Copyotpauth://totp/PayGate.to:Reloadable%20Card?secret={totp_secret}&issuer=PayGate.to&algorithm=SHA1&digits=6&period=30\n\n Warn the customer to back the secret up before confirming. Like the account token, it is shown once. Losing the authenticator locks reveal and wallet provisioning for that account.\n\nParameters:\n- `session` — Active session (example: `tRUJ_J_OOp34gDVUZywkroKrkokU1TqmvX5TZWp4HC0`)"
          },
          "response": [
            {
              "name": "OK — Enrolment secret issued (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/totp-setup.php?session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "totp-setup.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"totp_secret\": \"BM5BVFLJBWN2XOMM4HKZHI7DRHAHJXH7\"\n}"
            }
          ]
        },
        {
          "name": "TOTP Submit",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/totp-submit.php?session={session}&code=651957",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "totp-submit.php"
              ],
              "query": [
                {
                  "key": "session",
                  "value": "{session}"
                },
                {
                  "key": "code",
                  "value": "651957"
                }
              ]
            },
            "description": "Does double duty. With setup=1 it confirms a new enrolment; without it, it steps up an existing session so sensitive calls will answer.\n\n Query Parameters\n\n - session: active session.\n\n - code: the current six-digit code from the authenticator.\n\n - setup: pass 1 only on the confirmation step of a first-time enrolment. Passing it against an account that already has TOTP fails with already_enabled.\n\n Response\n\n - ok: true when the code was accepted.\n\n - trusted: true — the session is now stepped up. Retry the sensitive call immediately.\n\n - rotated: present on enrolment; indicates whether an existing secret was replaced.\n\nParameters:\n- `session` — Active session (example: `Z3EkzT4Y1LRdfWgdmKCsOdRAtQ_10K57mf32bSenAxE`)\n- `code` — Current six-digit TOTP code (example: `651957`)\n- `setup` — Optional. First-time enrolment confirmation only (example: `1`)"
          },
          "response": [
            {
              "name": "OK — Enrolled and trusted (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/totp-submit.php?session={session}&code=651957",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "totp-submit.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "code",
                      "value": "651957"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"rotated\": false,\n    \"trusted\": true\n}"
            },
            {
              "name": "OK — Session stepped up (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/totp-submit.php?session={session}&code=651957",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "totp-submit.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "code",
                      "value": "651957"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"trusted\": true\n}"
            },
            {
              "name": "Error — setup=1 sent against an enrolled account (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/totp-submit.php?session={session}&code=651957",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "totp-submit.php"
                  ],
                  "query": [
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "code",
                      "value": "651957"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"error\": \"already_enabled\"\n}"
            }
          ]
        },
        {
          "name": "Reveal Card Number",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/reveal-card-number.php?id={cardId}&session={session}",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "reveal-card-number.php"
              ],
              "query": [
                {
                  "key": "id",
                  "value": "{cardId}"
                },
                {
                  "key": "session",
                  "value": "{session}"
                }
              ]
            },
            "description": "Returns the full card credentials: PAN, CVV, expiry and PIN. This is the most sensitive call in the collection and is gated twice — by TOTP step-up, and by the card being funded.\n\n Query Parameters\n\n - id: the card id.\n\n - session: active session, stepped up.\n\n An unfunded card will not reveal. A card whose funded is false has never been loaded; it holds nothing, declines everything and has no credentials to show. Load it with at least $15.00 first — see Load Card.\n\n Response\n\n - ok: true.\n\n - pan: the full 16-digit card number.\n\n - cvv: the three-digit security code.\n\n - expMonth / expYear: expiry, as integers.\n\n - pin: the card PIN, where the issuer provides one.\n\n Handling rules for the response. Never log it, never persist it, never send it to your own backend or analytics, and never place it in the URL, the page title or any element that a browser extension or screenshot tool would sweep up. Render it into the DOM only, mask it until the customer explicitly clicks to show, auto-hide after a short interval, and clear the variable afterwards. Card credentials belong on screen and nowhere else.\n\nParameters:\n- `id` — Card id (example: `cmtkm8nk600j7lp07gv3lis6a`)\n- `session` — Stepped-up session (example: `Z3EkzT4Y1LRdfWgdmKCsOdRAtQ_10K57mf32bSenAxE`)"
          },
          "response": [
            {
              "name": "Step-up Session is not trusted yet (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/reveal-card-number.php?id={cardId}&session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "reveal-card-number.php"
                  ],
                  "query": [
                    {
                      "key": "id",
                      "value": "{cardId}"
                    },
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"error\": \"step_up_required\",\n    \"method\": \"totp\"\n}"
            },
            {
              "name": "OK — Card credentials (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/reveal-card-number.php?id={cardId}&session={session}",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "reveal-card-number.php"
                  ],
                  "query": [
                    {
                      "key": "id",
                      "value": "{cardId}"
                    },
                    {
                      "key": "session",
                      "value": "{session}"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"pan\": \"4466148010102479\",\n    \"cvv\": \"300\",\n    \"expMonth\": 1,\n    \"expYear\": 2031,\n    \"pin\": \"089136\"\n}"
            }
          ]
        }
      ]
    },
    {
      "name": "Apple Pay & Google Pay",
      "description": "Adding a card to Apple Wallet or Google Wallet needs a verification code. The wallet app offers to send that code by SMS, phone call or email; the customer must choose **email**, because that is the channel this API listens on. The code is then relayed back to your page.\n\nThe mechanic is a short arming window: you arm a listener on the card, the customer triggers \"Get code\" inside their wallet app, and you poll for about a minute until the code arrives or the window times out.\n\n**Only offer this on cards that support it.** Show the Apple Pay and Google Pay controls when the card's `walletEligible` is `true` *and* `walletEdition.enabled` is `true` in the list-cards.php response. In the reference response, the Aurora card is `walletEligible: true` while the Eclipse card is `false` — never assume by tier, always read the field.\n\n**Order of operations matters.** Arm the listener *before* the customer presses \"Get code\" in their wallet app, not after. A code that arrives while nothing is armed is discarded, and the customer has to start the wallet flow again.",
      "item": [
        {
          "name": "Arm Wallet Code",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/arm-wallet-code.php?id={cardId}&session={session}&type=apple",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "arm-wallet-code.php"
              ],
              "query": [
                {
                  "key": "id",
                  "value": "{cardId}"
                },
                {
                  "key": "session",
                  "value": "{session}"
                },
                {
                  "key": "type",
                  "value": "apple"
                }
              ]
            },
            "description": "Opens a one-minute window during which a wallet verification code for this card will be captured and made available to check-wallet-code.php.\n\n Query Parameters\n\n - id: the card id.\n\n - session: active session — this call is step-up protected, exactly like reveal.\n\n - type: apple or google.\n\n Response\n\n - ok: true.\n\n - status: arming — the window is open. Begin polling.\n\nParameters:\n- `id` — Card id (example: `cmtkm8nk600j7lp07gv3lis6a`)\n- `session` — Stepped-up session (example: `Z3EkzT4Y1LRdfWgdmKCsOdRAtQ_10K57mf32bSenAxE`)\n- `type` — apple or google (example: `apple`)"
          },
          "response": [
            {
              "name": "Step-up Session is not trusted yet (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/arm-wallet-code.php?id={cardId}&session={session}&type=apple",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "arm-wallet-code.php"
                  ],
                  "query": [
                    {
                      "key": "id",
                      "value": "{cardId}"
                    },
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "type",
                      "value": "apple"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"error\": \"step_up_required\",\n    \"method\": \"totp\"\n}"
            },
            {
              "name": "OK — Listener armed (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/arm-wallet-code.php?id={cardId}&session={session}&type=apple",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "arm-wallet-code.php"
                  ],
                  "query": [
                    {
                      "key": "id",
                      "value": "{cardId}"
                    },
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "type",
                      "value": "apple"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"status\": \"arming\"\n}"
            }
          ]
        },
        {
          "name": "Check Wallet Code",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "https://api.paygate.to/crypto/cards/reloadable/check-wallet-code.php?id={cardId}&session={session}&type=apple",
              "protocol": "https",
              "host": [
                "api",
                "paygate",
                "to"
              ],
              "path": [
                "crypto",
                "cards",
                "reloadable",
                "check-wallet-code.php"
              ],
              "query": [
                {
                  "key": "id",
                  "value": "{cardId}"
                },
                {
                  "key": "session",
                  "value": "{session}"
                },
                {
                  "key": "type",
                  "value": "apple"
                }
              ]
            },
            "description": "Polls the armed window. Call it every 10 seconds after arming, for as long as the status stays arming.\n\n Query Parameters\n\n - id: the card id.\n\n - session: active session.\n\n - type: apple or google — must match what was armed.\n\n Response\n\n - ok: true.\n\n - status: arming while the window is open and no code has arrived; ready once a code has been captured; timeout if the minute elapses with nothing captured.\n\n - code: the six digits, present when status is ready. Stop polling and show them.\n\n - expiresAt: the ISO-8601 UTC instant the arming window closes. It describes the window, not the life of the code — a captured code is not invalidated when this passes. Use it to anchor your countdown.\n\n - armedAt: ISO-8601 UTC instant the window opened, returned while arming. With the one-minute window this gives the same deadline as expiresAt; anchor the countdown to whichever you receive rather than to a local counter, so a throttled background tab cannot make it drift.\n\n There is one deadline, and it is the arming window — not the code. expiresAt tells you when the window to capture a code closes. Once ready has handed you the six digits, that countdown has done its job.\n\n Never hide or expire a captured code. Leave it on screen for the rest of the session. The customer has to switch to their wallet app to type it in, and a code that disappears while they are doing so cannot be recovered — they would have to arm and capture all over again. Offer a \"request another code\" control instead, so a new one is always a click away.\n\n timeout is recoverable and common. It usually means the customer had not yet pressed \"Get code\", or picked SMS instead of email. Show a plain \"no code arrived — try again\" state with a single button that re-arms, and repeat the reminder to choose Email in the wallet app.\n\nParameters:\n- `id` — Card id (example: `cmtkm8nk600j7lp07gv3lis6a`)\n- `session` — Active session (example: `Z3EkzT4Y1LRdfWgdmKCsOdRAtQ_10K57mf32bSenAxE`)\n- `type` — Must match the armed type (example: `apple`)"
          },
          "response": [
            {
              "name": "Waiting Window open — keep polling (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/check-wallet-code.php?id={cardId}&session={session}&type=apple",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "check-wallet-code.php"
                  ],
                  "query": [
                    {
                      "key": "id",
                      "value": "{cardId}"
                    },
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "type",
                      "value": "apple"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"status\": \"arming\",\n    \"armedAt\": \"2026-09-04T21:09:13.214Z\"\n}"
            },
            {
              "name": "Timeout Minute elapsed, no code captured (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/check-wallet-code.php?id={cardId}&session={session}&type=apple",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "check-wallet-code.php"
                  ],
                  "query": [
                    {
                      "key": "id",
                      "value": "{cardId}"
                    },
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "type",
                      "value": "apple"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"status\": \"timeout\",\n    \"armedAt\": \"2026-09-04T21:09:21.749Z\"\n}"
            },
            {
              "name": "Ready Code captured — show it and stop polling (200)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.paygate.to/crypto/cards/reloadable/check-wallet-code.php?id={cardId}&session={session}&type=apple",
                  "protocol": "https",
                  "host": [
                    "api",
                    "paygate",
                    "to"
                  ],
                  "path": [
                    "crypto",
                    "cards",
                    "reloadable",
                    "check-wallet-code.php"
                  ],
                  "query": [
                    {
                      "key": "id",
                      "value": "{cardId}"
                    },
                    {
                      "key": "session",
                      "value": "{session}"
                    },
                    {
                      "key": "type",
                      "value": "apple"
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n    \"ok\": true,\n    \"status\": \"ready\",\n    \"code\": \"641614\",\n    \"expiresAt\": \"2026-09-04T15:13:40.631Z\"\n}"
            }
          ]
        }
      ]
    }
  ],
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://api.paygate.to",
      "type": "string"
    }
  ]
}
