Skip to main content

Điều Kiện Tiên Quyết

Để tích hợp API Dodo Payments, bạn cần:
  • Một tài khoản thương nhân Dodo Payments
  • Thông tin xác thực API (khóa API và khóa bí mật webhook) từ bảng điều khiển
Để có hướng dẫn chi tiết hơn về các điều kiện tiên quyết, hãy kiểm tra phần này.

Tích Hợp API

Phiên Thanh Toán

Sử dụng Phiên Thanh toán để bán sản phẩm đăng ký qua một trang thanh toán được lưu trữ an toàn. Truyền sản phẩm đăng ký của bạn vào product_cart và chuyển hướng khách hàng đến checkout_url được trả về.
Thanh toán hỗn hợp: Bạn có thể kết hợp sản phẩm đăng ký với sản phẩm thanh toán một lần trong cùng một phiên thanh toán. Điều này cho phép các trường hợp sử dụng như phí cài đặt với đăng ký, gói phần cứng cùng SaaS, và hơn thế nữa. Xem Hướng dẫn Phiên Thanh toán để biết ví dụ.

Phản Hồi API

Dưới đây là một ví dụ về phản hồi:
Chuyển hướng khách hàng đến checkout_url.

Webhooks

Khi tích hợp các gói đăng ký, bạn sẽ nhận được webhooks để theo dõi vòng đời của gói thuê bao. Các webhooks này giúp bạn quản lý trạng thái thuê bao và các kịch bản thanh toán một cách hiệu quả. Để thiết lập endpoint webhook của bạn, vui lòng làm theo Hướng dẫn Tích hợp Chi tiết.

Các Loại Sự Kiện Thuê Bao

Các sự kiện webhook sau theo dõi các thay đổi trạng thái thuê bao:
  1. subscription.active - Thuê bao được kích hoạt thành công.
  2. subscription.updated - Đối tượng thuê bao đã được cập nhật (khởi động khi có bất kỳ thay đổi nào).
  3. subscription.on_hold - Thuê bao bị tạm dừng do gia hạn thất bại.
  4. subscription.failed - Tạo thuê bao thất bại trong quá trình tạo ủy quyền.
  5. subscription.renewed - Thuê bao được gia hạn cho chu kỳ thanh toán tiếp theo.
Để quản lý vòng đời thuê bao đáng tin cậy, chúng tôi khuyến nghị theo dõi các sự kiện thuê bao này.
Sử dụng subscription.updated để nhận thông báo theo thời gian thực về bất kỳ thay đổi nào của thuê bao, giữ cho trạng thái ứng dụng của bạn đồng bộ mà không cần phải hỏi API.

Kịch Bản Thanh Toán

Luồng Thanh Toán Thành Công Các webhook bạn nhận được và thời điểm nhận phụ thuộc vào việc sản phẩm có thời gian dùng thử hay không. Thanh toán ngay (0 ngày dùng thử):
  1. subscription.active: mandate được ủy quyền và gói đăng ký được kích hoạt.
  2. payment.succeeded: xác nhận khoản phí đầu tiên. Dự kiến nhận được sự kiện này trong vòng 2–10 phút sau khi thanh toán.
Có thời gian dùng thử:
  1. Khi bắt đầu dùng thử (thanh toán): subscription.active được kích hoạt sau khi phương thức thanh toán được ủy quyền. Chưa thu khoản phí định kỳ nào. Khoản phí thực tế đầu tiên được trì hoãn cho đến khi thời gian dùng thử kết thúc.
  2. Khi thời gian dùng thử kết thúc: số tiền định kỳ được thu và bạn nhận được payment.succeeded cùng với subscription.renewed.
Mỗi lần gia hạn tiếp theo:
  • subscription.renewed: được kích hoạt trong mỗi chu kỳ thanh toán khi khoản phí gia hạn được khấu trừ, luôn cùng với payment.succeeded. Sự kiện này cũng chứa next_billing_date đã được cập nhật.
