> ## Documentation Index
> Fetch the complete documentation index at: https://waffo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# ミニプログラム決済

> ウォレットのミニプログラム内で決済を受け付ける方法：連携が必要なフロントエンド JS API と Waffo のエンドポイント、注文作成時に送信する内容、返金の仕組み、userid/inquiry によるユーザーの特定方法、追加スコープが承認されない限りユーザーの公開 ID しか取得できない理由。

一部のウォレットは、そのウォレット自身のアプリ内で動作する小さなアプリ、**ミニプログラム**をサードパーティに
提供しています。ミニプログラムを公開している場合、ユーザーをブラウザに送り出すことなくその中で決済を回収できます。
ミニプログラムがウォレットに支払いを依頼し、貴社のバックエンドは他の注文とまったく同じように Waffo とやり取りします。

このページでは連携全体、すなわち決済の経路、返金の経路、そして別建てのユーザー識別の経路を扱います。署名、鍵、
ヘッダーは他のすべての Waffo API と変わりません。[認証と署名](/docs/ja/support/auth-signature-faq)を参照してください。
ミニプログラム固有でない注文フィールドは
[注文作成フィールドガイド](/docs/ja/support/order-create-field-guide)にあります。

> [!NOTE]
>
> ミニプログラムの公開には、そのウォレット自身のミニプログラムプラットフォームでの開発者アカウントが必要で、
> API 呼び出しで送信するアプリ識別子は Waffo が割り当てます。コードを書き始める前に、Waffo の連携担当者にその手続きの
> 開始を依頼してください。識別子はセルフサービスでは取得できません。

## 実際に何を構築する必要がありますか？

2 つの独立したトラックがあります。決済は必須で、識別は最初のステップのみが必須です。

**決済トラック**

| 構成要素 | 場所 | 必須 |
| - | - | - |
| `my.tradePay`（ウォレットの JS API） | ミニプログラムのフロントエンド | はい |
| `POST /api/v1/order/create` | 貴社のバックエンド | はい |
| `POST /api/v1/order/inquiry` | 貴社のバックエンド | はい |
| 決済結果の通知（Webhook） | 貴社のバックエンド | はい |
| `POST /api/v1/order/refund` | 貴社のバックエンド | 返金する場合のみ |
| `POST /api/v1/refund/inquiry` | 貴社のバックエンド | 2 つのうちいずれか |
| 返金結果の通知（Webhook） | 貴社のバックエンド | 2 つのうちいずれか |

**識別トラック**

| 構成要素 | 場所 | 必須 |
| - | - | - |
| `my.getSystemInfo`（ウォレットの JS API） | フロントエンド | はい |
| `my.getAuthCode`（ウォレットの JS API） | フロントエンド | はい |
| `POST /api/v1/userid/inquiry` | 貴社のバックエンド | はい |
| `POST /api/v1/userinfo/inquiry` | 貴社のバックエンド | プロフィールデータが必要な場合のみ |

識別の 2 つのエンドポイントはいずれも API キーの **payin** スコープにあるため、注文作成に使うのと同じキーで呼び出せます。

## 決済フローは最初から最後までどのように進みますか？

1. ユーザーがミニプログラムで*支払う*をタップします。フロントエンドは Waffo ではなく**貴社自身の**バックエンドを
   呼び出します。API キーと署名用の秘密鍵は決してフロントエンドに渡してはいけません。
2. バックエンドが下記のミニプログラム用フィールドとともに `/api/v1/order/create` を呼び出し、決済 URL を受け取ります。
3. フロントエンドがその URL を `my.tradePay` に渡します。
4. ウォレットが独自の決済 UI を実行し、成功または失敗をフロントエンドに返します。
5. Waffo が正式な結果を `notifyUrl` に送信します。バックエンドはステップ 4 ではなく、これに基づいて注文を履行します。

