feat(kit): add read-only order lookup - #285
Conversation
Support tooling requested in discussion #284: paste an Apple or Google order ID from a customer's receipt and get the full order plus, for subscription orders, the current subscription status. Backend (convex/orders): - lookupOrder action, dashboard-session + org-membership only — never an API key, since this is operator tooling rather than public API - Apple: App Store Server API lookUpOrderId, signed transactions verified through the same SignedDataVerifier path receipt verification uses, then optional getAllSubscriptionStatuses - Google: androidpublisher orders.get plus optional subscriptionsv2 - Reuses the credentials each project already configured; nothing is persisted and no lookup is logged - Optional subscription fetches never invalidate the order result; their failure surfaces as a technical notice Dashboard: Orders tab with summary, transaction identifiers, payment and subscription status, and collapsible raw payloads. The Google purchase token is masked with explicit Show and Copy actions. Correctness details worth noting: - The Apple subscription status is matched by originalTransactionId across every subscription group. Taking the first entry would report an unrelated subscription for customers holding several. - Apple status is only fetched for auto-renewable orders. Every Apple transaction carries an originalTransactionId, so gating on that alone fired the request for consumables too. - Order lookup always runs against production, which SignedDataVerifier refuses without the App Apple ID, so that is preflighted with an actionable message instead of failing deep inside JWS verification. - Apple order IDs are charset-validated: the client concatenates the value straight into the request path without percent-encoding. - Errors are ConvexError so their guidance survives Convex's production redaction, and the dashboard unwraps ReceiptVerificationError's JSON envelope instead of printing it. Docs: new Order lookup section in the IAPKit backend guide covering credentials, the Apple production-only and App Apple ID requirements, the Play "View financial data" permission, and the privacy note; kit README lists the capability. Verified: kit lint, 913 vitest tests, smoke:server, docs build, audit:docs. Four review-self rounds converged (13 findings fixed, final round clean); the two selection helpers that carried the subtlest bugs are pure functions with regression tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdded authenticated Apple and Google order lookup through Convex. Added normalized order and subscription responses, a project Orders dashboard page, navigation, tests, and documentation. ChangesOrder lookup
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant ProjectOrders
participant lookupOrder
participant AppleOrGoogleAPI
ProjectOrders->>lookupOrder: submit store and order ID
lookupOrder->>AppleOrGoogleAPI: request order details
AppleOrGoogleAPI-->>lookupOrder: order data or lookup error
lookupOrder->>AppleOrGoogleAPI: request optional subscription status
AppleOrGoogleAPI-->>lookupOrder: subscription data or secondary error
lookupOrder-->>ProjectOrders: return normalized lookup response
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/docs/src/pages/docs/kit-backend.tsx`:
- Around line 210-214: Update the order lookup description in
packages/docs/src/pages/docs/kit-backend.tsx at lines 210-214 to say
subscription status is returned “when available.” Also update
packages/kit/README.md at line 50 to replace “subscription state” with “when
available, subscription status,” preserving the documented best-effort behavior.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 5c6fd957-57ef-4e6f-82b3-05a6648f6211
⛔ Files ignored due to path filters (1)
packages/kit/convex/_generated/api.d.tsis excluded by!**/_generated/**
📒 Files selected for processing (10)
packages/docs/src/pages/docs/kit-backend.tsxpackages/kit/README.mdpackages/kit/convex/orders/action.tspackages/kit/convex/orders/shared.test.tspackages/kit/convex/orders/shared.tspackages/kit/convex/purchases/android.tspackages/kit/convex/purchases/ios.tspackages/kit/src/pages/auth/index.tsxpackages/kit/src/pages/auth/organization/project/index.tsxpackages/kit/src/pages/auth/organization/project/orders.tsx
Per review: the subscription fetch is optional and its failure does not invalidate the order result, so the docs and README should not read as if every subscription order always returns a status. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The page states it is the canonical changelog and that every shipped PR lands an entry, but the last one was 2026-07-28 while five production changes had deployed since. Entries reconstructed from each PR, dated by its merge to main, which is when deploy-kit.yml ships it: order lookup (#285), sync/verification/MCP session correctness (#292), the production Convex target guard (#314), store verification integrity (#313), and the entitlement defects the conformance suite surfaced (#316). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Closes #284 (feature request from @LukasB-DEV).
Summary
Changes
Backend (
packages/kit/convex/orders/)lookupOrderaction gated on dashboard session + organization membership. It never accepts an API key — this is operator tooling, not part of the public/api/v1surface.lookUpOrderId, with each signed transaction verified through the sameSignedDataVerifierpath receipt verification already uses, then an optionalgetAllSubscriptionStatusesfetch.androidpublisher.orders.get, then an optionalpurchases.subscriptionsv2.getfor subscription line items.shared.tswith unit tests.Dashboard (
Orderstab)Summary, transaction identifiers, payment & subscription status, and collapsible raw payloads, with the status colors from the request. The Google purchase token is masked by default with explicit Show / Copy actions.
Docs
New Order lookup section in the IAPKit backend guide (credentials, Apple production-only + App Apple ID requirement, Play
View financial datapermission, privacy note) and a capability bullet in the kit README.Correctness notes
These came out of the review rounds and are the parts most worth a reviewer's eye:
originalTransactionIdacross every subscription group.getAllSubscriptionStatusesreturns all of the customer's subscriptions, so taking the first entry would report an unrelated subscription's state as this order's — actionable misinformation in a support tool.originalTransactionId(it equalstransactionIdfor one-time purchases), so gating on that alone fired the request — and rendered a failure notice — for consumable orders.SignedDataVerifierrefuses to construct for production without it; without the preflight a normal sandbox-first project gotUnknown verification errorfrom deep inside JWS verification.ConvexErrorso their guidance survives Convex's production redaction of plainErrormessages, and the dashboard unwrapsReceiptVerificationError's JSON envelope rather than printing it verbatim.Test plan
bun run lint(tsc + convex typecheck + eslint)bun run test— 913 tests pass (13 new, covering the two selection helpers that carried the subtlest bugs)bun run smoke:servertsc+vite build,bun run audit:docscleanFour review-self rounds converged: 13 findings (1 high, 5 medium, 7 low) fixed, final round clean.
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation