サブスクリプションの実装を構築する
サブスクリプションを作成して、継続支払いを受け付けるように管理します。
Appearance API を使用してカスタマイズします。
このガイドで、固定料金のサブスクリプションを販売する方法をご確認ください。Mobile Payment Element を使用して、アプリに埋め込むカスタムの決済フォームを作成します。
注
アプリ内で使用されるデジタル商品やサービス (サブスクリプション、ゲーム内通貨、ゲームレベル、プレミアムコンテンツへのアクセス、フルバージョンのロック解除など) を販売している場合は、Apple のアプリ内課金 API を使用する必要があります。このルールには、1 対 1 の個人向けサービスや特定の地域に所在するアプリなど、いくつかの例外があります。詳細については、App Store の Review ガイドラインをご覧ください。
サブスクリプションを構築する
このガイドは以下の方法を説明します。
- 商品カタログを構築して、ビジネスをモデル化します。
- 顧客を追加するための登録プロセスを作成します。
- サブスクリプションを作成して、決済情報を収集します。
- 支払いとサブスクリプションのステータスをテストして、モニタリングします。
- 顧客がプランを変更したりサブスクリプションをキャンセルしたりできるようにします。
Stripe でモデル化する方法
Subscription (サブスクリプション) は、Invoice と PaymentIntent を自動作成することで請求業務をシンプルにします。サブスクリプションを作成して有効化するには、まず販売対象をモデル化する Product と、請求する期間と金額を決定する Price を作成する必要があります。また、毎回の継続支払いに使用される PaymentMethods を格納する Customer (顧客) も必要です。
API オブジェクトの定義
Stripe を設定する
React Native SDK はオープンソースであり、詳細なドキュメントが提供されています。内部では、ネイティブの iOS および Android の SDK を使用します。Stripe の React Native SDK をインストールするには、プロジェクトのディレクトリーで (使用するパッケージマネージャーによって異なる) 次のいずれかのコマンドを実行します。
次に、その他の必要な依存関係をインストールします。
- iOS の場合は、ios ディレクトリーに移動して
pod install
を実行し、必要なネイティブ依存関係もインストールします。 - Android の場合は、依存関係をインストールする必要はありません。
Stripe の初期化
React Native アプリで Stripe を初期化するには、決済画面を StripeProvider
コンポーネントでラップするか、initStripe
初期化メソッドを使用します。publishableKey
の API 公開可能キーのみが必要です。次の例は、StripeProvider
コンポーネントを使用して Stripe を初期化する方法を示しています。
import { StripeProvider } from '@stripe/stripe-react-native'; function App() { const [publishableKey, setPublishableKey] = useState(''); const fetchPublishableKey = async () => { const key = await fetchKey(); // fetch key from your server here setPublishableKey(key); }; useEffect(() => { fetchPublishableKey(); }, []); return ( <StripeProvider publishableKey={publishableKey} merchantIdentifier="merchant.identifier" // required for Apple Pay urlScheme="your-url-scheme" // required for 3D Secure and bank redirects > // Your app code here </StripeProvider> ); }
次に Stripe CLI をインストールします。CLI は Webhook のテストを提供します。これを実行すると Stripe への API コールを実行できます。このガイドの後続セクションでは、CLI を使った料金体系モデルの設定方法を紹介します。
その他のインストールオプションについては、Stripe CLI を使ってみるをご覧ください。
顧客を作成するクライアントとサーバー
Stripe では、各サブスクリプションに顧客が必要です。アプリケーションのフロントエンドでユーザーから必要な情報を収集し、それをバックエンドに渡します。
住所の詳細を収集する必要がある場合、Address Element を使用すると顧客の配送先住所または請求先住所を収集できます。Address Element についての詳細は、Address Element のページをご覧ください。
import React from 'react'; import {View, TextInput, StyleSheet, Button, Platform} from 'react-native'; function RegisterView() { const [email, setEmail] = React.useState(''); const createCustomer = async () => { const apiEndpoint = Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567'; const response = await fetch(`${apiEndpoint}/create-customer`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email: email, }), }); if (response.status === 200) { const customer = await response.json(); console.log(customer); } }; return ( <View> <TextInput style={styles.input} placeholder="Email" value={email} onChangeText={setEmail} /> <Button title="Register" onPress={async () => { await createCustomer(); }} /> </View> ); } const styles = StyleSheet.create({ input: { height: 40, margin: 12, borderWidth: 1, padding: 10, }, }); export default RegisterView;
サーバーで、Stripe の Customer オブジェクトを作成します。
サブスクリプションを作成するクライアントとサーバー
注
最初にサブスクリプションを作成せずに Payment Element をレンダリングする場合は、インテントを作成する前に支払いの詳細を収集するをご覧ください。
新しい顧客がプランを選択してからサブスクリプションを作成できるようにします。このガイドでは、顧客は基本またはプレミアムから選択します。
アプリで、選択した価格 ID と顧客レコードの ID をバックエンドに渡します。
const createSubscription = async (priceId, customerId) => { const apiEndpoint = Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567'; const response = await fetch(`${apiEndpoint}/create-subscription`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ priceId: priceId, customerId: customerId, }), }); if (response.status === 200) { const subscription = await response.json(); return subscription; } };
バックエンドで payment_
を使用することで、ステータスが incomplete
のサブスクリプションを作成できます。次に、サブスクリプションの最初の PaymentIntent の client_
をフロントエンドに返して、支払いを完了します。
支払いが完了したときに決済手段をデフォルトとして保存する場合は、save_default_payment_method を on_
に設定します。デフォルトの決済手段を保存すると、その後のサブスクリプションの決済の成功率が高くなります。
注
多通貨の Price を使用している場合、currency パラメーターを使用して、サブスクリプションに使用する Price の通貨を指定します (currency
パラメーターを省略すると、サブスクリプションは Price のデフォルトの通貨を使用します)。
この時点でサブスクリプションは inactive
であり、支払いを待っています。次に示すのはレスポンスの例です。強調表示されているのは保存が必要な最小限のフィールドですが、アプリケーションが頻繁にアクセスするフィールドをすべて保存します。
{ "id": "sub_JgRjFjhKbtD2qz", "object": "subscription", "application_fee_percent": null, "automatic_tax": { "enabled": false }, "billing": "charge_automatically", "billing_cycle_anchor": 1623873347, "billing_thresholds": null,
決済情報を収集するクライアント
Stripe Elements を使用して支払いの詳細を収集し、サブスクリプションを有効化します。Elements は、お使いのアプリケーションのデザインに合わせてカスタマイズできます。
The Mobile Payment Element securely collects all necessary payment details for a wide variety of payments methods. You can visit this page to learn what payment methods are supported by both Mobile Payment Element and Subscriptions.
アプリに Payment Element を追加する
PaymentSheet クラスを使用して、Mobile Payment Element を初期化して表示します。
import React from 'react'; import {useStripe, PaymentSheetError} from '@stripe/stripe-react-native'; import {View, Button} from 'react-native'; function SubscribeView({clientSecret}) { const {initPaymentSheet, presentPaymentSheet} = useStripe(); React.useEffect(() => { const initializePaymentSheet = async () => { const {error} = await initPaymentSheet({ paymentIntentClientSecret: clientSecret, returnURL: 'stripe-example://payment-sheet', // Set `allowsDelayedPaymentMethods` to true if your business handles // delayed notification payment methods like US bank accounts. allowsDelayedPaymentMethods: true, }); if (error) { // Handle error } }; initializePaymentSheet(); }, [clientSecret, initPaymentSheet]); return ( <View> <Button title="Subscribe" onPress={async () => { const {error} = await presentPaymentSheet(); if (error) { if (error.code === PaymentSheetError.Failed) { // Handle failed } else if (error.code === PaymentSheetError.Canceled) { // Handle canceled } } else { // Payment succeeded } }} /> </View> ); } export default SubscribeView;
Mobile Payment Element によって支払い画面が表示され、顧客はここで支払い方法を選択できます。このフォームでは、顧客が選択した支払い方法で必要な支払い詳細のすべてが自動的に収集されます。
allowsDelayedPaymentMethods
を true に設定すると、アメリカの銀行口座などの 遅延通知型の支払い方法を使用できます。これらの支払い方法では、PaymentSheet
が完了した時点では最終的な支払いステータスが判明せず、後になって成功または失敗が確定します。このようなタイプの支払い方法に対応する場合は、注文が確定済みであることを顧客に通知し、支払いが成功した場合にのみ注文のフルフィルメント (商品の発送など) を実行するようにします。
PaymentSheet.
オブジェクトで appearance
プロパティを使用して、アプリのデザインに合わせて Payment Element をカスタマイズできます。
支払いを確定する
Mobile Payment Element によって PaymentMethod が作成され、未完了のサブスクリプションの最初の PaymentIntent が確定され、その結果支払いが実行されます。支払いに強力な顧客認証 (SCA) が必要とされる場合は、PaymentIntent の確定前に Payment Element で認証プロセスが処理されます。
戻り先 URL を設定する (iOS のみ)クライアント側
顧客が Safari や銀行アプリで認証するなどしてアプリを終了した際に、後で自動的にアプリに戻るための方法を提供します。多くの支払い方法タイプでは戻り先 URL が必須であるため、貴社で支払い方法を有効にしていても、URL を指定していない場合、Stripe ではユーザーにその支払い方法を提示することはできません。
To provide a return URL:
- Register a custom URL. Universal links aren’t supported.
- Configure your custom URL.
- Set up your root component to forward the URL to the Stripe SDK as shown below.
注
Expo を使用している場合は、app.
ファイルでスキームを設定します。
import React, { useEffect, useCallback } from 'react'; import { Linking } from 'react-native'; import { useStripe } from '@stripe/stripe-react-native'; export default function MyApp() { const { handleURLCallback } = useStripe(); const handleDeepLink = useCallback( async (url: string | null) => { if (url) { const stripeHandled = await handleURLCallback(url); if (stripeHandled) { // This was a Stripe URL - you can return or add extra handling here as you see fit } else { // This was NOT a Stripe URL – handle as you normally would } } }, [handleURLCallback] ); useEffect(() => { const getUrlAsync = async () => { const initialUrl = await Linking.getInitialURL(); handleDeepLink(initialUrl); }; getUrlAsync(); const deepLinkListener = Linking.addEventListener( 'url', (event: { url: string }) => { handleDeepLink(event.url); } ); return () => deepLinkListener.remove(); }, [handleDeepLink]); return ( <View> <AwesomeAppComponent /> </View> ); }
さらに、initPaymentSheet
メソッドを呼び出す際に returnURL
を設定します。
await initPaymentSheet({ ... returnURL: 'your-app://stripe-redirect', ... });
Webhook をリッスンするサーバー
導入を完了するには、Stripe から送信される Webhook を処理する必要があります。Webhook は、サブスクリプションによって新しい請求書が作成されるなど、Stripe 内の状態が変化するたびにトリガーされるイベントです。アプリケーションで、Webhook イベントを含む POST リクエストを受け取る HTTP ハンドラを設定し、イベントの署名を検証します。
開発中は、Stripe CLI を使用して Webhook を監視し、アプリケーションに転送します。開発アプリの実行中に、新しい端末で以下を実行します。
stripe listen --forward-to localhost:4242/webhook
本番環境では、ダッシュボードで Webhook エンドポイント URL を設定するか、Webhook Endpoints API を使用します。
いくつかのイベントをリッスンして、このガイドの残りのステップを完了します。サブスクリプション固有の Webhook については、サブスクリプションのイベントで詳細をご覧ください。
サービスへのアクセスを提供するクライアントとサーバー
ここまでのステップでサブスクリプションが有効になりました。次は、ユーザーがサービスにアクセスできるようにします。これを行うには、customer.
、customer.
、customer.
の各イベントをリッスンします。これらのイベントは、Subscription オブジェクトを渡します。このオブジェクトには、サブスクリプションが有効か、期日経過か、キャンセルされたかを示す status
フィールドが含まれます。ステータスの一覧については、サブスクリプションのライフサイクルをご覧ください。
Webhook ハンドラで、以下を実行します。
- サブスクリプションのステータスを確認します。
active
の場合、ユーザーは商品の支払いを実行しています。 - 顧客が登録している商品を確認し、サービスへのアクセス権を付与します。価格ではなく商品を確認することにより、料金体系や請求期間の変更が必要になった場合に、柔軟に対応できます。
product.
、id subscription.
およびid subscription.
を、すでに保存されているstatus customer.
とともにデータベースに保存します。アプリケーションでユーザーに対して有効にする機能を決定する際に、このレコードを確認します。id
サブスクリプションのステータスは、存続期間のどの時点でも変化する可能性があります。アプリケーションが Stripe への直接の呼び出しを行っていない場合でも同様です。たとえば、クレジットカードの有効期限が切れて更新が失敗した場合、サブスクリプションは期日経過の状態になります。また、カスタマーポータルを実装している場合、ユーザーが直接アプリケーションを開かずにサブスクリプションをキャンセルすることがあります。ハンドラを正しく実装することで、いつでもアプリケーションを Stripe と同期した状態に維持できます。
サブスクリプションをキャンセルするクライアントとサーバー
顧客にサブスクリプションのキャンセルを許可するのは一般的です。この例では、アカウントの設定ページにキャンセルオプションを追加します。
このサンプルではフロントエンドでサブスクリプション ID を収集していますが、アプリケーションではこの情報をデータベース内のログインユーザーに関する情報から取得できます。
サブスクリプションのキャンセル機能が設定されたアカウント設定
const cancelSubscription = async subscriptionId => { const apiEndpoint = Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567'; const response = await fetch(`${apiEndpoint}/cancel-subscription`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ subscriptionId: subscriptionId, }), }); if (response.status === 200) { const subscription = await response.json(); return subscription; } };
バックエンドで、アプリから呼び出すエンドポイントを定義します。
バックエンドが customer.
イベントを受信します。
サブスクリプションがキャンセルされたら、データベースを更新して以前に保存された Stripe サブスクリプション ID を削除し、サービスへのアクセスを制限します。
キャンセルされたサブスクリプションを、再びアクティブにすることはできません。代わりに、顧客から更新された請求先情報を収集し、顧客のデフォルトの支払い方法を更新して、既存の顧客レコードから新しいサブスクリプションを作成します。
実装内容をテストする
支払い方法をテストする
次の表を使用して、さまざまな支払い方法とシナリオをテストします。
支払い方法 | シナリオ | テスト方法 |
---|---|---|
BECS ダイレクトデビット | 顧客が BECS ダイレクトデビットによる支払いに成功します。 | 口座番号 900123456 と BSB 000-000 を使用して、フォームに入力します。確定された PaymentIntent のステータスは、まず processing に移行し、3 分後に succeeded ステータスに移行します。 |
BECS ダイレクトデビット | 顧客の支払いが account_ エラーコードで失敗します。 | 口座番号 111111113 と BSB 000-000 を使用して、フォームに入力します。 |
クレジットカード | カード支払いは成功し、認証は要求されません。 | クレジットカード番号 4242 4242 4242 4242 と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 |
クレジットカード | カード決済で認証が要求されます。 | クレジットカード番号 4000 0025 0000 3155 と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 |
クレジットカード | カードが insufficient_ などの拒否コードで支払い拒否されます。 | クレジットカード番号 4000 0000 0000 9995 と、任意の有効期限、セキュリティコード、郵便番号を使用してクレジットカードフォームに入力します。 |
SEPA ダイレクトデビット | 顧客が SEPA ダイレクトデビットによる支払いに成功します。 | 口座番号 AT321904300235473204 を使用して、フォームに入力します。確定された PaymentIntent のステータスはまず、processing に移行し、3 分後に succeeded ステータスに移行します。 |
SEPA ダイレクトデビット | 顧客の Payment Intent のステータスが、processing から requires_ に移行します。 | 口座番号 AT861904300235473202 を使用して、フォームに入力します。 |
イベントをモニタリングする
Set up webhooks to listen to subscription change events like upgrades and cancellations. Read the guide to learn more about subscription webhooks. You can view events in the Dashboard or with the Stripe CLI.
詳しくは、Billing の実装のテストをご覧ください。
Stripe について顧客に開示する
Stripe は顧客の Elements とのやり取りに関する情報を収集して、サービスを提供し、不正利用を防止し、サービスを向上します。これには、Cookie と IP アドレスを使用して、1 つの決済フローセッションで顧客に表示する Elements を特定することが含まれます。Stripe がこのような方法でデータを使用するために必要なすべての権利と同意について開示し、これらを取得することはお客様の責任です。詳細については、プライバシーセンターをご覧ください。