最後の点が実際のインシデントを引き起こします。`my.tradePay` が返す値は **UI 上の結果**です。ユーザーのアプリで
何が起きたかを伝えるもので、資金に何が起きたかではありません。ウォレットをバックグラウンドにした、電波を失った、
アプリを強制終了したユーザーは、成功した決済についてフロントエンドの結果をまったく残さないことがあります。
[決済結果の確認](/docs/ja/support/payment-results-faq)に記載のとおり、Webhook、または
`/api/v1/order/inquiry` のポーリングを唯一の正とみなしてください。

## 注文作成時には何を送信しますか？

通常の注文に必要なすべてに加えて、ミニプログラム固有の 3 つです。

| フィールド | 値 |
| - | - |
| `paymentInfo.productName` | `MINI_PROGRAM_PAYMENT` |
| `paymentInfo.payMethodName` | 決済手段設定に表示されているとおりの、そのウォレットの決済手段名 |
| `paymentInfo.payMethodProperties.appId` | Waffo が割り当てたミニプログラムのアプリ識別子 |
| `userInfo.userTerminal` | `IN_MINI_PROGRAM` |

`userTerminal` は見た目以上に重要です。Waffo がこの特定のリクエストに決済手段を提供できるかを判断する要素の 1 つだからです。
`WEB` として送信されたミニプログラムの注文は、使用可能な決済手段がないとして拒否されることがあります。すべての決済手段が
すべての端末をサポートしているわけではないからです。他に受け付けられる値は `WEB`、`APP`、`IN_WALLET_APP`
（ユーザーがウォレットアプリ内にいるが、ミニプログラム内ではない）です。

どの決済手段名とどの通貨がアカウントに設定されているか不明な場合は、`/api/v1/paymethodconfig/inquiry` で読み戻してください。
[決済手段の設定と注文制限](/docs/ja/support/payment-method-config-and-limits-faq)を参照してください。

## ミニプログラム決済はどのように返金しますか？

通常の返金 API、すなわち `/api/v1/order/refund` を使い、結果は `/api/v1/refund/inquiry` または返金 Webhook で追跡します。
ミニプログラム専用の返金エンドポイントはなく、1 注文あたりの返金回数に関するミニプログラム固有のルールもありません。

異なるのは**決済手段**の返金能力です。一部返金がそもそも許可されているか、繰り返せるかです。仮定するのではなく
決済手段設定から `refundAllowed` を読み取り、各能力が実際に何を意味するかは
[決済手段別の返金制限](/docs/ja/support/payment-method-refund-limits-faq)を参照してください。

## ミニプログラム内でユーザーをどのように特定しますか？

ミニプログラム自身はユーザーが誰かを知ることができません。ウォレットが仲介します。

1. フロントエンドが必要なスコープとともに `my.getAuthCode` を呼び出します。短命の `authCode` が返されます。
2. フロントエンドがその `authCode` をバックエンドに送ります。
3. バックエンドが `merchantId`、`appId`、`authCode`、`appPlatform`（Waffo が割り当てたウォレットプラットフォームのコード）
   とともに `/api/v1/userid/inquiry` を呼び出します。
4. 次の値が返されます。

| フィールド | 備考 |
| - | - |
| `userId` | そのウォレットにおけるユーザーの**公開識別子**。貴社のミニプログラム内でそのユーザーについて安定しています |
| `accessToken` | 続けてプロフィールデータを要求する場合にのみ必要 |
| `accessTokenExpiryTime` | ISO 8601。トークンは無期限ではありません。これを過ぎてキャッシュしないでください |

`userId` を貴社自身のアカウント紐づけのキーとして使用してください。電話番号、メールアドレス、ウォレットをまたぐ
アイデンティティとして扱わ**ないで**ください。これは貴社のミニプログラムにスコープされた不透明な識別子です。

## 商品を届けるためにユーザーのメールアドレスを取得できますか？

デフォルトでは取得できません。これがこの連携で最も多い驚きです。

