Hollywis LLC

湘南にある小さなシステム会社

← 技術ブログ一覧に戻る

StripeのSubscriptionのhookについて

hatena

f:id:hollywis:20220303120557p:plain

こんにちは、のすけです。

クレジットカード決済プラットフォームStripeの新しいバージョン。と言っても数年前のアップデートですが

によって、機能がいろいろ拡充されてますよね。

ただ機能が多過ぎてドキュメントを読んで仕様を理解するのも一苦労。

その中で、便利なサブスクの機能なのですが

かなり柔軟に料金設定ができるのですが、既存のシステムにもサブスクの管理がある場合

重複して管理しなくてはならなくなります。

例えば他の決済プラットフォームも併用している場合には、仕方なく、自社システムにも

サブスク管理の仕組みを作って、Stripeのサブスクといい感じに連動させる必要があるかと思います。

それで、サブスクの入会、退会はどうやって検出したらいいの?

という問題にぶち当たるのですが。

そこはStripe、イベントをhookする仕組みが用意されています。

着信する Webhook を使用してリアルタイムで更新を取得する | Stripe のドキュメント

ただ、いっぱいイベントあるんですよね。。

サブスクの登録、キャンセルはどのhookを使えば、、、

'customer.subscription.created'を使ってみる

サブスクが登録された時、このイベントが走ります

ですのでこちらをhookするのが正攻法かと思います。

ただ、自社のサブスク管理システムとの連携の際に、

契約されたサブスクがどのサブスクかを識別するためには、あらかじめ登録時に

metadataに識別のためのプランidなどを仕込んで置く必要があります。

ただ、Stripeの管理画面の商品設定画面ではproduct(商品)やprice(価格)にはメタデータをあらかじめ設定できるのですが

サブスク契約(sub_xxxx)は契約時に作成されるので

事前にメタデータを仕込むことができないっぽです。

なので、やり方としては

登録は例えばコーディング不要のStripe既存のcheckout sessionの仕組みを使う場合

どうすればいいのかと言うと

checkout.session.create時に

subscription_dataというパラメータを設定できるので、そこのmetadataに

自社のサブスクを識別する識別子を設定しています。

これで、例えば'invoice.payment_succeeded'をhookして、渡されたJSONデータをパースすると

どのサブスクか判別できます。

'invoice.payment_succeeded'での検出

Stripeでの支払いの際には(トライアルの¥0決済含む)必ず発行されるイベントに

invoice.payment_succeeded'があります。

こちらをhookすることでサブスクの登録と継続決済の検出ができるのでいいかなと思います。

なぜなら、billing_reasonという項目にサブスクの状態が入っているからです

登録時には"subscription_create"が、継続決済時には"subscription_cycle"が入ってくるので

こちらを識別する方法があります

'customer.subscription.updated'の場合

このイベントは、[サブスクリプション](http://d.hatena.ne.jp/keyword/%A5%B5%A5%D6%A5%B9%A5%AF%A5%EA%A5%D7%A5%B7%A5%E7%A5%F3)が変更されるたびにトリガーされます。

たとえば、クーポンの追加、割引の適用、インボイス項目の追加、プランの変更はすべて、このイベントを発生します。

この変更検知では、サブスクの継続支払いをだけを綺麗にhookできないです。

関係ない設定変更でも検出されてしまうので、何の変更なのかを吟味する必要があります。

個人的には使いづらいので、私はこちらは継続決済の検出には使ってません。

'customer.subscription.deleted'

これは普通にサブスクがキャンセルになったら発動します。

適切に検出してキャンセル手続きをしましょう。

番外:無料トライアル期間の設定

サブスクの無料トライアル期間はStripe管理画面からはできません。

登録しようとすると、レガシー機能で非推奨ですなんて出て、実際反映されません。

なのでAPI経由で設定が必要です。

これもStripe既存のcheckout sessionの仕組みを使う場合

どうすればいいのかと言うと

checkout.session.create時に

subscription_dataというパラメータを設定できるので、そこのtrial_period_daysというのがあるので

そこに日数を設定してやればOKのようです