ELA · Decision brief · 24 Aug 2026 · written in Simplified Technical English

Deploy now, or wait for the Apple product?

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.

LIVE RISK YOUR DECISION DONE / SAFE FACT

01The one-line answer

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.

02The security hole LIVE RISK

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.

What the hole is, in plain steps

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.

  1. The brief page carries a hidden "accept token" inside its data.
  2. Anyone who holds the secret link can read that token.
  3. Before the fix, that token alone could accept the case — with no phone code check.
  4. So a forwarded or leaked link could let the wrong party take a real emergency case. The member would then be told "a lawyer has your case". This is a life-safety mis-route.

How exposed are you right now? FACT

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.

What the fix does DONE / SAFE

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.

03What is the "Apple product" (ASC product)?

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.

04Deploy or wait — three options YOUR DECISION

OptionWhat it doesCost / 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.

05Test the payment on the simulator, end to end

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.

  1. Open terminal 1. Run just api-local. This starts the server on your Mac with the payment code and a test login door.
  2. Open terminal 2. Run just sim-iap. This wires the test store into the app and builds it on the simulator.
  3. When Xcode opens, press Run (⌘R) on the ELA scheme. The test store attaches only on a scheme launch.
  4. In the app, sign up. Use an email that ends in @example.test. The login code is 123456.
  5. At the priors step, answer no recorded prior. This routes you to the Essential plan.
  6. On the payment screen, the test store shows the price. Complete the purchase with Apple's test flow. No card and no charge.

One limit to know

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):

  1. In Xcode, open Products.storekit.
  2. Choose menu Editor → Save Public Certificate… and save the file.
  3. Point 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.

06The bug I fixed on the payment screen DONE / SAFE

You saw the message "We couldn't check your membership status, so purchasing is paused." This had two causes.

  1. A real app bug. The app added an extra field to its status check that the server refuses. So the check always failed. I removed the field. This is fixed in the code.
  2. Version gap. Production is older than the app and does not have the payment endpoints yet. So the check finds nothing and pauses — on purpose, for safety. This clears once the payment code deploys (Option A does not include it; Option B does).

07What is risky now READ THIS

ChangeRiskState
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.

08What I need from you

  1. Deploy choice: A (security-only, recommended), B (full), or C (wait).
  2. Apple product: do you want to create the App Store Connect subscription items next? I can write the exact names, codes, and prices for you to enter.
  3. Nothing is on production from this session except the two safe device-meta database changes. I have not deployed. I am waiting for your call.