1# OpenIAP Commerce Protocol example2 3A runnable purchase-to-access backend, built and reviewed with AI in seven4milestones. Follow a purchase through verification, ownership, access, and5signed event delivery, and account deletion. Inspect the actual HTTP responses and database changes.6 7The backend uses the published **`openiap-commerce-protocol`** package. HTTP,8SQLite, and webhook signatures run locally; the store, users, and clock are9fictional fixtures. This is a learning example, not a production provider.10 11## Quick start12 13Install [Bun](https://bun.sh/docs/installation) for the HTTP and SQLite runtime14(tested with Bun 1.3.13). Use your favorite package manager for dependencies and15scripts; npm is shown here:16 17```sh18git clone https://github.com/hyodotdev/openiap-commerce-protocol-example.git19cd openiap-commerce-protocol-example20npm install # or pnpm install, yarn install, bun install21npm test22npm start23```24 25Open **http://127.0.0.1:5181**, then click **Run step 1 →** and continue through26step 7. Each step changes real local state. The dashboard shows purchases,27current access, delivery attempts, and expandable request/response details.28No store account, API key, OpenIAP checkout, or IAPKit account is required.29Modern Yarn uses the included `node_modules` linker.30 3132 33The screenshot comes from an executed source checkpoint. See its34[run report](https://github.com/hyodotdev/openiap-commerce-protocol-example/blob/main/docs/build/06-recover-reviewed-8/run.json)35and the [complete build history](https://github.com/hyodotdev/openiap-commerce-protocol-example/blob/main/docs/build/README.md).36 37## What you will see38 39| Step | What changes | Result to check |40| ----------- | ------------------------------------------------ | ---------------------------------------------------- |41| 1. Contract | Load schemas; start with empty storage | No purchases or access yet |42| 2. Verify | Validate fixture evidence; save a purchase | Verification alone grants no access |43| 3. Bind | Attach the purchase to the backend-selected user | Alice gains Premium; Bob cannot claim it |44| 4. Cancel | Turn off renewal; queue an event | Paid access remains until expiry |45| 5. Deliver | Sign events; retry a failed receiver | A repeated delivery has one inbox effect |46| 6. Expire | Advance the clock; reopen SQLite | Access closes; ownership and delivery records remain |47| 7. Erase | Remove provider identity and receiver copies | Repeated deletion and late deliveries cannot restore the user |48 49Restarting `npm start` creates a fresh temporary database, so you can replay the50walkthrough. Step 6 reopens the existing databases **inside the running process**;51it does not simulate an OS crash or a new process recovering external secrets.52If port 5181 is occupied, run `COMMERCE_LAB_PORT=5183 npm start`.53 54## Use the part you need55 56| Your role | Start here | What this example provides |57| -------------------- | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |58| Paywall / experience | [Integration brief](INTEGRATE.md) | Host purchase/result boundaries; no paywall UI implementation |59| Commerce provider | [AI build brief](BUILD.md) | Fixture verifier, ownership/access rules, REST, SQLite, and delivery |60| Data / automation | [Event receiver guide](https://github.com/hyodotdev/openiap-commerce-protocol-example/blob/main/docs/receiver.md) | A ready signed-event receiver with a durable inbox |61| Integrated platform | [Integration brief](INTEGRATE.md) | How the roles compose without splitting account authority |62 63`client-bridge.mjs` maps Apple, Google, Amazon, and Horizon OpenIAP purchase fields into the installed64verification schema **on the app backend**. Run `npm run demo:bridge` to check it.65`npm test` also exercises all four fixture shapes through verification, binding,66access and erasure. Amazon/Horizon cases include negative rechecks and outages.67It does not perform a mobile purchase or authenticate store evidence. The68current client `verifyPurchaseWithProvider` helper uses IAPKit's own API; other69providers connect through the app's authenticated backend.70 71## Receive events72 73```sh74npm run demo:consumer75```76 77This standalone check sends fictional purchase, renewal, cancellation, expiry,78refund, and entitlement events over HTTP. It repeats deliveries, rejects79changed signatures, and reopens the SQLite inbox. It needs no provider server.80 81For a persistent receiver, set `COMMERCE_WEBHOOK_SECRET` and run82`npm run consumer`. The endpoint is `http://127.0.0.1:5182/webhooks/commerce`.83See the [receiver guide](https://github.com/hyodotdev/openiap-commerce-protocol-example/blob/main/docs/receiver.md)84for HTTPS proxy setup, database location, processing responsibilities, and85expected results. Event ingestion does not calculate revenue or grant access.86 87## Build with AI, then check the result88 89Give [BUILD.md](BUILD.md) to your AI for a backend, or [INTEGRATE.md](INTEGRATE.md)90for an existing product. Ask it to implement one milestone, run it, inspect the91screen and responses, fix a failure, and repeat that same check.92 93The [build record](https://github.com/hyodotdev/openiap-commerce-protocol-example/blob/main/docs/build/README.md)94contains independent source archives, patches, screenshots, and execution95reports. The [review log](https://github.com/hyodotdev/openiap-commerce-protocol-example/blob/main/docs/build/REVIEW.md)96keeps the observed mistakes and corrections, including unfinished discovery in97the early snapshots. This implementation grew from an earlier internal98prototype; it was not generated from a blank project in one prompt. Task briefs99are implementation notes, not model transcripts or editor recordings.100 101## Verify or record a change102 103| Command | Checks |104| ---------------------------- | ------------------------------------------------------------------------- |105| `npm test` | Current backend flow, failure cases, request mapper, and receiver |106| `npm run test:tooling` | Capture and patch tooling |107| `npm run verify:checkpoints` | Every archive, its exact patch chain, and an independent npm install/test |108| `npm run capture` | A new immutable source checkpoint and actual desktop/mobile screenshots |109 110Backend commands require Bun. Recording also requires Node.js/npm, Git, tar,111and Google Chrome. The [recording guide](https://github.com/hyodotdev/openiap-commerce-protocol-example/blob/main/docs/recording.md)112explains how to preserve a checkpoint and export evidence. GitHub CI runs the113runtime, tooling, archive, and documentation-export checks.114 115## Account deletion116 117Step 7 runs `eraseUser` using server credentials. The provider removes identity118from purchases and removes identity-bearing event records in one transaction.119A repeated request returns the same completed job, including after restart.120 121The app owns already-delivered copies: it erases its receiver inbox and retains122a keyed deletion marker so late signed events are acknowledged without storing123the deleted identity. The example also refuses rebinding erased evidence.124This is a local ownership policy; the protocol does not cancel the store subscription.125Database backups and the app’s own account records remain the operator’s responsibility.126 127Run `bun verify-erasure.mjs` to exercise deletion while a delivery is in flight,128late lifecycle events, repeated requests, and storage reopening.129 130## Replace the example with IAPKit131 132The OpenIAP checkout includes `packages/kit/scripts/docs/run-commerce-interop.mjs`.133It starts IAPKit with an isolated local Convex deployment and keeps one app134backend and receiver running while switching the commerce provider. See the135[composition guide](https://openiap.dev/commerce-protocol/ecosystem#composition-proof)136for the executed report, source, and command. No IAPKit account or store keys are needed.137 138## What remains for production139 140Real store validation and sandbox purchases, login, tenant141isolation, GraphQL, public HTTPS delivery protections, and operational recovery142are not implemented here. The backend advertises **no complete profiles**.143Schema checks and the local walkthrough do not establish profile conformance.144 145Implement every obligation of your chosen profiles from the installed146`SPEC.md`; add store sandbox, isolation, deployment, and recovery tests.147IAPKit is a reference implementation, not a substitute for those checks.148 149MIT licensed. See [LICENSE](LICENSE).150