laravel Cashier（Stripe）クレカ情報登録のテストですごい詰まった

## 概要

laravel Cashier（Stripe）のクレカ情報登録時の一連の実装の確認部分で信じられないくらい詰まったので簡単にまとめる。

## 情報

一般的にわかりやすいようにクライアント送信ツールを「Postman」と書いているが実際に筆者が使っているのは「Thunder Client」である。

## クレカ情報登録処理の流れ。

laravelはAPIサーバーとして使っているのでフロントエンドと一体となってクレカ情報は登録する。

```mermaid
sequenceDiagram
		actor user as ユーザー
		participant front as FrontEnd
		participant back as BackEnd
		participant stripe as Stripe
		user->>front: クレカ情報入力<br>登録実行
		front->>back: client secret<br>取得API実行<br>setup intent ID取得
		back->>stripe: 顧客情報取得命令
		stripe->>stripe: 顧客未登録の場合登録
		stripe->>back: 顧客情報
		back->>stripe: 支払い情報<br>設定開始依頼
		stripe->>back: 支払い情報<br>オブジェクト
		back->>front: 支払い情報<br>オブジェクト<br>クライアント<br>シークレット<br>（setupIntentId）<br>返却
		front->>stripe: クレカ情報送信（Stripe.js使用）
		stripe->>front: 支払い方法ID（paymetMethodId）
		front->>back: 支払い方法<br>ユーザー紐づけ<br>API実行
		back->>stripe: 支払い方法<br>ユーザー紐づけ<br>リクエスト
		stripe->>back: 成功可否
		back->>front: 200 ok
		front->>user: 正常登録表示
```

## 詰まった作業

バックエンドのみでPostmanのようなリクエスト送信ツールを使ってクレカ情報が登録できるか手動のテストをしたかった。
上記でいうと「支払い方法ユーザー紐づけAPI実行」がちゃんと動作するかテストしたかった。

## お膳立てをしていく途中で詰まる

試したいAPIを実行するために「setupIntentIDを取得（client secret取得API実行）」 → 「テストのクレカ情報登録（ターミナルから命令）」 → 「試したいAPI実行（支払い方法ユーザー紐づけAPI）」というふうに試そうと思った。

1. 手動でPostmanから「client secret取得API実行」しsetupIntentIdを取得する。
1. 下記の方法のcURLの例を使ってテスト用クレジットカードの登録を試みた。（これが間違いの発端）

    https://stripe.com/docs/api/payment_methods/create?lang=curl

1. ターミナルで上記を実行したところ下記のエラーが出る。簡単に言うと「クレカ情報を平文で送ることはNGだよ、どうしてもやりたいなら下記リンクから方法を調べてね」

    ```
    "error": {
        "message": "Sending credit card numbers directly to the Stripe API is generally unsafe. We suggest you use test tokens that map to the test card you are using, see https://stripe.com/docs/testing. To enable raw card data APIs in test mode, see https://support.stripe.com/questions/enabling-access-to-raw-card-data-apis.",
        "request_log_url": "https://dashboard.stripe.com/test/logs/req_Jt4lXSHTkoy0HV?t=1701707620",
        "type": "invalid_request_error"
    }
    ```

1. 当該リンク先を読むと平文で送信したいならサポートにリクエストしてほしい旨が書かれている。テスト環境 + テストクレカ情報でもNGとのことなのでこの方法はなんかおかしそう。

## テスト用クレカのPAYMENTMETHODからpaymentMethodIdを確認し解決へ、、、

下記にStripeのテスト用クレカ情報がある。これはすでにpayment methodとしてStripeに登録済みのもの。

https://stripe.com/docs/testing?testing-method=payment-methods#visa

自分の今回テストしたいAPI（支払い方法ユーザー紐づけAPI）は`setupIntentId`と`paymentMethodId`をリクエストボディで受け取る。この場合PAYMENTMETHODに記された記載をそのまま`paymentMethodId`に渡してもそもそも「`pm_`から始まる文字列であること」などのバリデーションルールを指定しているので通らない。

下記をターミナルで実行してPAYMENTMETHODからpaymentMethodIdを取得してみる。

```
stripe payment_methods retrieve pm_card_jp
```

下記のように出力された。

```
$ stripe payment_methods retrieve pm_card_jp
{
  "id": "pm_1OJfNdEwNfmSaNN2Mg1gsEhy",
  "object": "payment_method",
  "billing_details": {
    "address": {
      "city": null,
      "country": null,
      "line1": null,
      "line2": null,
      "postal_code": null,
      "state": null
    },
    "email": null,
    "name": null,
    "phone": null
  },
・
・
・
```

これでpm_から始まるpaymentMethodIdを確認することができた。これで「支払い方法ユーザー紐づけAPI」が実行できそう。

無事APIが実行されて下記のようにクレカ情報がテスト環境のStripe画面上でも確認する事ができた。

![顧客_–_DokuPro_test_–_Stripe__テスト_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/bff3d245-29de-d08e-4102-126c01c3ef82.png)

## 教訓

Stripeのテスト用クレカ情報は自分でクレカ登録しようとせず、すでにpayment methodとして登録済みのPAYMENTMETHODを使ってターミナルで`$ stripe payment_methods retrieve PAYMENTMETHOD`を実行してpm_から始まるpaymentMethodIdを取得して使おう。


## 参考文献

https://stripe.com/docs/api/payment_methods/retrieve?lang=cli

https://stripe.com/docs/api/payment_methods/create?lang=curl

https://stripe.com/docs/api/payment_methods/retrieve?lang=cli