概要
laravel cashierが提供する特定のユーザーモデル->defaultPaymentMethod()
メソッドのふるまいを簡単にまとめる
メソッド定義場所と内容
当該のメソッドはvendor/laravel/cashier/src/Concerns/ManagesPaymentMethods.php
に定義されている。
/**
* Get the default payment method for the customer.
*
* @return \Laravel\Cashier\PaymentMethod|\Stripe\Card|\Stripe\BankAccount|null
*/
public function defaultPaymentMethod()
{
if (! $this->hasStripeId()) {
return;
}
/** @var \Stripe\Customer */
$customer = $this->asStripeCustomer(['default_source', 'invoice_settings.default_payment_method']);
if ($customer->invoice_settings->default_payment_method) {
return new PaymentMethod($this, $customer->invoice_settings->default_payment_method);
}
// If we can't find a payment method, try to return a legacy source...
return $customer->default_source;
}
PHPDocを確認するとどうやら下記のいずれかが返るらしい
- laravel cashierが定義するPaymentMethodオブジェクト
- StripeのPHP SDKが定義するCardオブジェクト
- StripeのPHP SDKが定義するBankAccount
- null
上記を見た感じ「デフォルトの支払い方法が設定されていない場合nullが返る」と思いそうだが、これは間違いである。
nullが返るのは「当該のユーザーがStripeの顧客IDを持っていないとき」である。
処理を一つ一つ見ていこう
まず下記を見てみる。これは「当該のユーザーがStripeの顧客IDを持っているか」をチェックしている。この場合の「ユーザーがStripeの顧客IDを持っているか」は「usersテーブルのstripe_idカラムがnullか否か」でチェックしている。チェックしているメソッドはvendor/laravel/cashier/src/Concerns/ManagesCustomer.php
に定義されている。(vendorディレクトリに移動し、grep -ilr "function hasStripeId(" ./*
を実行してhasStripeId()のメソッド定義を探した。)
「当該のユーザーがStripeの顧客IDを持っていない」場合、defaultPaymentMethod()はnullを返す。
if (! $this->hasStripeId()) {
return;
}
次の処理に移る
これは単純にusersテーブルのstripe_idの値を使ってStripeの顧客情報を取得している。(ただし、オブションとしてdefault_source
とinvoice_settings.default_payment_method
を指定しているのでCustomerオブジェクトに付随して2種類のデフォルト支払い情報が返されている。)StripeのPHP SDKが定義するCustomerオブジェクトが返される。当該のオブジェクトの元になるクラスはvendor/stripe/stripe-php/lib/Customer.php
で定義されている。
/** @var \Stripe\Customer */
$customer = $this->asStripeCustomer(['default_source', 'invoice_settings.default_payment_method']);
次の処理に移る
これは先に取得したCustomerオブジェクトのinvoice_settings.default_payment_method
の値に注目している。(当該の値の説明は後述する)当該の値がnullではない場合PaymentMethodのオブジェクトを作成して返す。
if ($customer->invoice_settings->default_payment_method) {
return new PaymentMethod($this, $customer->invoice_settings->default_payment_method);
}
最後の処理に移る
これはCustomerオブジェクトのinvoice_settings.default_payment_method
がnullだったので別
のデフォルト支払い情報(default_source)を返している。登録されていない場合nullが入っているっぽいのでnullが返る場合もある。
// If we can't find a payment method, try to return a legacy source...
return $customer->default_source;
invoice_settings.default_payment_methodとdefault_source
invoice_settings.default_payment_method
端的に言うとPayment Intents APIという新しい仕組みを用いて登録されたデフォルトの支払い方法の値が入っている。
基本的にこれから開発する場合はこっちにデフォルトの支払い情報が入っている。
default_source
Charges APIという古い仕組みを用いて登録されたデフォルトの支払い方法の値が入っている。おそらくバージョンの後方互換をもたせるためにこの値も取るようになっている模様、、。
これから開発する人でクレカ情報を登録する場合、まずこのキーにデフォルトの支払い方法の値が入ることは無いと思っていいはず。(特殊なことをやる場合は入るかも・・?)
ざっくりまとめ
defaultPaymentMethod()
がnullを返すパターンは「デフォルトの支払い方法が設定されていない場合」だけではなく「顧客としてStripeに登録されていないとき」も含まれるので注意する。
仕様や要件によるがhasDefaultPaymentMethod()
で先にデフォルトの支払い方法が設定されているかどうかをチェックしたほうが良さそう。
嘘でした
hasPaymentMethod()
を使ったほうが良さそうです。
参考文献