Jewelry AI, store screen
An empty screen after the payment sheet is reporting a cancellation
The store screen shows nothing at all for exactly one outcome: a cancellation the store reports back to the app. Everything the app cannot recognise as that is classified as a failure and shown to you as a failure message. An empty screen is therefore a result being reported, not a result being hidden.
What an empty screen after the payment sheet is reporting
When the store flow returns an outcome of cancelled, the app draws nothing. There is no error, no warning and no confirmation, and the flow returns to the store screen you started from (apps/jewelry-mobile/src/app/store/index.tsx). That absence is the report.
This matters because the same screen does display messages in other cases. Every other kind of error produces a visible message, so an empty screen is not a missing message: it is the one outcome for which no message was written.
The reading is narrow, though. It tells you the attempt ended in the outcome the app calls a cancellation. It does not tell you what the store recorded, and it says nothing about money.
The rule the app applies to an outcome
The classification is small, and it is deliberately biased towards speaking rather than staying quiet.
- Two specific signals, and nothing wider, make an outcome a cancellation.
- The test lives in the client and checks the returned outcome against two specific signals (apps/jewelry-mobile/src/features/purchases/catalog-mapping.ts). The signals themselves are not published here, and neither is the question of when the provider software sends them - that part was not verified.
- Anything the test does not match is a failure.
- There is no third category. An unfamiliar error is not treated as a probable cancellation; it becomes a failure, and a failure is shown.
- Uncertainty produces a message rather than silence.
- The default direction of the rule is to report. That is what makes an empty screen readable at all: it can only have come from the narrow branch, never from the unknown one.
- A failure can occur before the store is contacted.
- If the product identifier is missing from the packages the store returns at that moment, the call fails at the client and the same general failure message is shown (apps/jewelry-mobile/src/features/purchases/revenuecat-provider.tsx). A mismatch in how identifiers are recorded on the store side therefore reaches a seller as a plain purchase failure; a test holds the app's fallback identifier list and the server-side source together (apps/jewelry-mobile/src/features/store/fallback-product-ids.test.ts:161).
Each outcome, and what the screen does with it
Read the table in one direction only, from what happened to what is drawn. It does not work in reverse, because several different situations share a single row.
| Outcome of the attempt | What the screen does |
|---|---|
| The store reports a cancellation, matching one of the two signals | Nothing is drawn; the flow returns to the store screen it started from |
| Any error the cancellation test does not match | A failure message is shown, without a cause |
| The product identifier is not among the packages the store currently returns | The call fails before it starts, and the same general failure message is shown |
| An attempt is already running | The other purchase buttons and the restore action do not respond |
Why a second tap does not open a second purchase
While an attempt is in progress the store screen holds a busy state, and that single state disables both the remaining purchase buttons and the restore action (apps/jewelry-mobile/src/app/store/index.tsx). Tapping the same button again inside that window does not start a second purchase.
The protection is client-side and its scope is this screen. Two sessions running at the same time on different devices are a different situation, and nothing on this surface addresses it.
This is also why a screen that looks unresponsive is not evidence that the attempt was lost. The buttons are disabled because the attempt is still running.
Conclusions that do not follow from this screen
Each row pairs a reasonable-sounding conclusion with what was actually verified.
Reading silence as a fault in the app.
Silence is produced by one branch of the classification. A fault the app does not recognise takes the other branch and produces a message.
Reading silence as a statement that nothing was charged.
What was verified is how the app classifies and displays an outcome. Billing on the store side was not read on this surface and is not claimed here.
Reading the failure message as a diagnosis.
The message is the same for every failure path, so it separates nothing. Treating it as a hint sends a seller to change settings that were never implicated.
Reading a locked screen as a lost attempt.
The lock exists only while an attempt is running, and it exists to stop a second attempt from being opened.
What this page does not settle
- Whether a cancelled attempt left a charge behind. The app's classification was verified; the store's billing was not.
- Which signals the provider software sends in which situation. Only the client's test was verified, and the signal values are not published here.
- Why a particular failure happened. The app does not separate causes on screen, and this page offers no way to infer one from the message.
- Whether credit appears after a purchase completes, which is a separate question on a separate surface.
- How prices reach the store screen, which is read from somewhere else entirely and is not covered here.
- Anything about amounts, packages, plans or currency. The source behind this page was read for mechanics only and does not support those statements.
- Simultaneous attempts from a second device or session. The one-at-a-time rule described here is enforced inside this screen.
Questions
I backed out of the payment sheet and nothing appeared. Did something break?
No. A cancelled outcome is the one result the screen reports by drawing nothing at all, and the flow returns to the store screen it started from (apps/jewelry-mobile/src/app/store/index.tsx). Anything the app cannot recognise as a cancellation produces a visible failure message instead, so an error would have been shown rather than hidden.
Does a cancelled purchase mean I was definitely not charged?
That is not something this page can confirm. What was verified is how the app classifies the returned outcome and what it displays; the store's billing behaviour was not read on this surface, so a cancelled classification is not evidence either way about a charge.
Can a second tap on the buy button start a second purchase?
Not from this screen. While an attempt is running, the screen holds a busy state that disables the other purchase buttons and the restore action, and a repeat tap on the same button does not open a second attempt (apps/jewelry-mobile/src/app/store/index.tsx). The protection is client-side, so its scope is this screen rather than two devices used at once.
The failure message does not say why. How do I find the cause?
The screen is not built to tell you. Every failure path produces the same general message, including one that fails inside the app because the product identifier is not among the packages the store currently returns (apps/jewelry-mobile/src/features/purchases/revenuecat-provider.tsx). Because the paths are not separated, the sentence you read carries no information about which one occurred.