> ## 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.

# Tickets and comments

> Create and manage merchant-visible support tickets, comments, and ticket history

# Tickets and comments

Use ticket methods for integration questions, payment investigations, disputes, and other support conversations. Tickets are merchant-scoped and return only merchant-visible fields, comments, and attachments.

<Info>
  **Prerequisites:** use `tickets.create` to create a ticket, `tickets.read` to
  read it, `tickets.update` to edit/reopen it, and `tickets.comment` to write
  comments.
</Info>

## Methods

| Method                      | Scope             | Purpose                                         |
| --------------------------- | ----------------- | ----------------------------------------------- |
| `ticket.create`             | `tickets.create`  | Create a ticket                                 |
| `ticket.get`                | `tickets.read`    | Read one ticket by exactly one `c_id` or `h_id` |
| `ticket.list`               | `tickets.read`    | List tickets with cursor pagination             |
| `ticket.summary`            | `tickets.read`    | Count tickets by status                         |
| `ticket.description.update` | `tickets.update`  | Edit the merchant-authored description          |
| `ticket.reopen`             | `tickets.update`  | Reopen a resolved or closed ticket              |
| `ticket.comment.create`     | `tickets.comment` | Add a merchant-visible comment                  |
| `ticket.comments.list`      | `tickets.read`    | List merchant-visible comments                  |
| `ticket.comment.update`     | `tickets.comment` | Edit a merchant-authored comment                |

All methods are sent to `POST /public/api/multihub/v1`. Do not include `service_id`.

## Categories and priorities

Allowed categories are `payment_issue`, `integration`, `limits`, `account`, `bug`, `question`, `dispute`, `refund_request`, and `other`.

`payment_issue`, `dispute`, and `refund_request` require a merchant-owned payment reference. `payment_issue` also requires at least one previously verified attachment. A payment can have only one non-deleted ticket; a duplicate returns the existing ticket's public identifier and status.

You can set `low`, `medium`, or `high`; the default is `medium`. Responses can also contain operator-assigned `urgent` priority.

<Warning>
  `ticket.create` with category `refund_request` opens a support conversation.
  It never moves money. Use `refund.request` for a monetary refund.
</Warning>

## Create a ticket

The merchant `c_id` is the idempotency key for creation. For a payment investigation, upload and finalize evidence first, then reference the `ready` attachment IDs.

<CodeGroup>
  ```bash cURL theme={null}
  BODY='{"method":"ticket.create","params":{"identifiers":{"c_id":"ticket-order-8401"},"title":"Payment credited incorrectly","description":"The customer supplied a receipt.","category":"payment_issue","priority":"high","payment":{"c_id":"order-8401"},"attachment_ids":["e1924ea5-b980-49d5-a3fa-f2a34646bd4f"]}}'
  SECRET='your_secret_key'
  HASH=$(printf '%s%s' "$BODY" "$SECRET" | openssl dgst -sha512 -r | awk '{print $1}')
  curl -X POST 'https://api.bafanglaicai88.com/public/api/multihub/v1' \
    -H 'Content-Type: application/json' -H 'X-Data-Application-Id: 1' \
    -H "X-Data-Hash: $HASH" -H "X-Data-Timestamp: $(date +%s)" \
    -H "X-Data-Nonce: $(uuidgen)" --data-binary "$BODY"
  ```

  ```python Python theme={null}
  import hashlib, json, time, uuid, requests

  payload = {"method": "ticket.create", "params": {
      "identifiers": {"c_id": "ticket-order-8401"},
      "title": "Payment credited incorrectly",
      "description": "The customer supplied a receipt.",
      "category": "payment_issue", "priority": "high",
      "payment": {"c_id": "order-8401"},
      "attachment_ids": ["e1924ea5-b980-49d5-a3fa-f2a34646bd4f"],
  }}
  body = json.dumps(payload, separators=(",", ":")); secret = "your_secret_key"
  response = requests.post("https://api.bafanglaicai88.com/public/api/multihub/v1", data=body, headers={
      "Content-Type": "application/json", "X-Data-Application-Id": "1",
      "X-Data-Hash": hashlib.sha512((body + secret).encode()).hexdigest(),
      "X-Data-Timestamp": str(int(time.time())), "X-Data-Nonce": str(uuid.uuid4()),
  }, timeout=30)
  print(response.json())
  ```

  ```javascript Node.js theme={null}
  import crypto from "node:crypto";

  const payload = {
    method: "ticket.create",
    params: {
      identifiers: { c_id: "ticket-order-8401" },
      title: "Payment credited incorrectly",
      description: "The customer supplied a receipt.",
      category: "payment_issue",
      priority: "high",
      payment: { c_id: "order-8401" },
      attachment_ids: ["e1924ea5-b980-49d5-a3fa-f2a34646bd4f"],
    },
  };
  const body = JSON.stringify(payload);
  const secret = "your_secret_key";
  const response = await fetch("https://api.bafanglaicai88.com/public/api/multihub/v1", {
    method: "POST",
    body,
    headers: {
      "Content-Type": "application/json",
      "X-Data-Application-Id": "1",
      "X-Data-Hash": crypto
        .createHash("sha512")
        .update(body + secret)
        .digest("hex"),
      "X-Data-Timestamp": String(Math.floor(Date.now() / 1000)),
      "X-Data-Nonce": crypto.randomUUID(),
    },
  });
  console.log(await response.json());
  ```
