ACH ダイレクトデビットによる将来の支払いに備えて詳細を保存する
将来の ACH ダイレクトデビットによる支払いに備えて支払い方法の詳細を保存する方法を紹介します。
You can use the Setup Intents API to collect payment method details in advance, with the final amount or payment date determined later. This is useful for:
- Saving payment methods to a wallet to streamline future purchases
- Collecting surcharges after fulfilling a service
- Starting a free trial for a subscription
注
ACH Direct Debit is a delayed notification payment method, which means that funds aren’t immediately available after payment. A payment typically takes 4 business days to arrive in your account.
顧客を作成または取得する推奨サーバー側
ユーザーがビジネスでアカウントを作成する際に、Customer オブジェクトを作成するか、このユーザーに関連付けられた既存の Customer を取得します。この Customer オブジェクトの ID を、顧客を表す社内の内部表記と関連付けることで、保存されている支払い方法の詳細を後で取得して使用することができます。Financial Connections のリピートユーザーの最適化を有効にするには、Customer にメールアドレスを含めます。
SetupIntent を作成するサーバー側
A SetupIntent is an object that represents your intent to set up a customer’s payment method for future payments. The SetupIntent
tracks the steps of this set-up process.
Create a SetupIntent on your server with payment_method_types set to us_bank_account and specify the Customer’s id.
デフォルトでは、銀行口座の支払い情報の収集では、手動の口座番号入力と少額入金の確認のフォールバックオプションを使用し、Financial Connections で顧客のアカウントを即時確認します。Financial Connections を設定し、ACH の実装を最適化するために追加の口座データにアクセスする方法については、Financial Connections に関するドキュメントをご覧ください。たとえば、Financial Connections を使用して、ACH 決済の開始前にアカウントの残高を確認できます。
注
顧客がアカウントを認証した後で、追加データにアクセスを拡張するには、権限を拡張してアカウントを再度関連付ける必要があります。
client secret を取得する
SetupIntent には、client secret が含まれています。これは、支払いプロセスを安全に完了するためにクライアント側で使用されます。client secret をクライアント側に渡す際は、いくつかの方法を使用できます。
支払い方法の詳細を収集するクライアント側
顧客が ACH Direct Debitでの支払いをクリックしたときに、Stripe.js を使用してその支払いを Stripe に送信することをお勧めします。Stripe.js は、決済フローを構築するための Stripe の基本的な JavaScript ライブラリです。これにより、実装に関する複雑な処理が自動的に行われ、将来、他の決済手段にも対応できるように実装を簡単に拡張できます。
Stripe.js スクリプトを決済ページに含めるには、このスクリプトを HTML ファイルの head
に追加します。
<head> <title>Checkout</title> <script src="https://js.stripe.com/v3/"></script> </head>
決済ページで以下の JavaScript を使用して、Stripe.js のインスタンスを作成します。
// Set your publishable key. Remember to change this to your live publishable key in production! // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe(
);'pk_test_TYooMQauvdEDq54NiTphI7jx'
SetupIntent オブジェクト全体をクライアントに送信する代わりに、前のステップからの client secret を使用します。これは、Stripe API リクエストを認証する API キーとは異なります。
client secret は Payment Method の設定プロセスを完了できるため、慎重に取り扱う必要があります。記録したり、URL に埋め込んだり、当該の顧客以外に漏洩することがないようにしてください。
stripe.collectBankAccountForSetup を使用して、Financial Connections で銀行口座の詳細を収集し、PaymentMethod を作成して SetupIntent に関連付けます。ACH ダイレクトデビットの PaymentMethod を作成するには、billing_
パラメーターに口座名義人を含める必要があります。
// Use the form that already exists on the web page. const paymentMethodForm = document.getElementById('payment-method-form'); const confirmationForm = document.getElementById('confirmation-form'); paymentMethodForm.addEventListener('submit', (ev) => { ev.preventDefault(); const accountHolderNameField = document.getElementById('account-holder-name-field'); const emailField = document.getElementById('email-field'); // Calling this method will open the instant verification dialog. stripe.collectBankAccountForSetup({ clientSecret: clientSecret, params: { payment_method_type: 'us_bank_account', payment_method_data: { billing_details: { name: accountHolderNameField.value, email: emailField.value, }, }, }, expand: ['payment_method'], }) .then(({setupIntent, error}) => { if (error) { console.error(error.message); // PaymentMethod collection failed for some reason. } else if (setupIntent.status === 'requires_payment_method') { // Customer canceled the hosted verification modal. Present them with other // payment method type options. } else if (setupIntent.status === 'requires_confirmation') { // We collected an account - possibly instantly verified, but possibly // manually-entered. Display payment method details and mandate text // to the customer and confirm the intent once they accept // the mandate. confirmationForm.show(); } }); });
Financial Connections 認証フローでは、銀行口座の詳細の収集と確認を自動的に処理します。顧客が認証フローを完了すると、PaymentMethod が自動的に SetupIntent に関連付けられ、Financial Connections アカウントが作成されます。
よくある間違い
手動入力と少額入金によって顧客が関連付けた銀行口座では、残高、所有権、取引などの追加の銀行口座データにアクセスできません。
すべてのデバイスで最適なユーザー体験を提供できるように、ビューポートの meta
タグを使用して、ページのビューポートの minimum-scale
を 1 に設定します。
<meta name="viewport" content="width=device-width, minimum-scale=1" />
同意書承認を収集し送信するクライアント側
SetupIntent を完了して顧客の支払い方法の詳細を保存する前に、顧客に同意書の規約を表示して、顧客から承認を得る必要があります。
To be compliant with Nacha rules, you must obtain authorization from your customer before you can initiate payment by displaying mandate terms for them to accept. For more information on mandates, see Mandates.
顧客が同意書の規約を承認する場合、SetupIntent を確定する必要があります。顧客がフォームを送信したら、stripe.confirmUsBankAccountSetup を使用して支払いを完了します。
confirmationForm.addEventListener('submit', (ev) => { ev.preventDefault(); stripe.confirmUsBankAccountSetup(clientSecret) .then(({setupIntent, error}) => { if (error) { console.error(error.message); // The payment failed for some reason. } else if (setupIntent.status === "requires_payment_method") { // Confirmation failed. Attempt again with a different payment method. } else if (setupIntent.status === "succeeded") { // Confirmation succeeded! The account is now saved. // Display a message to customer. } else if (setupIntent.next_action?.type === "verify_with_microdeposits") { // The account needs to be verified via microdeposits. // Display a message to consumer with next steps (consumer waits for // microdeposits, then enters a statement descriptor code on a page sent to them via email). } }); });
注
stripe.confirmUsBankAccountSetup の完了には数秒かかる場合があります。この間、フォームが再送信されないように無効化し、待機中のインジケーター (スピナーなど) を表示します。エラーが発生した場合は、それを顧客に表示し、フォームを再度有効化し、待機中のインジケーターを非表示にします。
If successful, Stripe returns a SetupIntent object, with one of the following possible statuses:
Status | Description | Next Steps |
---|---|---|
succeeded | The bank account has been instantly verified or verification was not necessary. | アクションは不要です |
requires_ | Further action needed to complete bank account verification. | Step 6: Verifying bank accounts with microdeposits |
After successfully confirming the SetupIntent, an email confirmation of the mandate and collected bank account details must be sent to your customer. Stripe handles these by default, but you can choose to send custom notifications if you prefer.
少額入金で銀行口座を確認するクライアント側
Not all customers can verify the bank account instantly. This step only applies if your customer has elected to opt out of the instant verification flow in the previous step.
このような場合、Stripe は descriptor_
による少額入金を送金し、銀行口座の確認でさらに問題が発生した場合には、amount
による少額入金に戻る場合があります。これらの入金が顧客のオンライン明細書に表示されるには 1 ~ 2 営業日かかります。
- 明細書表記コード。SM で始まる一意の 6 桁の
descriptor_
を指定して、0.01 USD の 1 件の少額入金を顧客の銀行口座に送金します。顧客は、この文字列を使用して、銀行口座を確認します。code - 金額。Stripe は、
ACCTVERIFY
という明細書表記を使用し、一意でない 2 件の少額入金を顧客の銀行口座に送金します。顧客は、この入金額を使用して銀行口座を確認します。
前のステップの stripe.confirmUsBankAccountSetup メソッドの呼び出しの結果として、requires_
状態の SetupIntent が返されます。この SetupIntent には、確認を完了するための有益な情報を含む next_
フィールドが含まれています。
next_action: { type: "verify_with_microdeposits", verify_with_microdeposits: { arrival_date: 1647586800, hosted_verification_url: "https://payments.stripe.com/…", microdeposit_type: "descriptor_code" } }
請求書メールを指定した場合、Stripe はこのメールで入金の到着予定日を顧客に通知します。このメールには、Stripe がオンラインで提供する確認ページへのリンクが含まれ、顧客はそのページで入金額を確認して銀行口座の確認を完了することができます。
警告
確認の失敗は、明細書表記ベースの少額入金の場合は 10 回、金額ベースの少額入金の場合は 3 回までです。この上限を超えると、Stripe は銀行口座を確認できなくなります。また、少額入金の確認は 10 日経過するとタイムアウトになります。この期間内に少額入金を確認できなかった場合、SetupIntent は新しい支払い方法の詳細を要求する状態に戻ります。少額入金とは何か、どのように使用されるのかを顧客に明確に伝えることで、確認に関する問題を回避できます。
オプション: カスタムのメール通知を送信する
Optionally, you can send custom email notifications to your customer. After you set up custom emails, you need to specify how the customer responds to the verification email. To do so, choose one of the following:
Use the Stripe-hosted verification page. To do this, use the
verify_
URL in the next_action object to direct your customer to complete the verification process.with_ microdeposits[hosted_ verification_ url] Stripe がオンラインで提供する確認ページを使用しない場合、ご自身のサイトにフォームを作成します。顧客はこのフォームを使用して少額入金の金額を伝え、Stripe.js を使用して、銀行口座を確認します。
- 確認のために、少なくとも 6 桁のストリングの
descriptor code
パラメーターを処理するフォームを設定します。 - また、Stripe は、フォームで
amounts
パラメーターを処理するように設定することもお勧めします。顧客が利用する一部の銀行で必要になる場合があるためです。
組み込みは、
descriptor_
「または」code amounts
でのみ渡されます。組み込みでどちらが使用されているかを判断するには、next_
オブジェクトのaction verify_
の値を確認します。with_ microdeposits[microdeposit_ type] - 確認のために、少なくとも 6 桁のストリングの
stripe.verifyMicrodepositsForSetup(clientSecret, { // Provide either a descriptor_code OR amounts, not both descriptor_code: `SMT86W`, amounts: [32, 45], });
銀行口座の確認に成功すると、Stripe は SetupIntent オブジェクトを succeeded
の status
で返し、setup_intent.succeeded Webhook イベントを送信します。
確認が失敗する原因はいくつか存在します。失敗は直接的なエラー応答として同期的に発生することも、setup_intent.setup_failed Webhook イベントを通じて非同期で発生することもあります (以下の例を参照してください)。
エラーコード | 同期または非同期 | メッセージ | Status change |
---|---|---|---|
payment_ | 同期、または Webhook イベントを通じて非同期で発生 | 少額入金に失敗しました。指定した銀行口座、金融機関、支店の番号を確認してください | status は requires_ で、last_ が設定されます。 |
payment_ | 同期 | 指定された金額が銀行口座に送金された金額と一致しません。確認試行の残り回数は {attempts_remaining} 回です。 | 変化なし |
payment_ | 同期、または Webhook イベントを通じて非同期で発生 | 許容された確認の試行回数を超えました | status は requires_ で、last_ が設定されます。 |
payment_ | Webhook イベントを通じて非同期で発生 | 少額入金がタイムアウトになりました。顧客は要求された 10 日の期間内に銀行口座を確認しませんでした。 | status は requires_ で、last_ が設定されます。 |
組み込みをテストする
Financial Connections を使用して即時確認を行うシナリオをテストする方法をご紹介します。
テスト環境で取引に関するメールを送信する
銀行口座の詳細を収集し、同意書を受け付けたら、テスト環境で同意書の確認メールと少額入金の確認メールを送信します。これを実行するには、支払い方法の詳細を収集するときに、payment_
フィールドに {any-prefix}+test_
の形式でメールアドレスを指定します。
よくある間違い
テスト環境でこれらのメールをトリガーするには、Stripe の本番環境利用の申請を行う必要があります。
Test account numbers
Stripe では、手動入力の銀行口座の組み込みが本番環境に移行する準備が整ったかどうかを確認するため、テスト用の口座番号と対応するトークンをいくつか用意しています。
Account number | トークン | Routing number | 動作 |
---|---|---|---|
000123456789 | pm_ | 110000000 | 支払いは成功します。 |
000111111113 | pm_ | 110000000 | 口座が解約済みであるため、支払いは失敗します。 |
000111111116 | pm_ | 110000000 | 口座が見つからないため、支払いは失敗します。 |
000222222227 | pm_ | 110000000 | 残高不足のため、支払いは失敗します。 |
000333333335 | pm_ | 110000000 | 引き落としがオーソリされていないため、支払いは失敗します。 |
000444444440 | pm_ | 110000000 | 通貨が無効であるため、支払いは失敗します。 |
000666666661 | pm_ | 110000000 | 支払いで少額入金の送金が失敗します。 |
000555555559 | pm_ | 110000000 | 支払いによって不審請求の申請が開始されています。 |
000000000009 | pm_ | 110000000 | 支払いは無期限に処理中のままになります。これは PaymentIntent のキャンセルをテストするのに便利です。 |
000777777771 | pm_ | 110000000 | The payment fails due to payment amount causing the account to exceed its weekly payment volume limit. |
テスト取引を完了する前に、自動的に支払いに成功または失敗するテスト用のすべての口座を確認する必要があります。確認するには、下記の少額入金のテスト用の金額または明細書表記コードを使用します。
少額入金の金額と明細書表記コードをテストする
さまざまなシナリオを再現するために、これらの少額入金の金額「または」明細書表記コードの値 0.01 を使用します。
少額入金の金額 | 明細書表記コードの値 0.01 | シナリオ |
---|---|---|
32 and 45 | SM11AA | アカウントの確認をシミュレーションします。 |
10 および 11 | SM33CC | 許容された確認回数の超過をシミュレーションします。 |
40 および 41 | SM44DD | 少額入金のタイムアウトをシミュレーションします。 |
将来の決済を受け付けるサーバー側
When the SetupIntent succeeds, it will create a new PaymentMethod attached to a Customer. These can be used to initiate future payments without having to prompt the customer for their bank account a second time.