# 支払いステータスの更新

支払いステータスを監視および確認して、支払いの成功と失敗に対応できるようにします。

*PaymentIntents* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) は、顧客が実行したアクションまたは支払い方法に応じて更新されます。組み込みでは PaymentIntent を確認することで支払いプロセスのステータスを特定できるため、お客様はビジネスアクションを実行したり、さらなる介入が必要な状態に対応できます。

Stripe ダッシュボードを使用して、支払いの成功などの支払いのステータスをメールで送信するようにアカウントを設定することもできます。それには、[ユーザー設定](https://dashboard.stripe.com/settings/user)で[メール通知](https://docs.stripe.com/get-started/account/teams.md#email-notifications)を変更します。

## クライアントで PaymentIntent ステータスを確認する

[confirmCardPayment](https://docs.stripe.com/js.md#stripe-confirm-card-payment) 関数を使用してクライアントで支払いを完了する際に、返される PaymentIntent を確認して現在のステータスを特定できます。

```javascript
(async () => {
  const {paymentIntent, error} = await stripe.confirmCardPayment(clientSecret);
  if (error) {
    // Handle error here
  } else if (paymentIntent && paymentIntent.status === 'succeeded') {
    // Handle successful payment here
  }
})();
```

以下に、`confirmCardPayment` 関数を使用する際に想定される結果を示します。

| **イベント**          | **発生内容**          | **想定される組み込み**                   |
| ----------------- | ----------------- | ------------------------------- |
| PaymentIntent で解決 | 顧客が決済ページで支払いを完了した | 支払いが成功したことを顧客に通知する              |
| エラーで解決            | 決済ページで顧客の支払いが失敗した | エラーメッセージを表示して、顧客に支払いを再度実行するよう促す |

`confirmCardPayment` によって返される Promise は、支払いプロセスが完了したか、エラーにより失敗したときに解決されます。正常に完了して PaymentIntent が返されると、ステータスは常に `succeeded` (または、[後でキャプチャーする](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md)場合は、`requires_capture`) になります。支払いに認証などの追加のステップが必要な場合、そのステップが完了するかタイムアウトになるまで、Promise は解決されません。

## confirmCardPayment を使用せずにクライアントで PaymentIntent ステータスを確認する

`confirmCardPayment` 関数を使用せずに PaymentIntent のステータスを確認するには、[retrievePaymentIntent](https://docs.stripe.com/js/payment_intents/retrieve_payment_intent) 関数を使用して、*クライアントシークレット* (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)) を渡すことにより、個別にステータスを取得します。

```javascript
(async () => {
  const {paymentIntent} = await stripe.retrievePaymentIntent(clientSecret);
  if (paymentIntent && paymentIntent.status === 'succeeded') {
    // Handle successful payment here
  } else {
    // Handle unsuccessful, processing, or canceled payments and API errors here
  }
})();
```

以下に、確定後の PaymentIntent の[想定されるステータス](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-status)を示します。

| **発生内容**          | **想定される PaymentIntent ステータス** |
| ----------------- | ----------------------------- |
| 顧客が決済ページで支払いを完了した | `succeeded`                   |
| 顧客が決済フローを完了しなかった  | `requires_action`             |
| 決済ページで顧客の支払いが失敗した | `requires_payment_method`     |

[PaymentIntent のステータスの詳細をご覧ください](https://docs.stripe.com/payments/paymentintents/lifecycle.md)。

## Webhook で PaymentIntent を監視する

Stripe は、PaymentIntent のステータスが変化した時にサーバーに *Webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) イベントを送信して通知することできます。この機能は、商品やサービスのフルフィルメントを実行する時期の決定などに利用できます。

顧客が支払いの完了後、フルフィルメントプロセスの開始前にページを離れる可能性があるため、クライアント側で注文の*フルフィルメント* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected)を処理しないようにしてください。クライアント側でフルフィルメントを開始するのではなく、Webhook を使用して `payment_intent.succeeded` イベントを監視し、その完了を非同期で処理します。

> 技術的には、Webhook の代わりにポーリングを使用して、非同期の操作によって発生した変化を監視することも可能です。その場合、そのステータスを確認するために PaymentIntent の取得を繰り返します。ただし、この方法は信頼性がかなり低く、レート制限の問題が発生する可能性があります。Stripe では API リクエストの[レート制限](https://docs.stripe.com/testing.md#rate-limits)を実施しているため、ポーリングを使用する際には注意が必要です。

Webhook イベントを処理するには、サーバーにルートを作成し、[ダッシュボード](https://dashboard.stripe.com/account/webhooks)で対応する Webhook エンドポイントを設定します。Stripe は、支払いが成功した場合は `payment_intent.succeeded` イベントを、支払いが失敗した場合は `payment_intent.payment_failed` イベントを送信します。

Webhook ペイロードには PaymentIntent オブジェクトが含まれます。次の例は、この 2 つのイベントの処理方法を示しています。

#### Ruby

```ruby
require 'sinatra'
require 'stripe'

post '/webhook' do
    payload = request.body.read
    sig_header = request.env['HTTP_STRIPE_SIGNATURE']
    event = nil

    begin
        event = Stripe::Webhook.construct_event(
            payload, sig_header, endpoint_secret
        )
    rescue JSON::ParserError => e
        # Invalid payload
        status 400
        return
    rescue Stripe::SignatureVerificationError => e
        # Invalid signature
        status 400
        return
    end

    case event['type']
    when 'payment_intent.succeeded'
        intent = event['data']['object']
        puts "Succeeded:", intent['id']
        # Fulfill the customer's purchase
    when 'payment_intent.payment_failed'
        intent = event['data']['object']
        error_message = intent['last_payment_error'] && intent['last_payment_error']['message']
        puts "Failed:", intent['id'], error_message
        # Notify the customer that payment failed
    end

    status 200
end
```

支払いに失敗した場合、PaymentIntent の `last_payment_error` プロパティを調査することで詳細を確認できます。顧客に支払いが完了していないことを通知し、別の支払い方法で再実行するように促すことができます。同じ PaymentIntent を再利用して顧客の購入を引き続き追跡します。

### 特定の Webhook イベントを処理する

次のリストは、Webhook イベントの処理方法を示しています。

| イベント                        | 説明                                                                                                                            | 次のステップ                                  |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
| `processing`                | 顧客の決済は Stripe に正常に送信されました。[成功の確認が遅延する](https://docs.stripe.com/payments/payment-methods.md#payment-notification)決済手段にのみ該当します。 | 開始された支払いが成功するか、失敗するかの結果を待ちます。           |
| `succeeded`                 | 顧客の決済が成功しました。                                                                                                                 | 購入された商品やサービスのフルフィルメントを行います。             |
| `amount_capturable_updated` | 顧客の決済がオーソリされ、キャプチャーが可能になりました。                                                                                                 | 決済に利用できる資金をキャプチャーします。                   |
| `payment_failed`            | 顧客の決済がカードネットワークから拒否されたか、有効期限が切れています。                                                                                          | 顧客にメールまたはプッシュ通知で連絡し、別の決済手段を指定するよう依頼します。 |

Webhook をローカルでテストするには、[Stripe CLI](https://docs.stripe.com/stripe-cli.md) を使用できます。Stripe CLI をインストールすると、サーバーにイベントを転送できるようになります。

```bash
stripe listen --forward-to localhost:4242/webhook
Ready! Your webhook signing secret is '{{WEBHOOK_SIGNING_SECRET}}' (^C to quit)
```

[Webhook の設定](https://docs.stripe.com/webhooks.md)についてもっと知る。

## PaymentIntent で支払いを識別する

顧客からの支払いを回収しようとしたときに、PaymentIntent によって [Charge (支払い)](https://docs.stripe.com/api/charges.md) が作成されます。最新の支払いの ID を取得するには、PaymentIntent の [latest_charge](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-latest_charge) プロパティを調べます。

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

intent = client.v1.payment_intents.retrieve('{{PAYMENT_INTENT_ID}}')
latest_charge = intent.latest_charge
```

失敗した支払いも含めて PaymentIntent に関連するすべての支払いを表示するには、[すべての支払いをリスト](https://docs.stripe.com/api/charges/list.md#list_charges-payment_intent)して、`payment_intent​` パラメーターを指定します。

```curl
curl -G https://api.stripe.com/v1/charges \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "payment_intent={{PAYMENTINTENT_ID}}"
```

## 次のアクションを処理する

支払い方法によっては、支払いプロセスの完了に、認証などの追加ステップが必要になります。Stripe.js は PaymentIntent の確定時に追加ステップを自動的に処理しますが、高度な実装では手動での処理が必要になることもあります。

PaymentIntent の [next_action](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action) プロパティーは、支払いを完了するために実装で処理する必要がある次のステップを示します。想定される次のアクションのタイプは、支払い方法ごとに異なる可能性があります。想定される次のアクションの詳細リストについては、[API ドキュメント](https://docs.stripe.com/api.md#payment_intent_object-next_action-type)をご覧ください。

必要な次のアクションの処理方法について、詳細は[支払い方法のドキュメント](https://docs.stripe.com/payments/payment-methods/overview.md)をご覧ください。
