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

# Withdraw Funds with the Gcashier Pay Payout API

> Register a withdrawal payee, initiate a payout, and track the result via webhook — a complete guide to the Gcashier Pay withdrawal flow.

Gcashier Pay's payout system lets you withdraw your collected and exchanged balances to a registered bank account. Before you can initiate a withdrawal, you must register the destination account as a **withdrawal payee** via **sp1401** and wait for Gcashier Pay's approval. Once the payee is active, withdrawals are as simple as a single API call — you'll receive a real-time status in the response and a final settlement result via the **sp3303** webhook.

## Overview

<Steps>
  <Step title="Register a withdrawal payee (sp1401)">
    Submit the destination bank account details for compliance review.
  </Step>

  <Step title="Receive payee approval (sp3401 webhook)">
    Gcashier Pay delivers the approved `payeeId` to your callback URL.
  </Step>

  <Step title="Initiate a withdrawal (sp1305)">
    Submit the withdrawal request referencing the approved `payeeId`.
  </Step>

  <Step title="Receive the withdrawal result (sp3303 webhook)">
    Gcashier Pay posts the final settlement outcome to your callback URL.
  </Step>

  <Step title="Query withdrawal history (sp2303)">
    Look up past withdrawals by flow reference or time range.
  </Step>
</Steps>

***

## Step 1 — Register a Withdrawal Payee

Call **POST /api/sp1401** with `payeeType` set to `WITHDRAW_PAYEE` to register the bank account you want to withdraw funds into. Gcashier Pay will review the account details before activating the payee.

<Note>
  The **account name** on the registered payee must exactly match your merchant's registered business name. Mismatches will cause the payee application — and subsequent withdrawals — to be rejected.
</Note>

<CodeGroup>
  ```json sp1401 Request — Withdrawal Payee theme={null}
  {
    "merOrderNo": "PAYEE20240601001",
    "payeeType": "WITHDRAW_PAYEE",
    "payeeName": "Acme Trade Pte Ltd",
    "bankName": "DBS Bank Ltd",
    "bankAccountNo": "0012345678",
    "bankCode": "7171",
    "swiftCode": "DBSSSGSG",
    "currency": "USD",
    "countryCode": "SG",
    "bankAddress": "12 Marina Boulevard, DBS Asia Central, Singapore 018982",
    "callbackUrl": "https://api.acme-trade.com/webhooks/gcashier/payee-result"
  }
  ```

  ```json sp1401 Response theme={null}
  {
    "bizFlowNo": "BF20240601000501",
    "code": "S00001",
    "message": "Payee registration submitted and under review."
  }
  ```
</CodeGroup>

Store `bizFlowNo` to correlate the approval webhook when it arrives.

***

## Step 2 — Receive Payee Approval (sp3401 Webhook)

Once Gcashier Pay's compliance team approves the payee, an **sp3401** webhook is posted to your `callbackUrl`. The payload includes the `payeeId` you'll use in all subsequent withdrawal requests.

<CodeGroup>
  ```json sp3401 Webhook — Approved theme={null}
  {
    "bizFlowNo": "BF20240601000501",
    "merOrderNo": "PAYEE20240601001",
    "code": "S00000",
    "message": "Payee approved.",
    "payeeId": "PYE0000234",
    "payeeName": "Acme Trade Pte Ltd",
    "bankAccountNo": "0012345678",
    "status": "ACTIVE"
  }
  ```

  ```json sp3401 Webhook — Rejected theme={null}
  {
    "bizFlowNo": "BF20240601000501",
    "merOrderNo": "PAYEE20240601001",
    "code": "S00002",
    "message": "Payee rejected: account name does not match merchant registration.",
    "payeeId": "",
    "status": "REJECTED"
  }
  ```
</CodeGroup>

<Warning>
  Do not hard-code `payeeId` values in your application. Always retrieve them dynamically from webhook deliveries or your own database, as payee IDs are environment-specific and differ between sandbox and production.
</Warning>

***

## Step 3 — Initiate a Withdrawal

With an approved `payeeId`, call **POST /api/sp1305** to initiate the withdrawal. Provide the amount, your internal order reference, and a callback URL for the result notification.

