0
1

Stripe PHP SDK 顧客にデフォルトの支払い方法をアタッチする際の手順で詰まった

Posted at

概要

Stripeの顧客にStripe.jsを使って追加したクレカ情報のPaymentMethodIdを紐づけてデフォルトの支払い方法に設定しようとしていた。一部でめっちゃ詰まったので簡単にまとめておく。

前提

本記事で紹介しているコードは「コピペすれば動く」というものではない。

エラーになるコード

下記はイケてないコードである。

/**
 * 顧客に紐づくデフォルトの支払い方法を更新
 *
 * @param UserObject $userObject
 * @param string $paymentMethodId
 * @return void
 */
private function updateDefaultPaymentMethod(UserObject $userObject, string $paymentMethodId): void
{
    $this->makeStripeClient();
    try {
        // NOTE: 顧客と支払い方法を紐づけ
        $this->attachPaymentMethodToCustomer(paymentMethodId: $paymentMethodId, userObject: $userObject);
        // NOTE: 紐づけた支払い方法をデフォルトに設定
        $this->setDefaultPaymentMethodToCustomer(paymentMethodId: $paymentMethodId, userObject: $userObject);
    } catch (ApiErrorException $e) {
        throw $e;
    }
    return;
}

/**
 * 顧客に支払い方法を紐付ける
 *
 * @param string $paymentMethodId
 * @param UserObject $userObject
 * @return PaymentMethod
 */
private function attachPaymentMethodToCustomer(string $paymentMethodId, UserObject $userObject): PaymentMethod
{
    $this->makeStripeClient();
    try {
        $this->stripeClient->paymentMethods->attach(
            $paymentMethodId,
            [
                'customer' => $userObject->getStripeCustomerId(),
            ]
        );
    } catch (ApiErrorException $e) {
        throw $e;
    }
}

/**
 * 顧客にデフォルトの支払い方法を設定する
 *
 * @param string $paymentMethodId
 * @param UserObject $userObject
 * @return void
 */
private function setDefaultPaymentMethodToCustomer(string $paymentMethodId, UserObject $userObject): void
{
    try {
        $this->updateCustomer(
            userObject: $userObject,
            options: [
                'invoice_settings' => [
                    'default_payment_method' => $paymentMethodId,
                ]
            ]
        );
    } catch (ApiErrorException $e) {
        throw $e;
    }
}

これを実行するとThe customer does not have a payment method with the ID pm_XXXXXXXXXXXXXX. The payment method must be attached to the customer.のようなエラーが出てしまう。
実は原因は単純で、setDefaultPaymentMethodToCustomer()$this->updateCustomer()default_payment_methodに紐づいて渡すPaymentMethodIdはattachPaymentMethodToCustomer()$this->stripeClient->paymentMethods->attach()が返すPaymentMethodのidである必要がある。↑のコードはリクエストでもたらされたPaymentMethodIdをdefault_payment_methodに紐づけて渡してしまっている。ここでエラーになる模様、、!

修正後のコード

下記だと正常に動作した。

/**
 * 顧客に紐づくデフォルトの支払い方法を更新
 *
 * @param UserObject $userObject
 * @param string $paymentMethodId
 * @return void
 */
private function updateDefaultPaymentMethod(UserObject $userObject, string $paymentMethodId): void
{
    $this->makeStripeClient();
    try {
        // NOTE: 顧客と支払い方法を紐づけ
        $paymentMethod = $this->attachPaymentMethodToCustomer(paymentMethodId: $paymentMethodId, userObject: $userObject);
        // NOTE: 紐づけた支払い方法をデフォルトに設定
        $this->setDefaultPaymentMethodToCustomer(paymentMethod: $paymentMethod, userObject: $userObject);
    } catch (ApiErrorException $e) {
        throw $e;
    }
    return;
}

/**
 * 顧客に支払い方法を紐付ける
 *
 * @param string $paymentMethodId
 * @param UserObject $userObject
 * @return PaymentMethod
 */
private function attachPaymentMethodToCustomer(string $paymentMethodId, UserObject $userObject): PaymentMethod
{
    $this->makeStripeClient();
    try {
        $paymentMethod = $this->stripeClient->paymentMethods->attach(
            $paymentMethodId,
            [
                'customer' => $userObject->getStripeCustomerId(),
            ]
        );
    } catch (ApiErrorException $e) {
        throw $e;
    }
    return $paymentMethod;
}

/**
 * 顧客にデフォルトの支払い方法を設定する
 *
 * @param PaymentMethod $paymentMethod
 * @param UserObject $userObject
 * @return void
 */
private function setDefaultPaymentMethodToCustomer(PaymentMethod $paymentMethod, UserObject $userObject): void
{
    try {
        $this->updateCustomer(
            userObject: $userObject,
            options: [
                'invoice_settings' => [
                    'default_payment_method' => $paymentMethod->id,
                ]
            ]
        );
    } catch (ApiErrorException $e) {
        throw $e;
    }
}
0
1
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
1