`my.getAuthCode` には、スコープ `MINI_PROGRAM` と `PUBLIC_ID` を**必ず**含める必要があります。この 2 つで得られるのは
公開ユーザー識別子のみです。それ以外はすべて、ウォレットプラットフォームによって**マーチャントごとに承認が必要な
オプションスコープ**です。

| オプションスコープ | 解放されるもの |
| - | - |
| `USER_CONTACTINFO_EMAIL` | メールアドレス |
| `USER_CONTACTINFO` | 連絡先情報 |
| `USER_ADDRESS` | 住所 |
| `USER_BIRTHDAY` | 生年月日 |
| `USER_GENDER` | 性別 |
| `USER_LOGIN_ID` | ウォレットにおけるユーザーのログイン識別子 |
| `USER_NAME` | 氏名 |

デフォルトでは**公開 ID を超える個人情報は一切付与されません**。上記のいずれかを取得するには、特定のスコープを要求し、
そのスコープなしではミニプログラムが機能しない理由を文書で説明する必要があります。承認は Waffo ではなくウォレット
プラットフォームの判断であり、スコープごとに付与されます。

それを前提に設計してください。公開 ID しか持たないユーザーでも購入を完了し、購入したものを受け取れるようにフローを
構築するということです。実際には、配送先メールアドレスを貴社のミニプログラム UI 内で収集し、ウォレットが付与する
プロフィールフィールドは必須の入力ではなく、フォームを事前入力する利便性として扱うことを意味します。

## プロフィール照会は何を返しますか？

`POST /api/v1/userinfo/inquiry` は `merchantId`、`appId`、`appPlatform`、および識別ステップで得た `accessToken` を受け取り、
承認されたスコープの範囲を返します。

| フィールド | 備考 |
| - | - |
| `userName` | 氏名 |
| `nickName` | 表示名 |
| `gender` | 1 文字のコード（`M` / `F`） |
| `birthday` | 整形された日付文字列 — 区切り文字を仮定せず、防御的にパースしてください |
| `contactEmail` | メールアドレス |
| `contactMobileNumber` | 国番号を含む携帯電話番号 |
| `addressInfo[]` | `address`、`city`、`region`、`postcode`、`addressCountryCode` |
| `userLoginId` | ウォレットにおけるユーザーのログイン識別子 |
| `kyc` | ユーザーの本人確認レベル。2 桁のコード：未確認、一部確認、完全確認 |

これらはすべて**条件付き**です。付与されていないフィールドは単に届かず、付与されたフィールドでもユーザーが入力して
いなければ欠落しえます。フィールドの欠落がエラーではなく通常のケースとなるようにマッピングを書いてください。

## 識別のエラーコードは何を意味しますか？

| コード | 意味 | 対処 |
| - | - | - |
| `A0001` | Invalid API secret key | キーが誤っているか、環境が誤っています。 |
| `A0002` | Invalid signature | 署名 FAQ を参照してください。 |
| `A0003` | Parameter validation failed | 詳細にフィールド名が示されます。ボディのマーチャント ID と API キーのマーチャント ID の不一致もここに該当します。 |
| `A0006` | Merchant status abnormal | アカウントレベルの問題です。サポートにご連絡ください。 |
| `A0010` | Operation not allowed in merchant contract | 貴社のアカウントはこれに対応する設定になっていません。 |
| `B0008` | Auth code is invalid | `my.getAuthCode` から新しいコードを取得してください。 |
| `B0009` | Auth code is already expired | コードは短命です。直ちに交換し、決して保存しないでください。 |
| `B0010` | Auth code has been used | 各コードは 1 回限りです。同じコードで交換を再試行しないでください。 |
| `B0011` | Access token is invalid | `my.getAuthCode` から識別ステップをやり直してください。 |
| `B0012` | Access token is expired | 識別ステップをやり直し、`accessTokenExpiryTime` を尊重してください。 |
| `C0001` | System error | リトライしてください。 |