Bất cứ khi nào tiền thực sự được khấu trừ cho một sản phẩm gói đăng ký, bạn sẽ nhận được subscription.renewed payment.succeeded. Hãy sử dụng subscription.renewed (thay vì chỉ sử dụng payment.succeeded) làm tín hiệu để gia hạn quyền truy cập cho chu kỳ tiếp theo.
Các kịch bản thanh toán thất bại
  1. Gói đăng ký thất bại
  • subscription.failed - Không thể tạo gói đăng ký do không thể tạo mandate.
  • payment.failed - Cho biết thanh toán thất bại.
  1. Gói đăng ký bị tạm giữ
  • subscription.on_hold - Gói đăng ký bị tạm giữ do khoản thanh toán gia hạn hoặc khoản phí thay đổi gói thất bại.
  • Khi gói đăng ký bị tạm giữ, gói sẽ không tự động gia hạn cho đến khi phương thức thanh toán được cập nhật.
Thực hành tốt nhất: Để đơn giản hóa việc triển khai, chúng tôi khuyến nghị chủ yếu theo dõi các sự kiện gói đăng ký để quản lý vòng đời gói đăng ký.
Để xem hướng dẫn đầy đủ về cách đọc error_code/error_message, quyết định thời điểm thử lại và hiển thị lỗi cho khách hàng, hãy xem Xử lý lỗi thanh toán.

subscription.failedsubscription.on_hold

Hai sự kiện này rất dễ bị nhầm lẫn, nhưng cần được xử lý theo những cách hoàn toàn khác nhau:
subscription.failed là trạng thái kết thúc. Không thể kích hoạt lại gói đăng ký. Khách hàng phải tạo một gói đăng ký mới. Không bao giờ cấp quyền lợi khi sự kiện này được kích hoạt.

Xử lý gói đăng ký bị tạm giữ

Khi gói đăng ký chuyển sang trạng thái on_hold, bạn cần cập nhật phương thức thanh toán để kích hoạt lại gói. Phần này giải thích thời điểm gói đăng ký bị tạm giữ và cách xử lý.

Khi gói đăng ký bị tạm giữ

Gói đăng ký bị tạm giữ khi:
  • Thanh toán gia hạn thất bại: Khoản phí gia hạn tự động thất bại do không đủ tiền, thẻ hết hạn hoặc ngân hàng từ chối
  • Khoản phí thay đổi gói thất bại: Khoản phí phát sinh ngay lập tức trong quá trình nâng cấp/hạ cấp gói thất bại
  • Ủy quyền phương thức thanh toán thất bại: Không thể ủy quyền phương thức thanh toán cho các khoản phí định kỳ
Các gói đăng ký ở trạng thái on_hold sẽ không tự động gia hạn. Bạn phải cập nhật phương thức thanh toán để kích hoạt lại gói đăng ký.

Kích hoạt lại gói đăng ký đang bị tạm giữ

Để kích hoạt lại gói đăng ký từ trạng thái on_hold, hãy sử dụng Update Payment Method API. API này sẽ tự động:
  1. Tạo khoản phí cho các khoản còn nợ
  2. Tạo hóa đơn cho khoản phí
  3. Xử lý thanh toán bằng phương thức thanh toán mới
  4. Kích hoạt lại gói đăng ký về trạng thái active sau khi thanh toán thành công
1

Handle subscription.on_hold webhook

Khi nhận được webhook subscription.on_hold, hãy cập nhật trạng thái ứng dụng và thông báo cho khách hàng:
2

Update payment method

Khi khách hàng sẵn sàng cập nhật phương thức thanh toán, hãy gọi Update Payment Method API:
Bạn cũng có thể sử dụng ID phương thức thanh toán hiện có nếu khách hàng đã lưu các phương thức thanh toán:
3

Monitor webhook events

Sau khi cập nhật phương thức thanh toán, hãy theo dõi các sự kiện webhook sau:
  1. payment.succeeded - Khoản phí cho các khoản còn nợ đã thành công
  2. subscription.active - Gói đăng ký đã được kích hoạt lại

Payload sự kiện gói đăng ký mẫu


Thay đổi gói đăng ký

Bạn có thể nâng cấp hoặc hạ cấp gói đăng ký bằng endpoint change plan API. API này cho phép bạn sửa đổi sản phẩm, số lượng của gói đăng ký và xử lý proration.

Change Plan API Reference

Để biết thông tin chi tiết về việc thay đổi gói đăng ký, vui lòng tham khảo tài liệu Change Plan API của chúng tôi.

Tùy chọn proration

Khi thay đổi gói đăng ký, bạn có hai tùy chọn để xử lý khoản phí phát sinh ngay lập tức:

