From b848e34b713ffb7509b1b2704fc34bb795c3a6fd Mon Sep 17 00:00:00 2001 From: Devin Zuczek Date: Wed, 26 Aug 2026 10:28:48 -0400 Subject: [PATCH] [commerce] stub endpoint --- apps/commerce/src/commerce.app.ts | 20 +++++++++++++++++++ .../commerce/src/test/integration/api.test.ts | 10 ++++++++++ 2 files changed, 30 insertions(+) diff --git a/apps/commerce/src/commerce.app.ts b/apps/commerce/src/commerce.app.ts index 3dca88b..a4abc23 100644 --- a/apps/commerce/src/commerce.app.ts +++ b/apps/commerce/src/commerce.app.ts @@ -114,6 +114,26 @@ const app = new Hono() (c) => c.json(catalog) ) + // Pending purchases the client asks the server to reconcile — platform transactions + // it started but never saw finish. Nothing is ever recorded here, so there is never + // anything pending and the answer is always an empty list. Accepts GET or POST since + // the client may use either. + .on( + ['GET', 'POST'], + '/purchase/v1/cleanuppending', + describeRoute({ + tags: ['Purchase'], + summary: 'Reconcile pending purchases (no-op)', + description: [ + 'Always `[]` — no purchase is ever recorded, so nothing can be left pending. A 404', + 'here makes the client treat the call as an error, so the empty list is served', + 'instead. Accepts GET or POST.', + ].join(' '), + responses: { 200: json(JsonArray, 'Always empty (nothing pending)') }, + }), + (c) => c.json([]) + ) + // Current purchase campaigns (limited-time offers/promos). None exist, and // an empty list is the client's "no active campaigns" state. .get( diff --git a/apps/commerce/src/test/integration/api.test.ts b/apps/commerce/src/test/integration/api.test.ts index c1f8c2f..a25cc1d 100644 --- a/apps/commerce/src/test/integration/api.test.ts +++ b/apps/commerce/src/test/integration/api.test.ts @@ -43,6 +43,14 @@ describe('commerce endpoints', () => { expect(skus[0]).toHaveProperty('skuId') }) + it('GET|POST /purchase/v1/cleanuppending returns []', async () => { + for (const method of ['GET', 'POST']) { + const res = await SELF.fetch(`${ORIGIN}/purchase/v1/cleanuppending`, { method }) + expect(res.status).toBe(200) + expect(await res.json()).toEqual([]) + } + }) + it('GET /purchasecampaign/allcurrent/v2 returns []', async () => { const res = await SELF.fetch(`${ORIGIN}/purchasecampaign/allcurrent/v2`) expect(res.status).toBe(200) @@ -78,9 +86,11 @@ describe('commerce endpoints', () => { expect([...documented].sort()).toEqual([ 'GET /', 'GET /api/catalog/v1/all', + 'GET /purchase/v1/cleanuppending', 'GET /purchase/v1/hasspentmoney', 'GET /purchasecampaign/allcurrent/v2', 'GET /reminder/currentTokenBundles/v2', + 'POST /purchase/v1/cleanuppending', 'POST /purchase/v1/initiatepurchase', ])