Skip to content

Commit ba8a847

Browse files
ralyodioclaude
andcommitted
Return the sale promise, so the write lands before the receipt
The gateway awaits onSale before sending the buyer's receipt (its JSDoc said otherwise; profullstack/x402-gateway#5 fixes the comment and tests the behaviour). Dropping the promise made the write fire and forget, which is fine while a long-lived server keeps running and silently loses the sale anywhere the runtime can stop once the response is sent. Returning it makes the sale land first. A rejection is still swallowed by the gateway, so a database failure never costs a buyer the pass it paid for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0144uEVbZK3jdaQkwcLYTXPE
1 parent 42bcdd7 commit ba8a847

1 file changed

Lines changed: 19 additions & 14 deletions

File tree

‎apps/web/src/app.js‎

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -235,21 +235,26 @@ const crawlGateway = createGateway({
235235
/*
236236
* Write the sale down. Until now a pass existed only for as long as the
237237
* response took to send, so neither "what did this earn" nor "who is the
238-
* customer" could be answered afterwards. Never awaited into the answer: a
239-
* bookkeeping failure must not fail a payment the buyer already made.
238+
* customer" could be answered afterwards.
239+
*
240+
* The promise is returned rather than dropped: the gateway awaits this hook
241+
* before the receipt goes out, so returning it is what makes the sale land
242+
* before the buyer is told it succeeded. The gateway swallows a rejection,
243+
* so a database failure still sells the pass it was paid for.
240244
*/
241-
onSale: (sale) => {
242-
q.recordCrawlSale({
243-
payer: sale.payer,
244-
ref: sale.ref,
245-
days: sale.days,
246-
priceCents: sale.priceCents,
247-
totalCents: sale.totalCents,
248-
currency: sale.currency,
249-
userAgent: sale.userAgent,
250-
expiresAt: sale.expiresAt,
251-
}).catch((err) => console.error('[x402] could not record the sale', err));
252-
},
245+
onSale: (sale) =>
246+
q
247+
.recordCrawlSale({
248+
payer: sale.payer,
249+
ref: sale.ref,
250+
days: sale.days,
251+
priceCents: sale.priceCents,
252+
totalCents: sale.totalCents,
253+
currency: sale.currency,
254+
userAgent: sale.userAgent,
255+
expiresAt: sale.expiresAt,
256+
})
257+
.catch((err) => console.error('[x402] could not record the sale', err)),
253258
});
254259

255260
/*

0 commit comments

Comments
 (0)