# カード支払いを回収する

Stripe Terminal を使用したカード支払いの回収ができるように、アプリケーションとバックエンドを準備します。

# JavaScript


> #### スマートリーダーの推奨事項
> 
> [BBPOS WisePOS E リーダー](https://docs.stripe.com/terminal/payments/setup-reader/bbpos-wisepos-e.md)、[Stripe Reader S700/S710](https://docs.stripe.com/terminal/readers/stripe-reader-s700-s710.md)、[Verifone リーダー](https://docs.stripe.com/terminal/payments/setup-reader/verifone.md)などのスマートリーダーでは、JavaScript SDK ではなく[サーバー主導の実装](https://docs.stripe.com/terminal/payments/setup-integration.md?terminal-sdk-platform=server-driven)を使用することをお勧めします。
> 
> JavaScript SDK では、POS とリーダーが、有効なローカル DNS と同じローカルネットワーク上にある必要があります。サーバー主導型の統合では、代わりに Stripe API を使用するため、複雑なネットワーク環境ではよりシンプルになります。ニーズに最適なプラットフォームの選択に役立つ[プラットフォーム比較](https://docs.stripe.com/terminal/payments/setup-reader.md#sdk)をご覧ください。

Payment Intents API を初めて使用する場合には、以下のリソースが役立ちます。

- [Payment Intents API](https://docs.stripe.com/payments/payment-intents.md)
- [PaymentIntent (支払いインテント) オブジェクト](https://docs.stripe.com/api/payment_intents.md)
- [その他の支払いシナリオ](https://docs.stripe.com/payments/more-payment-scenarios.md)

Stripe Terminal で支払いを回収するには、アプリケーションに決済フローを記述する必要があります。Stripe Terminal SDK を使用して、1 つの支払いセッションを表すオブジェクトである [PaymentIntent (支払いインテント)](https://docs.stripe.com/api.md#payment_intents) を作成して更新します。

Terminal の組み込みは支払いプロセスにおける失敗に対応できるように設計されており、支払いプロセスを複数のステップに分割し、各ステップを安全に再試行できるようになっています。

1. [PaymentIntent を作成](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-payment)します。
2. [決済手段を収集する](https://docs.stripe.com/terminal/payments/collect-card-payment.md#collect-payment)支払いを[自動](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-capture_method)と[手動](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md)のどちらでキャプチャーするかを定義できます。
3. [決済を処理](https://docs.stripe.com/terminal/payments/collect-card-payment.md#confirm-payment)します。顧客のカードの承認は、SDK が決済を処理するときに行われます。
4. (オプション) [支払いをキャプチャーする](https://docs.stripe.com/terminal/payments/collect-card-payment.md#capture-payment)

> この実装タイプは、[オフラインのカード決済](https://docs.stripe.com/terminal/features/operate-offline/collect-card-payments.md)に対応していません。

## PaymentIntent を作成する [サーバー側]

支払いを回収する最初のステップは、支払いフローを開始することです。顧客がチェックアウトを開始するとき、アプリケーションは `PaymentIntent` オブジェクトを作成する必要があります。これは、Stripe での新しい支払いセッションを表します。

[テスト金額](https://docs.stripe.com/terminal/references/testing.md#physical-test-cards)を使用して、さまざまな結果を生成してみてください。`00` で終わる金額では、支払いが承認されます。

> #### 拒否されたカードの PaymentIntents を再作成しない
> 
> クレジットカードが拒否された場合は、決済インテントを再作成しないでください。代わりに、同じ決済インテントを再利用して、[二重請求を回避](https://docs.stripe.com/terminal/payments/collect-card-payment.md#avoiding-double-charges)します。

次の例は、サーバで `PaymentIntent` を作成する方法を示しています。

#### curl

```bash
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -d "amount"=1000 \
  -d "currency"="usd" \
  -d "payment_method_types[]"="card_present" \
  -d "capture_method"="manual"
```

Terminal の支払いでは、`payment_method_types` パラメータに `card_present` が含まれている必要があります。

以下のように決済フローを制御できます。

- `card_present` 支払いの支払いフローを完全に制御するには、`capture_method` を `manual` に設定します。これにより、支払いを確定する前に照合ステップを追加できます。
- 1 ステップで支払いのオーソリとキャプチャーを行うには、`capture_method` を `automatic` に設定します。

カナダで Interac の支払いを受け入れるには、`payment_method_types` に `interac_present` も含める必要があります。詳細については、[カナダのドキュメント](https://docs.stripe.com/terminal/payments/regional.md?integration-country=CA)をご覧ください。

`PaymentIntent` には、個々の `PaymentIntent` に固有のキーである [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) が含まれています。client secret を使用するには、これをサーバーで `PaymentIntent` から取得し、[クライアント側に渡す](https://docs.stripe.com/payments/payment-intents.md#passing-to-client)必要があります。

#### Ruby

```ruby
post '/create_payment_intent' do
  intent = # ... Create or retrieve the PaymentIntent
  {client_secret: intent.client_secret}.to_json
end
```

[collectPaymentMethod](https://docs.stripe.com/terminal/references/api/js-sdk.md#collect-payment-method) を呼び出す際に、client secret をパラメーターとして使用します。

決済手段の収集に進むためにクライアント側アプリケーションで必要なものは、`client_secret` だけです。

## 支払い方法を収集する  [クライアント側]

- [collectPaymentMethod (JavaScript)](https://docs.stripe.com/terminal/references/api/js-sdk.md#collect-payment-method)

`PaymentIntent` を作成したら、次のステップは SDK で決済手段を収集することです。

 決済手段を収集するには、アプリがリーダーに接続されている必要があります。アプリが `collectPaymentMethod` を呼び出した後、接続されたリーダーはカードの提示を待ちます。

```javascript
async () => {
  // clientSecret is the client_secret from the PaymentIntent you created in Step 1.
  const result = await terminal.collectPaymentMethod(clientSecret);
  if (result.error) {
    // Placeholder for handling result.error
  } else {
    // Placeholder for processing result.paymentIntent
  }
}
```

この方法では、接続されたカードリーダーを使用して暗号化された決済手段のデータを収集し、その暗号化されたデータをローカルの `PaymentIntent` に関連付けます。

### 支払い方法の詳細をオプションで調査する

- [collectPaymentMethod config_override (JavaScript)](https://docs.stripe.com/terminal/references/api/js-sdk.md#collect-payment-method)

高度なユースケースでは、提示されたカードの支払い方法の詳細を調査し、オーソリ前に自社のビジネスロジックを実行できます。

 `update_payment_intent` パラメーターを使用して、`PaymentMethod` をサーバー側の `PaymentIntent` に関連付けます。このデータは `collectPaymentMethod` レスポンスで返されます。  

```javascript
async () => {
  // clientSecret is the client_secret from the PaymentIntent you created in Step 1.
  const result = await terminal.collectPaymentMethod(clientSecret, {
    config_override: {
      update_payment_intent: true
    }
  });
  if (result.error) {
    // Placeholder for handling result.error
  } else {
    const pm = result.paymentIntent.payment_method
    const card = pm?.card_present ?? pm?.interac_present

    // Placeholder for business logic on card before processing result.paymentIntent
  }
}
```

このメソッドは、収集した暗号化済みの決済手段データを、`PaymentIntent` オブジェクトの更新とともにアタッチします。 [決済を処理する](https://docs.stripe.com/terminal/payments/collect-card-payment.md#confirm-payment)まで、オーソリは不要です。

決済手段を収集したら、30 秒以内に支払いを承認するか、収集をキャンセルする必要があります。

SDK が[オフラインで実行](https://docs.stripe.com/terminal/features/operate-offline/collect-card-payments.md)されている場合、`PaymentIntent` オブジェクトには `paymentMethod` フィールドがありません。

この時点で、カードブランド、口座情報、その他の役立つデータなどの属性にアクセスできます。

Stripe は `wallet.type` 属性で示すとおり、取引でモバイルウォレットが使用されたかどうかを検出するよう試みます。ただし、カード発行会社がモバイルウォレットのリーダーによる識別に対応していない場合、この属性は自動入力されないため、正確な検出は保証されません。[確定](https://docs.stripe.com/terminal/payments/collect-card-payment.md#confirm-payment)ステップでオーソリが行われた後に、Stripe はネットワークから最新の情報を取得し、`wallet.type` を確実に更新します。

### 収集をキャンセルする

#### プログラムによるキャンセル

JavaScript SDK で [cancelCollectPaymentMethod](https://docs.stripe.com/terminal/references/api/js-sdk.md#cancel-collect-payment-method) を呼び出すと、決済手段の収集をキャンセルできます。

#### 顧客によるキャンセル

- [enable_customer_cancellation (JavaScript)](https://docs.stripe.com/terminal/references/api/js-sdk.md#collect-payment-method)

取引の `enable_customer_cancellation` を true に設定すると、スマートリーダーのユーザーにキャンセルボタンが表示されます。

キャンセルボタンをタップすると、現在の取引がキャンセルされます。

```javascript
terminal.collectPaymentMethod(
  clientSecret,
  {
    config_override: {
      enable_customer_cancellation: true,
    }
  }
)
```

### イベントを処理する

> JavaScript SDK は、内蔵ディスプレイを備えた Stripe Reader S700/S710 と BBPOS WisePOS E にのみ対応しています。リーダーが決済手段の収集プロセスのイベントを表示するため、アプリケーションでそれらのイベントをユーザーに表示する必要はありません。取引の決済手段をクリアするには、レジ係がキャンセルキー (❌) を押せます。

## 支払いを確定する [クライアント側]

- [processPayment (JavaScript)](https://docs.stripe.com/terminal/references/api/js-sdk.md#process-payment)

顧客から決済手段を収集したら、次のステップに進み、SDK で支払いを処理します。支払いを続行する準備ができたら、[ステップ 2](https://docs.stripe.com/terminal/payments/collect-card-payment.md#collect-payment) の更新後の `PaymentIntent` を使用して `processPayment` を呼び出します。

- 支払いの手動キャプチャーでは、`processPayment` コールが成功すると、`PaymentIntent` のステータスが `requires_capture` になります。
- 支払いの自動キャプチャーでは、`PaymentIntent` は `succeeded` 状態に移行します。

クライアント側で必ず Terminal SDK を使用して PaymentIntents を確定してください。サーバー側での確定では PIN プロンプトなどの重要なメッセージが無視されるため、取引の失敗につながる可能性があります。

```javascript
async () => {
  const result = await terminal.processPayment(paymentIntent);
  if (result.error) {
    // Placeholder for handling result.error
  } else if (result.paymentIntent) {
    // Placeholder for notifying your backend to capture result.paymentIntent.id
  }
}
```

2 日以内に PaymentIntent を手動でキャプチャーする必要があり、キャプチャーしなければオーソリは期限切れになり、売上は顧客にリリースされます。

### 失敗に対処する

- [Error codes (JavaScript)](https://docs.stripe.com/terminal/references/api/js-sdk.md#error-codes)

 決済の処理に失敗すると、SDK は更新された `PaymentIntent` を含むエラーを返します。アプリケーションは `PaymentIntent` を調べて、エラーへの対処方法を決定する必要があります。

| PaymentIntent のステータス       | 意味                                                 | 解決策                                                                            |
| -------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------ |
| `requires_payment_method`  | 支払い方法が拒否されました                                      | 同じ `PaymentIntent` を使用して `collectPaymentMethod` を再度呼び出し、別の決済手段の収集を試みます。        |
| `requires_confirmation`    | 一時的な接続の問題                                          | 同じ `PaymentIntent` を使用して `processPayment` を再度呼び出し、リクエストを再試行します。                |
| `PaymentIntent` が `nil` です | Stripe へのリクエストがタイムアウトし、`PaymentIntent` のステータスが不明です | 元の `PaymentIntent` の処理を再試行します。新しく作成しないでください。新しく作成すると、カード会員に複数の承認が発生する可能性があります。 |

タイムアウトが複数回、連続して発生する場合、接続に問題がある可能性があります。アプリがインターネットと通信できることを確認してください。

### 二重支払いの防止

`PaymentIntent` オブジェクトは、Stripe での資金移動を可能にします。1 つの取引を表すには、`PaymentIntent` を 1 つ使用します。

カードが (残高不足などのために) 拒否された後、同じ `PaymentIntent` を再利用して、顧客が別のカードで再試行できるようにします。

 `PaymentIntent` を編集する場合は、`collectPaymentMethod` を呼び出してリーダー上の決済情報を更新する必要があります。

 `PaymentIntent` は、Stripe で処理する前に `requires_payment_method` ステータスである必要があります。承認済み、キャプチャー済み、キャンセル済みの `PaymentIntent` はリーダーで処理できません。

## 支払いをキャプチャーする [サーバー側]

[ステップ 1](https://docs.stripe.com/terminal/payments/collect-card-payment.md#create-payment) の `PaymentIntent` の作成時に `capture_method` を `manual` として定義した場合、SDK はオーソリ済みでキャプチャーはされていない `PaymentIntent` をアプリケーションに返します。[オーソリとキャプチャー](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md)の違いについて、詳細を確認してください。

アプリが SDK から確定済みの `PaymentIntent` を受信したら、その支払いをキャプチャーするようにアプリからバックエンドに対して通知するようにしてください。バックエンドにエンドポイントを作成し、`PaymentIntent` ID を受け付け、それをキャプチャーするように Stripe API にリクエストを送信します。

```curl
curl -X POST https://api.stripe.com/v1/payment_intents/{{PAYMENT_INTENT_ID}}/capture \
  -u "<<YOUR_SECRET_KEY>>:"
```

`capture` コールが成功すると、`PaymentIntent` のステータスは `succeeded` になります。

キャプチャーされたプラットフォーム手数料が連結アカウントに対して正確であることを確認するために、支払いを手動でキャプチャーする前にそれぞれの `PaymentIntent` を調べ、必要に応じてプラットフォーム手数料を修正します。

### 支払いを照合する

ビジネスの支払いアクティビティを監視するため、毎日の最後の作業としてサーバで PaymentIntent と内部注文システムを照合することをお勧めします。

`PaymentIntent` のステータスが `requires_capture` のままの場合には、以下の 2 つの可能性があります。

**顧客のカード明細上の不要なオーソリ**

- 原因: ユーザーが取引の途中でアプリの決済フローを中止した
- 解決策:キャプチャーされていない `PaymentIntent` が、サーバーにある完了済みの注文に関連付けられていない場合には、[キャンセル](https://docs.stripe.com/api/payment_intents/cancel.md)できます。キャンセルされた `PaymentIntent` を使用して支払いを実行することはできません。

**顧客からの売上回収が未完了**

- 原因: 支払いをキャプチャーするようにバックエンドに通知する、アプリからのリクエストのエラー
- 解決策:キャプチャーされていない `PaymentIntent` が、サーバにある完了済みの注文に関連付けられており、その注文について他の支払い (現金による支払いなど) を受けていない場合には、この PaymentIntent を[キャプチャー](https://docs.stripe.com/api/payment_intents/capture.md)できます。

### チップを徴収する (アメリカのみ)

アメリカでは、対象となるユーザーは[売上確定時に領収書でチップを受け取る](https://docs.stripe.com/terminal/features/collecting-tips/on-receipt.md)ことができます。

