Stripe をマーチャントオブレコードとして、iOS でデジタル製品の決済を受け付けます公開プレビュー
Stripe Checkout と Managed Payments をブラウザで開くと、アプリ内でデジタル製品やサブスクリプションを販売できます。
利用規約が必要
Managed Payments を利用する前に、ダッシュボードにある Managed Payments 利用規約に同意する必要があります。
一部の国 では、iOS の Managed Payments を使用して、外部のウェブサイトにリンクして決済を受け付けることができます。Stripe Checkout を使用して、顧客を Stripe がホストする支払いページにリダイレクトします。例として、このガイドではアプリで使用するデジタルクレジットを販売する方法を説明します。1 回限りまたはサブスクリプションの両方の支払いを受け付けることができます。

Managed Payments を利用した一括払いの顧客に表示される UI

Managed Payments を利用したサブスクリプション支払いで顧客に表示される UI
制限事項
このガイドではカバーしていません:
- ユーザー認証。既存の認証プロバイダーがない場合には、Sign in with Apple (Apple でサインイン) や Firebase Authentication などのサードパーティプロバイダーを使用できます。
- ネイティブのアプリ内購入。StoreKit を使用してアプリ内購入を実装するには、Apple のアプリ内課金 ガイドをご覧ください。
このガイドでは、この資格基準に従ったアプリ内デジタル商品の販売プロセスのみを説明します。デジタル商品がこの基準に適合しない場合は、iOS でデジタル商品の決済を受け付ける を参照してください。物理的な商品を販売する場合は、Stripe アプリ内決済を参照してください。
はじめに
- 貴社の製品が Managed Payments の対象要件 を満たしていることをご確認ください。Managed Payments で支払いを処理するには、顧客が購入するすべての製品が対象である必要があります。
- ダッシュボードで Managed Payments を有効にします。
- 開発環境を設定します。
- API バージョン
2025-03-31.以降を使用していることを確認してください。 API バージョンのアップグレード手順をご覧ください。basil
商品および価格を作成する
ダッシュボードまたは Stripe CLI で 商品 と 価格 を作成します。単発価格のデジタル商品や、定期価格のサブスクリプションを追加できます。また、 顧客が支払う金額を決定する を選択することで、顧客が希望する金額を支払うこともできます (例えば、購入するクレジットの数を決めるなど)。商品を作成する際、選択する税コードは Managed Payments の対象となるものでなければなりません。対象となる税コードには、「Managed Payments の対象」と表示されます。
この例では、単一の 商品 と 価格 を使用して、10 USD の 100 コイン束を表しています。
顧客を作成するサーバー側
Checkout セッションを作成するたびに、そのユーザーにまだ設定されていなければ Customer オブジェクトを作成します。
警告
ユーザーアカウントと Stripe 顧客 ID との関連付けを、サーバーに必ず保存してください。顧客を購入に関連付ける方法がなければ、顧客は購入を回復できなくなります。
アプリが既存の認証プロバイダーを持たない場合は、代わりに Apple でサインインを利用できます。
customer 引数を使用して、Checkout Session の作成時に顧客 ID を渡します。これにより、セッション中に作成されるすべてのオブジェクトが正しい Customer オブジェクトに関連付けられます。
ユニバーサルリンクを設定するクライアント側サーバー側
ユニバーサルリンクを使用すると、Checkout をお使いのアプリにディープリンクできます。ユニバーサルリンクを設定するには、次の手順を行います。
- ドメインに
apple-app-site-associationファイルを追加します。 - アプリに Associated Domains Entitlement を追加します。
- Checkout リダイレクト URL のフォールバックページを追加します。
関連ドメインを定義する
.well-known/apple-app-site-association メインにファイルを追加し、アプリで処理する URL を定義します。アプリ ID の前にチーム ID を付加します。チーム IDは、Apple Developer Portal のメンバーシップページにあります。
{ "applinks": { "apps": [], "details": [ { "appIDs": [ "A28BC3DEF9.com.example.MyApp1", "A28BC3DEF9.com.example.MyApp1-Debug" ], "components": [ { "/": "/checkout_redirect*", "comment": "Matches any URL whose path starts with /checkout_redirect" } ] } ] } }
このファイルは、MIME タイプ application/json で提供する必要があります。curl -I を使用してコンテンツタイプを確認します。
curl -I https://example.com/.well-known/apple-app-site-association
詳細については、関連ドメインのサポートに関する Apple のページを参照してください。
アプリに Associated Domains エンタイトルメントを追加する
- アプリのターゲットの、Signing & Capabilities (署名とケイパビリティ) ウィンドウを開きます。
- + ケイパビリティ をクリックし、関連ドメイン を選択します。
applinks:example.のエントリーを Associated Domains リストに追加します。com
ユニバーサルリンクの詳細については、Apple の Universal Links for Developers (開発者のためのユニバーサルリンク) (英語) ページをご覧ください。
iOS は、apple-app-site-association ファイルで定義された URL へのリンクをインターセプトしますが、リダイレクトでアプリを開くことができないケースが発生することがあります。
必ず success_ にフォールバックページを作成してください。たとえば、アプリにカスタム URL スキームを定義し、ユニバーサルリンクが失敗した場合にリンクバックに使用できます。
Checkout セッションを作成するサーバー側
Checkout Sessionは、支払いフォームにリダイレクトされた顧客に表示される内容をプログラムで表現したものです。Checkout Session は作成後 24 時間で有効期限が切れます。以下のように設定してください。
- 顧客 ID
- プロダクト ID (一括払いまたはサブスクリプションのいずれか)
- アプリからウェブへの購入に最適化された UI を選択するために、
mobile_に設定されたapp origin_。context managed_パラメータをpayments[enabled] trueに設定します。- バージョンヘッダーは、
;managed_ですpayments_ preview=v1 success_。支払いが完了した後に、顧客をお客様のアプリにリダイレクトするユニバーサルリンクです。url
よくある間違い
managed_、バージョンヘッダーに managed_、そして origin_ を指定して Checkout Session を作成し、アプリからウェブへの購入に最適化された Managed Payments 専用の UI を有効にします。
TypeScript を使用している場合は、Managed Payments がプライベートプレビューにあるため、この操作時に型エラーが発生することがあります。これらのエラーは、// @ts-expect-error を追加することで安全に無視できます。
Checkout セッションを作成したら、レスポンスからの URL をお客様のアプリに返します。
Safari で Checkout を開くクライアント側
アプリに決済ボタンを追加します。このボタンは以下を行います。
- サーバー側のエンドポイントを呼び出して、Checkout セッションを作成します。
- クライアントに Checkout セッションを返します。
- Safari でセッション URL を開きます。
import Foundation import SwiftUI import StoreKit struct BuyCoinsView: View { @EnvironmentObject var myBackend: MyServer @State var paymentComplete = false var body: some View { // Check if payments are blocked by Parental Controls on this device. if !SKPaymentQueue.canMakePayments() { Text("Payments are disabled on this device.") } else { if paymentComplete { Text("Payment complete!") } else { Button { myBackend.createCheckoutSession { url in UIApplication.shared.open(url, options: [:], completionHandler: nil) } } label: { Text("Buy 100 coins") }.onOpenURL { url in // Handle the universal link from Checkout. if url.absoluteString.contains("success") { // The payment was completed. Show a success // page and fetch the latest customer entitlements // from your server. paymentComplete = true } } } } } }
クライアントで Checkout URL を取得する
サーバーエンドポイントを使用して、Checkout セッションを取得します。
class MyServer: ObservableObject { // The cached login token var token: String? func createCheckoutSession(completion: @escaping (URL) -> Void) { // Send the login token to the `/create_checkout_session` endpoint let request = URLRequest(url: URL(string: "https://example.com/create-checkout-session?token=\(self.token)")!) let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in guard let unwrappedData = data, let json = try? JSONSerialization.jsonObject(with: unwrappedData, options: []) as? [String : Any], let urlString = json["url"] as? String, let url = URL(string: urlString) else { // Handle error return } DispatchQueue.main.async { // Call the completion block with the Checkout session URL returned from the backend completion(url) } }) task.resume() } func login() { // Login using the server and set the login token. let request = URLRequest(url: URL(string: "https://example.com/login")!) let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in guard let unwrappedData = data, let json = try? JSONSerialization.jsonObject(with: unwrappedData, options: []) as? [String : Any], let token = json["token"] as? String else { // Handle error return } self.token = token }) task.resume() } }
注文のフルフィルメントを処理するサーバー側
購入が成功すると、Stripe は checkout. Webhook を送信します。このイベントを受け取ったら、サーバー上の顧客にコインを追加できます。
イベントを受信したことを確認すると、Checkout は購入者を success_ にリダイレクトします。エンドポイントが停止していたり、イベントが正しく確認されない場合、Checkout は支払い成功の 10 秒後に購入者を success_ にリダイレクトします。
テスト目的の場合は、ダッシュボードまたは Stripe CLI を使用してイベントをモニタリングできます。本番環境では、Webhook エンドポイントを設定して、適切なイベントタイプに登録します。STRIPE_ キーが不明な場合は、ダッシュボードで Webhook をクリックして表示します。
テスト
顧客をStripe Checkout にリダイレクトする決済ボタンをテストします。
- 決済ボタンをクリックすると、Stripe Checkout 支払いフォームにリダイレクトされます。
- のテストカード番号、3 桁のセキュリティコード、将来の有効期限日、および任意の有効な郵便番号を入力します。
- 支払う をタップします。
checkout.Webhook が起動して、Stripe は取引についてお客様のサーバーに通知します。session. completed - リダイレクトによってアプリへと戻されます。
実装が機能していない場合には、以下のその他のテスト用リソースのセクションをご覧ください。
支払いの詳細
領収書のプレビュー
- 決済サマリー で、 請求書 をクリックします。
- 領収書を送信 をクリックして、顧客に送信される領収書メールをプレビューします。領収書をダウンロードすることもできます。
メモ
サンドボックスでは、購入後にメール領収書が自動的には届きません。前のセクションの手順を使用して手動で送信してください。
Link
Link は決済時のマーチャントオブレコードとして機能し、Link.com でサブスクリプション管理と取引サポートを提供します。
Link をテストする:
- 決済画面を開く
- 決済ボタンをクリックします。
- 決済画面のテストに使用したのと同じメールアドレスを入力してください。
- ポップアップモーダルで、テストパスコード
000000を使用して認証します。
初回の決済時に Save my information for faster checkout (情報を保存して決済をスピードアップする) チェックボックスをオンにした場合、Link アカウントに保存された 4242 テストカードも表示されます。
オプションその他のテスト用リソース
実装を本番環境に移行する準備ができたかの確認に使用できる、テスト用の番号がいくつかあります。任意のセキュリティコード、郵便番号、および今後の有効期限を指定して使用します。
| 数字 | 説明 |
|---|---|
| 支払いが成功し、すぐに処理されます。 | |
| 支払いを正常に完了させるために、3D セキュア 2 認証を実行します。 | |
常に支払い拒否コード insufficient_ で失敗します。 |
全テストカードの一覧については、テストに関するガイドをご覧ください。
ユニバーサルリンクをテストする
ユニバーサルリンクで Checkout からアプリにリダイレクトされない場合は、SharedWebCredentials ログでエラーがないかを確認してください。
Associated Domains エンタイトルメントにデバッグパラメーターを追加する
- アプリのターゲットの、Signing & Capabilities (署名とケイパビリティ) ウィンドウを開きます。
- 関連ドメインのエントリーに
?mode=developerフラグを追加します。「(例:applinks:example.)」com?mode=developer
デバイスを開発者モードに設定します。
- デバイスで Xcode からアプリを実行し、開発者メニューを有効にします。
- iPhone で、Settings (設定) を開き、Developer (開発者) をタップし、Associated Domains Development (関連ドメイン開発) を有効にします。
アプリを削除して、再インストールします。これにより、iOS は apple-app-site-association ファイルを再取得します。
アプリで決済フローを完了します。
Checkout によってアプリにリダイレクトされます。そうでない場合は、sysdiagnose を取得します。
音量アップ、音量ダウン、および電源ボタンを同時に 1 秒間押してから離します。短い振動を感じますが、視覚的なフィードバックは表示されません。
5 分間待ってから、Settings (設定) > Privacy (プライバシー) > Analytics & Improvement (分析と改善) > Analytics Data (分析データ) に移動し、リストの最後の sysdiagnose ファイルまでスクロールします。
共有ボタンをタップして、お使いのコンピューターにファイルを AirDrop (エアドロップ) します。
sysdiagnose アーカイブを開き、次に
swcutil_を開きますshow. txt このファイルでアプリ ID を検索します。アプリのデバッグ情報のセクションが表示されます。エラーがある場合には、それも含まれます。
Service: applinks App ID: Y28TH9SHX7.com.stripe.FruitStore App Version: 1.0 App PI: <LSPersistentIdentifier 0x115e1a390> { v = 0, t = 0x8, u = 0xc98, db = E335D78F-D49E-4F19-A150-F657E50DEDAE, {length = 8, bytes = 0x980c000000000000} } Domain: example.com?mode=developer User Approval: unspecified Site/Fmwk Approval: unspecified Flags: developer Last Checked: 2021-09-23 18:16:58 +0000 Next Check: 2021-09-23 21:21:34 +0000 Error: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set. around line 1, column 0." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set. around line 1, column 0., NSJSONSerializationErrorIndex=0} Retries: 1