ELA · Decision brief · 24 Aug 2026 · written in Simplified Technical English
This brief explains three things in plain steps. One: a security hole is live on the server. Two: what the "Apple product" is, and why the payment cannot work without it. Three: how to test the payment on the simulator today, and what is risky now.
DECISION EXECUTED · 24 Aug 17:07 UTC
You chose Option A. It is done. The security fix is now live on production. Production moved from 140f0130 to 43e874a1. The health check passed. No payment code and no database migration went out. The firm hole is closed.
Still to do, when you are ready: create the Apple product (Section 03), and ship the step-2 copy to phones by TestFlight. Read on for the detail that led here.
You can test the payment end to end on the simulator today. You do not need to deploy for that. You do not need Apple for that.
The deploy is a separate question. The deploy does not make real payments work, because the Apple product does not exist yet. The deploy matters for one real reason: it closes a security hole that is now live on the server.
Recommendation: test on the simulator now. Deploy the security fix on its own soon. Hold the payment code until the Apple product and the pricing rulings are ready.
Correction first. The handoff note said this hole was not on the server. That note was wrong. I checked the server directly. The vulnerable code is live on production now.
A law firm gets a secret web link when the app sends a case to it. The link opens a case brief. The fix concerns who is allowed to accept the case from that link.
The hole is live, but the real-world exposure today is very low. Two facts hold it down:
The exposure becomes real the moment a real outside law firm starts receiving links, or at public launch. Fix it before that point.
The fix removes all power from the public accept token. The token can now only start the phone-code step. To accept a case, a firm must enter a one-time code sent to its registered duty number. A new, separate "portal session" — issued only after that code — is the sole key to the case actions.
Two independent reviewers checked the fix across four rounds. The security result is clean. It is covered by 24 automated tests.
ASC means App Store Connect. It is Apple's website where you set up what your app sells.
An "ASC product" is the subscription item itself — for example Essential · Monthly · AED 79.99. Apple must hold this item on file. The app asks Apple for it by a product code (for example ela.essential.monthly).
Today that item does not exist in App Store Connect. So on a real phone, the Apple payment sheet has nothing to show, and a real purchase cannot complete.
Only you can create it. It needs a name, a price, and a short Apple review. This is a form-filling task in App Store Connect, not a code task.
Key point. Deploying the code does not create the Apple product. So a deploy alone does not make real payments work.
| Option | What it does | Cost / risk |
|---|---|---|
| A. Security-only deploy recommended |
Ship the firm fix and the step-2 copy on their own. Leave the payment code out. | Low. Closes the live hole. Does not ship the unfinished payment feature. Needs a small cherry-pick branch, which I can prepare and hold ready. |
| B. Full deploy | Ship everything on the main branch, including the whole payment feature. | Higher. The payment screens go live but every real purchase still fails, because the Apple product is missing. It also applies 8 payment database migrations to production. Best done after the Apple product exists. |
| C. Wait | Change nothing on the server for now. | Acceptable only because the links go to your own test details today. Not acceptable once real firms onboard. |
My recommendation: Option A.
It closes the live hole with the least risk and does not drag the unfinished payment feature into production. Tell me to prepare it, and I will build the cherry-pick branch and hold it for your go.
YES — you can do this now. A local test rig runs the payment fully. It does not need Apple. It does not need the Apple product. It uses Xcode's built-in test store.
just api-local. This starts the server on your Mac with the payment code and a test login door.just sim-iap. This wires the test store into the app and builds it on the simulator.@example.test. The login code is 123456.The purchase completes on the Apple side. But the server grant stays off by default, because the server needs Apple's test certificate to trust the receipt.
To test the full grant (the app shows you as a paid member afterwards):
Products.storekit.ELA_APPSTORE_ROOT_CERTS_PATH at that file before you start just api-local.Without this step, you will still see the whole purchase flow — you just will not see the "you are covered" state that follows a verified receipt.
You saw the message "We couldn't check your membership status, so purchasing is paused." This had two causes.
| Change | Risk | State |
|---|---|---|
| Firm accept fix (the auth rewrite) | If wrong, a real law firm could be blocked from accepting or closing a case. That is a life-safety path. | Held down by 24 tests and four review rounds. One known limit: a firm that loses its browser tab after accepting must phone the ops desk to report the case resolved, until the durable link feature is built (your open §10 decision). |
| Device-meta database change | Low. The new columns are optional and empty. | Already applied to production and staging. Safe: nothing writes those columns until the app code deploys. |
| Payment code and the local test rig | None on production. It is not deployed. | On the main branch only. It affects nothing on production until you choose Option B. |
Bottom line on risk. Nothing from this work has degraded production. The only live risk is the pre-existing firm hole, and Option A closes it. The main branch is safe to test from, but a full deploy (Option B) ships the unfinished payment feature — do that after the Apple product exists.