0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

miriwoお一人様Advent Calendar 2023

Day 22

laravel cashier defaultPaymentMethod()のふるまい

Last updated at Posted at 2023-12-21

概要

laravel cashierが提供する特定のユーザーモデル->defaultPaymentMethod()メソッドのふるまいを簡単にまとめる

メソッド定義場所と内容

当該のメソッドはvendor/laravel/cashier/src/Concerns/ManagesPaymentMethods.phpに定義されている。

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_sourceinvoice_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()を使ったほうが良さそうです。

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?