# 銀行の認証なしでカードを保存する

カードの詳細を収集して、後で顧客に請求します。

Stripe では、顧客のカード詳細を収集して後で請求できます。一部の地域では、銀行により、2 段階目の認証 (スマートフォンに送信されたコードの入力など) が要求されます。この追加ステップにより、顧客が Web サイトまたはアプリケーションをアクティブに使用していない場合は、購入の認証ができないためにコンバージョン率が低下します。

アメリカとカナダを中心にして事業を運営している場合は、銀行によって認証が要求されないため、より簡単なこの実装を使用できます。この実装は、カードの保存に認証が必要な国では非準拠となるため、この実装を構築すると、他の国に事業を拡大する場合や他の決済手段を追加する場合に、大幅な変更が必要になります。[認証が必要なカード情報の保存](https://docs.stripe.com/payments/save-and-reuse.md)方法をご確認ください。

> #### 法令遵守
> 
> お客様は、顧客の支払い情報を保存する際の該当する法律、規制、ネットワークのルールのすべてに準拠する責任を負います。たとえば、顧客がお客様のウェブサイトやアプリを積極的には使用していない時期に顧客に請求するなど、将来の利用に備えて顧客の支払い方法を保存する場合が該当します。支払い方法の保存をどのように計画しているかを示す規約をウェブサイトやアプリに追加し、顧客が許可できるようにします。顧客がオフラインのときに請求する予定である場合は、規約に以下の内容も含める必要があります。
> 
> - 指定された取引で顧客の代理として単独の支払いまたは一連の支払いを開始することを許可するという、顧客からお客様への同意。
> - 決済の予想時期と頻度 (例: 定期分割払い、サブスク決済、または不定期のチャージに関する請求かどうか)。
> - 支払い金額の決定方法。
> - 支払い方法をサブスクリプションサービスに使用する場合は、キャンセルに関するポリシー。
> 
> これらの規約に関する顧客の書面による同意の記録を必ず保管してください。

## カード詳細を収集する [クライアント側]

このガイドを参照する前に、Stripe アカウントが必要です。[今すぐ登録](https://dashboard.stripe.com/register)してください。

顧客のカード詳細を収集するための決済ページを構築します。カスタムの決済フォームの構築に利用可能な UI ライブラリである [Stripe Elements](https://docs.stripe.com/payments/elements.md) を使用します。Elements を使用した作業を開始するには、次のスクリプトを使用して、決済ページに Stripe.js ライブラリを組み込みます。

```html
<script src="https://js.stripe.com/endive/stripe.js"></script>
```

常に js.stripe.com から Stripe.js を直接読み込むことにより、PCI への準拠が維持されます。スクリプトをバンドルに含めたり、そのコピーを自身でホストしたりしないでください。

Stripe の[アドバンス不正利用機能](https://docs.stripe.com/radar.md)を最大限に活用するには、このスクリプトを決済画面だけでなく、自社サイトのすべてのページに追加してください。すべてのページにスクリプトを追加することで、ウェブサイトを閲覧するユーザーの不正利用を示唆するような不審な動作を [Stripe が検知できるようになります](https://docs.stripe.com/disputes/prevention/advanced-fraud-detection.md)。

### Elements をページに追加する

顧客からカード詳細を安全に収集するために、Stripe がオンラインで提供する UI コンポーネントは、お客様が直接作成するのではなく、Elements によって作成され、その後決済フォームに配置されます。これらのコンポーネントの挿入先を決定するには、決済フォームで一意の ID を持つ空の DOM 要素 (コンテナー) を作成してください。

```html
<input id="cardholder-name" type="text">
<!-- placeholder for Elements -->
<div id="card-element"></div>
<div id="card-result"></div>
<button id="card-button">Save Card</button>
```

次に、[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 を組み合わせることで、柔軟で複数の入力が可能なカードフォームを実現できます。

> カードの支払い成功率を向上し、不正使用を削減するため、常に郵便番号を収集してください。
> 
> [単一行の 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('<<YOUR_PUBLISHABLE_KEY>>');

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)します。

```javascript
const cardholderName = document.getElementById('cardholder-name');
const cardButton = document.getElementById('card-button');
const resultContainer = document.getElementById('card-result');

cardButton.addEventListener('click', async (ev) => {
  const {paymentMethod, error} = await stripe.createPaymentMethod({
      type: 'card',
      card: cardElement,
      billing_details: {
        name: cardholderName.value,
      },
    }
  );

  if (error) {
    // Display error.message in your UI.
    resultContainer.textContent = error.message;
  } else {
    // You have successfully created a new PaymentMethod
    resultContainer.textContent = "Created payment method: " + paymentMethod.id;
  }
});
```

結果として得られた *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) ID をサーバーに送信します。

## 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'
```

## カードを保存する [サーバー側]

PaymentMethod を *Customer* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) に関連付けることでカードを保存します。`Customer` オブジェクトを使用して、顧客に関する他の情報 (配送の詳細、メールアドレスなど) を格納できます。

```curl
curl https://api.stripe.com/v1/customers \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d payment_method={{PAYMENT_METHOD_ID}}
```

既存の Customer がある場合は、代わりにそのオブジェクトに PaymentMethod を関連付けることがきます。

```curl
curl https://api.stripe.com/v1/payment_methods/{{PAYMENT_METHOD_ID}}/attach \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer={{CUSTOMER_ID}}"
```

この時点で、独自の内部的な顧客の表記がある場合は、この表記に顧客 ID と PaymentMethod ID を関連付けます。

## 保存されたカードに請求する [サーバー側]

準備ができたら、請求する PaymentMethod ID と Customer ID を取得します。これは、両方の ID を自社のデータベースに格納するか、Customer ID を使用して顧客の使用可能なすべての PaymentMethod を検索することで実行できます。

#### Accounts v2

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d type=card
```

#### Customers v1

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer={{CUSTOMER_ID}}" \
  -d type=card
```

PaymentMethod ID と Customer ID を使用して新しい PaymentIntent を作成します。[error_on_requires_action](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-error_on_requires_action) を `true` に設定して、二要素認証など、顧客のアクションを必要とする決済を拒否します。

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "customer={{CUSTOMER_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  -d error_on_requires_action=true \
  -d confirm=true \
  --data-urlencode "return_url=https://example.com/return"
```

支払いが失敗すると、リクエストも 402 HTTP ステータスコードで失敗し、エラーが返されます。アプリケーションに戻って支払いを完了するように (メールを送信するなどして) 顧客に通知する必要があります。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) を確認し、カード発行会社が支払いを拒否した理由を調べます。

## カードエラーを処理する

支払いが失敗したことを顧客に通知し、ステップ 1 で作成した決済フォームに顧客を誘導します。顧客はそこで新しいカード詳細を入力できます。その新しい PaymentMethod ID を自社のサーバーに送信して、Customer オブジェクトに[関連付け](https://docs.stripe.com/api/payment_methods/attach.md)、再度決済を行います。

別の方法として、すでに Customer を作成している場合は、PaymentIntent の作成とカードの保存を 1 回の API コールで実行できます。

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "customer={{CUSTOMER_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  -d error_on_requires_action=true \
  -d confirm=true \
  -d setup_future_usage=on_session \
  --data-urlencode "return_url=https://example.com/return"
```

[setup_future_usage](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-setup_future_usage) を `on_session` に設定すると、不要な認証をトリガーせずにカードを後で使用するために保存することを Stripe に示します。

## 構築したシステムをテストする

Stripe はサンドボックスで使用してさまざまなカードの動作をシミュレーションできる[テストカード](https://docs.stripe.com/testing.md)を提供しています。任意のセキュリティコード、郵便番号、将来の有効期限を指定してこれらのカードを使用してください。

| 番号 | 説明 |
| --- | --- |
| 4242424242424242 | 成功し、支払いがすぐに処理されます。 |
| 4000000000009995 | 常に支払い拒否コード `insufficient_funds` で失敗します。 |
| 4000002500003155 | 認証が必要なため、この導入では、`authentication_required` というコードで拒否されます。 |

## Optional: セキュリティコードの再収集

保存されたクレジットカードで以降の支払いを作成する際には、不正使用防止の追加対策としてカードのセキュリティセキュリティコードを再収集して、ユーザを確認することをお勧めします。

まずサーバーから決済の金額と通貨を使用して PaymentIntent を作成し、[Customer](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer) を顧客の ID に設定します。次に、顧客に関連付けられた PaymentMethod を[一覧表示](https://docs.stripe.com/api/payment_methods/list.md)して、セキュリティコードの再回収のためにどの PaymentMethod をユーザーに対して表示するかを判断します。

PaymentIntent の client secret をブラウザーに渡したら、クライアントで Stripe Elements を使用してセキュリティコード情報を再収集する準備が整います。`cardCvc` Element を使用してユーザーからセキュリティコードの値を再収集し、次に [stripe.confirmCardPayment](https://docs.stripe.com/js.md#stripe-confirm-card-payment) を使用してクライアントからの支払いを確認します。`payment_method` を PaymentMethod ID に、`payment_method_options[card][cvc]` を `cardCvc` Element に設定します。

```javascript
const result = await stripe.confirmCardPayment(clientSecret, {
  payment_method: '{{PAYMENT_METHOD_ID}}',
  payment_method_options: {
    card: {
      cvc: cardCvcElement
    }
  },
});

if (result.error) {
  // Show error to your customer
  console.log(result.error.message);
} else {
  if (result.paymentIntent.status === 'succeeded') {
    // Show a success message to your customer
    // There's a risk of the customer closing the window before callback
    // execution. Set up a webhook or plugin to listen for the
    // payment_intent.succeeded event that handles any business critical
    // post-payment actions.
  }
}
```

セキュリティコードの確認に失敗しても支払いが成功することがあります。これを防ぐには、セキュリティコードの確認に失敗した支払いをブロックする [Radar ルール](https://docs.stripe.com/radar/rules.md#traditional-bank-checks)を設定します。

## カード認証を処理するために組み込みをアップグレードする

この導入では、*決済時に認証を必要とするカードは拒否されます*。ダッシュボードに多くの決済が `Failed` としてリストされるようになった場合は、[導入をアップグレードする](https://docs.stripe.com/payments/payment-intents/upgrade-to-handle-actions.md)タイミングです。Stripe のグローバルな導入では、そのような決済を自動的に拒否するのではなく処理します。
