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

> ## Agent Instructions
> Describe only the public 123hub merchant API documented on this site. The primary endpoint is POST /public/api/multihub/v1.
> Preserve API method names, field names, header names, and error codes exactly as documented. Do not invent endpoints or parameters.
> Treat every amount as an integer in minor units unless a page explicitly states otherwise.
> Never expose, request, or fabricate a merchant secret key. The SDK pages contain reference implementations, not official SDK packages.

# API Reference Overview

> Public API surfaces and source-of-truth contracts for 123hub integrations

# API Reference

The public merchant API is centered on the payment API endpoint:

```http theme={null}
POST https://api.bafanglaicai88.com/public/api/multihub/v1
```

All method-dispatched operations in this surface use that URL; the JSON body
`method` field selects the operation. Webhook resend is a separate route listed
below and has a stricter route-bound signature contract.

## Public Surfaces

| Surface                 | Endpoint                                      | Audience                                 | Authentication                                                        |
| ----------------------- | --------------------------------------------- | ---------------------------------------- | --------------------------------------------------------------------- |
| 123hub API              | `POST /public/api/multihub/v1`                | Merchant backend integrations            | `X-Data-Application-Id` + `X-Data-Hash`; optional replay pair         |
| Outgoing webhooks       | Merchant callback URL                         | Merchant webhook receivers               | Signed with `X-Data-Hash` and webhook metadata headers                |
| Merchant webhook resend | `/api/v1/payments/{paymentId}/webhook/resend` | Re-queue callback for a terminal payment | Raw-body hash or optional route-bound replay pair + `webhooks.update` |

Provider callback endpoints, health checks, metrics, and internal admin APIs are not part of the merchant-facing public API documentation.

## API Methods

| Method                 | Description                                                                       | `service_id` |
| ---------------------- | --------------------------------------------------------------------------------- | ------------ |
| `payment.in`           | Create a deposit                                                                  | Required     |
| `payment.out`          | Create a withdrawal                                                               | Required     |
| `payment.status`       | Get payment status by `c_id` or `h_id`                                            | Optional     |
| `payment.notification` | Re-send webhook notification by `c_id` or `h_id`; optional durable `operation_id` | Optional     |
| `balance.get`          | Get merchant balances                                                             | Optional     |
| `gateway.ping`         | Verify credentials and connectivity                                               | Not used     |
| `ticket.*`             | Create/read/update tickets and merchant-visible comments                          | Not allowed  |
| `refund.*`             | Request/read monetary refunds and merchant-visible comments                       | Not allowed  |
| `chargeback.*`         | Read chargeback history and evidence                                              | Not allowed  |
| `attachment.*`         | Prepare/finalize/read safe support attachments                                    | Not allowed  |

See [API Methods](/api-reference/methods) for request and response shapes and [Support API fundamentals](/guides/support-api) for strict support authentication, idempotency, scopes and pagination.

## Authentication

Requests to `POST /public/api/multihub/v1` require
`X-Data-Application-Id` and `X-Data-Hash`. For that method-dispatched endpoint,
timestamp and nonce are optional:

| Header                  | Type         | Description                                                |
| ----------------------- | ------------ | ---------------------------------------------------------- |
| `X-Data-Application-Id` | integer      | Application ID issued during onboarding                    |
| `X-Data-Hash`           | string       | Lowercase SHA-512 hex hash of `rawRequestBody + secretKey` |
| `X-Data-Timestamp`      | Unix seconds | Optional current request timestamp for replay protection   |
| `X-Data-Nonce`          | string       | Optional unique nonce for this request                     |

The bytes you hash must match the HTTP request body exactly. Compact JSON and pretty JSON produce different signatures.

Send `X-Data-Timestamp` and `X-Data-Nonce` as a pair when you use replay proof.
Every method dispatched through `/public/api/multihub/v1` accepts requests with
neither replay header; one-without-the-other is rejected. If replay storage is
temporarily unavailable, a correctly signed request is not rejected solely
because it included the optional pair.

`POST /api/v1/payments/{paymentId}/webhook/resend` also requires only
application id and hash. Without replay headers it signs the raw request body;
with the complete optional pair it uses the route-bound v1 signature described
in [Webhooks](/api-reference/webhooks). Its body requires `payment_id` and
`operation_id`.

Successful and error responses may include an `X-Data-Hash` response header. When present, it is computed as:

```text theme={null}
SHA512(JSON.stringify(responseBody) + secretKey)
```

## Response Envelope

Successful responses return HTTP 200:

```json theme={null}
{
  "success": true,
  "result": {},
  "request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "processing_time": 42
}
```

Errors use HTTP 400 for validation/authentication, 403 for scope/policy denial, 404 for unknown methods or tenant-safe absence, 409 for state/idempotency conflicts, 429 for quotas, and 503 for unavailable support dependencies:

```json theme={null}
{
  "success": false,
  "error": {
    "code": 6010,
    "message": "Payment does not exist",
    "details": null,
    "context": null
  },
  "request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "processing_time": 5
}
```

Always use `success` as the primary outcome flag. HTTP status only separates transport-level success from API errors.

## Identifiers

| Identifier | Direction            | Description                                                                                      |
| ---------- | -------------------- | ------------------------------------------------------------------------------------------------ |
| `c_id`     | Request and response | Merchant-supplied unique reference. Required when creating a payment.                            |
| `h_id`     | Response             | Hub-assigned payment identifier. Can be used for `payment.status` and `payment.notification`.    |
| `p_id`     | Response             | Provider transaction identifier. It is returned when known, but is not accepted as a lookup key. |
| `utr`      | Response             | Provider/bank tracking reference when available.                                                 |

## Rate Limits

The public API controller is not limited by the default gateway IP throttler, but authenticated applications have per-method protective buckets for payment, balance, ticket, refund, chargeback, and attachment methods. Buckets are keyed by merchant/application and method. When a bucket is exhausted, the API returns HTTP `429` with the standard API error envelope and `Retry-After-*` headers; retry with backoff rather than tight polling.

HTTP `403` is used for credential-policy or merchant-ownership denials. DTO validation errors use code `9000` with HTTP `400`; strict validation rejects unknown fields. Gateway readiness checks can return a non-envelope HTTP `503` while dependencies are not ready.

For `balance.get`, `value_blocking` is currently always `0` and `enabled` is currently always `true` in runtime responses. Treat them as compatibility fields unless your account manager confirms a product change.

Payment-page endpoints use gateway throttling and route-specific limits. See their reference pages for details.
