Jewelry AI・ストア画面
支払いシートのあとに何も表示されない画面は、キャンセルを伝えています
ストア画面が何も表示しないのは、ただ1つの結果に対してだけです。ストアがアプリに返すキャンセルという結果です。アプリがそれとして認識できない結果は、すべて失敗として分類され、失敗のメッセージとして表示されます。つまり、何も表示されない画面は、結果が隠されている状態ではなく、結果が伝えられている状態です。
支払いシートのあとの何も表示されない画面が伝えていること
ストアの処理がキャンセルという結果を返すと、アプリは何も描画しません。エラーも警告も完了の知らせも出ず、処理は開始したストア画面に戻ります(apps/jewelry-mobile/src/app/store/index.tsx)。表示がないこと自体が通知です。
これが意味を持つのは、同じ画面がほかの場合にはメッセージを表示するからです。それ以外の種類のエラーは、すべて目に見えるメッセージを出します。したがって、何も表示されない画面はメッセージが欠けている状態ではなく、メッセージが用意されていない唯一の結果です。
ただし、そこから読み取れることは限られています。分かるのは、試行がアプリのいうキャンセルという結果で終わったということだけです。ストアが何を記録したかは分かりませんし、金銭については何も示しません。
アプリが結果に適用する規則
分類の仕組みは小さく、黙るよりも伝える側に意図的に寄せてあります。
- 結果がキャンセルになるのは2つの特定のシグナルに一致した場合だけで、それより広い条件では判定しません。
- 判定はクライアント側にあり、返ってきた結果を2つの特定のシグナルと照合します(apps/jewelry-mobile/src/features/purchases/catalog-mapping.ts)。シグナルの値そのものは、ここでは公開しません。プロバイダーのソフトウェアがそれをいつ送るかも同様で、その部分は検証していません。
- 判定に一致しないものは、すべて失敗です。
- 3つ目の区分はありません。見覚えのないエラーがキャンセルらしきものとして扱われることはなく、失敗になり、失敗として表示されます。
- 判断がつかない場合は、表示されないのではなくメッセージが出ます。
- この規則は、既定では伝える方向に働きます。何も表示されない画面が読み取れるものになるのは、そのためです。この状態は狭いほうの分岐からしか生じず、未知の分岐から生じることはありません。
- ストアに接続する前に失敗することがあります。
- 商品識別子が、その時点でストアが返すパッケージに含まれていない場合、呼び出しはクライアント側で失敗し、同じ一般的な失敗メッセージが表示されます(apps/jewelry-mobile/src/features/purchases/revenuecat-provider.tsx)。そのため、ストア側で識別子がどう登録されているかの食い違いは、出品者には単なる購入の失敗として届きます。アプリ側の予備の識別子一覧とサーバー側の定義は、テストによって突き合わせられています(apps/jewelry-mobile/src/features/store/fallback-product-ids.test.ts:161)。
結果ごとに、画面が何をするか
この表は一方向にだけ読んでください。起きたことから、描画されるものへの方向です。逆向きには使えません。異なる複数の状況が、1つの行を共有しているためです。
| 試行の結果 | 画面の動き |
|---|---|
| ストアがキャンセルを返し、2つのシグナルのいずれかに一致する | 何も描画されず、処理は開始したストア画面に戻る |
| キャンセルの判定に一致しないエラー | 原因を示さない失敗メッセージが表示される |
| 商品識別子が、その時点でストアが返すパッケージに含まれていない | 呼び出しは始まる前に失敗し、同じ一般的な失敗メッセージが表示される |
| すでに試行が実行中である | ほかの購入ボタンと購入を復元する操作が反応しない |
2回目のタップで2件目の購入が始まらない理由
試行の実行中、ストア画面は処理中の状態を保ちます。この1つの状態が、残りの購入ボタンと購入を復元する操作の両方を無効にします(apps/jewelry-mobile/src/app/store/index.tsx)。その間に同じボタンをもう一度タップしても、2件目の購入は始まりません。
この保護はクライアント側にあり、及ぶ範囲はこの画面に限られます。異なる端末で2つのセッションが同時に動いている場合は別の状況であり、この画面では扱っていません。
反応しないように見える画面が、試行が失われた証拠にならないのも、このためです。ボタンが無効になっているのは、試行がまだ実行されているからです。
この画面からは導けない結論
各行は、もっともらしく聞こえる結論と、実際に検証した内容を並べています。
何も表示されないことを、アプリの不具合と読むこと。
何も表示されない状態は、分類の一方の分岐から生じます。アプリが認識しない不具合はもう一方の分岐に入り、メッセージを出します。
何も表示されないことを、請求がなかったという説明と読むこと。
検証したのは、アプリが結果をどう分類し、どう表示するかです。ストア側の請求はこの画面では読み取っておらず、ここでは主張しません。
失敗のメッセージを、原因の診断と読むこと。
メッセージはすべての失敗経路で同一なので、何も区別しません。手がかりとして扱うと、関係のない設定を変更しに行くことになります。
ロックされた画面を、試行が失われた状態と読むこと。
ロックは試行の実行中にだけ存在し、2件目の試行が始まらないようにするためのものです。
このページで確定しないこと
- キャンセルされた試行が請求を残したかどうか。検証したのはアプリの分類であり、ストアの請求ではありません。
- プロバイダーのソフトウェアが、どの状況でどのシグナルを送るか。検証したのはクライアント側の判定だけで、シグナルの値はここでは公開しません。
- ある失敗がなぜ起きたか。アプリは画面上で原因を区別せず、このページも、メッセージから原因を推測する方法を示しません。
- 購入が完了したあとにクレジットが表示されるかどうか。これは別の画面に属する、別の問いです。
- 価格がどのようにストア画面に届くか。これはまったく別のところから読み込まれており、ここでは扱いません。
- 金額、パッケージ、プラン、通貨に関すること。このページの根拠は仕組みの確認のためだけに読んでおり、そうした記述を裏づけません。
- 2台目の端末や別のセッションからの同時の試行。ここで説明した一度に1件という規則は、この画面の内部で適用されます。
よくある質問
支払いシートを閉じて戻ったら、何も表示されませんでした。何か壊れたのですか。
いいえ。キャンセルという結果は、画面が何も描画しないことで伝える唯一の結果で、処理は開始したストア画面に戻ります(apps/jewelry-mobile/src/app/store/index.tsx)。アプリがキャンセルとして認識できない結果は、代わりに目に見える失敗メッセージを出します。そのため、エラーであれば、隠されずに表示されていたはずです。
購入がキャンセルされたということは、請求されていないと確実に言えますか。
それは、このページでは確認できません。検証したのは、アプリが返ってきた結果をどう分類し、何を表示するかです。ストアの請求の動作はこの画面では読み取っていないため、キャンセルという分類は、請求の有無どちらの証拠にもなりません。
購入ボタンをもう一度タップすると、2件目の購入が始まりますか。
この画面からは始まりません。試行の実行中、画面は処理中の状態を保ち、ほかの購入ボタンと購入を復元する操作を無効にします。同じボタンをもう一度タップしても、2件目の試行は始まりません(apps/jewelry-mobile/src/app/store/index.tsx)。この保護はクライアント側にあるため、及ぶ範囲はこの画面であり、2台の端末を同時に使う場合ではありません。
失敗のメッセージに理由が書かれていません。原因はどう調べればよいですか。
この画面は、原因を伝えるようには作られていません。すべての失敗経路が同じ一般的なメッセージを出します。その中には、商品識別子がその時点でストアが返すパッケージに含まれていないために、アプリ内で失敗する経路も含まれます(apps/jewelry-mobile/src/features/purchases/revenuecat-provider.tsx)。経路が区別されていないため、表示される一文には、どれが起きたかについての情報が含まれていません。