1. prorated_immediately

  • Tính số tiền được phân bổ theo tỷ lệ dựa trên thời gian còn lại trong chu kỳ thanh toán hiện tại
  • Chỉ tính phí khách hàng cho phần chênh lệch giữa gói cũ và gói mới
  • Trong thời gian dùng thử, tùy chọn này sẽ chuyển người dùng sang gói mới ngay lập tức và tính phí khách hàng ngay

2. full_immediately

  • Tính phí khách hàng toàn bộ số tiền gói đăng ký của gói mới
  • Bỏ qua thời gian còn lại hoặc khoản tín dụng từ gói trước đó
  • Hữu ích khi bạn muốn đặt lại chu kỳ thanh toán hoặc tính toàn bộ số tiền bất kể proration

3. difference_immediately

  • Khi nâng cấp, khách hàng sẽ bị tính ngay phần chênh lệch giữa số tiền của hai gói.
  • Ví dụ, nếu gói hiện tại là 30 Dollars và khách hàng nâng cấp lên gói 80 Dollars, họ sẽ bị tính phí $50 ngay lập tức.
  • Khi hạ cấp, số tiền chưa sử dụng của gói hiện tại được thêm vào dưới dạng tín dụng nội bộ và tự động áp dụng cho các lần gia hạn gói đăng ký trong tương lai.
  • Ví dụ, nếu gói hiện tại là 50 Dollars và khách hàng chuyển sang gói 20 Dollars, khoản $30 còn lại được ghi có và dùng cho chu kỳ thanh toán tiếp theo.

4. do_not_bill

  • Áp dụng thay đổi gói ngay lập tức nhưng không tính phí tại thời điểm thay đổi.
  • Gói đã cập nhật (cùng số lượng/add-on) được tính phí vào lần gia hạn theo lịch tiếp theo, và ngày thanh toán ban đầu được giữ nguyên.
Cả ba chế độ “charge now” đều đặt lại chu kỳ thanh toán. prorated_immediately, difference_immediatelyfull_immediately chuyển next_billing_date của gói đăng ký sang ngày thay đổi. Chỉ do_not_bill giữ nguyên ngày gia hạn ban đầu, nhưng không áp dụng khoản phí ngay lập tức.

Hành vi

  • Khi gọi API này, Dodo Payments ngay lập tức bắt đầu tính phí dựa trên tùy chọn proration đã chọn
  • Nếu thay đổi gói là hạ cấp và bạn sử dụng prorated_immediately, các khoản tín dụng sẽ được tự động tính toán và thêm vào số dư tín dụng của gói đăng ký. Các khoản tín dụng này chỉ thuộc về gói đăng ký đó và chỉ được dùng để bù trừ cho các khoản thanh toán định kỳ trong tương lai của cùng gói đăng ký
  • Tùy chọn full_immediately bỏ qua việc tính tín dụng và tính toàn bộ số tiền của gói mới
Hãy cẩn thận khi chọn tùy chọn proration: Sử dụng prorated_immediately để tính phí công bằng, có xét đến thời gian chưa sử dụng, hoặc full_immediately khi bạn muốn tính toàn bộ số tiền của gói mới bất kể chu kỳ thanh toán hiện tại.

Xử lý khoản phí

  • Khoản phí ngay lập tức được bắt đầu khi thay đổi gói thường hoàn tất xử lý trong chưa đến 2 phút
  • Nếu khoản phí ngay lập tức này thất bại vì bất kỳ lý do nào, gói đăng ký sẽ tự động bị tạm giữ cho đến khi vấn đề được giải quyết

Gói đăng ký theo yêu cầu

Create Subscription

Tham khảo API tạo sản phẩm thuê bao và quản lý vòng đời thuê bao

Change Subscription Plan

Tham khảo API nâng cấp, hạ cấp, hoặc thay đổi kế hoạch thuê bao với các tùy chọn phân bổ

Update Payment Method

Tham khảo API cập nhật phương thức thanh toán và kích hoạt lại thuê bao bị tạm dừng

Patch Subscription

