Khôi phục Webhook thanh toán LINE MINI App bị bỏ sót: Runbook đối soát 7 ngày
Để khôi phục một Webhook thanh toán LINE MINI App bị bỏ sót, hãy truy vấn lịch sử sự kiện chính thức của LINE trong vòng 7 ngày, phân trang mà không thay đổi khoảng thời gian hoặc bộ lọc ban đầu, rồi đưa từng sự kiện purchaseComplete trả về qua cùng một handler idempotent dùng orderId làm khóa. Reserve giao dịch thành công không chứng minh rằng khách hàng đã thanh toán; endpoint lịch sử là nguồn phục hồi sự cố, không phải lý do để ngừng giám sát Webhook trực tiếp.
Điểm chính
- Lịch sử sự kiện của LINE bao phủ các lần gửi Webhook trong 7 ngày gần nhất và trả về tối đa 100 bản ghi mỗi trang.
status=FAILEDcó nghĩa là việc gửi Webhook thất bại, không có nghĩa là giao dịch mua của khách hàng thất bại.- Hãy lưu
orderIdngay khi reserve giao dịch, rồi dùng giá trị đó để loại trùng cho cả sự kiệnpurchaseCompletetrực tiếp lẫn sự kiện được khôi phục. - Tách quy trình khôi phục thanh toán khỏi routing tin nhắn chăm sóc khách hàng. Hai luồng dùng loại sự kiện, thông tin xác thực, chữ ký và đội vận hành khác nhau.
Vì sao reserve thành công không đồng nghĩa với mua hàng hoàn tất
In-app purchase của LINE MINI App là một quy trình chính thức gồm nhiều bước. Trước tiên, server của bạn reserve giao dịch bằng POST https://api.line.me/iap/v1/product/reserve. LINE trả về một orderId, nhưng người dùng vẫn có thể đóng ứng dụng, hủy trong app store, mất kết nối hoặc không hoàn tất thanh toán. Vì vậy, hướng dẫn tích hợp của LINE yêu cầu chỉ cấp vật phẩm số sau khi nhận được Webhook báo mua hàng hoàn tất.
Ranh giới này tạo ra bốn câu hỏi xử lý sự cố riêng biệt:
| Câu hỏi | Bằng chứng cần tin cậy |
|---|---|
| Yêu cầu reserve có thành công không? | Response của reserve, orderId đã lưu và x-line-request-id |
| Giao dịch mua có hoàn tất không? | Sự kiện purchaseComplete hoặc kết quả đối soát chính thức |
| Endpoint của bạn có nhận được lần gửi trực tiếp không? | Log request thô và bản ghi xử lý Webhook |
| Handler nghiệp vụ có cấp quyền lợi đúng một lần không? | Bản ghi idempotency dùng orderId làm khóa |
Hướng dẫn về phí LINE MINI App và Webhook hỗ trợ hiện có giải thích vì sao sự kiện thanh toán và tin nhắn khách hàng thuộc về hai hệ thống riêng. Runbook này bắt đầu ở lớp sâu hơn: Webhook thanh toán lẽ ra phải đến, nhưng endpoint của bạn ngừng hoạt động hoặc khâu xử lý thất bại.
Cách khôi phục Webhook thanh toán LINE MINI App bị bỏ sót
1. Phát hiện khoảng trống trước khi cửa sổ 7 ngày đóng lại
Hãy lưu các giá trị sau khi reserve một giao dịch:
- checkout ID nội bộ;
orderIdcủa LINE;- response header
x-line-request-id; - thời điểm reserve và sản phẩm dự kiến;
- trạng thái cho biết sự kiện
purchaseCompleteđã được áp dụng hay chưa.
Phát cảnh báo khi một giao dịch đã reserve vẫn chưa được xử lý xong sau khoảng thời gian checkout thông thường. Đừng lập tức đánh dấu là đã thanh toán và cũng đừng chờ đến ngày thứ bảy mới điều tra: endpoint lịch sử chính thức chỉ chấp nhận khoảng thời gian nằm trong 7 ngày trước đó.
2. Truy vấn một cửa sổ phục hồi cố định
LINE MINI App API reference chính thức mô tả endpoint phục hồi sau:
curl --get "https://api.line.me/iap/v1/webhook/events" \
-H "Authorization: Bearer ${LINE_CHANNEL_ACCESS_TOKEN}" \
--data-urlencode "startEpochSeconds=1784678400" \
--data-urlencode "endEpochSeconds=1784700000" \
--data-urlencode "pageSize=100" \
--data-urlencode "status=FAILED"
Các timestamp trên chỉ là một cửa sổ ví dụ cụ thể vào ngày 22/7/2026, không phải giá trị để sao chép vào production. Hãy tạo số giây epoch UTC từ thời điểm bắt đầu và kết thúc sự cố. Dùng status=FAILED để tìm những lần LINE không thể gửi thành công, hoặc bỏ status khi đối soát mọi lần gửi trong cửa sổ. SUCCESS và FAILED mô tả trạng thái gửi, không phải kết quả thanh toán.
3. Giữ nguyên truy vấn trong khi phân trang
Kết quả được sắp xếp theo thời điểm LINE bắt đầu gửi từng Webhook. Mỗi trang chứa tối đa 100 bản ghi và có thể có nextCursor. Với mọi trang tiếp theo, hãy giữ nguyên startEpochSeconds, endEpochSeconds, pageSize và status; chỉ thay đổi cursor.
Ví dụ Node.js sau thể hiện rõ ranh giới này:
const baseUrl = "https://api.line.me/iap/v1/webhook/events";
const fixedQuery = {
startEpochSeconds: "1784678400",
endEpochSeconds: "1784700000",
pageSize: "100",
status: "FAILED",
};
let cursor;
do {
const query = new URLSearchParams(fixedQuery);
if (cursor) query.set("cursor", cursor);
const response = await fetch(`${baseUrl}?${query}`, {
headers: { Authorization: `Bearer ${process.env.LINE_CHANNEL_ACCESS_TOKEN}` },
});
if (!response.ok) {
throw new Error(`LINE event history failed: ${response.status}`);
}
const page = await response.json();
for (const record of page.events) {
if (record.event.type === "purchaseComplete") {
await applyPurchaseOnce(record.event.orderId, record.event);
}
}
cursor = page.nextCursor ?? undefined;
} while (cursor);
applyPurchaseOnce là ranh giới transaction của nghiệp vụ. Trong một thao tác atomic, hàm này phải chèn bản ghi idempotency và cấp vật phẩm; nếu orderId đó đã được xử lý thì không làm gì. Hướng dẫn phát triển in-app purchase của LINE đặc biệt khuyến nghị dùng orderId để ngăn cấp trùng, vì cùng một Webhook có thể được gửi nhiều lần.
4. Đối soát lịch sử với quy trình xử lý trực tiếp
Đừng xây một đường cấp quyền lợi thứ hai chỉ dành cho phục hồi. Hãy chuyển sự kiện được khôi phục thành cùng một internal command mà Webhook trực tiếp sử dụng, đồng thời ghi nguồn là line_event_history. Sau đó đối chiếu:
- các giá trị
orderIdđã reserve nhưng chưa có trạng thái hoàn tất trong hệ thống nội bộ; - log Webhook trực tiếp;
- bản ghi lịch sử trong cửa sổ sự cố cố định;
- bản ghi idempotency và thay đổi quyền lợi.
Response lịch sử được lấy bằng channel access token. Đây không phải lần gửi HTTP ban đầu, vì vậy không nên kỳ vọng nó chứa header x-line-signature gốc. Hãy tiếp tục xác minh header này trên Webhook trực tiếp: LINE dùng channel secret để tính HMAC-SHA256 trên raw request body, rồi mã hóa digest bằng Base64.
5. Khép lại sự cố bằng một checkpoint đo lường được
Việc phục hồi chỉ hoàn tất khi mọi giao dịch reserve trong phạm vi đều được phân loại là đã hoàn tất và đã áp dụng, chưa hoàn tất, đã hủy hoặc đã chuyển sang điều tra thủ công. Hãy ghi lại chính xác khoảng thời gian UTC, bộ lọc, số trang, các giá trị orderId đã khôi phục và thời điểm chạy thành công gần nhất. Lên lịch một job đối soát gọn nhẹ với tần suất ngắn hơn giới hạn lưu giữ 7 ngày để một sự cố cuối tuần không hết hạn mà không được phát hiện.
Tài liệu lịch sử sự kiện hiện tại cho biết endpoint truy xuất các sự kiện purchaseComplete, còn khả năng hỗ trợ lịch sử hoàn tiền được dự kiến cung cấp riêng. Hãy kiểm tra reference đang hoạt động trước khi cho rằng cùng một đường phục hồi đã bao phủ hoàn tiền.
UnifyPort phù hợp ở đâu — và không phù hợp ở đâu
UnifyPort không reserve giao dịch mua LINE MINI App, xác nhận thanh toán qua app store, khôi phục sự kiện thanh toán LINE, cấp vật phẩm số hay đáp ứng thay các yêu cầu xét duyệt của LINE. Luồng in-app purchase chính thức của LINE mới là hệ thống chịu trách nhiệm cho toàn bộ các công việc đó.
UnifyPort phù hợp khi sự kiện tiếp theo là một tin nhắn khách hàng thông thường. Ví dụ, người mua nhắn sau khi thanh toán vì vật phẩm chưa xuất hiện. Một tài khoản LINE được hỗ trợ có thể đưa cuộc trò chuyện đó vào hệ thống dưới dạng message.received event đã chuẩn hóa. Nếu endpoint Webhook UnifyPort có signing_secret, lần gửi sẽ dùng X-Device-Timestamp và X-Device-Signature; đây là cơ chế chữ ký riêng, khác với x-line-signature của Webhook thanh toán LINE.
Với đội ngũ tại Việt Nam, Zalo có thể là kênh chăm sóc khách hàng nội địa, còn LINE có thể phục vụ một nhóm khách hàng xuyên biên giới tùy theo thị trường thực tế. Đây là quyết định phân tuyến của hệ thống hỗ trợ; nó không thay đổi phạm vi của LINE IAP và không biến tin nhắn chăm sóc khách hàng thành bằng chứng thanh toán.
Để tìm hiểu sâu hơn về retry và idempotency phía tin nhắn khách hàng, hãy đọc Bảo vệ Webhook HMAC khỏi replay: timestamp, retry và idempotency. Hãy giữ hai handler tách biệt ngay cả khi cuối cùng chúng cùng cập nhật một hệ thống hỗ trợ hoặc đơn hàng.
Giới hạn và đánh đổi
- API lịch sử chính thức là đường phục hồi phù hợp cho Webhook thanh toán LINE MINI App. Một giao diện không chính thức không thể kéo dài thời gian lưu giữ hoặc lấy lại bản ghi thanh toán của nền tảng.
- Khoảng nhìn lại 7 ngày không phải là sổ cái dài hạn. Hãy tự lưu bền vững các bản ghi reserve, sự kiện, quyền lợi và quyết toán.
status=FAILEDthu hẹp phạm vi vào lỗi gửi nhưng có thể bỏ sót trường hợp endpoint đã chấp nhận request rồi ứng dụng xử lý thất bại. Hãy chạy đối soát rộng hơn khi điểm lỗi nằm ở ứng dụng chứ không phải transport.- In-app purchase vẫn là một bề mặt MINI App dành riêng cho Nhật Bản và phải qua xét duyệt. Hãy xác nhận điều kiện hiện hành trước khi thiết kế luồng thanh toán; checklist LINE MINI App đã xác minh và chưa xác minh bao quát quyết định sớm hơn này.
FAQ
Tôi có thể truy xuất lịch sử Webhook thanh toán LINE MINI App trong bao lâu?
Endpoint chính thức chấp nhận lịch sử Webhook trong 7 ngày gần nhất. Hãy chạy phục hồi trước giới hạn đó và duy trì sổ cái bền vững của riêng bạn cho các sự cố cũ hơn.
status=FAILED có nghĩa là khách hàng thanh toán thất bại không?
Không. Nó có nghĩa là LINE gửi Webhook thất bại. Trạng thái mua hàng và trạng thái gửi là hai việc khác nhau; hãy dùng sự kiện trả về cùng với bản ghi reserve và quyền lợi của bạn để đối soát đơn hàng.
Tôi có thể cấp vật phẩm sau khi endpoint reserve trả về 200 không?
Không. Reserve thành công không đảm bảo giao dịch mua đã hoàn tất. Chỉ cấp vật phẩm sau khi xử lý sự kiện purchaseComplete, với idempotency theo orderId.
Phục hồi từ lịch sử có thể xử lý cùng một giao dịch mua hai lần không?
Truy vấn có thể trả về một sự kiện mà handler trực tiếp đã áp dụng. Hãy để cả hai đường gọi cùng một handler atomic và idempotent dùng orderId làm khóa, để lần thử thứ hai trở thành no-op.
x-line-signature của LINE có giống chữ ký Webhook của UnifyPort không?
Không. LINE ký raw body của Webhook thanh toán và gửi chữ ký Base64. Khi signing_secret được bật, UnifyPort ký timestamp cùng raw body rồi gửi các header timestamp và chữ ký riêng. Hãy xác minh độc lập từng giao thức.
Bước tiếp theo
Triển khai và kiểm thử truy vấn phục hồi theo LINE MINI App API reference chính thức, sau đó lên lịch chạy trong cửa sổ lưu giữ 7 ngày. Nếu yêu cầu riêng của bạn là tiếp nhận tin nhắn hỗ trợ LINE thông thường, hãy làm theo hướng dẫn xác thực LINE của UnifyPort sau khi đường thanh toán đã ổn định.
Nguồn
- LINE MINI App API reference: in-app purchase và lịch sử sự kiện Webhook
- Tích hợp tính năng in-app purchase của LINE MINI App
- Hướng dẫn phát triển in-app purchase của LINE MINI App
Các thông tin chính thức được kiểm tra ngày 22/7/2026.