🍎

Stripe Checkoutのsetup_future_usageについて

2024/04/08に公開

はじめに

株式会社ウェイブCoolmicのエンジニアをしている布施です。
Coolmicは日本のコミックを海外向けに配信するWEBサービスです。

CoolmicではStripeを利用してクレジットカード、Apple Pay、Google Payの決済を実装しています。
この決済機能を修正するにあたり詰まったところがあったので記事にしました。
同様のケースで困っている方の助けになればうれしいです。

サンプルコードは全てRuby(Rails)です。

結論から言うと

Checkoutをmode: "payment"で使う時、setup_future_usageパラメータの使用とApple Pay決済の有効化の両立はできない。

やりたかったこと

以下2点が今回の要件でした。

  • Checkoutでユーザーにクレジットカード、Apple Pay、Google Payの決済手段を提示する
  • ユーザーがクレジットカード決済を行なった場合カード情報を保存し、次回の決済時にはカード情報を自動入力する

Checkout

CheckoutはStripeが用意する決済画面です。以下の3つのモードがあります。

  • payment: 一回限りの決済
  • subscription: サブスクリプションの購入
  • setup: 決済方法を保存する

今回はpaymentモードの話です。
payment_method_typesパラメータを設定しない場合、Stripe Dashboardで有効に設定している決済手段が自動で表示されます。
CoolmicではStripe Dashboardで設定していたので、端末が対応していればCheckoutの画面にApple Pay/Google Payのボタンが自動で表示されるようになっていました。

コードはこんな感じです。

session = Stripe::Checkout::Session.create(
  {
    success_url: success_url,
    cancel_url: cancel_url,
    mode: "payment",
    customer: customer_id,
    line_items: [
      # 省略
    ],
  }
)
redirect_to session.url, allow_other_host: true

setup_future_usage

あとはクレジットカード決済時にカード情報が保存されればOKです。
これを実現するためにはpayment_intent_data.setup_future_usageパラメータを設定する必要があります。

session = Stripe::Checkout::Session.create(
  {
    # 省略
    mode: "payment",
    payment_intent_data: {
      setup_future_usage: "off_session",
    },
  }
)
redirect_to session.url, allow_other_host: true

しかし、
このパラメータを設定するとCheckoutの画面にApple Payボタンが表示されなくなります。
StripeのDiscordサーバーで質問してみたところ、これはそういう仕様のようです。😭
ちなみにpayment_intent_data.setup_future_usageが設定されていてもGoogle Payのボタンは表示されます。
↓discordの回答

・・・。それならこれはどうだ!

Checkoutには決済手段ごとに詳細な設定ができるpayment_method_optionsパラメータがあります。
その中にpayment_method_options.card.setup_future_usageがあったのでこちらも試してみると・・・、理想の挙動になりました!(Apple Payボタンは表示され、カード決済をすると次回はカード情報が自動入力されている)

session = Stripe::Checkout::Session.create(
  {
    # 省略
    mode: "payment",
    payment_method_options: {
      card: {
        setup_future_usage: "off_session",
      },
    },
  }
)
redirect_to session.url, allow_other_host: true

念のためDiscordで聞いてみると・・・、

バグだったようです😇
当初の要件は実現が難しくなったので変更することになりました・・・

最後に

StripeはAPIがとても充実しているので今回も多分できるだろ!と、
調査が不十分なまま実装を進めてしまいました。
反省して以後気をつけたいと思います。

StripeのDiscordサーバーは質問を投稿するとすごく親切に返信してくれます。
Stripeの実装をする際に困ったことがあったらここに聞いてみるのがおすすめです。

宣伝

株式会社ウェイブでは、電子コミックやアニメの配信サービスなどを自社開発で運営しております。
新しい技術を積極的に取り入れたモダンな環境が整っているウェイブで一緒に働いてみませんか?
興味ある方は是非こちらをご覧ください!

https://recruit.wwwave.jp/

wwwave's Techblog

Discussion