Reputation: 3702
I want to use Stripe Upcoming Invoices to display how much a user will be billed when he makes changes to his subscriptions. But it seems that I miss something...
dump($plans['basic_monthly']->price);
29.0
dump($plans['premium_monthly']->price);
49.0
$stripe_customer = step1_create_customer();
$stripe_subscription = step2_create_subscription($stripe_customer, $plans['basic_monthly']->stripe_price_id);
dump([
'reason' => 'Nohting was changed (price_id and quantity are the same), so 0 is expected. Why 29 is here?',
'expected' => 0,
'actual' => upcoming($stripe_subscription, $plans['basic_monthly']->stripe_price_id)->amount_due/100,
]);
array:3 [▼
"reason" => "Nohting was changed (price_id and quantity are the same), so 0 is expected. Why 29 is here?"
"expected" => 0
"actual" => 29
]
dump([
'reason' => 'Transition to more expensive plan was made. 49 - 29 = 20 is expected',
'expected' => 20,
'actual' => upcoming($stripe_subscription, $plans['premium_monthly']->stripe_price_id)->amount_due/100,
]);
array:3 [▼
"reason" => "Transition to more expensive plan was made. 49 - 29 = 20 is expected"
"expected" => 20
"actual" => 20
]
function step1_create_customer()
{
$stripe = new \Stripe\StripeClient(env('STRIPE_SECRET_KEY'));
$test_clock = $stripe->testHelpers->testClocks->create([
'frozen_time' => time(),
'name' => sprintf('Testing Upcoming Invoices'),
]);
$stripe_customer = $stripe->customers->create([
'test_clock' => $test_clock->id,
'payment_method' => 'pm_card_visa',
'invoice_settings' => ['default_payment_method' => 'pm_card_visa'],
'metadata' => [
'testing_upcoming_invoices' => 1,
],
'expand' => [
'test_clock',
'invoice_settings.default_payment_method',
],
]);
return $stripe_customer;
}
function step2_create_subscription($stripe_customer, $stripe_price_id)
{
$stripe = new \Stripe\StripeClient(env('STRIPE_SECRET_KEY'));
$stripe_subscription = $stripe->subscriptions->create([
'customer' => $stripe_customer->id,
'items' => [
[
'price' => $stripe_price_id,
'quantity' => 1,
],
],
'metadata' => [
'testing_upcoming_invoices' => 1,
],
]);
return $stripe_subscription;
}
function upcoming($stripe_subscription, $stripe_price_id)
{
$stripe = new \Stripe\StripeClient(env('STRIPE_SECRET_KEY'));
$stripe_invoice = $stripe->invoices->upcoming([
'subscription' => $stripe_subscription->id,
'subscription_items' => [
[
'id' => $stripe_subscription->items->data[0]->id,
'price' => $stripe_price_id,
'quantity' => 1,
],
],
'subscription_cancel_at_period_end' => false,
'subscription_proration_behavior' => 'always_invoice',
//'subscription_proration_date' => $now,
]);
return $stripe_invoice;
}
Upvotes: 0
Views: 1784
Reputation: 25582
What your code is doing here is upgrading a Subscription from Price A ($29/month) to Price B ($49/month) immediately after creation. You're also passing subscription_proration_behavior: 'always_invoice'
.
When you upgrade or downgrade a subscription, Stripe calculates the proration for you automatically. This is something Stripe documents in details here and here.
In a nutshell, since you move from $29/month to $49/month immediately after creation, what happens is that Stripe calculates that:
In a default integration, the proration is created as 2 separate InvoiceItems that are pending until the next cycle. In your case you pass proration_behavior: 'always_invoice'
so an Invoice is created immediately with only those 2 line items. -$29 + $49 = $20 which is where the amount comes from.
Upvotes: 1