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

# Khôi phục

> Các dữ liệu được gửi đến điểm cuối webhook của bạn khi xảy ra các sự kiện khôi phục giỏ hàng bị bỏ quên hoặc dunning đăng ký.

## Sự kiện Khôi phục Giỏ hàng Bị bỏ quên

Các sự kiện webhook dưới đây theo dõi vòng đời khôi phục giỏ hàng bị bỏ quên:

| Sự kiện                        | Mô tả                                                                                                                                                           |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `abandoned_checkout.detected`  | Đã phát hiện một thanh toán bị bỏ quên. Được gửi khi một thanh toán được xác định là bị bỏ quên (thất bại hoặc chưa hoàn thành) và quy trình khôi phục bắt đầu. |
| `abandoned_checkout.recovered` | Khách hàng đã hoàn tất thanh toán qua liên kết khôi phục. Trường `recovered_payment_id` chứa ID thanh toán thành công.                                          |

### Trường Payload Thanh toán Bị bỏ quên

<ParamField body="payment_id" type="string" required>
  Thanh toán gốc đã bị bỏ quên. Sử dụng thông tin này để tra cứu chi tiết sản phẩm, số tiền và đơn vị tiền tệ.
</ParamField>

<ParamField body="customer_id" type="string" required>
  Khách hàng đã bỏ quên thanh toán.
</ParamField>

<ParamField body="abandonment_reason" type="string" required>
  Lý do thanh toán bị bỏ quên. Một trong các lý do:

  * `payment_failed` — Khách hàng đã thử thanh toán nhưng thất bại
  * `checkout_incomplete` — Khách hàng đã truy cập thanh toán nhưng không thử thanh toán
</ParamField>

<ParamField body="status" type="string" required>
  Trạng thái vòng đời hiện tại của nỗ lực khôi phục này. Một trong các trạng thái:

  * `abandoned` — Đã phát hiện, chưa gửi email
  * `recovering` — Đã gửi ít nhất một email khôi phục
  * `recovered` — Khách hàng đã hoàn tất thanh toán
  * `exhausted` — Đã gửi tất cả email hoặc đã tìm thấy thanh toán mới hơn
  * `opted_out` — Khách hàng đã hủy đăng ký
</ParamField>

<ParamField body="abandoned_at" type="string" required>
  Dấu thời gian ISO 8601 khi phát hiện thanh toán bị bỏ quên.
</ParamField>

<ParamField body="recovered_payment_id" type="string | null">
  ID thanh toán của lần khôi phục thanh toán thành công. `null` cho đến khi thanh toán được khôi phục.
</ParamField>

### Ví dụ: Xử lý ACR Webhooks

```javascript theme={null}
app.post('/webhooks/dodo', async (req, res) => {
  const event = req.body;

  switch (event.type) {
    case 'abandoned_checkout.detected':
      console.log(`Checkout abandoned: ${event.data.payment_id}`);
      console.log(`Reason: ${event.data.abandonment_reason}`);
      // Track abandonment in your analytics
      await trackAbandonment(event.data);
      break;

    case 'abandoned_checkout.recovered':
      console.log(`Checkout recovered: ${event.data.payment_id}`);
      console.log(`Recovery payment: ${event.data.recovered_payment_id}`);
      // Grant access, update records
      await handleRecovery(event.data);
      break;
  }

  res.json({ received: true });
});
```

***

## Sự kiện Dunning

Các sự kiện webhook dưới đây theo dõi vòng đời dunning đăng ký:

| Sự kiện             | Mô tả                                                                                                                                     |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `dunning.started`   | Một nỗ lực dunning đã được tạo ra cho một đăng ký đã vào `on_hold` hoặc bị khách hàng hủy bỏ.                                             |
| `dunning.recovered` | Khách hàng đã cập nhật phương thức thanh toán của họ và thanh toán kết quả thành công. Trường `payment_id` chứa ID thanh toán thành công. |

### Trường Payload Nỗ Lực Dunning

<ParamField body="subscription_id" type="string" required>
  Đăng ký đã kích hoạt nỗ lực dunning.
</ParamField>

<ParamField body="customer_id" type="string" required>
  Khách hàng sở hữu đăng ký.
</ParamField>

<ParamField body="trigger_state" type="string" required>
  Trạng thái đăng ký kích hoạt dunning. Một trong các trạng thái:

  * `on_hold` — Đăng ký bị tạm dừng do thất bại thanh toán
  * `cancelled` — Khách hàng hủy từ cổng thông tin khách hàng
</ParamField>

<ParamField body="status" type="string" required>
  Trạng thái vòng đời hiện tại của nỗ lực dunning này. Một trong các trạng thái:

  * `recovering` — Đang gửi email dunning
  * `recovered` — Khách hàng cập nhật phương thức thanh toán và thanh toán thành công
  * `exhausted` — Đã gửi tất cả email hoặc trạng thái đăng ký thay đổi
</ParamField>

<ParamField body="created_at" type="string" required>
  Dấu thời gian ISO 8601 khi nỗ lực dunning được tạo ra.
</ParamField>

<ParamField body="payment_id" type="string | null">
  ID thanh toán của lần khôi phục thanh toán thành công. `null` trong khi khôi phục.
</ParamField>

### Ví dụ: Xử lý Dunning Webhooks

```javascript theme={null}
app.post('/webhooks/dodo', async (req, res) => {
  const event = req.body;

  switch (event.type) {
    case 'dunning.started':
      console.log(`Dunning started for subscription: ${event.data.subscription_id}`);
      console.log(`Trigger: ${event.data.trigger_state}`);
      // Track dunning in your system
      await trackDunning(event.data);
      break;

    case 'dunning.recovered':
      console.log(`Subscription recovered: ${event.data.subscription_id}`);
      console.log(`Recovery payment: ${event.data.payment_id}`);
      // Reactivate access, update records
      await handleDunningRecovery(event.data);
      break;
  }

  res.json({ received: true });
});
```

<Tip>
  Đăng ký cả hai `dunning.started` và `dunning.recovered` để theo dõi toàn bộ vòng đời dunning. Sử dụng `dunning.started` để tạm dừng thời gian ân hạn hoặc gắn cờ cho các đăng ký có nguy cơ trong hệ thống của bạn.
</Tip>

<CardGroup cols={2}>
  <Card title="Abandoned Cart Recovery" icon="cart-shopping" href="/features/recovery/abandoned-cart-recovery">
    Cấu hình chuỗi email ACR và các ưu đãi giảm giá.
  </Card>

  <Card title="Subscription Dunning" icon="rotate" href="/features/recovery/subscription-dunning">
    Cấu hình chuỗi email dunning cho các đăng ký bị gián đoạn.
  </Card>

  <Card title="Subscription Webhooks" icon="repeat" href="/developer-resources/webhooks/intents/subscription">
    Các sự kiện vòng đời đăng ký liên quan như `subscription.on_hold` và `subscription.cancelled`.
  </Card>
</CardGroup>

## Mô Hình Dữ Liệu Webhook