Tham khảo API cập nhật chi tiết và cấu hình thuê bao
Để tạo gói đăng ký theo yêu cầu: Để tạo gói đăng ký theo yêu cầu, hãy sử dụng endpoint API POST /subscriptions và bao gồm trường on_demand trong request body. Điều này cho phép bạn ủy quyền một phương thức thanh toán mà không tính phí ngay lập tức hoặc đặt mức giá ban đầu tùy chỉnh. Để tính phí gói đăng ký theo yêu cầu: Đối với các khoản phí tiếp theo, hãy sử dụng endpoint POST /subscriptions//charge và chỉ định số tiền cần tính cho khách hàng trong giao dịch đó.
Để xem hướng dẫn đầy đủ từng bước (bao gồm các ví dụ request/response, chính sách thử lại an toàn và cách xử lý webhook), hãy xem Hướng dẫn gói đăng ký theo yêu cầu.

Những điều quan trọng cần biết về thanh toán gói đăng ký

Đặt thời hạn gói đăng ký dài hơn tần suất thanh toán. Nếu thời hạn gói đăng ký bằng tần suất thanh toán (ví dụ: period = 1 month, frequency = 1 month), gói đăng ký chỉ có hiệu lực trong một chu kỳ rồi chuyển sang expired thay vì gia hạn. Đối với gói hàng tháng liên tục, hãy đặt thời hạn gói đăng ký dài (ví dụ: 20 years) với tần suất thanh toán hàng tháng.
Tiền tệ được cố định sau khoản phí thành công đầu tiên. Luôn truyền rõ ràng billing_currency billing_address.country khi tạo checkout. Nếu bỏ qua, tiền tệ sẽ được phát hiện từ IP của khách hàng (Adaptive Currency), và một khi gói đăng ký phát sinh khoản phí đầu tiên, tiền tệ sẽ được cố định trong suốt thời gian tồn tại của gói. Khách hàng không thể chuyển đổi tiền tệ khi đi du lịch sau đó.
Thời gian dùng thử thực hiện ủy quyền $0, không phải tính phí. Khi gói đăng ký có thời gian dùng thử, thời điểm bắt đầu dùng thử sẽ tạo ủy quyền mandate $0 để lưu thẻ; khoản phí thực tế đầu tiên được thực hiện khi thời gian dùng thử kết thúc. Trong danh sách thanh toán, gói đăng ký đang dùng thử hiển thị chính xác một khoản thanh toán với amount: 0.
Vòng đời gói đăng ký: on_hold = lần gia hạn thất bại (có thể khôi phục: yêu cầu khách hàng cập nhật phương thức thanh toán; áp dụng các lần thử lại dunning). expired = thời hạn kết thúc mà không gia hạn và không thể kích hoạt lại. Khách hàng phải đăng ký lại. cancelled = bị khách hàng hoặc merchant kết thúc. Hầu hết các lỗi gia hạn là do bên issuer từ chối (không đủ tiền, thẻ bị từ chối), không phải lỗi của Dodo.
Thẻ Ấn Độ hoạt động trên RBI e-mandate. Các khoản phí off-session (gia hạn và phí thay đổi gói) có thể mất tối đa khoảng 48 giờ để hoàn tất, và các khoản tự động trích nợ định kỳ trên ₹15,000 yêu cầu khách hàng xác thực lại (do đó, việc nâng cấp vượt quá giới hạn này không thể sử dụng mandate hiện có). Khi một khoản phí vẫn đang ở trạng thái processing, khoản phí thứ hai trên cùng gói đăng ký sẽ thất bại với thông báo “Cannot create new charge as previous payment is not successful yet.” Thẻ ngoài Ấn Độ được xác nhận gần như ngay lập tức.
Khoản phí gói đăng ký có mức tối thiểu là $1 (hoặc giá trị tương đương theo tiền tệ). Các số tiền $0.01–$0.99 bị từ chối với product_price: value out of range; chỉ cho phép $0 thông qua quy trình thiết lập mandate_only theo yêu cầu.

Tài liệu tham khảo API liên quan

Create Subscription

Tài liệu tham khảo API để tạo sản phẩm gói đăng ký và quản lý vòng đời gói đăng ký

Change Subscription Plan

Tài liệu tham khảo API để nâng cấp, hạ cấp hoặc thay đổi gói đăng ký với các tùy chọn proration

Update Payment Method

Tài liệu tham khảo API để cập nhật phương thức thanh toán và kích hoạt lại các gói đăng ký bị tạm giữ

Patch Subscription

Tài liệu tham khảo API để cập nhật thông tin chi tiết và cấu hình gói đăng ký
Lần sửa đổi cuối 31 tháng 7, 2026