`B0008`〜`B0010` の 3 つのコードはいずれも「認可コードがもう使えない」ことを意味します。いずれについても正しい対処は
同じで、バックエンド呼び出しをリトライするのではなく、フロントエンドに戻って新しいコードを取得することです。

決済のエラーは通常のものです。
[よくあるエラーのトラブルシューティング](/docs/ja/support/errors-troubleshooting-guide)を参照してください。

## ミニプログラム内でサブスクリプションを運用できますか？

はい。`MINI_PROGRAM_PAYMENT` ではなく `MINI_PROGRAM_SUBSCRIPTION` という別のプロダクトとして運用します。1 つ追加の
要件があり、サブスクリプション作成時に上記の識別フローで取得した**ユーザーアクセストークン**を提供する必要があります。
ウォレットは、どのユーザーが継続課金を承認しているのかを知る必要があるためです。

金額のルール、通知、キャンセルを含め、サブスクリプションに関するそれ以外はすべて変わりません。
[サブスクリプション FAQ](/docs/ja/support/subscription-faq) から始め、ユーザーに機能を約束する前に決済手段が何を
サポートしているかを確認してください。

## 通常のホスト型チェックアウト連携と何が異なりますか？

| | ホスト型チェックアウト | ミニプログラム |
| - | - | - |
| ユーザーが支払う場所 | ブラウザ内の Waffo チェックアウトページ | ウォレットアプリ内、`my.tradePay` によって駆動 |
| 決済 UI をレンダリングする主体 | Waffo | ウォレット |
| 結果を知る方法 | リダイレクト（表示上）＋ Webhook（正式） | JS コールバック（表示上）＋ Webhook（正式） |
| ユーザーが誰か | 貴社が収集したもの | ウォレットの公開ユーザー ID と、承認されたスコープ |
| チェックアウトのカスタマイズ | Portal の設定が適用される | 該当なし — Waffo のページが存在しない |

重要な帰結：**チェックアウトページの設定は一切適用されません。** 表示言語、決済手段の並び順、ブランディング、結果ページは
すべてウォレットの UI 内にあるため、体験は貴社のミニプログラムが所有します。
[チェックアウトの表示ルール](/docs/ja/support/cashier-display-rules-faq)とチェックアウトカスタマイズのページの内容は
この経路には無関係です。

## レポートは同じように取得できますか？

はい。ミニプログラムの注文は、他の注文と同様に Portal の取引一覧、エクスポート、精算に現れ、プロダクトによって
区別できます。注文識別子の挙動も同一なので、照合に特別なケースは不要です。
[精算レポートとエクスポート](/docs/ja/support/settlement-reports-faq)を参照してください。

## ミニプログラム向けの Waffo SDK や JS パッケージはありますか？

いいえ。ミニプログラム側にインストールするものはありません。連携の 2 つの半分は次のとおりです。

| 側 | 使用するもの |
| - | - |
| ミニプログラムのフロントエンド | **ウォレット自身の** JS API — `my.getSystemInfo`、`my.getAuthCode`、`my.tradePay`。これらは Waffo ではなくウォレットのランタイムから提供されます。 |
| 貴社のバックエンド | Waffo の通常の REST エンドポイント。通常どおり署名します |

Waffo が公開している SDK は REST API を呼び出すための**サーバーサイド**のヘルパーであり、ミニプログラム用の
パッケージではなく、埋め込むフロントエンドのバンドルもありません。したがって「どの Waffo ライブラリをミニプログラムに
インポートするのか」には答えがありません。正しい答えは「ない」であり、フロントエンドが Waffo と直接やり取りすることは
ありません。

## `appPlatform` は何のためのもので、省略するとどうなりますか？

`appPlatform` は、**認可コードがどのウォレットプラットフォームから来たか**を Waffo に伝えます。識別の両エンドポイントに
おける文書化されたリクエスト仕様の一部であり、受け付けられる値は `appId` とともに Waffo から割り当てられます。

