> For the complete documentation index, see [llms.txt](https://docs.loomgate.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.loomgate.io/concepts/payments.md).

# Payment và trạng thái

Vòng đời của một payment, số lần thử thanh toán và khi nào tiền đã thực sự về.

Một **payment** (trong API là `payment_intent`, id dạng `lg_pi_…`) là một số tiền, bằng một loại tiền tệ, mà bạn yêu cầu một người mua trả, kèm thông tin nó trả cho cái gì. Tạo một payment cho mỗi lần thanh toán của một đơn hàng và dùng lại nó khi người mua thử lại.

## Trạng thái

```mermaid
stateDiagram-v2
    [*] --> pending: tạo payment
    pending --> processing: người mua xác nhận
    processing --> succeeded: thu tiền thành công
    processing --> pending: bị từ chối, release
    pending --> canceled: bị hủy
    processing --> canceled: bị hủy
    succeeded --> [*]
    canceled --> [*]
```

| Trạng thái   | Nghĩa                                                                   | Bạn có thể                                              |
| ------------ | ----------------------------------------------------------------------- | ------------------------------------------------------- |
| `pending`    | Chờ người mua trả (hoặc trả lại sau một lần bị từ chối)                 | Sửa số tiền, tiền tệ, chi tiết giao dịch; hiện form thẻ |
| `processing` | Đã gửi xác nhận, đang chờ kết quả (ví dụ người mua đang làm 3-D Secure) | Chờ webhook. **Chưa phải là đã thu tiền**               |
| `succeeded`  | Đã thu tiền. Không đổi nữa                                              | Giao hàng, hoàn tiền                                    |
| `canceled`   | Đã hủy, không thể thanh toán tiếp                                       | Tạo payment mới nếu người mua vẫn muốn trả              |

{% hint style="warning" %}
Chỉ coi đơn là đã thanh toán khi máy chủ của bạn nhận webhook `payment_intent.succeeded`, hoặc khi `GET /partner/v1/payment_intents/{id}` trả `status: "succeeded"`. Kết quả `processing` ở trình duyệt chưa phải là đã thu tiền.
{% endhint %}

### Payment bị hủy và payment bỏ dở

API không có route hủy payment, và bạn không cần hủy: payment người mua bỏ dở chỉ ở lại `pending` và không phát sinh phí (phí chỉ được ghi khi payment `succeeded`). Trạng thái `canceled` do hệ thống thanh toán đặt khi payment không thể tiếp tục; khi đó bạn nhận webhook `payment_intent.canceled`.

## Hai cách xác nhận thanh toán

* **Trình duyệt xác nhận** (phổ biến nhất): `session.confirm()` của `loomgate.js` làm mọi bước, kể cả 3-D Secure và release khi bị từ chối. Xem [Form thanh toán](/integrations/browser.md).
* **Máy chủ xác nhận**: trình duyệt chỉ tạo confirmation token, máy chủ gọi `POST /partner/v1/payment_intents/{id}/confirm` bằng secret key, rồi trình duyệt chạy bước tiếp theo nếu có `next_action`. Dùng khi nền tảng của bạn bắt buộc xác nhận ở máy chủ (ví dụ WooCommerce Blocks).

## Bị từ chối và release

Khi thẻ bị từ chối (`402 card_error`), payment phải được **release** để quay về `pending` trước khi người mua thử thẻ khác.

* Ở luồng trình duyệt, `loomgate.js` tự release.
* Ở luồng máy chủ, bạn gọi `POST /partner/v1/payment_intents/{id}/release` (hoặc `session.release()` trong trình duyệt). Chỉ mời người mua thử lại khi release trả về `pending`.
* Chỉ release sau một lần xác nhận **đã gửi** và nhận `card_error`. Khi timeout, lỗi mạng hay 5xx, kết quả chưa rõ: đọc lại payment trước, đừng release.

## Giới hạn số lần thử

Để chống dò thẻ (card testing), mỗi lần xác nhận được gửi đi đều tính là một lần thử, dù kết quả ra sao:

| Giới hạn                                              | Mặc định | Vượt thì                                                                                            |
| ----------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------- |
| Số lần thử trên mỗi payment (`confirmation_attempts`) | 5        | `400 payment_intent_not_pending`: không gửi gì thêm; người mua phải bắt đầu lại với một payment mới |
| Số lần thử của cả tài khoản trong mỗi khung 10 phút   | 50       | `429 rate_limited` kèm header `Retry-After`: thử lại sau số giây đó                                 |

Hai con số này do Loomgate đặt cho tài khoản của bạn; xem giá trị hiện tại trong mục **Cài đặt** của dashboard. Một lần xác nhận bị từ chối trước khi gửi đi (thiếu thông tin, tài khoản bị tạm ngưng…) không tính.

## Khi số tiền đổi sau khi form đã hiện

Bạn có thể sửa `amount` hoặc `currency` của payment đang `pending` (ví dụ người mua đổi phí ship). Khi đó form thẻ đã tải trước đó không còn hợp lệ: lần xác nhận tiếp theo trả `409 payment_intent_updated`, không trừ tiền. `loomgate.js` tự tải lại form với số tiền mới và phát sự kiện `change`; bạn hiển thị số tiền mới và để người mua bấm thanh toán lại. Sửa `metadata` hay chi tiết giao dịch thì form không cần tải lại.

## Tài khoản bị tạm ngưng hoặc chưa được duyệt

* `merchant_suspended`: tài khoản đang bị tạm ngưng. Tạo, sửa, hiện form và xác nhận payment đều bị từ chối; release và hoàn tiền vẫn dùng được.
* `merchant_not_approved`: tài khoản do đại lý tạo đang chờ duyệt hoặc bị từ chối; chưa nhận được thanh toán.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.loomgate.io/concepts/payments.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
