テストモード

テストモードでは、領収書の自動送信などの設定項目はあるが、実際には自動送信されることはない。
どうやってメールのフォーマット確認などを行うかというと、インボイスの項目から、領収書を再送する機能があるため、そちらから行うと実際にメールを送信することができる。

領収書

領収書は決済完了メールにPDFファイルで添付される。
フォーマットは管理画面から調整できる。
決済完了メールの返信先は管理画面で登録したメールアドレスだから、変なアドレスを登録しないように注意。
決済完了メールの送信元ドメインは「@stripe.com」であり、これは管理画面から変更できそう(試していない)。
完全にカスタマイズしたい場合はWebhookを使うといい。

サブスクリプション

決済に失敗したときに再度決済を試行する設定などができたり、決済前のリマインドメールの設定などもできる。
決済完了のメールもStripe側で送信してくれるため、メール送信処理を組み込む必要はない。
メールのフォーマットには制限があるが、Web Hook を使用すると自由に組み立てられそう。

また試用期間やクーポンなどの設定が可能。

Subscription 関連リソース
https://tech.actindi.net/2021/03/02/083000?utm_source=feed
Subscriptionの状態遷移
https://tech.actindi.net/2021/03/02/083000?utm_source=feed

またサブスクリプションには段階制と従量課金がある。

組み込み

フロントエンドのフォームはStripe側が提供しているスクリプトを読み込むとiframeで設置されるため、フォームのDOMは用意する必要はない。
npmのラッパーライブラリを使うとstripeのライブラリが複数読み込まれることがなくなるため、使用する。
バックエンドは多言語のAPIやREST APIが使用でき、たとえばPHPであれば composer にライブラリがあるためこれを使用すると楽。

支払いの時差

サブスクリプションの初回請求時、ほとんどの場合すぐに決済処理が行われるが、23時間の猶予がある。
翌月以降の請求は、登録したた起点日に請求され、起点日のない月はその月の月末に請求となる。
例えば、1/2に初回の請求があった場合、2/2、3/2、4/2…が請求日となり、1/31に請求があった場合、2/28(うるう年は2/29)、3/31、4/30…というスケジュールとなる。

だが、StripeのタイムゾーンはUTC基準で動作するのに対して、日本時間(JST)でサブスクリプションを作成した場合、UTCの時刻から9時間の時差が発生する。
そのため、UTCでは月末だが、JSTだと翌月と判定されてしまうケースがある。

その場合、Subscriptionのbilling_cycle_anchor(起点日の設定)を指定して毎月指定日に請求するか、あるいはtrial_end(本来はトライアル期間の終了日を示すが、請求の開始日をずらすことができる)を使用することで対策できる。

// 固定決済日なし、トライアルあり
Stripe::Subscription.create({
  customer: STRIPE_CUSTOMER_ID,
  items: [
    { price: STRIPE_PRICE_ID },
  ],
  trial_end: TRIAL_END_DATETIME,
})

// 固定決済日なし、トライアルなし
Stripe::Subscription.create({
  customer: STRIPE_CUSTOMER_ID,
  items: [
    { price: STRIPE_PRICE_ID },
  ],
})

// 固定決済日あり、日割り決済あり、トライアルあり
// トライアル終了後に次の決済日(billing_cycle_anchor)までの残り日数を元に日割りの決済が行われる
Stripe::Subscription.create({
  customer: STRIPE_CUSTOMER_ID,
  items: [
    { price: STRIPE_PRICE_ID },
  ],
  trial_end: TRIAL_END_DATETIME,
  billing_cycle_anchor: FIRST_BILLING_DATETIME, // trial_endよりも先の期間
})

// 固定決済日あり、日割り決済あり、トライアルなし
Stripe::Subscription.create({
  customer: STRIPE_CUSTOMER_ID,
  items: [
    { price: STRIPE_PRICE_ID },
  ],
  billing_cycle_anchor: FIRST_BILLING_DATETIME,
})

// 固定決済日あり、日割り決済なし、トライアルなし
// 最初の決済は billing_cycle_anchor で指定した日時が初回の決済タイミング
Stripe::Subscription.create({
  customer: STRIPE_CUSTOMER_ID,
  items: [
    { price: STRIPE_PRICE_ID },
  ],
  billing_cycle_anchor: FIRST_BILLING_DATETIME,
  prorate: false,
})

// サブスクリプション開始時に決済し、次回の決済タイミングを固定したい場合
// billing_cycle_anchor を最初は指定せず、Subscription を作成し、後から billing_cycle_anchor を変更する
// ただ、 billing_cycle_anchor を変更する場合、'now' しか指定できないため、終了日が次回決済日になるトライアルを後から追加する
stripe_subscription = Stripe::Subscription.create({
  customer: STRIPE_CUSTOMER_ID,
  items: [
    { price: STRIPE_PRICE_ID },
  ],
  prorate: false,
})
Stripe::Subscription.update(stripe_subscription.id, trial_end: FIRST_BILLING_DATETIME, proration_behavior: 'none')

参考:https://qiita.com/phigasui/items/8bdc20ecd46a0d504bec

差額について

Stripeで推奨する差額の扱いは、決済日は変えずに請求金額の増減で対応することであり、プランの変更と同時に差額を請求・返金することが可能だが、APIやWebhookを利用した追加の開発が必要となる。

https://qiita.com/tady/items/7617e62b2a5402ebd0fb

余剰残高が発生した状態でユーザーが退会してしまうと、返金できなくなることに注意する必要がある。