常に送信してください。貴社のアカウントが複数のウォレットプラットフォームで設定されている場合に交換を一意に特定する
フィールドであり、省略を頼りにすべきではありません。依存できる定義済みのフォールバック動作はなく、すでに保持している
`appId` の隣にこの値を保存するコストはかかりません。

## `B0013` は何を意味し、`B0011` や `B0012` とどう違いますか？

| コード | 意味 |
| - | - |
| `B0011` | Access token is invalid — その値は Waffo が解決できるトークンではない |
| `B0012` | Access token is expired — 有効だったが、有効期間が過ぎた |
| `B0013` | Access token is not exist — このリクエストに対応するトークンが記録にない |

貴社の連携においては、3 つとも同じ復旧手順に収束します。**フロントエンドに戻り、`my.getAuthCode` で新しいコードを取得し、
新しいトークンに交換してください。** 同じトークンでバックエンド呼び出しをリトライしても、いずれの場合も成功しません。

3 つに別々の分岐を作らないでください。「識別フローをやり直す」経路を 1 つ作り、`B0011`、`B0012`、`B0013` をそこに
振り向けてください。認可コードの `B0008`〜`B0010` とまったく同じです。

## トークンが `accessTokenExpiryTime` に達していないのに、サブスクリプション作成でトークンが期限切れと言われます

充当の瞬間にトークンがまだ有効かどうかの権限を持つのは Waffo ではなく**ウォレット**だからです。
`accessTokenExpiryTime` はトークンが有効でありうる最も遅い時点であり、まだ有効であることの保証ではありません。
顧客が承認を取り消した、サインアウトした、あるいはウォレットが自らセッションを無効化した場合、トークンは早期に
機能しなくなることがあります。

その場合、ウォレットの判断は識別エンドポイントからではなく、作成呼び出しの `B0009`（認可コードがすでに期限切れ）または
`B0008`（認可コードが無効）として届きます。どちらも**リトライ不可**に分類され、同じ認証情報での同じ呼び出しは
失敗し続けます。

そこから導かれる設計ルール：**保存済みのトークンを再利用するのではなく、注文またはサブスクリプションを作成するフローの
一部として新しいトークンを取得してください。** トークンをキャッシュし、`accessTokenExpiryTime` を有効性の約束として
扱うことが、このエラーの最も一般的な原因です。

## ミニプログラムでサブスクリプションを運用できますか？ 正確には何を送りますか？

はい。`MINI_PROGRAM_SUBSCRIPTION` プロダクトとして運用します。通常のサブスクリプションのフィールドに加えて、
顧客のアクセストークンを送信します。

| フィールド | 値 |
| - | - |
| `paymentInfo.productName` | `MINI_PROGRAM_SUBSCRIPTION` |
| `paymentInfo.payMethodUserAccessToken` | `/api/v1/userid/inquiry` から得た `accessToken` |

トークンは、ウォレットのどのユーザーが継続課金のマンデートを承認しているかを示し、ウォレットがマンデートを正しい
アカウントに紐づけられるようにします。同じフィールドは `/api/v1/subscription/change` にも存在するため、
ミニプログラムでのプラン変更にも新しく取得したトークンが必要です。

サイクル、トライアル、金額、ステータス、リトライ、通知、キャンセルを含め、サブスクリプションに関するそれ以外はすべて
変わらず、
[サブスクリプションの作成とバリデーション](/docs/ja/support/subscription-creation-validation-faq)
およびそこからリンクされているページのとおりに動作します。

## その後の更新のたびに新しいトークンが必要ですか？

いいえ。トークンはマンデートを確立するために**署名時に 1 回だけ**提供されます。以降の期間は保存されたマンデートに
対して課金されるため、更新のたびに識別フローをやり直す必要はありません。更新は顧客不在でフロントエンドも関与しない
バックグラウンドの課金です。

