🖥
#Stripe API / サブスクリプションのスケジュール登録が開始済みでも予約中でも SubscriptionSchedule を Up
points
- 1ヶ月サイクルのプラン1個だけをスケジュール登録して、あとから end_date = キャンセル日を登録する場合
- Subscription に対してであれば Update で cance_at を登録すれば良いのだが、SubscriptionSchedule が開始していない場合は、そもそも Subscription が発生していないため、できない
- どちらの場合も SubscriptionSchedule への update で APIリクエストを完結させたいが、SubscriptionSchedule はちょっと癖があるやつ
- SubscriptionSchedule が active = 開始している場合は、 current_phase.start_date を起点に、そこから数ヶ月後の end_date をぴったりと指定する。なぜなら中途半端な日時を指定すると、日割り計算的な請求が発生してしまうから。
- SubscriptionSchedule が not_started= 開始していない場合は、 未来に開始される最初のフェーズ = phasse の start_date を起点に、そこから数ヶ月後の end_date をぴったりと指定する。なぜなら中途半端な日時を指定すると、日割り計算的な請求が発生してしまうから。ちなみに現在フェーズの期間 ( current_phase ) はサブスクリプションの請求サイクルとは異なる。
- SubscriptionSchedule Update で phase 単位で iterations を指定することもできるだろうが、start_date / end_date を明確に与えてあげたほうが、場合によってはやりやすそうだ。いや、やりやすい方でお願いします。
Docs
- https://stripe.com/docs/billing/subscriptions/subscription-schedules
- https://stripe.com/docs/billing/subscriptions/subscription-schedules/use-cases
- https://support.stripe.com/questions/create-update-and-schedule-subscriptions
参考 - Stripeの基本
日本正式リリースしたStripeを使ってサブスクリプション型決済システムを実装する - Qiita
Stripe Billing 101 - Qiita
Stripe初心者のための基本的な使い方(Rails編) - Qiita
Docs
- https://stripe.com/docs/billing/subscriptions/subscription-schedules
- https://stripe.com/docs/billing/subscriptions/subscription-schedules/use-cases
- https://support.stripe.com/questions/create-update-and-schedule-subscriptions
Code
# Docs
# https://stripe.com/docs/billing/subscriptions/subscription-schedules
# https://stripe.com/docs/billing/subscriptions/subscription-schedules/use-cases
#
# https://stripe.com/docs/api/subscription_schedules/release
# https://support.stripe.com/questions/create-update-and-schedule-subscriptions
require 'active_support/core_ext'
require 'stripe'
Stripe::api_key = ENV['STRIPE_SECRET_KEY']
[1.month, 3.months].each do |end_at_from|
product1 = Stripe::Product.create(name: "Gold plan #{rand(9999999999)}")
plan1 = Stripe::Plan.create(interval: 'month', currency: 'jpy', amount: 5000, product: product1.id, usage_type: 'licensed')
tax_rate = Stripe::TaxRate.create(display_name: 'Tax Rate', percentage: 10.0, inclusive: false)
customer = Stripe::Customer.create
payment_method = Stripe::PaymentMethod.create(type: 'card', card: { number: '4242424242424242', exp_year: 2030, exp_month: 01})
customer_payment_method = Stripe::PaymentMethod.attach(payment_method.id, customer: customer.id)
def put_subscription_schedule(subscription_schedule, message)
puts '-' * 100
puts "Subscription Schedule"
puts message
puts '-' * 100
puts subscription_schedule
puts '-' * 100
puts "https://dashboard.stripe.com/test/subscription_schedules/#{subscription_schedule.id}"
end
# https://stripe.com/docs/api/subscription_schedules/create
soon_start_subscription_schedule = Stripe::SubscriptionSchedule.create(
{
customer: customer.id,
start_date: Time.now.to_i + 5,
default_settings: {
default_payment_method: customer_payment_method.id,
},
phases: [
{
plans:
[
{ plan: plan1.id, quantity: 1 },
],
prorate: false,
default_tax_rates: [tax_rate],
},
],
}
)
puts '-' * 100
puts "Wait until subscription schedule starts"
puts '-' * 100
until soon_start_subscription_schedule.status == 'active' do
soon_start_subscription_schedule = Stripe::SubscriptionSchedule.retrieve(soon_start_subscription_schedule.id)
puts soon_start_subscription_schedule.status
sleep 2
end
started_subscription_schedule = Stripe::SubscriptionSchedule.retrieve(id: soon_start_subscription_schedule.id, expand: ['subscription'])
future_subscription_schedule = Stripe::SubscriptionSchedule.create(
{
customer: customer.id,
start_date: Time.now.to_i + 100*24*60*60,
default_settings: {
default_payment_method: customer_payment_method.id,
},
phases: [
{
plans:
[
{ plan: plan1.id, quantity: 1 },
],
prorate: false,
default_tax_rates: [tax_rate],
},
],
}
)
# current_phase.start_date is not subscription cycle start_date
def update_subscription_schedule(base_subscription_schedule)
if base_subscription_schedule.status == 'active'
start_date = base_subscription_schedule.current_phase.start_date
elsif base_subscription_schedule.status == 'not_started'
start_date = base_subscription_schedule.phases[0].start_date
else
raise
end
end_date = Time.at(start_date).since(3.months).to_i
Stripe::SubscriptionSchedule.update(
base_subscription_schedule.id,
{
# Set "cancel" not "releasse"
end_behavior: 'cancel',
phases: [
{
plans:
[
{
plan: base_subscription_schedule.phases[0].plans[0].plan,
quantity: base_subscription_schedule.phases[0].plans[0].quantity
},
],
# prorate does not effect to Subscription or SubscriptionSchedule Canceling
# prorate: true / false,
default_tax_rates: base_subscription_schedule.phases[0].default_tax_rates.map(&:id),
# For Update You must set start_date in first phase not in subscription schedule directly
start_date: start_date,
# If you do not want to get upcoming invoice on Subscription
# Then you must specify end_date with Subscription natural cycle interval
end_date: end_date
},
]
}
)
end
updated_started_subscription_schedule = update_subscription_schedule(started_subscription_schedule)
updated_future_subscription_schedule = update_subscription_schedule(future_subscription_schedule)
put_subscription_schedule(updated_started_subscription_schedule, 'UPDATED')
put_subscription_schedule(updated_future_subscription_schedule, 'UPDATED')
end
# NOTE
# SubscriptionSchedule current_phase is not same as Subscription cycle
# it is "phase" start_date and end_date
#
# If phase end_date is 3.months after then ...
#
# Time.at(updated_started_subscription_schedule.current_phase.start_date)
# => 2020-01-02 17:44:23 +0900
# Time.at(updated_started_subscription_schedule.current_phase.end_date)
# => 2020-04-02 17:44:23 +0900
Started Subscription - cancel at current phase
Upcoming invoice leaves from dashboard
Not Started Subscription - cancel at first phase
Theres Starts Ends in both in future
Theres upcoming invoice becauce Schedule will start in future
Not current invoice because Schedule not started
Started Subscription - cancel at future phase
Change end_date in code and run Case
Not Started Subscription - cancel at not first phase
Change end_date in code and run Case
Result
- This is run code resutls example but not correctly same as Image capture images in this article.
----------------------------------------------------------------------------------------------------
Wait until subscription schedule starts
----------------------------------------------------------------------------------------------------
not_started
not_started
not_started
not_started
not_started
not_started
active
----------------------------------------------------------------------------------------------------
Subscription Schedule
CREATED
----------------------------------------------------------------------------------------------------
{
"id": "sub_sched_1FwPNZCmti5jpytUe3xhuCdN",
"object": "subscription_schedule",
"canceled_at": null,
"completed_at": null,
"created": 1577955005,
"current_phase": null,
"customer": "cus_GTM5yQ0vRozYUW",
"default_settings": {
"billing_thresholds": null,
"collection_method": "charge_automatically",
"default_payment_method": "pm_1FwPNHCmti5jpytURUDXSKtE",
"default_source": null,
"invoice_settings": null
},
"end_behavior": "release",
"livemode": false,
"metadata": {
},
"phases": [
{
"application_fee_percent": null,
"billing_thresholds": null,
"collection_method": null,
"coupon": null,
"default_payment_method": null,
"default_tax_rates": [
{
"id": "txr_1FwPNHCmti5jpytUA4yh9gmW",
"object": "tax_rate",
"active": true,
"created": 1577954987,
"description": null,
"display_name": "Tax Rate",
"inclusive": false,
"jurisdiction": null,
"livemode": false,
"metadata": {
},
"percentage": 10.0
}
],
"end_date": 1589187005,
"invoice_settings": null,
"plans": [
{
"billing_thresholds": null,
"plan": "plan_GTM5XKzi7c1qy8",
"quantity": 1,
"tax_rates": [
]
}
],
"prorate": false,
"start_date": 1586595005,
"tax_percent": 10.0,
"trial_end": null
}
],
"released_at": null,
"released_subscription": null,
"renewal_interval": null,
"revision": "sub_sched_rev_1FwPNZCmti5jpytUWUBqK4lG",
"status": "not_started",
"subscription": null
}
----------------------------------------------------------------------------------------------------
https://dashboard.stripe.com/test/subscription_schedules/sub_sched_1FwPNZCmti5jpytUe3xhuCdN
----------------------------------------------------------------------------------------------------
Subscription Schedule
UPDATED
----------------------------------------------------------------------------------------------------
{
"id": "sub_sched_1FwPNJCmti5jpytU8hFkMssH",
"object": "subscription_schedule",
"canceled_at": null,
"completed_at": null,
"created": 1577954989,
"current_phase": {
"end_date": 1585817393,
"start_date": 1577954993
},
"customer": "cus_GTM5yQ0vRozYUW",
"default_settings": {
"billing_thresholds": null,
"collection_method": "charge_automatically",
"default_payment_method": "pm_1FwPNHCmti5jpytURUDXSKtE",
"default_source": null,
"invoice_settings": {
"days_until_due": null
}
},
"end_behavior": "cancel",
"livemode": false,
"metadata": {
},
"phases": [
{
"application_fee_percent": null,
"billing_thresholds": null,
"collection_method": null,
"coupon": null,
"default_payment_method": null,
"default_tax_rates": [
{
"id": "txr_1FwPNHCmti5jpytUA4yh9gmW",
"object": "tax_rate",
"active": true,
"created": 1577954987,
"description": null,
"display_name": "Tax Rate",
"inclusive": false,
"jurisdiction": null,
"livemode": false,
"metadata": {
},
"percentage": 10.0
}
],
"end_date": 1585817393,
"invoice_settings": null,
"plans": [
{
"billing_thresholds": null,
"plan": "plan_GTM5XKzi7c1qy8",
"quantity": 1,
"tax_rates": [
]
}
],
"prorate": true,
"start_date": 1577954993,
"tax_percent": 10.0,
"trial_end": null
}
],
"released_at": null,
"released_subscription": null,
"renewal_interval": null,
"revision": "sub_sched_rev_1FwPNZCmti5jpytUoCQuoPaf",
"status": "active",
"subscription": "sub_GTM59xT4BS5E3j"
}
----------------------------------------------------------------------------------------------------
https://dashboard.stripe.com/test/subscription_schedules/sub_sched_1FwPNJCmti5jpytU8hFkMssH
----------------------------------------------------------------------------------------------------
Subscription Schedule
UPDATED
----------------------------------------------------------------------------------------------------
{
"id": "sub_sched_1FwPNZCmti5jpytUe3xhuCdN",
"object": "subscription_schedule",
"canceled_at": null,
"completed_at": null,
"created": 1577955005,
"current_phase": null,
"customer": "cus_GTM5yQ0vRozYUW",
"default_settings": {
"billing_thresholds": null,
"collection_method": "charge_automatically",
"default_payment_method": "pm_1FwPNHCmti5jpytURUDXSKtE",
"default_source": null,
"invoice_settings": {
"days_until_due": null
}
},
"end_behavior": "cancel",
"livemode": false,
"metadata": {
},
"phases": [
{
"application_fee_percent": null,
"billing_thresholds": null,
"collection_method": null,
"coupon": null,
"default_payment_method": null,
"default_tax_rates": [
{
"id": "txr_1FwPNHCmti5jpytUA4yh9gmW",
"object": "tax_rate",
"active": true,
"created": 1577954987,
"description": null,
"display_name": "Tax Rate",
"inclusive": false,
"jurisdiction": null,
"livemode": false,
"metadata": {
},
"percentage": 10.0
}
],
"end_date": 1594457405,
"invoice_settings": null,
"plans": [
{
"billing_thresholds": null,
"plan": "plan_GTM5XKzi7c1qy8",
"quantity": 1,
"tax_rates": [
]
}
],
"prorate": true,
"start_date": 1586595005,
"tax_percent": 10.0,
"trial_end": null
}
],
"released_at": null,
"released_subscription": null,
"renewal_interval": null,
"revision": "sub_sched_rev_1FwPNaCmti5jpytUnlvLBTke",
"status": "not_started",
"subscription": null
}
----------------------------------------------------------------------------------------------------
https://dashboard.stripe.com/test/subscription_schedules/sub_sched_1FwPNZCmti5jpytUe3xhuCdN
----------------------------------------------------------------------------------------------------
Wait until subscription schedule starts
----------------------------------------------------------------------------------------------------
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
not_started
active
----------------------------------------------------------------------------------------------------
Subscription Schedule
CREATED
----------------------------------------------------------------------------------------------------
{
"id": "sub_sched_1FwPOZCmti5jpytUqLGjGd5a",
"object": "subscription_schedule",
"canceled_at": null,
"completed_at": null,
"created": 1577955067,
"current_phase": null,
"customer": "cus_GTM5Wlau0N9HHj",
"default_settings": {
"billing_thresholds": null,
"collection_method": "charge_automatically",
"default_payment_method": "pm_1FwPNcCmti5jpytUPG6hdjRk",
"default_source": null,
"invoice_settings": null
},
"end_behavior": "release",
"livemode": false,
"metadata": {
},
"phases": [
{
"application_fee_percent": null,
"billing_thresholds": null,
"collection_method": null,
"coupon": null,
"default_payment_method": null,
"default_tax_rates": [
{
"id": "txr_1FwPNbCmti5jpytUOMYY1jCE",
"object": "tax_rate",
"active": true,
"created": 1577955007,
"description": null,
"display_name": "Tax Rate",
"inclusive": false,
"jurisdiction": null,
"livemode": false,
"metadata": {
},
"percentage": 10.0
}
],
"end_date": 1589187067,
"invoice_settings": null,
"plans": [
{
"billing_thresholds": null,
"plan": "plan_GTM5akDaPHCKOr",
"quantity": 1,
"tax_rates": [
]
}
],
"prorate": false,
"start_date": 1586595067,
"tax_percent": 10.0,
"trial_end": null
}
],
"released_at": null,
"released_subscription": null,
"renewal_interval": null,
"revision": "sub_sched_rev_1FwPOZCmti5jpytUsHM0JqYJ",
"status": "not_started",
"subscription": null
}
----------------------------------------------------------------------------------------------------
https://dashboard.stripe.com/test/subscription_schedules/sub_sched_1FwPOZCmti5jpytUqLGjGd5a
----------------------------------------------------------------------------------------------------
Subscription Schedule
UPDATED
----------------------------------------------------------------------------------------------------
{
"id": "sub_sched_1FwPNdCmti5jpytUnvii1fUR",
"object": "subscription_schedule",
"canceled_at": null,
"completed_at": null,
"created": 1577955009,
"current_phase": {
"end_date": 1585817414,
"start_date": 1577955014
},
"customer": "cus_GTM5Wlau0N9HHj",
"default_settings": {
"billing_thresholds": null,
"collection_method": "charge_automatically",
"default_payment_method": "pm_1FwPNcCmti5jpytUPG6hdjRk",
"default_source": null,
"invoice_settings": {
"days_until_due": null
}
},
"end_behavior": "cancel",
"livemode": false,
"metadata": {
},
"phases": [
{
"application_fee_percent": null,
"billing_thresholds": null,
"collection_method": null,
"coupon": null,
"default_payment_method": null,
"default_tax_rates": [
{
"id": "txr_1FwPNbCmti5jpytUOMYY1jCE",
"object": "tax_rate",
"active": true,
"created": 1577955007,
"description": null,
"display_name": "Tax Rate",
"inclusive": false,
"jurisdiction": null,
"livemode": false,
"metadata": {
},
"percentage": 10.0
}
],
"end_date": 1585817414,
"invoice_settings": null,
"plans": [
{
"billing_thresholds": null,
"plan": "plan_GTM5akDaPHCKOr",
"quantity": 1,
"tax_rates": [
]
}
],
"prorate": true,
"start_date": 1577955014,
"tax_percent": 10.0,
"trial_end": null
}
],
"released_at": null,
"released_subscription": null,
"renewal_interval": null,
"revision": "sub_sched_rev_1FwPOaCmti5jpytU2OqMiUUC",
"status": "active",
"subscription": "sub_GTM64npF4L1rop"
}
----------------------------------------------------------------------------------------------------
https://dashboard.stripe.com/test/subscription_schedules/sub_sched_1FwPNdCmti5jpytUnvii1fUR
----------------------------------------------------------------------------------------------------
Subscription Schedule
UPDATED
----------------------------------------------------------------------------------------------------
{
"id": "sub_sched_1FwPOZCmti5jpytUqLGjGd5a",
"object": "subscription_schedule",
"canceled_at": null,
"completed_at": null,
"created": 1577955067,
"current_phase": null,
"customer": "cus_GTM5Wlau0N9HHj",
"default_settings": {
"billing_thresholds": null,
"collection_method": "charge_automatically",
"default_payment_method": "pm_1FwPNcCmti5jpytUPG6hdjRk",
"default_source": null,
"invoice_settings": {
"days_until_due": null
}
},
"end_behavior": "cancel",
"livemode": false,
"metadata": {
},
"phases": [
{
"application_fee_percent": null,
"billing_thresholds": null,
"collection_method": null,
"coupon": null,
"default_payment_method": null,
"default_tax_rates": [
{
"id": "txr_1FwPNbCmti5jpytUOMYY1jCE",
"object": "tax_rate",
"active": true,
"created": 1577955007,
"description": null,
"display_name": "Tax Rate",
"inclusive": false,
"jurisdiction": null,
"livemode": false,
"metadata": {
},
"percentage": 10.0
}
],
"end_date": 1594457467,
"invoice_settings": null,
"plans": [
{
"billing_thresholds": null,
"plan": "plan_GTM5akDaPHCKOr",
"quantity": 1,
"tax_rates": [
]
}
],
"prorate": true,
"start_date": 1586595067,
"tax_percent": 10.0,
"trial_end": null
}
],
"released_at": null,
"released_subscription": null,
"renewal_interval": null,
"revision": "sub_sched_rev_1FwPObCmti5jpytU5eKvVg9W",
"status": "not_started",
"subscription": null
}
----------------------------------------------------------------------------------------------------
https://dashboard.stripe.com/test/subscription_schedules/sub_sched_1FwPOZCmti5jpytUqLGjGd5a
Original by Github issue
チャットメンバー募集
何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。
公開日時
2020-01-03
Discussion