# カード支払いの事前設定
手動でのサーバー側の確定を使用するか、支払い方法を別途提示します。
# Stripe がオンラインで提供するページ
> This is a Stripe がオンラインで提供するページ for when platform is web and payment-ui is stripe-hosted. View the full page at https://docs.stripe.com/payments/save-and-reuse-cards-only?platform=web&payment-ui=stripe-hosted.
> [将来の支払いの設定](https://docs.stripe.com/payments/checkout/save-and-reuse.md)ガイドに従うことをお勧めします。このガイドは、手動によるサーバー側の確定を行う必要がある場合、または構築済みのシステムで決済手段を別途提示する必要がある場合にのみ使用してください。すでに Elements の実装が完了している場合は、[Payment Element 移行ガイド](https://docs.stripe.com/payments/payment-element/migration.md)をご覧ください。
Checkout の設定モードを使用すると、顧客の支払い情報を収集して、今後の決済時に再利用できます。設定モードは、[Setup Intents API](https://docs.stripe.com/api/setup_intents.md) を使用して [Payment Methods](https://docs.stripe.com/api/payment_methods.md) を作成します。
[GitHub の実用サンプル](https://github.com/stripe-samples/checkout-remember-me-with-twilio-verify)をご覧ください。
## Stripe を設定する [サーバ側]
まず、Stripe アカウントが必要です。[今すぐ登録](https://dashboard.stripe.com/register)してください。
アプリケーションから Stripe API にアクセスするには、Stripe の公式ライブラリを使用します。
#### Ruby
```bash
# Available as a gem
sudo gem install stripe
```
```ruby
# If you use bundler, you can add this line to your Gemfile
gem 'stripe'
```
## Checkout セッションを作成する [クライアント側] [サーバ側]
ウェブサイトに決済ボタンを追加し、サーバー側のエンドポイントを呼び出して Checkout セッションを作成します。
```html
Checkout
```
設定モードのセッションを作成するには、セッションの作成時に `setup` の値を指定して `mode` パラメーターを使用します。オプションで [customer](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer) パラメーターを指定して、作成した決済手段を既存の顧客に自動的に関連付けることもできます。Checkout ではデフォルトで[動的決済手段](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)が使用されるため、`setup` モードを使用するときに [currency](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-currency) パラメーターを渡す必要があります。
`success_url` に `{CHECKOUT_SESSION_ID}` テンプレート変数を追加することで、顧客が Checkout セッションを正常に完了した後でセッション ID にアクセスできます。Checkout セッションを作成したら、レスポンスで返された [URL](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-url) に顧客をリダイレクトします。
```curl
curl https://api.stripe.com/v1/checkout/sessions \
-u "<>:" \
-d mode=setup \
-d currency=usd \
-d "customer={{CUSTOMER_ID}}" \
--data-urlencode "success_url=https://example.com/success?session_id={CHECKOUT_SESSION_ID}"
```
### 決済手段
デフォルトでは、カードとその他の一般的な決済手段が有効になっています。[Stripe ダッシュボード](https://dashboard.stripe.com/settings/payment_methods)で個々の決済手段をオンまたはオフにできます。Checkout では、Stripe は通貨と制限事項を評価して、対応している決済手段を顧客に動的に提示します。
決済手段が顧客にどのように表示されるか確認するには、ダッシュボードで取引 ID を入力するか、または注文金額と通貨を設定します。
[決済手段の設定](https://dashboard.stripe.com/settings/payment_methods)では Apple Pay と Google Pay を有効にすることができます。デフォルトでは、Apple Pay は有効で、Google Pay は無効になっています。ただし、有効になっていても Stripe が除外する場合があります。配送先住所を収集せずに[税金の自動計算を有効にした](https://docs.stripe.com/tax/checkout.md)場合、Google Pay は除外されます。
Checkout の Stripe 上のオンラインページでは、Apple Pay や Google Pay を有効にするために実装内容を変更する必要はありません。Stripe は、これらの決済を他のカード決済と同じように処理します。
## Checkout セッションを取得する [サーバ側]
顧客が Checkout セッションを正常に完了した後に、お客様は Session オブジェクトを取得する必要があります。これは、以下の 2 つの方法で実行できます。
- **非同期**: Session オブジェクトを含む `checkout.session.completed` *Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) を処理します。[Webhook の設定](https://docs.stripe.com/webhooks.md)の詳細をご覧ください。
- **同期:** ユーザーがサイトにリダイレクトされるときに `success_url` からセッション ID を取得します。セッション ID を使用して、Session オブジェクトを[取得](https://docs.stripe.com/api/checkout/sessions/retrieve.md)します。
```curl
curl https://api.stripe.com/v1/checkout/sessions/cs_test_MlZAaTXUMHjWZ7DcXjusJnDU4MxPalbtL5eYrmS2GKxqscDtpJq8QM0k \
-u "<>:"
```
顧客が支払いの成功後に必ず `success_url` に到達するとは限らないため、ドロップオフの許容度に応じて適切な判断をする必要があります。リダイレクトが発生する前に顧客がブラウザータブを閉じることもあります。Webhook を処理することで、システムがこのようなドロップオフの影響を受けずに済みます。
Session オブジェクトの取得後、Checkout セッションの際に作成された SetupIntent の ID である `setup_intent` キーの値を入手します。[SetupIntent](https://docs.stripe.com/payments/setup-intents.md) は、今後の支払いに備えて顧客の銀行口座情報を設定するために使用されるオブジェクトです。
以下に `checkout.session.completed` ペイロードの例を示します。
```json
{
"id": "evt_1Ep24XHssDVaQm2PpwS19Yt0",
"object": "event",
"api_version": "2019-03-14",
"created": 1561420781,
"data": {
"object": {
"id": "cs_test_MlZAaTXUMHjWZ7DcXjusJnDU4MxPalbtL5eYrmS2GKxqscDtpJq8QM0k",
"object": "checkout.session",
"billing_address_collection": null,
"client_reference_id": null,
"customer": "",
"customer_email": null,
"display_items": [],
"mode": "setup","setup_intent": "seti_1EzVO3HssDVaQm2PJjXHmLlM",
"submit_type": null,
"subscription": null,
"success_url": "https://example.com/success"
}
},
"livemode": false,
"pending_webhooks": 1,
"request": {
"id": null,
"idempotency_key": null
},
"type": "checkout.session.completed"
}
```
次のステップに備えて `setup_intent` ID を書き留めておきます。
## SetupIntent を取得する [サーバ側]
`setup_intent` ID を使用し、SetupIntent オブジェクトを[取得](https://docs.stripe.com/api/setup_intents/retrieve.md)します。返されるオブジェクトには `payment_method` ID が含まれ、これを次のステップで顧客に関連付けることができます。
```curl
curl https://api.stripe.com/v1/setup_intents/seti_1EzVO3HssDVaQm2PJjXHmLlM \
-u "<>:"
```
> この情報を (Webhook の処理とは異なり) Stripe API から同期的にリクエストする場合は、/v1/checkout/session エンドポイントに対するリクエスト内の SetupIntent オブジェクトを[拡張](https://docs.stripe.com/api/expanding_objects.md)することで、前のステップとこのステップを結合できます。このようにすることで、新しく作成された PaymentMethod ID にアクセスするためのネットワークリクエストを二重に作成する必要がなくなります。
## 後で決済手段に請求する [サーバ側]
既存の顧客を指定して Checkout セッションを作成しなかった場合は、PaymentMethod の ID を使用して、*PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) を *Customer* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) に[関連付けます](https://docs.stripe.com/api/payment_methods/attach.md)。PaymentMethod を顧客に関連付けた後、[PaymentIntent](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method) を使用して、*オフセッション* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information)の支払いを行うことができます。
- [customer](https://docs.stripe.com/api.md#create_payment_intent-customer) を 顧客の ID に、[payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) を PaymentMethod の ID に設定します。
- [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) が `true` の場合、支払いの試行時に顧客が決済フローを実行中でなく、カード発行会社、銀行、その他の決済機関といった提携機関からの認証リクエストに対応できないことを示します。決済フロー中に提携機関から認証をリクエストされた場合、Stripe は以前の*オンセッション* (A payment is described as on-session if it occurs while the customer is actively in your checkout flow and able to authenticate the payment method)取引の顧客情報を使用して免除をリクエストします。免除の条件が満たされていない場合、PaymentIntent はエラーを返す可能性があります。
- PaymentIntent の [confirm](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) プロパティの値を `true` に設定します。これにより、PaymentIntent が作成されると直ちに確定が行われます。
```curl
curl https://api.stripe.com/v1/payment_intents \
-u "<>:" \
-d amount=1099 \
-d currency=usd \
-d "customer={{CUSTOMER_ID}}" \
-d "payment_method={{PAYMENTMETHOD_ID}}" \
-d off_session=true \
-d confirm=true
```
支払いが失敗すると、リクエストも 402 HTTP ステータスコードで失敗し、PaymentIntent のステータスが *requires\_payment\_method* (This status appears as "requires_source" in API versions before 2019-02-11) になります。アプリケーションに戻って支払いを完了するよう (メールやアプリ内通知を送信するなどして) 顧客に通知し、顧客を新しい Checkout セッションに誘導して別の決済手段を選択するよう促します。
```curl
curl https://api.stripe.com/v1/checkout/sessions \
-u "<>:" \
-d "customer={{CUSTOMER_ID}}" \
-d "line_items[0][price_data][currency]=usd" \
-d "line_items[0][price_data][product_data][name]=T-shirt" \
-d "line_items[0][price_data][unit_amount]=1099" \
-d "line_items[0][quantity]=1" \
-d mode=payment \
--data-urlencode "success_url=https://example.com/success?session_id={CHECKOUT_SESSION_ID}"
```
# 高度な連携機能
> This is a 高度な連携機能 for when platform is web and payment-ui is direct-api. View the full page at https://docs.stripe.com/payments/save-and-reuse-cards-only?platform=web&payment-ui=direct-api.
> この場合、[支払いの事前設定](https://docs.stripe.com/payments/save-and-reuse.md)ガイドに従うことをお勧めします。このガイドは、手動でのサーバー側の確定を使用する必要がある場合、またはお使いのシステムで支払い方法を別に提示する必要がある場合にのみ使用してください。すでに Elements との連携が完了している場合は、[Payment Element 移行ガイド](https://docs.stripe.com/payments/payment-element/migration.md)をご覧ください。
[Setup Intents API](https://docs.stripe.com/api/setup_intents.md) を使用すると、初回の支払いなしで顧客のカードを保存することができます。これは、今すぐ顧客をアカウント登録して支払いを設定し、将来顧客がオフラインの際に請求するときに役立ちます。
この組み込みを使用して、継続支払いを設定したり、最終金額が後で (顧客がサービスを受け取った後などに) 決定される 1 回限りの支払いを作成します。
## Stripe を設定する [サーバー側]
アプリケーションから Stripe API にアクセスするには、Stripe の公式ライブラリーを使用します。
#### Ruby
```bash
# Available as a gem
sudo gem install stripe
```
```ruby
# If you use bundler, you can add this line to your Gemfile
gem 'stripe'
```
## 設定前に Customer を作成する [サーバー側]
将来の支払いに備えてカードを設定するには、カードを *Customer (顧客)* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) に関連付ける必要があります。顧客がビジネスでアカウントを作成する際に、Customer オブジェクトを作成します。Customer オブジェクトを使用すると、支払い方法を再利用したり、複数の支払いを追跡したりできます。
> #### Accounts v2 API を使用した顧客の表現
>
> 導入で [customer-configured Accounts](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) を使用している場合は、コード例内の `Customer` とイベント参照を、対応する Accounts v2 API リファレンスに置き換えてください。詳細については、[Account オブジェクトで顧客を表す](https://docs.stripe.com/connect/use-accounts-as-customers.md)をご覧ください。
```curl
curl https://api.stripe.com/v1/customers \
-u "<>:" \
-d "name=Jenny Rosen" \
--data-urlencode "email=jennyrosen@example.com"
```
作成に成功すると、[Customer](https://docs.stripe.com/api/customers/object.md) オブジェクトが返されます。オブジェクトで顧客の `id` を調べて、その値を後で取得できるようにデータベースに保存できます。
これらの顧客は、ダッシュボードの[顧客](https://dashboard.stripe.com/customers)ページで見つけることができます。
## SetupIntent を作成する [サーバー側]
[SetupIntent (支払い方法設定インテント)](https://docs.stripe.com/api/setup_intents.md) は、将来の支払いに備えて顧客のカードを設定するという意図を示すオブジェクトです。
`SetupIntent` オブジェクトには、[client secret](https://docs.stripe.com/api/setup_intents/object.md#setup_intent_object-client_secret) が含まれています。これは、カード詳細を収集するためにクライアント側で Stripe.js に渡す必要がある一意のキーです。client secret により、`customer` などの機密情報を非表示にすると同時に、設定の確認や支払い方法の詳細の更新などの一定のアクションをクライアント側で実行できます。client secret を使用すると、クレジットカードネットワークを使用してカード詳細を検証および認証できます。client secret は機密情報なので、ログに記録したり、URL に埋め込んだり、当該の顧客以外に漏洩することがないようにしてください。
お使いのアプリケーションがサーバー側のレンダリングを使用する場合は、テンプレートフレームワークを利用して、[データ属性](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes)または非表示の HTML Element によって client secret をページに埋め込みます。
#### curl
```bash
curl https://api.stripe.com/v1/setup_intents \
-u <>: \
-d "customer"="{{CUSTOMER_ID}}"
```
今後の支払いで、顧客が決済フローでオンセッション時にのみカードを使用する場合、[usage](https://docs.stripe.com/api/setup_intents/object.md#setup_intent_object-usage) パラメーターを *on\_session* (A payment is described as on-session if it occurs while the customer is actively in your checkout flow and able to authenticate the payment method) に設定して、オーソリ率を最適化します。
## カード詳細を収集する [クライアント側]
*Setup Intents API* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) は [Stripe.js](https://docs.stripe.com/payments/elements.md) と完全に統合されているため、Elements UI ライブラリを使用して、クライアント側でカード詳細を安全に収集できます。
> 特にヨーロッパでは、カードの再利用に関する規制があるため、カード詳細を保存して今後の *オフセッションの支払い* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information) に使用する際は、クレジットカードを保存するための [許可を取得](https://docs.stripe.com/strong-customer-authentication.md#sca-enforcement) します。カードをどのように使用するかをユーザーに知らせるテキストを決済フローに含めてください。
#### HTML + JS
Elements の利用を始めるには、決済ページに以下のスクリプトを含めます。Stripe.js を常に js.stripe.com から直接読み込むことにより、PCI への準拠が維持されます。スクリプトをバンドルに含めたり、そのコピーをご自身でホストすることがないようにしてください。
```html
```
Stripe の[高度な不正対策機能](https://docs.stripe.com/radar.md)を最大限に活用するには、このスクリプトを決済ページだけでなく、お客様のサイトのすべてのページに追加してください。すべてのページにスクリプトを追加することで、ユーザーがお客様のウェブサイトを閲覧する際に不正行為の可能性がある[不審な動作を Stripe が検知できる](https://docs.stripe.com/disputes/prevention/advanced-fraud-detection.md)ようになります。
### Elements をページに追加する
次に、[Stripe オブジェクト](https://docs.stripe.com/js.md#stripe-function)のインスタンスを作成し、公開可能な [API キー](https://docs.stripe.com/keys.md)を最初のパラメーターとして指定します。その後、[Elements オブジェクト](https://docs.stripe.com/js.md#stripe-elements)のインスタンスを作成し、それを使用して DOM に `card` Element をマウントします。
`card` Element は決済フォームを簡素化し、入力必須フィールドの数を最小限に抑えます。これには、1 つの柔軟な入力フィールドを挿入し、カードに関する必要な詳細情報をすべて安全に収集します。あるいは、`cardNumber`、`cardExpiry`、`cardCvc` の Element を組み合わせて、複数入力の柔軟なカードフォームを作成します。
GitHub で、Elements を使用して作成された[支払いフォームのサンプル](https://stripe.com/payments/elements/examples)をご確認ください。
> カードの支払い成功率を向上し、不正使用を削減するため、常に郵便番号を収集してください。
>
> [単一行の Card Element](https://docs.stripe.com/js/element/other_element?type=card) は、顧客の郵便番号を自動的に収集して Stripe に送信します。分割 Element ([Card Number](https://docs.stripe.com/js/element/other_element?type=cardNumber)、[Expiry](https://docs.stripe.com/js/element/other_element?type=cardExpiry)、[CVC](https://docs.stripe.com/js/element/other_element?type=cardCvc)) を使用して支払いフォームを構築する場合、顧客の郵便番号用に別個の入力フィールドを追加します。
```javascript
const stripe = Stripe('<>');
const elements = stripe.elements();
const cardElement = elements.create('card');
cardElement.mount('#card-element');
```
Stripe Element には、HTTPS 接続を介して支払い情報を Stripe に安全に送信する iframe が含まれています。組み込みを機能させるには、決済ページのアドレスの先頭を http:// ではなく https:// にする必要があります。
HTTPS を使用せずに実装をテストできます。本番環境で決済を受け付ける準備が整ったら、HTTPS を[有効化](https://docs.stripe.com/security/guide.md#tls)します。
### SetupIntent を確定する
設定を完了するには、前のステップで作成した SetupIntent から client secret を取得し、[stripe.confirmCardSetup](https://docs.stripe.com/js/setup_intents/confirm_card_setup) とカード Element を使用して設定を完了します。正常に設定が完了すると、返される SetupIntent の `status` プロパティの値が `succeeded` になります。
```javascript
const cardholderName = document.getElementById('cardholder-name');
const setupForm = document.getElementById('setup-form');
const clientSecret = setupForm.dataset.secret;
setupForm.addEventListener('submit', async (ev) => {
ev.preventDefault();
const {setupIntent, error} = await stripe.confirmCardSetup(
clientSecret,
{
payment_method: {
card: cardElement,
billing_details: {
name: cardholderName.value,
},
},
}
);
if (error) {
// Display error.message in your UI.
} else {
if (setupIntent.status === 'succeeded') {
// The setup has succeeded. Display a success message. Send
// setupIntent.payment_method to your server to save the card to a Customer
}
}
});
```
#### React
#### npm
npm パブリックレジストリーから [React Stripe.js](https://www.npmjs.com/package/@stripe/react-stripe-js) と [Stripe.js ローダー](https://www.npmjs.com/package/@stripe/stripe-js)をインストールします。
```bash
npm install --save @stripe/react-stripe-js @stripe/stripe-js
```
#### umd
Stripe は npm やモジュールを使用しないサイト向けに UMD ビルドも提供しています。
グローバルな `Stripe` 機能をエクスポートする Stripe.js スクリプトと、グローバルな `ReactStripe` オブジェクトをエクスポートする React Stripe.js の UMD ビルドを含めてください。常に **js.stripe.com** から Stripe.js スクリプトを直接読み込むことにより、PCI への準拠が維持されます。スクリプトをバンドルに含めたり、そのコピーを自身でホストすることがないようにしてください。
```html
```
> [CodeSandbox でのデモ](https://codesandbox.io/s/react-stripe-official-q1loc?fontsize=14&hidenavigation=1&theme=dark)を使用すると、新しいプロジェクトを作成することなく、React Stripe.js を試してみることができます。
### お客様のページへの Stripe.js および Elements の追加
Element コンポーネントを使用するには、決済ページコンポーネントを [Elements プロバイダー](https://docs.stripe.com/sdks/stripejs-react.md#elements-provider)でラップします。公開キーを使用して `loadStripe` を呼び出し、返された `Promise` を `Elements` プロバイダーに渡します。
```jsx
import React from 'react';
import ReactDOM from 'react-dom';
import {Elements} from '@stripe/react-stripe-js';
import {loadStripe} from '@stripe/stripe-js';
import CardSetupForm from './CardSetupForm';
// Make sure to call `loadStripe` outside of a component's render to avoid
// recreating the `Stripe` object on every render.
const stripePromise = loadStripe('<>');
function App() {
return (
);
};
ReactDOM.render(, document.getElementById('root'));
```
### CardElement コンポーネントを追加して設定する
`CardElement` などの個別の Element コンポーネントを使用して、お客様独自のフォームを構築します。
#### JSX
```jsx
/**
* Use the CSS tab above to style your Element's container.
*/
import React from 'react';
import {CardElement} from '@stripe/react-stripe-js';
import './Styles.css'
const CARD_ELEMENT_OPTIONS = {
style: {
base: {
color: "#32325d",
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: "antialiased",
fontSize: "16px",
"::placeholder": {
color: "#aab7c4",
},
},
invalid: {
color: "#fa755a",
iconColor: "#fa755a",
},
},
};
function CardSection() {
return (
);
};
export default CardSection;
```
Element は完全にカスタマイズ可能です。お客様のサイトのデザインと雰囲気に合わせて [Element のスタイルを設定](https://docs.stripe.com/js/elements_object/create_element?type=card#elements_create-options)して、顧客にシームレスな決済体験を提供できます。Element が選択されているときなど、さまざまな入力状態のスタイルを設定することもできます。
`CardElement` は、カードと請求書に関する必要な詳細情報のすべてを安全に収集する、1 つの柔軟な入力フィールドを挿入することで、フォームを簡素化し、入力必須フィールドの数を最小限に抑えます。また、`CardNumberElement`、`CardExpiryElement`、`CardCvcElement` の要素を組み合わせて、複数入力の柔軟なカードフォームを作成する方法もあります。
> カードの支払い成功率を向上し、不正使用を削減するため、常に郵便番号を収集してください。
>
> [単一行の Card Element](https://docs.stripe.com/js/element/other_element?type=card) は、顧客の郵便番号を自動的に収集して Stripe に送信します。分割 Element ([Card Number](https://docs.stripe.com/js/element/other_element?type=cardNumber)、[Expiry](https://docs.stripe.com/js/element/other_element?type=cardExpiry)、[CVC](https://docs.stripe.com/js/element/other_element?type=cardCvc)) を使用して支払いフォームを構築する場合、顧客の郵便番号用に別個の入力フィールドを追加します。
### SetupIntent を確定する
設定を完了するには、[ステップ 3](https://docs.stripe.com/payments/save-and-reuse-cards-only.md#web-create-setup-intent) で作成した SetupIntent から client secret を取得し、[stripe.confirmCardSetup](https://docs.stripe.com/js/setup_intents/confirm_card_setup) とカード Element を使用して設定を完了します。正常に設定が完了すると、返される SetupIntent の `status` プロパティの値が `succeeded` になります。
支払いフォームコンポーネントから `stripe.confirmCardSetup` を呼び出すには、[useStripe](https://docs.stripe.com/sdks/stripejs-react.md#usestripe-hook) フックと [useElements](https://docs.stripe.com/sdks/stripejs-react.md#useelements-hook) フックを使用します。フックではなく従来のクラスコンポーネントを使用する場合は、代わりに [ElementsConsumer](https://docs.stripe.com/sdks/stripejs-react.md#elements-consumer) を使用します。
#### フック
```jsx
import React from 'react';
import {useStripe, useElements, CardElement} from '@stripe/react-stripe-js';
import CardSection from './CardSection';
export default function CardSetupForm() {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (event) => {
// We don't want to let default form submission happen here,
// which would refresh the page.
event.preventDefault();
if (!stripe || !elements) {
// Stripe.js hasn't yet loaded.
// Make sure to disable form submission until Stripe.js has loaded.
return;
}
const result = await stripe.confirmCardSetup('{{CLIENT_SECRET}}', {
payment_method: {
card: elements.getElement(CardElement),
billing_details: {
name: 'Jenny Rosen',
},
}
});
if (result.error) {
// Display result.error.message in your UI.
} else {
// The setup has succeeded. Display a success message and send
// result.setupIntent.payment_method to your server to save the
// card to a Customer
}
};
return (
);
}
```
#### クラスコンポーネント
```jsx
import React from 'react';
import {ElementsConsumer, CardElement} from '@stripe/react-stripe-js';
import CardSection from './CardSection';
class CardSetupForm extends React.Component {
handleSubmit = async (event) => {
// We don't want to let default form submission happen here,
// which would refresh the page.
event.preventDefault();
const {stripe, elements} = this.props;
if (!stripe || !elements) {
// Stripe.js hasn't yet loaded.
// Make sure to disable form submission until Stripe.js has loaded.
return;
}
const result = await stripe.confirmCardSetup('{{CLIENT_SECRET}}', {
payment_method: {
card: elements.getElement(CardElement),
billing_details: {
name: 'Jenny Rosen',
},
}
});
if (result.error) {
// Display result.error.message in your UI.
} else {
// The setup has succeeded. Display a success message and send
// result.setupIntent.payment_method to your server to save the
// card to a Customer
}
};
render() {
return (
);
}
}
export default function InjectedCardSetupForm() {
return (
{({stripe, elements}) => (
)}
);
}
```
> `stripe.confirmCardSetup` の完了には数秒かかる場合があります。この間、再送信されることがないようにフォームを無効化し、スピナーのような待機中の標識を表示します。エラーが発生した場合は、それを顧客に表示し、フォームを再度有効化し、待機中の標識を非表示にします。支払いを完了するために、顧客による認証などの追加の手順が必要な場合、Stripe.js がそのプロセスをステップごとに顧客に提示します。
SetupIntent は、顧客が使用しているクレジットカード情報がネットワーク上で有効であることを検証します。ただし自動検証が常に行われるわけではありません。詳細は、[支払いをせずにクレジットカードの有効性を確認する](https://support.stripe.com/questions/check-if-a-card-is-valid-without-a-charge)でご確認ください。また、作成から長時間が経過した未処理の SetupIntent は、[stripe.confirmCardSetup](https://docs.stripe.com/js.md#stripe-confirm-card-setup) を呼び出す時点で無効になっている可能性があるため、保持しないでください。
以上でカード詳細を収集して認証リクエストを処理するフローができました。認証プロセスをテストするには、任意のセキュリティコード、郵便番号、および有効期限を指定して、テストカード `4000 0025 0000 3155` を使用します。
後で請求するためにカードを保存する際は、事前に顧客の許可を得ることが重要です。支払い条件を参照するテキストを決済フローに追加します。次に例を示します。
> 私は、私と貴社との契約に従って、[貴社のビジネス名]が、私のカードを発行した金融機関に対して私のカード口座から支払いを行うように指示することを許可します。
SetupIntent が成功すると、(`result.setupIntent.payment_method` で) 生成された *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) ID が、指定された *Customer* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) に保存されます。
## 保存されたカードに後で請求する [サーバー側]
顧客にオフセッションで支払いを行う準備ができたら、顧客 ID と PaymentMethod ID を使用して、PaymentIntent を作成します。支払いするクレジットカードを見つけるには、顧客に関連付けられた PaymentMethod を[リスト](https://docs.stripe.com/api/payment_methods/list.md)します。
#### Accounts v2
```curl
curl -G https://api.stripe.com/v1/payment_methods \
-u "<>:" \
-d "customer_account={{CUSTOMERACCOUNT_ID}}" \
-d type=card
```
#### Customers v1
```curl
curl -G https://api.stripe.com/v1/payment_methods \
-u "<>:" \
-d "customer={{CUSTOMER_ID}}" \
-d type=card
```
Customer ID と PaymentMethod ID を取得したら、支払いの金額と通貨を使用して PaymentIntent を作成します。下記のパラメータを設定し、オフセッションの支払いを行います。
- [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) を `true` に設定して、支払いの実行時に顧客が決済フローに存在しないことを示します。これにより、認証が必要な場合は PaymentIntent からエラーが返されます。
- PaymentIntent の [confirm](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) プロパティの値を `true` に設定します。これにより、PaymentIntent が作成されると直ちに確定されます。
- [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) を PaymentMethod の ID に設定し、[customer](https://docs.stripe.com/api.md#create_payment_intent-customer) を Customer の ID に設定します。
#### curl
```bash
curl https://api.stripe.com/v1/payment_intents \
-u <>: \
-d amount=1099 \
-d currency=usd \-d customer="{{CUSTOMER_ID}}" \
-d payment_method="{{PAYMENT_METHOD_ID}}" \
-d off_session=true \
-d confirm=true
```
支払いが失敗すると、リクエストも 402 HTTP ステータスコードで失敗し、PaymentIntent のステータスが *requires\_payment\_method* (This status appears as "requires_source" in API versions before 2019-02-11) になります。アプリケーションに戻って支払いを完了するよう (メールやアプリ内通知を送信するなどして) 顧客に通知する必要があります。Stripe API ライブラリによって示された[エラー](https://docs.stripe.com/api/errors/handling.md)のコードを確認するか、PaymentIntent の [last_payment_error.decline_code](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-last_payment_error-decline_code) を確認し、カード発行会社が支払いを拒否した理由を調べます。
支払いが [authentication_required](https://docs.stripe.com/declines/codes.md) 拒否コードで失敗した場合には、拒否された PaymentIntent の client secret と[支払い方法](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-last_payment_error-payment_method)を confirmCardPayment とともに使用し、顧客が支払いを認証できるようにします。
```javascript
// Pass the failed PaymentIntent to your client from your server
stripe.confirmCardPayment(intent.client_secret, {
payment_method: intent.last_payment_error.payment_method.id
}).then(function(result) {
if (result.error) {
// Show error to your customer
console.log(result.error.message);
} else {
if (result.paymentIntent.status === 'succeeded') {
// The payment is complete!
}
}
});
```
> `stripe.confirmCardPayment` の完了には数秒かかる場合があります。この間、フォームが再送信されないように無効化し、スピナーのような待機中のインジケーターを表示します。エラーが発生した場合は、それを顧客に表示し、フォームを再度有効化し、待機中のインジケーターを非表示にします。決済の完了のために顧客による認証などの追加の手順が必要な場合は、Stripe.js がそのプロセスをステップごとに顧客に提示します。
カードの利用可能額不足など、他の理由で支払いが失敗した場合、新しいカードを入力する支払いページを顧客に送信します。既存の PaymentIntent を再利用し、新しいカード詳細を利用して支払いを再試行できます。
## 組み込みをテストする
ここまでで、以下を実行する組み込みが完成しています。
1. SetupIntent を使用して、顧客に請求することなくカード詳細を収集・保存する
1. オフセッションでカードに請求し、支払い拒否と認証リクエストを処理するリカバリーフローが備わっている
この組み込みの稼働準備ができていることを確認するために使用できるいくつかのテストカードがあります。任意のセキュリティコード、郵便番号、および今後の有効期限を指定して使用します。
| 番号 | 説明 |
| ---------------- | --------------------------------------------------------------------------------------- |
| 4242424242424242 | 成功し、支払いがすぐに処理されます。 |
| 4000002500003155 | 初めての購入には認証が必要ですが、カードに `setup_future_usage` の設定があれば、以降の支払い (オフセッションの支払いを含む) に成功します。 |
| 4000002760003184 | 初めての購入には認証が必要で、以降の支払い (オフセッションの支払いを含む) には失敗し、支払い拒否コード `authentication_required` が返されます。 |
| 4000008260003178 | 初めての購入には認証が必要で、以降の支払い (オフセッションの支払いを含む) には失敗し、支払い拒否コード `insufficient_funds` が返されます。 |
| 4000000000009995 | (初めての購入を含め) 常に失敗し、支払い拒否コード `insufficient_funds` が返されます。 |
[テストカード](https://docs.stripe.com/testing.md)の全一覧をご覧ください。
# iOS
> This is a iOS for when platform is ios. View the full page at https://docs.stripe.com/payments/save-and-reuse-cards-only?platform=ios.
> [将来の支払いの設定](https://docs.stripe.com/payments/mobile/set-up-future-payments.md)ガイドに従うことをお勧めします。このガイドは、手動によるサーバー側の確定を行う必要がある場合、または構築済みのシステムで決済手段を別途提示する必要がある場合にのみ使用してください。すでに Elements の実装が完了している場合は、[Payment Element 移行ガイド](https://docs.stripe.com/payments/payment-element/migration.md)をご覧ください。
[Setup Intents API](https://docs.stripe.com/api/setup_intents.md) を使用すると、初回の支払いなしで顧客のカードを保存することができます。これは、今すぐ顧客をアカウント登録して支払いを設定し、将来顧客がオフラインの際に請求するときに役立ちます。
この組み込みを使用して、継続支払いを設定したり、最終金額が後で (顧客がサービスを受け取った後などに) 決定される 1 回限りの支払いを作成します。
> このガイドのステップは、GitHub で完全に実装されています。[リポジトリ](https://github.com/stripe-samples/mobile-saving-card-without-payment)のクローンを作成し、[手順](https://github.com/stripe-samples/mobile-saving-card-without-payment#how-to-run)に従ってデモ用のアプリを実行します。
## Stripe を設定する
まず、Stripe アカウントが必要です。[今すぐ登録](https://dashboard.stripe.com/register)してください。
### サーバー側
この接続方法では、Stripe API と通信するエンドポイントがサーバー上に必要です。サーバーから Stripe API にアクセスするには、Stripe の公式ライブラリーを使用します。
#### Ruby
```bash
# Available as a gem
sudo gem install stripe
```
```ruby
# If you use bundler, you can add this line to your Gemfile
gem 'stripe'
```
### クライアント側
[Stripe iOS SDK](https://github.com/stripe/stripe-ios) はオープンソースです。[詳細なドキュメントが提供されており](https://stripe.dev/stripe-ios/index.html)、iOS 13 以降をサポートするアプリと互換性があります。
#### Swift Package Manager
SDK をインストールするには、以下のステップに従います。
1. Xcode で、**File (ファイル)** > **Add Package Dependencies… (パッケージ依存関係を追加)** を選択し、リポジトリー URL として `https://github.com/stripe/stripe-ios-spm` を入力します。
1. [リリースページ](https://github.com/stripe/stripe-ios/releases)から最新のバージョン番号を選択します。
1. **StripePaymentsUI** 製品を[アプリのターゲット](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app)に追加します。
#### CocoaPods
1. まだインストールしていない場合は、[CocoaPods](https://guides.cocoapods.org/using/getting-started.html) の最新バージョンをインストールします。
1. 既存の [Podfile](https://guides.cocoapods.org/syntax/podfile.html) がない場合は、以下のコマンドを実行して作成します。
```bash
pod init
```
1. この行を `Podfile` に追加します。
```podfile
pod 'StripePaymentsUI'
```
1. 以下のコマンドを実行します。
```bash
pod install
```
1. これ以降は、Xcode でプロジェクトを開く際に、`.xcodeproj` ファイルではなく、必ず `.xcworkspace` ファイルを使用するということを忘れないでください。
1. 今後、SDK の最新バージョンに更新するには、以下を実行します。
```bash
pod update StripePaymentsUI
```
#### Carthage
1. まだインストールしていない場合は、[Carthage](https://github.com/Carthage/Carthage#installing-carthage) の最新バージョンをインストールします。
1. この行を `Cartfile` に追加します。
```cartfile
github "stripe/stripe-ios"
```
1. [Carthage のインストール手順](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos)に従います。必ず、[こちら](https://github.com/stripe/stripe-ios/tree/master/StripePaymentsUI/README.md#manual-linking)にリストされている必要なフレームワークのすべてを埋め込んでください。
1. 今後、SDK の最新バージョンに更新するには、以下のコマンドを実行します。
```bash
carthage update stripe-ios --platform ios
```
#### 手動のフレームワーク
1. Stripe の [GitHub リリースページ](https://github.com/stripe/stripe-ios/releases/latest)に移動して、**Stripe.xcframework.zip** をダウンロードして解凍します。
1. **StripePaymentsUI.xcframework** を、Xcode プロジェクトの **General (一般) ** 設定の **Embedded Binaries (埋め込みバイナリー)** セクションにドラッグします。**Copy items if needed (必要に応じてアイテムをコピーする)** を必ず選択してください。
1. [こちら](https://github.com/stripe/stripe-ios/tree/master/StripePaymentsUI/README.md#manual-linking)にリストされている必要なフレームワークのすべてに対して、ステップ 2 を繰り返します。
1. 今後、Stripe の SDK の最新バージョンに更新するには、ステップ 1 から 3 を繰り返します。
> SDK の最新リリースおよび過去バージョンの詳細については、GitHub の [Releases (リリース)](https://github.com/stripe/stripe-ios/releases) ページをご覧ください。リポジトリの[リリースをウォッチ](https://help.github.com/en/articles/watching-and-unwatching-releases-for-a-repository#watching-releases-for-a-repository)して、新しいリリースの公開時に通知を受け取ることも可能です。
アプリの起動時に Stripe [公開可能キー](https://dashboard.stripe.com/test/apikeys)を使用して SDK を設定します。これにより、アプリが Stripe API にリクエストを送信できるようになります。
#### Swift
```swift
import UIKitimportStripePaymentsUI
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {StripeAPI.defaultPublishableKey = "<>"
// do any other necessary launch configuration
return true
}
}
```
> テストおよび開発時には[テストキー](https://docs.stripe.com/keys.md#obtain-api-keys)を使用し、アプリの公開時には[本番環境](https://docs.stripe.com/keys.md#test-live-modes)キーを使用します。
## 設定前に Customer を作成する [サーバー側]
将来の支払いに備えてカードを設定するには、カードを *Customer (顧客)* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) に関連付ける必要があります。顧客がビジネスでアカウントを作成する際に、Customer オブジェクトを作成します。Customer オブジェクトを使用すると、支払い方法を再利用したり、複数の支払いを追跡したりできます。
> #### Accounts v2 API を使用した顧客の表現
>
> 導入で [customer-configured Accounts](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) を使用している場合は、コード例内の `Customer` とイベント参照を、対応する Accounts v2 API リファレンスに置き換えてください。詳細については、[Account オブジェクトで顧客を表す](https://docs.stripe.com/connect/use-accounts-as-customers.md)をご覧ください。
```curl
curl https://api.stripe.com/v1/customers \
-u "<>:" \
-d "name=Jenny Rosen" \
--data-urlencode "email=jennyrosen@example.com"
```
作成に成功すると、[Customer](https://docs.stripe.com/api/customers/object.md) オブジェクトが返されます。オブジェクトで顧客の `id` を調べて、その値を後で取得できるようにデータベースに保存できます。
これらの顧客は、ダッシュボードの[顧客](https://dashboard.stripe.com/customers)ページで見つけることができます。
## SetupIntent を作成する [サーバー側]
[SetupIntent (支払い方法設定インテント)](https://docs.stripe.com/api/setup_intents.md) は、将来の支払いに備えて支払い方法を設定するという意図を示すオブジェクトです。
SetupIntent オブジェクトには、[client secret](https://docs.stripe.com/api/setup_intents/object.md#setup_intent_object-client_secret) が含まれています。これは、お客様のアプリに渡す一意のキーです。client secret により、`customer` などの機密情報を非表示にすると同時に、設定の確認や支払い方法の詳細の更新などの一定のアクションをクライアント側で実行できます。client secret を使用すると、クレジットカードネットワークを使ってカード詳細を検証および認証できます。client secret は機密情報ですので、ログに記録したり、URL に埋め込んだり、当該の顧客以外に漏洩することがないようにしてください。
### サーバー側
サーバー側で SetupIntent を作成し、その client secret をアプリに返すエンドポイントを作成します。
#### curl
```bash
curl https://api.stripe.com/v1/setup_intents/ \
-u <>: \
-d "customer"="{{CUSTOMER_ID}}"
```
顧客がチェックアウトフローでオンセッション時にのみ、今後の支払いでカードを使用する場合、[usage](https://docs.stripe.com/api/setup_intents/object.md#setup_intent_object-usage) パラメータを *on\_session* (A payment is described as on-session if it occurs while the customer is actively in your checkout flow and able to authenticate the payment method) に設定して、オーソリ率を改善します。
### クライアント側
クライアント側でサーバーの SetupIntent をリクエストします。
#### Swift
```swift
import StripePaymentsUI
class CheckoutViewController: UIViewController {
var setupIntentClientSecret: String?
func startCheckout() {
// Request a SetupIntent from your server and store its client secret
// Click View full sample to see a complete implementation
}
}
```
## カード詳細を収集する [クライアント側]
顧客が支払いフォームを送信する際、SDK が提供するドロップイン UI コンポーネントである [STPPaymentCardTextField](https://stripe.dev/stripe-ios/stripe-payments-ui/Classes/STPPaymentCardTextField.html) を使用して、顧客からカード詳細を収集します。このコンポーネントは、カード番号、有効期限、セキュリティコード、郵便番号を収集します。

> 特にヨーロッパでは、カードの再利用に関する規制があるため、カード詳細を保存して今後のオフセッションの支払いに使用する際は、カードを保存するための [許可を取得](https://docs.stripe.com/strong-customer-authentication.md#sca-enforcement) します。カードをどのように使用するかをユーザーに知らせるテキストを決済フローに含めてください。
収集した情報を新しい [STPPaymentMethodCardParams](https://stripe.dev/stripe-ios/stripe-payments/Classes/STPPaymentMethodCardParams.html) と [STPPaymentMethodBillingDetails](https://stripe.dev/stripe-ios/stripe-payments/Classes/STPPaymentMethodBillingDetails.html) のインスタンスへ渡し、`STPSetupIntentConfirmParams` インスタンスを作成します。
#### Swift
```swift
class CheckoutViewController: UIViewController {
lazy var cardTextField: STPPaymentCardTextField = {
let cardTextField = STPPaymentCardTextField()
return cardTextField
}()
func pay() {
// Collect card details
let paymentMethodParams = cardTextField.paymentMethodParams
// Create SetupIntent confirm parameters with the above
let setupIntentParams = STPSetupIntentConfirmParams(clientSecret: setupIntentClientSecret)
setupIntentParams.paymentMethodParams = paymentMethodParams
// ...continued in next step
}
}
```
設定を完了するには、`STPPaymentHandler` [sharedManager](https://stripe.dev/stripe-ios/stripe-payments/Classes/STPPaymentHandler.html#/c:objc\(cs\)STPPaymentHandler\(cm\)sharedHandler) の [confirmSetupIntent](https://stripe.dev/stripe-ios/stripe-payments/Classes/STPPaymentHandler.html#/c:objc\(cs\)STPPaymentHandler\(im\)confirmSetupIntent:withAuthenticationContext:completion:) メソッドに `STPSetupIntentConfirmParams` オブジェクトを渡します。
支払いを完了するために顧客が認証などの追加のステップを実行する必要がある場合、`STPPaymentHandler` は、渡された [STPAuthenticationContext](https://stripe.dev/stripe-ios/stripe-payments/Protocols/STPAuthenticationContext.html) を使用してビューコントローラーを表示し、そのプロセスをステップごとに顧客に提示します。詳細は、[iOS で 3D セキュア認証をサポートする](https://docs.stripe.com/payments/3d-secure.md?platform=ios)をご覧ください。
#### Swift
```swift
class CheckoutViewController: UIViewController {
// ...
func pay() {
// ...
// Complete the setup
let paymentHandler = STPPaymentHandler.shared()
paymentHandler.confirmSetupIntent(withParams: setupIntentParams, authenticationContext: self) { status, setupIntent, error in
switch (status) {
case .failed:
// Setup failed
break
case .canceled:
// Setup canceled
break
case .succeeded:
// Setup succeeded
break
@unknown default:
fatalError()
break
}
}
}
}
extension CheckoutViewController: STPAuthenticationContext {
func authenticationPresentingViewController() -> UIViewController {
return self
}
}
```
SetupIntent は、顧客が使用しているクレジットカード情報がネットワーク上で有効であることを検証します。ただし自動検証が常に行われるわけではありません。詳細は、[支払いをせずにクレジットカードの有効性を確認する](https://support.stripe.com/questions/check-if-a-card-is-valid-without-a-charge)でご確認ください。また、作成から長時間が経過した未処理の SetupIntent は、`confirmSetupIntent` を呼び出す時点で無効になっている可能性があるため、保持しないでください。
以上でカード詳細を収集して認証リクエストを処理するフローができました。認証プロセスをテストするには、任意のセキュリティコード、郵便番号、および有効期限を指定して、テストカード `4000 0025 0000 3155` を使用します。
SetupIntent が成功すると、(`setupIntent.paymentMethodID` の) 生成された PaymentMethod ID が、指定された Customer に保存されます。
## 保存されたカードに後で請求する [サーバー側]
顧客にオフセッションで支払いを行う準備ができたら、顧客 ID と PaymentMethod ID を使用して、PaymentIntent を作成します。支払いするクレジットカードを見つけるには、顧客に関連付けられた PaymentMethod を[リスト](https://docs.stripe.com/api/payment_methods/list.md)します。
#### Accounts v2
```curl
curl -G https://api.stripe.com/v1/payment_methods \
-u "<>:" \
-d "customer_account={{CUSTOMERACCOUNT_ID}}" \
-d type=card
```
#### Customers v1
```curl
curl -G https://api.stripe.com/v1/payment_methods \
-u "<>:" \
-d "customer={{CUSTOMER_ID}}" \
-d type=card
```
Customer ID と PaymentMethod ID を取得したら、支払いの金額と通貨を使用して PaymentIntent を作成します。下記のパラメータを設定し、オフセッションの支払いを行います。
- [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) を `true` に設定して、支払いの実行時に顧客が決済フローに存在しないことを示します。これにより、認証が必要な場合は PaymentIntent からエラーが返されます。
- PaymentIntent の [confirm](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) プロパティの値を `true` に設定します。これにより、PaymentIntent が作成されると直ちに確定されます。
- [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) を PaymentMethod の ID に設定し、[customer](https://docs.stripe.com/api.md#create_payment_intent-customer) を Customer の ID に設定します。
#### curl
```bash
curl https://api.stripe.com/v1/payment_intents \
-u <>: \
-d amount=1099 \
-d currency=usd \-d customer="{{CUSTOMER_ID}}" \
-d payment_method="{{PAYMENT_METHOD_ID}}" \
-d off_session=true \
-d confirm=true
```
PaymentIntent の [status プロパティ](https://docs.stripe.com/payments/paymentintents/lifecycle.md)を調べ、支払いが成功したことを確認します。支払いの試行が成功した場合、PaymentIntent のステータスが `succeeded` になり、*オフセッションの支払い* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information)が完了します。
### リカバリフローを開始する
PaymentIntent に他のステータスがある場合、決済は成功せず、リクエストは失敗します。決済を完了するために (メール、テキスト、プッシュ通知などで) アプリケーションに戻るように顧客に通知します。決済が最初に失敗した理由を示し、顧客が再試行できるようにするリカバリフローをアプリで作成することをお勧めします。
リカバリフローで *client secret* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) を使用して PaymentIntent を取得します。PaymentIntent の [lastPaymentError](https://stripe.dev/stripe-ios/stripe-payments/Classes/STPPaymentIntent.html#/c:@M@StripePayments@objc\(cs\)STPPaymentIntent\(py\)lastPaymentError) を確認して、支払いの試行が失敗した理由を調べます。カードエラーの場合、最後の支払いエラーの[メッセージ](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-last_payment_error-message)をユーザーに表示できます。それ以外の場合は、一般的な失敗メッセージを表示できます。
#### Swift
```swift
func startRecoveryFlow(clientSecret: String) {
// Retrieve the PaymentIntent
STPAPIClient.shared.retrievePaymentIntent(withClientSecret: clientSecret) { (paymentIntent, error) in
guard error == nil, let lastPaymentError = paymentIntent?.lastPaymentError else {
// Handle error (for example, allow your customer to retry)
return
}
var failureReason = "Payment failed, try again." // Default to a generic error message
if lastPaymentError.type == .card {
failureReason = lastPaymentError.message
}
// Display the failure reason to your customer
// ...
}
}
```
### 顧客に再試行してもらう
保存されたカードを[更新](https://docs.stripe.com/api/payment_methods/update.md)または[削除](https://docs.stripe.com/api/payment_methods/detach.md)し、支払いを再試行するオプションをリカバリフローで顧客に提供します。最初の支払いを受け付けるのと同じ手順に従いますが、1 つ異なる点があります。元の失敗した PaymentIntent を*確定* (Confirming a PaymentIntent indicates that the customer intends to pay with the current or provided payment method. Upon confirmation, the PaymentIntent attempts to initiate a payment)するために新しい支払いインテントを作成するのではなく、その [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) を再利用します。
認証が必要なために支払いが失敗した場合は、新しい支払い方法を作成するのではなく、既存の *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) を使用して再試行してください。
#### Swift
```swift
func startRecoveryFlow(clientSecret: String) {
// ...continued from previous step
// Reuse the existing PaymentIntent's client secret
let paymentIntentParams = STPPaymentIntentParams(clientSecret: clientSecret)
if paymentIntent.lastPaymentError.code == STPPaymentIntentLastPaymentErrorCodeAuthenticationFailure {
// Payment failed because authentication is required, reuse the PaymentMethod
paymentIntentParams.paymentMethodId = paymentIntent.lastPaymentError.paymentMethod.stripeId
} else {
// Collect a new PaymentMethod from the customer...
}
// Submit the payment...
}
```
## 組み込みをテストする
ここまでで、以下を実行する組み込みが完成しています。
1. SetupIntent を使用して、顧客に請求することなくカード詳細を収集・保存する
1. オフセッションでカードに請求し、支払い拒否と認証リクエストを処理するリカバリーフローが備わっている
この組み込みの稼働準備ができていることを確認するために使用できるいくつかのテストカードがあります。任意のセキュリティコード、郵便番号、および今後の有効期限を指定して使用します。
| 番号 | 説明 |
| ---------------- | --------------------------------------------------------------------------------------- |
| 4242424242424242 | 成功し、支払いがすぐに処理されます。 |
| 4000002500003155 | 初めての購入には認証が必要ですが、カードに `setup_future_usage` の設定があれば、以降の支払い (オフセッションの支払いを含む) に成功します。 |
| 4000002760003184 | 初めての購入には認証が必要で、以降の支払い (オフセッションの支払いを含む) には失敗し、支払い拒否コード `authentication_required` が返されます。 |
| 4000008260003178 | 初めての購入には認証が必要で、以降の支払い (オフセッションの支払いを含む) には失敗し、支払い拒否コード `insufficient_funds` が返されます。 |
| 4000000000009995 | (初めての購入を含め) 常に失敗し、支払い拒否コード `insufficient_funds` が返されます。 |
[テストカード](https://docs.stripe.com/testing.md)の全一覧をご覧ください。
# Android
> This is a Android for when platform is android. View the full page at https://docs.stripe.com/payments/save-and-reuse-cards-only?platform=android.
> [将来の支払いの設定](https://docs.stripe.com/payments/mobile/set-up-future-payments.md)ガイドに従うことをお勧めします。このガイドは、手動によるサーバー側の確定を行う必要がある場合、または構築済みのシステムで決済手段を別途提示する必要がある場合にのみ使用してください。すでに Elements の実装が完了している場合は、[Payment Element 移行ガイド](https://docs.stripe.com/payments/payment-element/migration.md)をご覧ください。
[Setup Intents API](https://docs.stripe.com/api/setup_intents.md) を使用すると、初回の支払いなしで顧客のカードを保存することができます。これは、今すぐ顧客をアカウント登録して支払いを設定し、将来顧客がオフラインの際に請求するときに役立ちます。
この組み込みを使用して、継続支払いを設定したり、最終金額が後で (顧客がサービスを受け取った後などに) 決定される 1 回限りの支払いを作成します。
> このガイドのステップは、GitHub で完全に実装されています。[リポジトリ](https://github.com/stripe-samples/mobile-saving-card-without-payment)のクローンを作成し、[手順](https://github.com/stripe-samples/mobile-saving-card-without-payment#how-to-run)に従ってデモ用のアプリを実行します。
## Stripe を設定する
まず、Stripe アカウントが必要です。[今すぐ登録](https://dashboard.stripe.com/register)してください。
### サーバー側
この接続方法では、Stripe API と通信するエンドポイントがサーバー上に必要です。サーバーから Stripe API にアクセスするには、Stripe の公式ライブラリーを使用します。
#### Ruby
```bash
# Available as a gem
sudo gem install stripe
```
```ruby
# If you use bundler, you can add this line to your Gemfile
gem 'stripe'
```
### クライアント側
[Stripe Android SDK](https://github.com/stripe/stripe-android) はオープンソースであり、[詳細なドキュメントが提供されています](https://stripe.dev/stripe-android/)。
SDK をインストールするには、[app/build.gradle](https://developer.android.com/studio/build/dependencies) ファイルの `dependencies` ブロックに `stripe-android` を追加します。
#### Kotlin
```kotlin
plugins {
id("com.android.application")
}
android { ... }
dependencies {
// ...
// Stripe Android SDK
implementation("com.stripe:stripe-android:23.2.0")
// Include the financial connections SDK to support US bank account as a payment method
implementation("com.stripe:financial-connections:23.2.0")
}
```
> SDK の最新リリースおよび過去バージョンの詳細については、GitHub の [Releases](https://github.com/stripe/stripe-android/releases) ページをご覧ください。新しいリリースの公開時に通知を受け取るには、[リポジトリのリリースを確認](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository)してください。
Stripe の[公開可能キー](https://dashboard.stripe.com/apikeys)を使用して SDK を設定し、 `Application` サブクラスなどで、Stripe API へのリクエストを実行できるようにします。
#### Kotlin
```kotlin
import com.stripe.android.PaymentConfiguration
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
PaymentConfiguration.init(
applicationContext,
"<>"
)
}
}
```
> テストおよび開発時には[テストキー](https://docs.stripe.com/keys.md#obtain-api-keys)を使用し、アプリの公開時には[本番環境](https://docs.stripe.com/keys.md#test-live-modes)キーを使用します。
## 設定前に Customer を作成する [サーバー側]
将来の支払いに備えてカードを設定するには、カードを *Customer (顧客)* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) に関連付ける必要があります。顧客がビジネスでアカウントを作成する際に、Customer オブジェクトを作成します。Customer オブジェクトを使用すると、支払い方法を再利用したり、複数の支払いを追跡したりできます。
> #### Accounts v2 API を使用した顧客の表現
>
> 導入で [customer-configured Accounts](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) を使用している場合は、コード例内の `Customer` とイベント参照を、対応する Accounts v2 API リファレンスに置き換えてください。詳細については、[Account オブジェクトで顧客を表す](https://docs.stripe.com/connect/use-accounts-as-customers.md)をご覧ください。
```curl
curl https://api.stripe.com/v1/customers \
-u "<>:" \
-d "name=Jenny Rosen" \
--data-urlencode "email=jennyrosen@example.com"
```
作成に成功すると、[Customer](https://docs.stripe.com/api/customers/object.md) オブジェクトが返されます。オブジェクトで顧客の `id` を調べて、その値を後で取得できるようにデータベースに保存できます。
これらの顧客は、ダッシュボードの[顧客](https://dashboard.stripe.com/customers)ページで見つけることができます。
## SetupIntent を作成する [サーバー側]
[SetupIntent (支払い方法設定インテント)](https://docs.stripe.com/api/setup_intents.md) は、将来の支払いに備えて支払い方法を設定するという意図を示すオブジェクトです。
SetupIntent オブジェクトには、[client secret](https://docs.stripe.com/api/setup_intents/object.md#setup_intent_object-client_secret) が含まれています。これは、お客様のアプリに渡す一意のキーです。client secret により、`customer` などの機密情報を非表示にすると同時に、設定の確認や支払い方法の詳細の更新などの一定のアクションをクライアント側で実行できます。client secret を使用すると、クレジットカードネットワークを使ってカード詳細を検証および認証できます。client secret は機密情報ですので、ログに記録したり、URL に埋め込んだり、当該の顧客以外に漏洩することがないようにしてください。
### サーバー側
サーバー側で SetupIntent を作成し、その client secret をアプリに返すエンドポイントを作成します。
#### curl
```bash
curl https://api.stripe.com/v1/setup_intents/ \
-u <>: \
-d "customer"="{{CUSTOMER_ID}}"
```
顧客がチェックアウトフローでオンセッション時にのみ、今後の支払いでカードを使用する場合、[usage](https://docs.stripe.com/api/setup_intents/object.md#setup_intent_object-usage) パラメータを *on\_session* (A payment is described as on-session if it occurs while the customer is actively in your checkout flow and able to authenticate the payment method) に設定して、オーソリ率を改善します。
### クライアント側
クライアント側でサーバーの SetupIntent をリクエストします。
#### Kotlin
```kotlin
class CheckoutActivity : AppCompatActivity() {
private lateinit var setupIntentClientSecret: String
private fun loadPage() {
// Request a SetupIntent from your server and store its client secret
// Click View full sample to see a complete implementation
}
}
```
## カード詳細を収集する [クライアント側]
顧客が支払いフォームを送信したら、SDK が提供するドロップイン UI コンポーネント、[CardInputWidget](https://stripe.dev/stripe-android/payments-core/com.stripe.android.view/-card-input-widget/index.html) を使用してカード情報を収集します。このコンポーネントは、カード番号、有効期限、セキュリティコード、郵便番号を収集します。

> 特にヨーロッパでは、カードの再利用に関する規制があるため、カード詳細を保存して今後のオフセッションの支払いに使用する際は、カードを保存するための [許可を取得](https://docs.stripe.com/strong-customer-authentication.md#sca-enforcement) します。カードをどのように使用するかをユーザーに知らせるテキストを決済フローに含めてください。
カード詳細を取得するには、`getPaymentMethodCard` メソッドを呼び出します。収集した情報を新しい [PaymentMethodCreateParams](https://stripe.dev/stripe-android/payments-core/com.stripe.android.model/-payment-method-create-params/index.html) と `PaymentMethod.BillingDetails` のインスタンスに渡して、`ConfirmSetupIntentParams` インスタンスを作成します。
#### Kotlin
```kotlin
// Collect card details
val cardInputWidget =
findViewById(R.id.cardInputWidget)
val paymentMethodCard = cardInputWidget.paymentMethodCard
// Later, you will need to attach the PaymentMethod to the Customer it belongs to.
// This example collects the customer's email to know which customer the PaymentMethod belongs to, but your app might use an account id, session cookie, and so on.
val emailInput = findViewById(R.id.emailInput)
val billingDetails = PaymentMethod.BillingDetails.Builder()
.setEmail((emailInput.text ?: "").toString())
.build()
// Create SetupIntent confirm parameters with the above
if (paymentMethodCard != null) {
val paymentMethodParams = PaymentMethodCreateParams
.create(paymentMethodCard, billingDetails, null)
val confirmParams = ConfirmSetupIntentParams
.create(paymentMethodParams, setupIntentClientSecret)
lifecycleScope.launch {
paymentLauncher.confirm(confirmParams)
}
}
```
セットアップを完了するには`SetupIntentParams` オブジェクトを現在の Activity とともに [PaymentLauncher confirm](https://stripe.dev/stripe-android/payments-core/com.stripe.android.payments.paymentlauncher/-payment-launcher/index.html#74063765%2FFunctions%2F-1622557690) に渡します。SetupIntent は、顧客が使用しているカード情報がネットワーク上で有効であることを確認します。ただし、自動確認が常に行われるわけではありません。詳細は[支払いをせずにクレジットカードの有効性を確認する](https://support.stripe.com/questions/check-if-a-card-is-valid-without-a-charge)を参照してください。また、長期間保持され未処理の SetupIntent は`PaymentLauncher#confirm()` を呼び出す時点で無効になっている可能性があるため、管理しないでください。
一部の決済手段では、支払いを完了するために[追加の認証手順](https://docs.stripe.com/payments/payment-intents/verifying-status.md#next-actions)が必要です。SDK は、支払いの確認と認証のフローを管理しますが、これには認証に必要な追加の画面の表示が含まれる場合があります。*3D セキュア* (3D Secure (3DS) provides an additional layer of authentication for credit card transactions that protects businesses from liability for fraudulent card payments)認証と認証体験のカスタマイズについて、詳細は [Android での 3D セキュア認証のサポート](https://docs.stripe.com/payments/3d-secure.md?platform=android)を参照してください。
フローの結果は、指定されたコールバック (ここでは `onPaymentResult`) を介して呼び出し元のアクティビティに返されます。[PaymentLauncher](https://stripe.dev/stripe-android/payments-core/com.stripe.android.payments.paymentlauncher/-payment-launcher/index.html) によって返される [PaymentResult](https://stripe.dev/stripe-android/payments-core/com.stripe.android.payments.paymentlauncher/-payment-result/index.html) には、次のタイプがあります。
- `Completed`: 確定または認証に成功した
- `Canceled`: 必要な認証が顧客によってキャンセルされた
- `Failed`: 認証の試行が失敗し、[throwable](https://stripe.dev/stripe-android/payments-core/com.stripe.android.payments.paymentlauncher/-payment-result/-failed/index.html#257609069%2FProperties%2F-1622557690) によって理由が提供される
#### Kotlin
```kotlin
private fun onPaymentResult(paymentResult: PaymentResult) {
var title = ""
var message = ""
var restartDemo = false
when (paymentResult) {
is PaymentResult.Completed -> {
title = "Setup Completed"
restartDemo = true
}
is PaymentResult.Canceled -> {
title = "Setup Canceled"
}
is PaymentResult.Failed -> {
title = "Setup Failed"
message = paymentResult.throwable.message!!
}
}
displayAlert(title, message, restartDemo)
}
```
以上でカード詳細を収集して認証リクエストを処理するフローができました。認証プロセスをテストするには、任意のセキュリティコード、郵便番号、および有効期限を指定して、テストカード `4000 0025 0000 3155` を使用します。
SetupIntent が成功すると、(`setupIntent.getPaymentMethodId()` で) 生成された PaymentMethod ID が、指定された Customer に保存されます。
## 保存されたカードに後で請求する [サーバー側]
顧客にオフセッションで支払いを行う準備ができたら、顧客 ID と PaymentMethod ID を使用して、PaymentIntent を作成します。支払いするクレジットカードを見つけるには、顧客に関連付けられた PaymentMethod を[リスト](https://docs.stripe.com/api/payment_methods/list.md)します。
#### Accounts v2
```curl
curl -G https://api.stripe.com/v1/payment_methods \
-u "<>:" \
-d "customer_account={{CUSTOMERACCOUNT_ID}}" \
-d type=card
```
#### Customers v1
```curl
curl -G https://api.stripe.com/v1/payment_methods \
-u "<>:" \
-d "customer={{CUSTOMER_ID}}" \
-d type=card
```
Customer ID と PaymentMethod ID を取得したら、支払いの金額と通貨を使用して PaymentIntent を作成します。下記のパラメータを設定し、オフセッションの支払いを行います。
- [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) を `true` に設定して、支払いの実行時に顧客が決済フローに存在しないことを示します。これにより、認証が必要な場合は PaymentIntent からエラーが返されます。
- PaymentIntent の [confirm](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) プロパティの値を `true` に設定します。これにより、PaymentIntent が作成されると直ちに確定されます。
- [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) を PaymentMethod の ID に設定し、[customer](https://docs.stripe.com/api.md#create_payment_intent-customer) を Customer の ID に設定します。
#### curl
```bash
curl https://api.stripe.com/v1/payment_intents \
-u <>: \
-d amount=1099 \
-d currency=usd \-d customer="{{CUSTOMER_ID}}" \
-d payment_method="{{PAYMENT_METHOD_ID}}" \
-d off_session=true \
-d confirm=true
```
PaymentIntent の [status プロパティ](https://docs.stripe.com/payments/paymentintents/lifecycle.md)を調べ、支払いが成功したことを確認します。支払いの試行が成功した場合、PaymentIntent のステータスが `succeeded` になり、*オフセッションの支払い* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information)が完了します。
### リカバリフローを開始する
PaymentIntent に他のステータスがある場合、決済は成功せず、リクエストは失敗します。決済を完了するために (メール、テキスト、プッシュ通知などで) アプリケーションに戻るように顧客に通知します。決済が最初に失敗した理由を示し、顧客が再試行できるようにするリカバリフローをアプリで作成することをお勧めします。
リカバリフローで *client secret* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) を使用して PaymentIntent を取得します。PaymentIntent の [lastPaymentError](https://stripe.dev/stripe-android/payments-core/com.stripe.android.model/-payment-intent/index.html#com.stripe.android.model/PaymentIntent/lastPaymentError/#/PointingToDeclaration/) を確認して、支払いの試行が失敗した理由を調べます。カードエラーの場合、最後の支払いエラーの[メッセージ](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-last_payment_error-message)をユーザーに表示できます。それ以外の場合は、一般的な失敗メッセージを表示できます。
#### Kotlin
```kotlin
fun startRecoveryFlow(clientSecret: String) {
val stripe = Stripe(
applicationContext,
PaymentConfiguration.getInstance(applicationContext).publishableKey
)
lifecycleScope.launch {
runCatching {
stripe.retrievePaymentIntent(clientSecret)
}.fold(
onSuccess = { paymentIntent ->
var failureReason =
"Payment failed, try again" // Default to a generic error message
paymentIntent.lastPaymentError?.let { lastPaymentError ->
if (lastPaymentError.type == PaymentIntent.Error.Type.CardError) {
lastPaymentError.message?.let { errorMessage ->
failureReason = errorMessage
// Display the failure reason to your customer
}
}
}
},
onFailure = {
// Handle error
}
)
}
}
```
### 顧客に再試行してもらう
保存されたカードを[更新](https://docs.stripe.com/api/payment_methods/update.md)または[削除](https://docs.stripe.com/api/payment_methods/detach.md)し、支払いを再試行するオプションをリカバリフローで顧客に提供します。最初の支払いを受け付けるのと同じ手順に従いますが、1 つ異なる点があります。元の失敗した PaymentIntent を*確定* (Confirming a PaymentIntent indicates that the customer intends to pay with the current or provided payment method. Upon confirmation, the PaymentIntent attempts to initiate a payment)するために新しい支払いインテントを作成するのではなく、その [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) を再利用します。
認証が必要なために支払いが失敗した場合は、新しい支払い方法を作成するのではなく、既存の *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) を使用して再試行してください。
#### Kotlin
```kotlin
fun startRecoveryFlow(clientSecret: String) {
// ...continued from previous step
val paymentConfiguration = PaymentConfiguration.getInstance(applicationContext)
val paymentLauncher = PaymentLauncher.Companion.create(
this,
paymentConfiguration.publishableKey,
paymentConfiguration.stripeAccountId,
::onPaymentResult
)
val lastPaymentError = paymentIntent.lastPaymentError
val lastPaymentMethodId = lastPaymentError.paymentMethod?.id
if (lastPaymentError?.code == "authentication_required" && lastPaymentMethodId != null) {
// Payment failed because authentication is required, reuse the PaymentMethod
val paymentIntentParams =
ConfirmPaymentIntentParams.createWithPaymentMethodId(
lastPaymentMethodId,
clientSecret // Reuse the existing PaymentIntent
)
// Submit the payment...
paymentLauncher.confirm(paymentIntentParams)
} else {
// Collect a new PaymentMethod from the customer...
}
}
```
## 組み込みをテストする
ここまでで、以下を実行する組み込みが完成しています。
1. SetupIntent を使用して、顧客に請求することなくカード詳細を収集・保存する
1. オフセッションでカードに請求し、支払い拒否と認証リクエストを処理するリカバリーフローが備わっている
この組み込みの稼働準備ができていることを確認するために使用できるいくつかのテストカードがあります。任意のセキュリティコード、郵便番号、および今後の有効期限を指定して使用します。
| 番号 | 説明 |
| ---------------- | --------------------------------------------------------------------------------------- |
| 4242424242424242 | 成功し、支払いがすぐに処理されます。 |
| 4000002500003155 | 初めての購入には認証が必要ですが、カードに `setup_future_usage` の設定があれば、以降の支払い (オフセッションの支払いを含む) に成功します。 |
| 4000002760003184 | 初めての購入には認証が必要で、以降の支払い (オフセッションの支払いを含む) には失敗し、支払い拒否コード `authentication_required` が返されます。 |
| 4000008260003178 | 初めての購入には認証が必要で、以降の支払い (オフセッションの支払いを含む) には失敗し、支払い拒否コード `insufficient_funds` が返されます。 |
| 4000000000009995 | (初めての購入を含め) 常に失敗し、支払い拒否コード `insufficient_funds` が返されます。 |
[テストカード](https://docs.stripe.com/testing.md)の全一覧をご覧ください。
# React Native
> This is a React Native for when platform is react-native. View the full page at https://docs.stripe.com/payments/save-and-reuse-cards-only?platform=react-native.
> [将来の支払いの設定](https://docs.stripe.com/payments/mobile/set-up-future-payments.md)ガイドに従うことをお勧めします。このガイドは、手動によるサーバー側の確定を行う必要がある場合、または構築済みのシステムで決済手段を別途提示する必要がある場合にのみ使用してください。すでに Elements の実装が完了している場合は、[Payment Element 移行ガイド](https://docs.stripe.com/payments/payment-element/migration.md)をご覧ください。
[Setup Intents API](https://docs.stripe.com/api/setup_intents.md) を使用すると、初回の支払いなしで顧客のカードを保存することができます。これは、今すぐ顧客をアカウント登録して支払いを設定し、将来顧客がオフラインの際に請求するときに役立ちます。
この組み込みを使用して、継続支払いを設定したり、最終金額が後で (顧客がサービスを受け取った後などに) 決定される 1 回限りの支払いを作成します。
## Stripe を設定する [サーバ側] [クライアント側]
### サーバ側
この組み込みには、Stripe API と通信するエンドポイントがサーバ上に必要です。Stripe の公式ライブラリを使用して、サーバから Stripe API にアクセスします。
#### Ruby
```bash
# Available as a gem
sudo gem install stripe
```
```ruby
# If you use bundler, you can add this line to your Gemfile
gem 'stripe'
```
### クライアント側
[React Native SDK](https://github.com/stripe/stripe-react-native) はオープンソースであり、詳細なドキュメントが提供されています。内部では、[ネイティブの iOS](https://github.com/stripe/stripe-ios) および [Android](https://github.com/stripe/stripe-android) の SDK を使用します。Stripe の React Native SDK をインストールするには、プロジェクトのディレクトリーで (使用するパッケージマネージャーによって異なる) 次のいずれかのコマンドを実行します。
#### yarn
```bash
yarn add @stripe/stripe-react-native
```
#### npm
```bash
npm install @stripe/stripe-react-native
```
次に、その他の必要な依存関係をインストールします。
- iOS の場合は、**ios** ディレクトリに移動して `pod install` を実行し、必要なネイティブ依存関係もインストールします。
- Android の場合は、依存関係をインストールする必要はありません。
> [公式の TypeScript ガイド](https://reactnative.dev/docs/typescript#adding-typescript-to-an-existing-project)に従って TypeScript のサポートを追加することをお勧めします。
### Stripe の初期化
React Native アプリで Stripe を初期化するには、決済画面を `StripeProvider` コンポーネントでラップするか、`initStripe` 初期化メソッドを使用します。`publishableKey` の API [公開可能キー](https://docs.stripe.com/keys.md#obtain-api-keys)のみが必要です。次の例は、`StripeProvider` コンポーネントを使用して Stripe を初期化する方法を示しています。
```jsx
import { useState, useEffect } from 'react';
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 (
{/* Your app code here */}
);
}
```
> テストおよび開発時には API の[テストキー](https://docs.stripe.com/keys.md#obtain-api-keys)を使用し、アプリの公開時には[本番環境](https://docs.stripe.com/keys.md#test-live-modes)キーを使用します。
## 設定前に Customer を作成する [サーバー側]
将来の支払いに備えてカードを設定するには、カードを *Customer (顧客)* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) に関連付ける必要があります。顧客がビジネスでアカウントを作成する際に、Customer オブジェクトを作成します。Customer オブジェクトを使用すると、支払い方法を再利用したり、複数の支払いを追跡したりできます。
> #### Accounts v2 API を使用した顧客の表現
>
> 導入で [customer-configured Accounts](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) を使用している場合は、コード例内の `Customer` とイベント参照を、対応する Accounts v2 API リファレンスに置き換えてください。詳細については、[Account オブジェクトで顧客を表す](https://docs.stripe.com/connect/use-accounts-as-customers.md)をご覧ください。
```curl
curl https://api.stripe.com/v1/customers \
-u "<>:" \
-d "name=Jenny Rosen" \
--data-urlencode "email=jennyrosen@example.com"
```
作成に成功すると、[Customer](https://docs.stripe.com/api/customers/object.md) オブジェクトが返されます。オブジェクトで顧客の `id` を調べて、その値を後で取得できるようにデータベースに保存できます。
これらの顧客は、ダッシュボードの[顧客](https://dashboard.stripe.com/customers)ページで見つけることができます。
## SetupIntent を作成する [サーバー側]
[SetupIntent (支払い方法設定インテント)](https://docs.stripe.com/api/setup_intents.md) は、将来の支払いに備えて支払い方法を設定するという意図を示すオブジェクトです。SetupIntent オブジェクトには、アプリに渡すための一意のキーである、[client secret](https://docs.stripe.com/api/setup_intents/object.md#setup_intent_object-client_secret) が格納されます。
client secret を使用することで、`customer` のような機密情報を保護すると同時に、設定の確認や支払い方法の詳細の更新などの一定のアクションをクライアント側で実行できるようになります。client secret を使用すると、クレジットカードネットワークを利用してカード詳細を検証および認証できます。client secret は機密情報なので、ログに記録したり、URL に埋め込んだり、当該の顧客以外に漏洩することがないようにしてください。
### サーバー側
サーバー側で SetupIntent を作成し、その client secret をアプリに返すエンドポイントを作成します。
#### curl
```bash
curl https://api.stripe.com/v1/setup_intents/ \
-u <>: \
-d "customer"="{{CUSTOMER_ID}}"
```
顧客がチェックアウトフローでオンセッション時にのみ、今後の支払いでカードを使用する場合、[usage](https://docs.stripe.com/api/setup_intents/object.md#setup_intent_object-usage) パラメータを *on\_session* (A payment is described as on-session if it occurs while the customer is actively in your checkout flow and able to authenticate the payment method) に設定して、オーソリ率を改善します。
## カード詳細を収集する [クライアント側]
カード番号、有効期限、セキュリティコード、郵便番号を収集する、SDK が提供する UI コンポーネント、`CardField` を使用して、クライアント側でカード情報を安全に収集します。

`CardField` コンポーネントを支払い画面に追加することで、顧客からカード詳細を安全に収集します。`onCardChange` コールバックを使用して、カードのブランドや詳細情報の欠落の有無など、カードに関する機密性の低い情報を検査します。
```javascript
import { CardField, useStripe } from '@stripe/stripe-react-native';
function PaymentScreen() {
// ...
return (
{
console.log('cardDetails', cardDetails);
}}
onFocus={(focusedField) => {
console.log('focusField', focusedField);
}}
/>
);
}
```
> 特にヨーロッパでは、カードの再利用に関する規制があるため、カード詳細を保存して今後の *オフセッションの支払い* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information) に使用する際は、カードを保存するための [許可を取得](https://docs.stripe.com/strong-customer-authentication.md#sca-enforcement) します。カードをどのように使用するかを顧客に知らせるテキストを決済フローに含めてください。
設定を完了するには、顧客のカードと請求情報を `confirmSetupIntent` に渡します。このメソッドには、`useConfirmSetupIntent` フックまたは `useStripe` フックを使用してアクセスできます。
```javascript
function PaymentScreen() {
// ...
const { confirmSetupIntent, loading } = useConfirmSetupIntent();
// ...
const handlePayPress = async () => {
// Gather the customer's billing information (for example, email)
const billingDetails: BillingDetails = {
email: 'jenny.rosen@example.com',
};
// Create a setup intent on the backend
const clientSecret = await createSetupIntentOnBackend();
const { setupIntent, error } = await confirmSetupIntent(clientSecret, {
paymentMethodType: 'Card',
paymentMethodData: {
billingDetails,
}
});
if (error) {
//Handle the error
}
// ...
};
return (
// ...
);
}
```
一部の支払い方法では、支払いを完了するために[追加の認証手順](https://docs.stripe.com/payments/payment-intents/verifying-status.md#next-actions)が必要です。SDK が、支払いの確定と認証フローを管理します。これには、認証に必要な追加の画面の表示が含まれる場合があります。認証プロセスをテストするには、テストカード `4000 0025 0000 3155` を、セキュリティコード、郵便番号、および有効期限とともに使用します。
`SetupIntent` が成功すると、(`setupIntent.paymentMethodID` で) 生成された PaymentMethod ID が、指定された `Customer` に保存されます。
## 保存されたカードに後で請求する [サーバー側]
顧客にオフセッションで支払いを行う準備ができたら、顧客 ID と PaymentMethod ID を使用して、PaymentIntent を作成します。支払いするクレジットカードを見つけるには、顧客に関連付けられた PaymentMethod を[リスト](https://docs.stripe.com/api/payment_methods/list.md)します。
#### Accounts v2
```curl
curl -G https://api.stripe.com/v1/payment_methods \
-u "<>:" \
-d "customer_account={{CUSTOMERACCOUNT_ID}}" \
-d type=card
```
#### Customers v1
```curl
curl -G https://api.stripe.com/v1/payment_methods \
-u "<>:" \
-d "customer={{CUSTOMER_ID}}" \
-d type=card
```
Customer ID と PaymentMethod ID を取得したら、支払いの金額と通貨を使用して PaymentIntent を作成します。下記のパラメータを設定し、オフセッションの支払いを行います。
- [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) を `true` に設定して、支払いの実行時に顧客が決済フローに存在しないことを示します。これにより、認証が必要な場合は PaymentIntent からエラーが返されます。
- PaymentIntent の [confirm](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) プロパティの値を `true` に設定します。これにより、PaymentIntent が作成されると直ちに確定されます。
- [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) を PaymentMethod の ID に設定し、[customer](https://docs.stripe.com/api.md#create_payment_intent-customer) を Customer の ID に設定します。
#### curl
```bash
curl https://api.stripe.com/v1/payment_intents \
-u <>: \
-d amount=1099 \
-d currency=usd \-d customer="{{CUSTOMER_ID}}" \
-d payment_method="{{PAYMENT_METHOD_ID}}" \
-d off_session=true \
-d confirm=true
```
### リカバリフローを開始する
PaymentIntent に他のステータスがある場合、支払いは成功せず、リクエストは失敗します。支払いを完了するために (メール、テキスト、プッシュ通知などで) アプリケーションに戻るように顧客に通知します。支払いが最初に失敗した理由を示し、顧客が再試行できるようにするリカバリフローをアプリで作成することをお勧めします。
リカバリフローで *client secret* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) を使用して PaymentIntent を取得します。PaymentIntent の `lastPaymentError` を確認し、支払いの試行が失敗した理由を調べます。カードエラーの場合、支払いエラーの最後の[メッセージ](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-last_payment_error-message)をユーザーに表示できます。それ以外の場合は、汎用の失敗メッセ―ジを表示します。
```javascript
function PaymentScreen() {
// ...
const {retrievePaymentIntent} = useStripe();
// ...
const handleRecoveryFlow = async () => {
const {paymentIntent, error} = await retrievePaymentIntent(clientSecret);
if (error) {
Alert.alert(`Error: ${error.code}`, error.message);
} else if (paymentIntent) {
// Default to a generic error message
let failureReason = 'Payment failed, try again.';
if (paymentIntent.lastPaymentError.type === 'Card') {
failureReason = paymentIntent.lastPaymentError.message;
}
}
};
return (
// ...
);
}
```
### 顧客に再試行してもらう
保存されたカードを[更新](https://docs.stripe.com/api/payment_methods/update.md)または[削除](https://docs.stripe.com/api/payment_methods/detach.md)し、支払いを再試行するオプションをリカバリフローで顧客に提供します。最初の支払いを受け付けるのと同じ手順に従いますが、1 つ異なる点があります。元の失敗した PaymentIntent を*確定* (Confirming a PaymentIntent indicates that the customer intends to pay with the current or provided payment method. Upon confirmation, the PaymentIntent attempts to initiate a payment)するために新しい支払いインテントを作成するのではなく、その [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) を再利用します。
認証が必要なために支払いが失敗した場合は、新しい支払い方法を作成するのではなく、既存の PaymentMethod を使用して再試行してください。
```javascript
function PaymentScreen() {
// ...
const {retrievePaymentIntent} = useStripe();
// ...
const handleRecoveryFlow = async () => {
const {paymentIntent, error} = await retrievePaymentIntent(clientSecret);
if (error) {
Alert.alert(`Error: ${error.code}`, error.message);
} else if (paymentIntent) {
// Default to a generic error message
let failureReason = 'Payment failed, try again.';
if (paymentIntent.lastPaymentError.type === 'Card') {
failureReason = paymentIntent.lastPaymentError.message;
}
// If the last payment error is authentication_required, let the customer
// complete the payment without asking them to reenter their details.
if (paymentIntent.lastPaymentError?.code === 'authentication_required') {
// Let the customer complete the payment with the existing PaymentMethod
const {error} = await confirmPayment(paymentIntent.clientSecret, {
paymentMethodType: 'Card',
paymentMethodData: {
billingDetails,
paymentMethodId: paymentIntent.lastPaymentError?.paymentMethod.id,
},
});
if (error) {
// handle error
}
} else {
// Collect a new PaymentMethod from the customer
}
}
};
return (
// ...
);
}
```
## 組み込みをテストする
ここまでで、以下を実行する組み込みが完成しています。
1. SetupIntent を使用して、顧客に請求することなくカード詳細を収集・保存する
1. オフセッションでカードに請求し、支払い拒否と認証リクエストを処理するリカバリーフローが備わっている
この組み込みの稼働準備ができていることを確認するために使用できるいくつかのテストカードがあります。任意のセキュリティコード、郵便番号、および今後の有効期限を指定して使用します。
| 番号 | 説明 |
| ---------------- | --------------------------------------------------------------------------------------- |
| 4242424242424242 | 成功し、支払いがすぐに処理されます。 |
| 4000002500003155 | 初めての購入には認証が必要ですが、カードに `setup_future_usage` の設定があれば、以降の支払い (オフセッションの支払いを含む) に成功します。 |
| 4000002760003184 | 初めての購入には認証が必要で、以降の支払い (オフセッションの支払いを含む) には失敗し、支払い拒否コード `authentication_required` が返されます。 |
| 4000008260003178 | 初めての購入には認証が必要で、以降の支払い (オフセッションの支払いを含む) には失敗し、支払い拒否コード `insufficient_funds` が返されます。 |
| 4000000000009995 | (初めての購入を含め) 常に失敗し、支払い拒否コード `insufficient_funds` が返されます。 |
[テストカード](https://docs.stripe.com/testing.md)の全一覧をご覧ください。