> ## Documentation Index
> Fetch the complete documentation index at: https://docs.supercash.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Follow these steps for integration

> [!TIP]
>
> To start using the API, you need whitelisting from the team.
>
> Email us at [support@supercash.me](mailto:support@supercash.me) or\
> Message us on Telegram at [**https://supercash.me/join-tg**](https://supercash.me/join-tg)

## API Base URL

SuperCash API endpoints are hosted at: `https://api.supercash.me`

## Prerequisites

Every API user requires a SuperCash wallet:

1. **Sign up** for a SuperCash account at [https://app.supercash.me](https://app.supercash.me)
2. **Export your private key** at [https://app.supercash.me/export](https://app.supercash.me/export) - this is the key you authenticate and sign payments with.
3. **Fund the exported wallet** with:
   1. USDC or USDT on one of the supported chains, **and**
   2. the chain's native token for gas (ETH on Arbitrum/Base, BNB on BSC).
4. **(Optional) Complete KYC** at [https://app.supercash.me/kyc](https://app.supercash.me/kyc)
   1. Doubles daily and monthly payment limits

## 1. Authenticate

All payment endpoints require `Authorization: Bearer <token>`. Get the token via SIWE.

This token is valid for up to **7 days**. Re-authenticate when it expires.

The wallet you authenticate with must be the same wallet that signs the payment transaction.

**1. Request a payload**

```bash theme={null}
POST /auth/payload
{ "address": "0xYourWalletAddress" }
```

Response:

```bash theme={null}
{
  "address": "0xYourWalletAddress",
  "chainId": 56,
  "domain": "mobile.supercash.me",
  "uri": "https://mobile.supercash.me",
  "nonce": "aBc123dE",
  "statement": "Sign in to SuperCash",
  "version": "1",
  "notBefore": "2026-10-07T10:00:00.000Z"
}
```

**2. Build the SIWE message and sign it (personal\_sign)**

```bash theme={null}
import { SiweMessage } from 'siwe';
import { privateKeyToAccount } from 'viem/accounts';

const account = privateKeyToAccount('0x...');

const message = new SiweMessage({
  domain: payload.domain,
  address: payload.address,
  uri: payload.uri,
  version: payload.version,
  chainId: payload.chainId,
  nonce: payload.nonce,
  statement: payload.statement,
  issuedAt: new Date().toISOString(),
}).prepareMessage();

const signature = await account.signMessage({ message });
```

**3. Exchange it for a JWT**

```bash theme={null}
POST /auth/login
{ "message": "<the message you signed>", "signature": "<signature>" }
```

Response:

```bash theme={null}
{ "token": "eyJ..." }
```

## 2. Create an order

```bash theme={null}
POST /v1/payment/orders
{
  "qr": "<qr string>",
  "amount": "100000",      // required only if the QR has no amount; local fiat
  "chainIds": [56]
}
```

Response:

```bash theme={null}
{
  "data": {
    "id": "SC-8f3k2...",
    "fiatAmount": "100000",
    "fiatCurrency": "VND",
    "fiatRate": "0.0000380",
    "usdAmount": "3.80",
    "expiresAt": "2026-10-07T10:15:00.000Z",
    "routes": [
      {
        "chainId": 56,
        "token": "0x55d398326f99059fF775485246999027B3197955",
        "address": "0xf2B013591B02F51a6454aBdF6C1a7da6288575FF",
        "amount": "3800000000000000000"
      }
    ]
  }
}
```

* **Pick one route** to pay with. Each route is a (chain, token) pair.
* `address` - the recipient wallet for that chain. Differs per chain; never hardcode it.
* `amount` - exactly what to transfer, in the token's **base units** (USDC/USDT use 6 decimals on Arbitrum/Base, 18 on BSC — `amount` already accounts for this).
* `token` - the ERC-20 contract to call `transfer` on.
* The order expires at `expiresAt` (**15 minutes**). Submit the payment before then.

## 3. Sign the transfer

Build a regular ERC-20 `transfer(route.address, route.amount)` transaction on the route's chain and sign it with your private key.

```bash theme={null}
import { createWalletClient, http, encodeFunctionData } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { bsc } from 'viem/chains';

const account = privateKeyToAccount('0x...');
const walletClient = createWalletClient({
  account,
  chain: bsc,
  transport: http(process.env.BSC_RPC_URL),
});

const ERC20_ABI = [
  {
    name: 'transfer',
    type: 'function',
    stateMutability: 'nonpayable',
    inputs: [
      { name: 'to', type: 'address' },
      { name: 'amount', type: 'uint256' },
    ],
    outputs: [{ type: 'bool' }],
  },
] as const;

const signedTransaction = await walletClient.signTransaction({
  chain: bsc,
  to: route.token, // the route's token contract
  data: encodeFunctionData({
    abi: ERC20_ABI,
    functionName: 'transfer',
    args: [route.address, BigInt(route.amount)],
  }),
  account,
});
```

Requirements - the API validates all of these and rejects otherwise:

* Signs an ERC-20 `transfer` of **exactly** `route.amount` base units
* Recipient is **exactly** `route.address`
* Token contract is the route's `token` on the route's `chainId`
* Signed by the wallet you authenticated with

## 4. Submit the signed transaction

```bash theme={null}
POST /v1/payment/orders/transaction
{
  "orderId": "SC-8f3k2...",
  "chainId": 56,
  "signedTransaction": "0x02f8b0..."
}
```

Response:

```bash theme={null}
{ "data": { "hash": "0xabc123..." } }
```

We verify the transaction against your order's quote, broadcast it onchain and wait for it to land. `chainId` must match the route you paid.

## 5. Poll the order status

```bash theme={null}
GET /v1/payment/orders/SC-8f3k2...
```

Response:

```bash theme={null}
{
  "data": {
    "status": "SUCCESS",
    "hash": "0xabc123...",
    "message": null,
    "expiresAt": "2026-10-07T10:15:00.000Z"
  }
}
```

<table>
  <colgroup>
    <col width="166" />

    <col width="282" />
  </colgroup>

  <thead>
    <tr>
      <th>Status</th>
      <th>Meaning</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>`PENDING`</td>
      <td>Payment submitted, not yet confirmed: keep polling</td>
    </tr>

    <tr>
      <td>`SUCCESS`</td>
      <td>Confirmed: fiat sent to recipient</td>
    </tr>

    <tr>
      <td>`FAIL`</td>
      <td>Failed: see `message` for the reason</td>
    </tr>

    <tr>
      <td>`REFUND`</td>
      <td>Failed after payment, crypto was refunded onchain</td>
    </tr>

    <tr>
      <td>`TIMEOUT`</td>
      <td>Expired without payment</td>
    </tr>
  </tbody>
</table>

Poll every 5–10 seconds until the status leaves `PENDING`. `SUCCESS`/`FAIL`/`REFUND`/`TIMEOUT` are terminal.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.