</CodeGroup>

A ticket projection contains no staff identities or internal workflow fields:

```json theme={null}
{
  "success": true,
  "result": {
    "identifiers": {
      "c_id": "ticket-order-8401",
      "h_id": "47f04bbf-2b61-47ab-a7be-1730248145c9"
    },
    "category": "payment_issue",
    "status": "open",
    "priority": "high",
    "title": "Payment credited incorrectly",
    "description": "The customer supplied a receipt.",
    "payment": { "h_id": "3c3708bc-78d6-4bcb-b626-43dc9c05d0d6" },
    "reference": null,
    "sla_deadline": "2026-07-16T10:00:00.000Z",
    "attachments": [
      {
        "identifiers": {
          "h_id": "e1924ea5-b980-49d5-a3fa-f2a34646bd4f"
        },
        "name": "receipt.pdf",
        "mime_type": "application/pdf",
        "size": 48219,
        "created_at": "2026-07-15T10:00:00.000Z"
      }
    ],
    "created_at": "2026-07-15T10:00:00.000Z",
    "updated_at": "2026-07-15T10:00:00.000Z",
    "last_activity_at": "2026-07-15T10:00:00.000Z"
  },
  "request_id": "88c3d229-a658-48f3-bbc0-f5e607f64aed",
  "processing_time": 21
}
```

Ticket statuses are `open`, `in_progress`, `waiting_customer`, `on_hold`, `resolved`, `closed`, and `canceled`.

## Read and list tickets

Read one ticket with exactly one public identifier:

```json theme={null}
{
  "method": "ticket.get",
  "params": { "identifiers": { "c_id": "ticket-order-8401" } }
}
```

`ticket.list` accepts `statuses`, `categories`, `priorities`, one payment reference, `created_from`, `created_to`, `limit`, and `cursor`. Dates are ISO 8601 timestamps. Results are ordered newest first and return `items` plus `next_cursor`; there is no `total`.

```json theme={null}
{
  "method": "ticket.list",
  "params": {
    "statuses": ["open", "waiting_customer"],
    "categories": ["payment_issue"],
    "created_from": "2026-07-01T00:00:00Z",
    "limit": 25
  }
}
```

Use `ticket.summary` with optional `created_from` and `created_to` to receive `by_status` counts.

## Edit and reopen

Description edits and merchant-authored comment edits use a stable top-level `operation_id`. They are allowed for one hour after the original item was created. Support-authored content cannot be edited through the public API.

```json theme={null}
{
  "method": "ticket.description.update",
  "operation_id": "ticket-8401-description-v2",
  "params": {
    "identifiers": { "c_id": "ticket-order-8401" },
    "description": "Updated description with the correct bank reference."
  }
}
```

Only `resolved` or `closed` tickets can be reopened:

```json theme={null}
{
  "method": "ticket.reopen",
  "operation_id": "ticket-8401-reopen-1",
  "params": { "identifiers": { "c_id": "ticket-order-8401" } }
}
```

## Comments

Create a comment with an operation key. Optional attachment IDs must have purpose `ticket_comment` and status `ready`.

```json theme={null}
{
  "method": "ticket.comment.create",
  "operation_id": "ticket-8401-comment-2",
  "params": {
    "ticket": { "c_id": "ticket-order-8401" },
    "body": "Here is the additional bank confirmation.",
    "attachment_ids": ["75ba58d4-6705-4dfe-8901-707a07c2d53f"]
  }
}
```

List comments with `ticket.comments.list`; only merchant-visible comments are returned. Each comment has its own UUID `identifiers.h_id`, an `author` value of `merchant` or `support`, timestamps, and safe attachment projections.

```json theme={null}
{
  "method": "ticket.comment.update",
  "operation_id": "ticket-8401-comment-2-edit-1",
  "params": {
    "ticket": { "c_id": "ticket-order-8401" },
    "comment_h_id": "f5a557af-414a-4cf0-8430-af33c1abbd3f",
    "body": "Corrected bank confirmation details."
  }
}
```

## Error handling

|    Code | HTTP | Meaning                                           | Recovery                                                          |
| ------: | :--: | ------------------------------------------------- | ----------------------------------------------------------------- |
| `10001` |  404 | Ticket or merchant-owned payment is not visible   | Verify the public identifier and credential                       |
| `10002` |  409 | A ticket already exists for the payment or `c_id` | Use the public ID returned in conflict details                    |
| `10003` |  409 | Ticket state does not allow the action            | Refresh the ticket before deciding the next action                |
| `10004` |  409 | One-hour edit window expired                      | Add a new comment instead                                         |
| `10005` |  400 | A `payment_issue` has no verified attachment      | Complete the attachment workflow first                            |
|  `1013` |  409 | Operation key payload changed                     | Retry the exact original payload or start a new logical operation |

## Best practices

* Use one stable `c_id` per support case, not a title or customer-provided string that can collide.
* Store only the public projection; do not depend on staff assignment, tags, or internal lifecycle details.
* Refresh the ticket after webhook notifications because event payloads intentionally omit comment bodies and staff data.
* Treat a `404` as tenant-safe: it never reveals whether another merchant owns that identifier.
