状態遷移と期限
ここでは加盟店が判断に使う遷移条件をまとめます。ワーカーの排他制御・リトライの細部は扱いません。
図は、分岐の問いに「はい/いいえ」で答えながら上から下へたどります。矢印の横には、誰の操作で進むかを書いています。
正常系の流れ
利用者の JPYC 残高が足りるかどうかで、途中の状態が 2 通りに分かれます。どちらも最後は settled です。
残高が足りる場合
| 状態 | 何が起きたか | 誰が動いたか(画面) |
|---|---|---|
created | 決済を作った。署名待ち | 加盟店のサーバー |
signed | 支払い操作に署名した | 利用者(決済ページでパスキーで承認) |
deposit_confirmed | 支払える残高を確認した | STBLpay |
deploying | ウォレットを作成している。初回だけ通り、終わると deposit_confirmed に戻る | STBLpay |
executing | 送金を実行し、結果を待っている | STBLpay |
settled | 送金が成功し、加盟店の受取ウォレットに JPYC が届いた | ― |
振込が必要な場合
| 状態 | 何が起きたか | 誰が動いたか(画面) |
|---|---|---|
created | 決済を作った。署名待ち | 加盟店のサーバー |
signed | 支払い操作に署名した | 利用者(決済ページでパスキーで承認) |
issue_pending | 利用者が JPYC EX の手続きへ進んだ(予約開始の通知を STBLpay が受けた)。着金を待っている。JPYC EX での手続きが済んだかは確かめていない | 利用者(決済ページから JPYC EX へ) |
deposit_confirmed | 発行された JPYC が届き、支払える額がそろったことを確認した | 利用者が振込み、JPYC EX が発行。確認は STBLpay |
deploying 以降 | 残高が足りる場合と同じ | STBLpay |
Webhook が届くのは、settled などの終端に着いたときだけです。ただし、終端のうち nonce_conflict では Webhook が届きません。途中の状態と nonce_conflict は状態照会で確かめます。振込が必要な場合は利用者の振込を待つため、issue_pending のまま時間がかかることがありますが、失敗ではありません。
遷移の一覧
| 元の状態 | 条件 | 行き先 |
|---|---|---|
created | 署名を受け取った | signed |
created | 操作期限に達した | expired |
signed | 振込が必要で、決済ページから予約開始の通知を受けた(JPYC EX での手続きの成否は見ない) | issue_pending |
signed | 残高が足りることを STBLpay が確認した | deposit_confirmed |
signed | 操作期限に達した | expired |
signed | 利用者がマイページで取り消した | canceled |
issue_pending | 期限内に支払える額がそろった(発行された JPYC の着金、または今の残高との合計) | deposit_confirmed |
issue_pending | JPYC EX からの着金の宛先が、利用者が署名した支払い操作の sender(この決済に使う利用者のウォレット)と食い違う | failed |
issue_pending | 着金期限と確定待ちの猶予を過ぎた | expired |
issue_pending | 着金が確認される前に、利用者がマイページで取り消した | canceled |
deposit_confirmed | ウォレットがまだ作られていない | deploying |
deposit_confirmed | STBLpay が実行を始めた | executing |
deposit_confirmed | 実行の前に、やり直せない失敗が確定した、またはリトライを使い切った | failed |
deposit_confirmed | 送金の結果が確定できない | nonce_conflict |
deposit_confirmed | 送金がすでに済んでいて、結果が成功だったと分かった | settled |
deploying | 2 つのウォレットの準備が終わった | deposit_confirmed |
deploying | 失敗した、または試行の上限に達した | failed |
executing | 実行に成功した | settled |
executing | 失敗した、またはリトライを使い切った | failed |
executing | 送金の結果が確定できない | nonce_conflict |
図と一覧では、次の 3 つを省いたり、まとめたりしています。
issue_pendingからfailed(着金の宛先の食い違い)は、保存しているデータの食い違いに備えた防御で、通常の操作では起きません。そのため、図からは省いています。- 加盟店が利用停止になると、まだ送金を始めていない決済は
failed(failed_reasonはmerchant_suspended)になります。図と一覧では省いています。詳しくは加盟店の利用停止を参照してください。 deposit_confirmedから直接settled(送金がすでに済んでいて、成功だったと分かった場合)は、一覧には載せていますが、図からは省いています。
deploying と executing は確認や一時的失敗の間、同じ状態に留まることがあります。deploying から直接 executing へ進めません。終端状態からの遷移はありません。
着金と残高払い
振込の経路では、届いた着金の宛先・送金元(JPYC の発行体)・チェーン・時刻を照合します。そのうえで、利用者のウォレットの利用可能な残高(今の残高と着金の合計)が決済額に足りれば、deposit_confirmed に進みます。新しい着金だけでは決済額に届かなくても構いません。送金元が発行体でない着金は数えません。決済は issue_pending のまま残り、期限までに額がそろわなければ expired になります。着金は、取り消されない状態になってから検知します(技術的な詳細)。
たとえば、残高 ¥1,000 の利用者が ¥3,500 の決済をし、足りない分として ¥3,000 を発行した場合は、残高と着金の合計 ¥4,000 が決済額に足りるので deposit_confirmed に進みます。
残高払いは signed から deposit_confirmed へ進み、着金の検知を待ちません。残高が足りるかは STBLpay が定期的に確認するので、承認の直後ではなく、少し遅れて進むことがあります。同じ残高を複数の決済へ重複充当しない制御は STBLpay 側が行います。
操作期限と着金期限
createdと予約開始前のsignedはcheckoutExpiresAtで失効します。作成したまま永久に残ることはありません。- 予約開始通知の初回受理時に、発行予約期限に 14 日を加えた着金期限を確定します。着金期限は、作成応答・状態照会・Webhook には含まれません。着金期限の具体的な日時を知りたいときは、問い合わせ先に問い合わせてください。
issue_pendingは着金期限に確定待ちの猶予を加えても一致する着金が見つからない場合に失効します。着金が期限内かは、ブロックの時刻で判定します。- 期限内に届いた着金は、検知が期限の後になっても決済に充てます。そのための猶予が、上の「確定待ちの猶予」です。
任意の merchantExpiresAt を指定した場合は、着金期限と指定値の早い方を着金期限にします。操作期限は短くなりません(指定できるのは作成から 3 日より先だけで、操作期限はそれより短いため)。省略時はサーバーの期限をそのまま使います。作成時点から 3 日以内に切れる指定は拒否されます。同じ orderId の再作成で指定値を上書きできません。
着金期限と、利用者が署名した支払い操作の実行期限は別です。加盟店指定期限で実行期限を縮めません(技術的な詳細)。
キャンセル
決済を取り消せるのは利用者だけです。利用者が STBLpay のマイページで、パスキーで承認して取り消します。取り消せるのは signed と、着金が確認される前の issue_pending です。加盟店や STBLpay から取り消す方法はありません。取り消されると、加盟店に payment.canceled の Webhook が届きます。発行体の予約取消と、STBLpay の canceled を同一視しないでください。
技術的な詳細
ここまでの本文で平易に書いた内容の、ブロックチェーン側の呼び名です。加盟店が実装で扱う必要はありません。問い合わせのときなどに使います。
- nonce:ウォレットが出す操作に付く通し番号。同じ番号は一度しか使えません。送金の結果が確定できず
nonce_conflictになるのは、操作の結末を特定できないまま、確認の上限に達したときです。番号が使われたことを確かめられた場合に限らず、番号を読む通信の失敗が上限まで続いた場合も含みます。 - UserOperation:利用者が署名する、支払いのための操作の単位です。本文の「支払い操作」はこれを指します。
validUntil:署名済みの UserOperation の実行期限です。着金期限とは別に決まり、加盟店指定期限では縮めません。- revert:ブロックチェーンへ送った操作が実行の途中で拒否され、なかったことになること。状態が
failedになる理由の 1 つです。 - デプロイ:ウォレットをブロックチェーン上に作ること。初回の決済では、利用者のウォレットと加盟店の受取ウォレットが必要になり、状態が
deployingを経ます。本文の「ウォレットの作成」はこれを指します。 - 64 ブロック(finality):着金を含むブロックの後ろに 64 ブロックが積まれると、取り消されない状態になったと扱います。この状態を finality と呼びます。着金はこの状態になってから検知するので、その間、決済は
issue_pendingのままです。 - minter:JPYC を発行する権限を持つアドレス。振込の照合では、送金元が発行体の minter と一致するかを確かめます。
- sender:利用者が署名した UserOperation を出すウォレット(この決済に使う利用者の AA Wallet)のアドレス。JPYC EX からの着金の宛先がこれと食い違うと
failedになります(通常の操作では起きません)。 - Transfer:JPYC の移動を記録したイベント。着金の検知は、この記録を見て行います。
txHash:ブロックチェーン上の取引番号です。問い合わせに使います。