新しいトークンが必要なのは、顧客が目の前で新しい何かを承認しているときです。サブスクリプションの作成、またはプラン変更です。
第 2 期以降には不要です。

顧客がウォレットでマンデートを取り消したために更新が失敗した場合は、トークンのエラーではなく決済手段側のキャンセルとして
届きます。ウォレットでの取り消しの動作は
[サブスクリプション FAQ](/docs/ja/support/subscription-faq) を参照してください。

## 支払い後に顧客をミニプログラムの特定のページに戻せますか？

それは Waffo ではなく貴社のフロントエンドの仕事です。このフローのどこにも Waffo ホスト型のページが存在しないため、
注文作成時のリダイレクト URL はここでは作用する対象を持ちません。ナビゲーションはウォレット内にとどまり、ウォレットの
決済 UI が閉じると `my.tradePay` を呼び出したページに制御が戻ります。

したがって、離れたページで再開し、何を表示するかは Webhook によって駆動される**貴社のバックエンド**から見た注文の状態で
判断してください。[決済結果の確認](/docs/ja/support/payment-results-faq)に記載の理由により、JS コールバックだけで成功画面を
レンダリングしないでください。

## Portal のどこで、決済がどのミニプログラムから来たかを確認できますか？

**個別の決済の詳細ページ**です。該当する注文には **App ID** と **App Name** を含むミニプログラムのブロックが表示されます。
**Transactions → Payments** から決済を開くと、注文の他の情報と並んでそのブロックがあります。

利用**できない**もの：決済の**一覧**にはミニプログラムのフィルターや App ID の列がないため、一覧をミニプログラム単位で
絞り込むことはできません。複数のミニプログラムを運用しておりアプリごとのレポートが必要な場合は、Portal がグループ化して
くれることを期待するのではなく、貴社自身の注文記録（各 `/api/v1/order/create` でどの `appId` を送ったかは把握しています）を
キーにしてください。

ミニプログラムのプロダクトは取引のエクスポートで名前が付くため、トラフィックがミニプログラムのものであることは識別できます。
詳細ページのみで分かるのは*どの*ミニプログラムかという点です。

## その顧客は、ウェブのチェックアウトと同じ人物ですか？

自動的には分かりませんし、Waffo にそれを答えさせようとすべきではありません。返される `userId` は、**貴社のミニプログラムに
スコープされた**ウォレットの公開識別子です。メールアドレスでも電話番号でもチャネル横断のアイデンティティでもありません。

つまり：

* 識別子を比較してミニプログラムの購入者とウェブチェックアウトの購入者を突き合わせることはできません。比較できる
  共通のものがありません。
* ミニプログラムを 2 つ公開している場合、同じ人物の識別子が両方で同じだと仮定しないでください。同じではない前提で
  設計してください。
* 実用的なパターンは貴社自身のアカウントシステムです。顧客がミニプログラム内で貴社のアカウントにサインインし、
  そのアカウントに対してウォレットの `userId` を一度保存すれば、以降はチャネルをまたぐアイデンティティは貴社の
  アカウント ID になります。

連絡先のスコープが付与されている場合、メールアドレスは顧客に突き合わせを*提案する*のに役立ちますが、2 つの記録が
同一人物である証拠としてではなく、顧客に確認するためのヒントとして扱ってください。

## 次はどこを見ればよいですか？

* [決済結果の確認](/docs/ja/support/payment-results-faq) — JS コールバックではなく Webhook が正である理由。
* [注文作成フィールドガイド](/docs/ja/support/order-create-field-guide) — 注文作成仕様の残りの部分。
* [決済手段の設定と注文制限](/docs/ja/support/payment-method-config-and-limits-faq)
  — 利用可能な決済手段、通貨、金額範囲の読み戻し。

アプリ識別子やスコープの承認で行き詰まっていますか？
[サポートにお問い合わせください](mailto:support@waffo.com)。どちらもコードの問題ではなくプロビジョニングの手続きです。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.