<CodeGroup>
  ```json sp1305 Request theme={null}
  {
    "merOrderNo": "WD20240601001",
    "payeeId": "PYE0000234",
    "amount": "8500.00",
    "remark": "Monthly revenue withdrawal - June 2024",
    "callbackUrl": "https://api.acme-trade.com/webhooks/gcashier/withdrawal-result"
  }
  ```

  ```json sp1305 Response theme={null}
  {
    "merOrderNo": "WD20240601001",
    "bizFlow": "BF20240601000601",
    "status": "PROCESS",
    "code": "ACCEPT",
    "message": "Withdrawal request accepted and processing."
  }
  ```
</CodeGroup>

| Response `code` | Meaning                                               |
| --------------- | ----------------------------------------------------- |
| `ACCEPT`        | Withdrawal accepted — processing has begun            |
| `SUCC`          | Withdrawal completed immediately (rare in production) |
| `FAIL`          | Withdrawal rejected at submission — check `message`   |

A `status` of `PROCESS` is the normal initial state. The definitive settlement result arrives via the **sp3303** webhook.

***

## Step 4 — Receive the Withdrawal Result Webhook (sp3303)

Gcashier Pay posts the final outcome to your `callbackUrl` once the bank transfer completes or fails. Respond with HTTP 200 to acknowledge receipt.

<CodeGroup>
  ```json sp3303 Webhook — Success theme={null}
  {
    "bizFlow": "BF20240601000601",
    "merOrderNo": "WD20240601001",
    "payeeId": "PYE0000234",
    "payeeName": "Acme Trade Pte Ltd",
    "bankAccountNo": "0012345678",
    "amount": "8500.00",
    "currency": "USD",
    "status": "SUCC",
    "code": "S00000",
    "message": "Withdrawal completed. Funds credited to bank account.",
    "completedTime": "2024-06-01 16:45:22"
  }
  ```

  ```json sp3303 Webhook — Failed theme={null}
  {
    "bizFlow": "BF20240601000601",
    "merOrderNo": "WD20240601001",
    "payeeId": "PYE0000234",
    "amount": "8500.00",
    "currency": "USD",
    "status": "FAIL",
    "code": "E00021",
    "message": "Withdrawal failed: bank account number invalid.",
    "completedTime": "2024-06-01 16:46:05"
  }
  ```
</CodeGroup>

| Status    | Meaning                                                                  |
| --------- | ------------------------------------------------------------------------ |
| `SUCC`    | Funds have been credited to the payee's bank account                     |
| `FAIL`    | Transfer failed — balance has been refunded to your Gcashier Pay account |
| `PROCESS` | Transfer is still in progress — a subsequent webhook will follow         |

***

## Step 5 — Query Withdrawal History

Use **POST /api/sp2303** to retrieve past withdrawal records. You can query by `bizFlow`, `merOrderNo`, or a time range.

<CodeGroup>
  ```json sp2303 Request — by bizFlow theme={null}
  {
    "bizFlow": "BF20240601000601"
  }
  ```

  ```json sp2303 Request — by time range theme={null}
  {
    "startTime": "2024-06-01 00:00:00",
    "endTime": "2024-06-30 23:59:59"
  }
  ```

  ```json sp2303 Response theme={null}
  {
    "code": "S00000",
    "message": "success",
    "data": [
      {
        "bizFlow": "BF20240601000601",
        "merOrderNo": "WD20240601001",
        "payeeId": "PYE0000234",
        "payeeName": "Acme Trade Pte Ltd",
        "bankAccountNo": "0012345678",
        "amount": "8500.00",
        "currency": "USD",
        "status": "SUCC",
        "completedTime": "2024-06-01 16:45:22"
      }
    ]
  }
  ```
</CodeGroup>

<Tip>
  For monthly reconciliation, query sp2303 with a time range covering the full calendar month. Cross-reference each `bizFlow` against your internal `merOrderNo` records to verify all payouts are accounted for.
</Tip>

***

## Sandbox Testing

In the Gcashier Pay sandbox environment, the withdrawal outcome is controlled by the **last digit of `bankAccountNo`** registered on the payee:

| Last digit of `bankAccountNo` | Simulated result                                                 |
| ----------------------------- | ---------------------------------------------------------------- |
| `0` – `3`                     | `SUCC` — withdrawal completes successfully                       |
| `4` – `6`                     | `FAIL` — withdrawal rejected by the bank                         |
| `7` – `9`                     | No action — the withdrawal stays in `PROCESS` state indefinitely |

For end-to-end sandbox testing, register a payee with a `bankAccountNo` ending in `1` to reliably receive a success webhook.
