Recover Missed LINE MINI App Purchase Webhooks: A 7-Day Runbook
To recover a missed LINE MINI App purchase webhook, query LINE’s official event history within seven days, paginate without changing the original time range or filters, and replay each returned purchaseComplete event through an idempotent handler keyed by orderId. A successful purchase reservation is not proof of payment, and the history endpoint is a recovery source—not a reason to stop monitoring the live webhook.
Key takeaways
- LINE’s event history covers webhook deliveries from the past seven days and returns up to 100 records per page.
status=FAILEDmeans webhook delivery failed; it does not mean the customer’s purchase failed.- Record
orderIdwhen reserving a purchase, then use it to deduplicate both live and recoveredpurchaseCompleteevents. - Keep payment recovery separate from customer-message routing. They use different event types, credentials, signatures, and operational owners.
Why a successful reservation is not a completed purchase
LINE MINI App in-app purchase is a multi-step official flow. Your server first reserves the purchase with POST https://api.line.me/iap/v1/product/reserve. LINE returns an orderId, but the user can still close the app, cancel in the app store, lose connectivity, or fail to finish payment. LINE’s integration guide therefore says to grant the digital item only after the purchase-complete webhook arrives.
That boundary creates two separate failure questions:
| Question | Evidence to trust |
|---|---|
| Did the reservation request succeed? | The reserve response, saved orderId, and x-line-request-id |
| Did the purchase complete? | A purchaseComplete event or an official reconciliation result |
| Did your endpoint receive the live delivery? | Your raw request log and webhook processing record |
| Did your business handler apply the entitlement once? | An idempotency record keyed by orderId |
The existing LINE MINI App fee and support-webhook guide explains why payment events and customer messages belong to separate systems. This runbook starts one level deeper: the payment webhook should have arrived, but your endpoint was unavailable or processing failed.
How to recover missed LINE MINI App purchase webhooks
1. Detect the gap before the seven-day window closes
Store these values when you reserve a purchase:
- your internal checkout ID;
- LINE’s
orderId; - the
x-line-request-idresponse header; - reservation time and expected product;
- whether a
purchaseCompleteevent has been applied.
Alert when a reservation remains unresolved beyond your normal checkout duration. Do not immediately mark it paid, and do not wait seven days to investigate: the official history endpoint only accepts a range within the preceding seven days.
2. Query a fixed recovery window
The official LINE MINI App API reference documents this recovery endpoint:
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"
The timestamps above are an explicit example window on July 22, 2026, not values to copy into production. Generate UTC epoch seconds from the incident start and end. Use status=FAILED to find deliveries LINE could not complete, or omit status when reconciling every delivery in the window. SUCCESS and FAILED describe delivery status, not purchase outcome.
3. Keep the query stable while paginating
Results are ordered by the time LINE began sending each webhook. A page contains at most 100 records and may include nextCursor. For every later page, preserve startEpochSeconds, endEpochSeconds, pageSize, and status; change only cursor.
This Node.js example keeps that boundary explicit:
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 is your business transaction boundary. It should atomically insert an idempotency record and grant the item, or do nothing when the same orderId has already been applied. LINE’s in-app purchase development guidelines specifically recommend using orderId to prevent duplicate grants because the same webhook can be delivered more than once.
4. Reconcile history with live processing
Do not build a second entitlement path just for recovery. Convert a recovered event into the same internal command used by the live webhook, while recording its source as line_event_history. Then compare:
- reserved
orderIdvalues with no completed internal state; - live webhook logs;
- history records for the fixed incident window;
- idempotency records and entitlement changes.
The history response is obtained with a channel access token. It is not the original HTTP delivery and should not be expected to contain the original x-line-signature header. Continue verifying that header on live webhooks: LINE calculates a Base64-encoded HMAC-SHA256 digest of the raw request body with the channel secret.
5. Close the incident with a measurable checkpoint
A recovery is complete when every reservation in scope is classified as completed-and-applied, incomplete, canceled, or escalated for manual investigation. Record the exact UTC range, filters, page count, recovered orderId values, and the last successful run time. Schedule a lightweight reconciliation job more frequently than the seven-day retention boundary so a weekend outage cannot age out unnoticed.
The current event-history documentation says the endpoint retrieves purchaseComplete events and that refund history support is planned separately. Check the live reference before assuming the same recovery path covers refunds.
Where UnifyPort fits—and where it does not
UnifyPort does not reserve LINE MINI App purchases, confirm app-store payment, recover LINE payment events, grant digital items, or satisfy LINE’s review requirements. The official LINE in-app purchase flow is the correct owner for all of those jobs.
UnifyPort fits when the next event is an ordinary customer message: for example, a buyer writes after payment because an item did not appear. A supported LINE account can deliver that conversation as the normalized message.received event. If a UnifyPort webhook endpoint has a signing_secret, the delivery uses X-Device-Timestamp and X-Device-Signature; that is a separate signature scheme from LINE’s payment-webhook x-line-signature.
For a deeper treatment of retry and idempotency on the customer-message side, read Webhook HMAC Replay Protection: Timestamps, Retries, and Idempotency. Keep the two handlers separate even if they ultimately update the same support or order system.
Limitations and trade-offs
- The official history API is the right recovery path for LINE MINI App purchase webhooks. An unofficial interface cannot extend its retention or recover platform payment records.
- A seven-day lookback is not a long-term ledger. Keep your own reservation, event, entitlement, and settlement records.
status=FAILEDnarrows delivery failures but can miss a delivery your endpoint accepted and then failed to process. Run a broader reconciliation when your application, not the transport, was the failure point.- In-app purchase remains a Japan-specific, reviewed MINI App surface. Confirm current eligibility before designing a payment workflow; the verified versus unverified MINI App checklist covers that earlier decision.
FAQ
How long can I retrieve LINE MINI App purchase webhook history?
The official endpoint accepts webhook history from the past seven days. Run recovery before that boundary and keep your own durable ledger for older incidents.
Does status=FAILED mean the customer payment failed?
No. It means LINE’s webhook delivery failed. Purchase state and delivery state are different; use the returned event plus your reservation and entitlement records to reconcile the order.
Can I grant an item after the reservation endpoint returns 200?
No. A successful reservation does not guarantee purchase completion. Grant the item only after processing a purchaseComplete event, with orderId idempotency.
Can history recovery deliver the same purchase twice?
Your query can return an event that your live handler already applied. Make both paths call the same atomic idempotent handler keyed by orderId, so the second attempt becomes a no-op.
Is LINE’s x-line-signature the same as UnifyPort’s webhook signature?
No. LINE signs the raw payment-webhook body and sends a Base64 signature. UnifyPort signs the timestamp plus raw body when signing_secret is enabled and sends its own timestamp and signature headers. Verify each protocol independently.
Next step
Implement and test the recovery query against the official LINE MINI App API reference, then schedule it inside the seven-day retention window. If your separate requirement is to receive ordinary LINE support messages, follow the UnifyPort LINE authorization guide after the payment path is reliable.
Sources
- LINE MINI App API reference: in-app purchase and webhook event history
- Integrate the LINE MINI App in-app purchase feature
- LINE MINI App in-app purchase development guidelines
Official facts checked on July 22, 2026.