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

# Pay

> Initiate a payment for Mini Program or agreement-based scenarios.

`POST /v1/payments/pay`

Initiates a payment. Supports Mini Program cashier flows and agreement-based (recurring) payment scenarios.

## Request Parameters

<ParamField body="productCode" type="string" required>
  Payment product code assigned by Rebell (e.g., `51051000000011`).

  **Max length**: 32 characters
</ParamField>

<ParamField body="paymentRequestId" type="string" required>
  Merchant-generated unique identifier (idempotency key).

  **Max length**: 64 characters
</ParamField>

<ParamField body="paymentAmount" type="object" required>
  Payment amount. See [Amount](/openapis/v1/data-dictionary#amount).
</ParamField>

<ParamField body="paymentAuthCode" type="string">
  Authorization code.

  **Max length**: 128 characters
</ParamField>

<ParamField body="paymentExpiryTime" type="string">
  Payment expiry time in ISO 8601 format.
</ParamField>

<ParamField body="paymentNotifyUrl" type="string">
  Merchant callback URL for payment result notifications.

  **Max length**: 1024 characters
</ParamField>

<ParamField body="paymentRedirectUrl" type="string">
  URL to redirect the user to after payment.

  **Max length**: 1024 characters
</ParamField>

<ParamField body="cashierNotifyUrl" type="string">
  Cashier notification URL.

  **Max length**: 1024 characters
</ParamField>

<ParamField body="order" type="object">
  Order details including merchant, buyer, and goods information. See [Order](/openapis/v1/data-dictionary#order).

  For Mini Program and in-app payment flows, `order.env` is required and must include:

  * `terminalType`: `APP`
  * `osType`: `IOS` or `ANDROID`
</ParamField>

<ParamField body="agreedAmount" type="object">
  For agreement-based transactions. See [Amount](/openapis/v1/data-dictionary#amount).
</ParamField>

<ParamField body="serviceExpireTime" type="string">
  Service expiry date. Format: `yyyy-MM-dd`
</ParamField>

<ParamField body="nextPaymentDate" type="string">
  Next scheduled payment date. Format: `yyyy-MM-dd`
</ParamField>

<ParamField body="extendInfo" type="string">
  JSON-formatted extension data.

  **Max length**: 2048 characters

  | Sub-field             | Required                                                     | Description                                                                                                           |
  | --------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
  | `channelSource`       | Required for Mini Program flows                              | Payment channel origin. Use `MERCHANT_MP` for Mini Program, `MERCHANT_APP` for native app, `MOBILE_H5` for mobile H5. |
  | `supportMultiConfirm` | Required for auth-capture (`productCode` ending `...000012`) | Set to `true` to enable multi-confirmation auth-capture flow.                                                         |
  | `miniAppId`           | Optional                                                     | Mini Program app identifier.                                                                                          |
</ParamField>

## Response Parameters

<ResponseField name="result" type="object" required>
  Standard result object with `resultCode`, `resultStatus`, `resultMessage`
</ResponseField>

<ResponseField name="paymentRequestId" type="string">
  Echo of the merchant-provided request identifier.
</ResponseField>

<ResponseField name="paymentId" type="string">
  Wallet-generated unique payment ID.

  **Max length**: 64 characters
</ResponseField>

<ResponseField name="paymentTime" type="string">
  Payment completion time in ISO 8601 format.
</ResponseField>

<ResponseField name="redirectActionForm" type="object">
  Redirect instruction returned when the payment requires an H5 cashier step (e.g. direct pay and auth-capture flows with `MOBILE_H5` channel source).

  | Sub-field     | Type   | Description                                                             |
  | ------------- | ------ | ----------------------------------------------------------------------- |
  | `method`      | string | HTTP method for the redirect (usually `GET`)                            |
  | `redirectUrl` | string | H5 cashier page URL. Include a `sign` query parameter signed by Rebell. |

  <Warning>
    **Double-encode the `sign` parameter before rendering `redirectUrl` as a QR code.**

    The H5 cashier page decodes the URL once before parsing query parameters. Base64 characters in `sign` that are percent-encoded as `%2B` (`+`), `%2F` (`/`), or `%3D` (`=`) become `+`, `/`, `=` after that decode — but `+` is then parsed as a space, causing a `PUB_VERIFY_SIGN_ERROR`.

    Fix: replace those characters with their double-percent equivalents so they survive the H5 decode intact:

    ```js theme={null}
    function doubleEncodeSign(url) {
      return url.replace(/([?&]sign=)([^&#]*)/, (_, prefix, signVal) =>
        prefix + signVal
          .replace(/%2B/gi, '%252B')
          .replace(/%2F/gi, '%252F')
          .replace(/%3D/gi, '%253D')
          .replace(/\+/g, '%252B')
      );
    }

    const safeUrl = doubleEncodeSign(redirectActionForm.redirectUrl);
    await QRCode.toCanvas(canvas, safeUrl, { width: 300 });
    ```

    This is only needed when embedding the URL in a QR code. For direct browser redirects (`window.location.href = redirectUrl`), use the URL as-is.
  </Warning>
</ResponseField>

## Result Codes

| resultStatus | resultCode                            | Description                              |
| ------------ | ------------------------------------- | ---------------------------------------- |
| `S`          | `SUCCESS`                             | Payment successful                       |
| `A`          | `ACCEPT`                              | Accepted, further action required        |
| `F`          | `PARAM_ILLEGAL`                       | Invalid parameters                       |
| `F`          | `PROCESS_FAIL`                        | Processing failed                        |
| `F`          | `ACCESS_DENIED`                       | Access denied                            |
| `F`          | `USER_NOT_EXIST`                      | User does not exist                      |
| `F`          | `CURRENCY_NOT_SUPPORT`                | Currency not supported                   |
| `F`          | `PAYMENT_AMOUNT_EXCEED_LIMIT`         | Payment amount exceeds limit             |
| `F`          | `USER_AMOUNT_EXCEED_LIMIT`            | User amount exceeds limit                |
| `F`          | `REPEAT_REQ_INCONSISTENT`             | Duplicate request with inconsistent data |
| `F`          | `AUTH_CODE_ALREADY_USED`              | Auth code already used                   |
| `F`          | `PARTNER_STATUS_ABNORMAL`             | Partner status abnormal                  |
| `F`          | `USER_STATUS_ABNORMAL`                | User status abnormal                     |
| `F`          | `PARTNER_NOT_EXIST`                   | Partner does not exist                   |
| `F`          | `INVALID_ACCESS_TOKEN`                | Access token is invalid                  |
| `F`          | `RISK_REJECT`                         | Transaction rejected by risk engine      |
| `U`          | `UNKNOWN_EXCEPTION`                   | Unknown error occurred                   |
| `U`          | `ORDER_AMOUNT_EXCEED_CONTRACT_LIMIT`  | Order amount exceeds contract limit      |
| `U`          | `CONTRACT_DEFAULT_PAY_METHOD_INVALID` | Default payment method invalid           |
