Reputation: 581
I am trying to preview an upcoming invoice with prorated charges.
The client is changing from a 30 euros / Year plan to a 65 euros / Year plan on day 1 (important for proration date calculations).
According to the documentation here the client should be charged:
Which comes out to 35 euros in total. The next invoice issued should be for 35 euros. The following call is made using the Java library to fetch the upcoming invoice:
InvoiceUpcomingParams params = InvoiceUpcomingParams.builder()
.setCustomer(userId)
.setSubscription(subscriptionId)
.addSubscriptionItem(
InvoiceUpcomingParams.SubscriptionItem.builder()
.setId(subscription.getItems().getData().get(0).getId())
.setPrice(priceId)
.build()
).setSubscriptionProrationDate(prorationDate)
.build();
The resulting invoice has the following properties:
...and the following invoice lines (ids have been obfuscated):
{
"data": [
{
"amount": -3000,
"currency": "eur",
"description": "Unused time on xxxxx after 09 Jan 2021",
"discount_amounts": [],
"discountable": false,
"discounts": [],
"id": "---",
"invoice_item": "---",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1641756061,
"start": 1610222989
},
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 3000,
"amount_decimal": 3000,
"billing_scheme": "per_unit",
"created": 1598220277,
"currency": "eur",
"deleted": null,
"id": "---",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": null,
"object": "plan",
"product": "---",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"price": {
"active": true,
"billing_scheme": "per_unit",
"created": 1598220277,
"currency": "eur",
"deleted": null,
"id": "---",
"livemode": false,
"lookup_key": null,
"metadata": {},
"nickname": null,
"object": "price",
"product": "---",
"recurring": {
"aggregate_usage": null,
"interval": "year",
"interval_count": 1,
"trial_period_days": null,
"usage_type": "licensed"
},
"tiers": null,
"tiers_mode": null,
"transform_quantity": null,
"type": "recurring",
"unit_amount": 3000,
"unit_amount_decimal": 3000
},
"proration": true,
"quantity": 1,
"subscription": "---",
"subscription_item": "---",
"tax_amounts": [],
"tax_rates": [],
"type": "invoiceitem",
"unified_proration": null
},
{
"amount": 6499,
"currency": "eur",
"description": "Remaining time on xxxx after 09 Jan 2021",
"discount_amounts": [],
"discountable": false,
"discounts": [],
"id": "---",
"invoice_item": "---",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1641756061,
"start": 1610222989
},
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 6500,
"amount_decimal": 6500,
"billing_scheme": "per_unit",
"created": 1598220248,
"currency": "eur",
"deleted": null,
"id": "---",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": null,
"object": "plan",
"product": "---",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"price": {
"active": true,
"billing_scheme": "per_unit",
"created": 1598220248,
"currency": "eur",
"deleted": null,
"id": "---",
"livemode": false,
"lookup_key": null,
"metadata": {},
"nickname": null,
"object": "price",
"product": "---",
"recurring": {
"aggregate_usage": null,
"interval": "year",
"interval_count": 1,
"trial_period_days": null,
"usage_type": "licensed"
},
"tiers": null,
"tiers_mode": null,
"transform_quantity": null,
"type": "recurring",
"unit_amount": 6500,
"unit_amount_decimal": 6500
},
"proration": true,
"quantity": 1,
"subscription": "---",
"subscription_item": "---",
"tax_amounts": [],
"tax_rates": [],
"type": "invoiceitem",
"unified_proration": null
},
{
"amount": 6500,
"currency": "eur",
"description": "1 × xxxx (at €65.00 / year)",
"discount_amounts": [],
"discountable": true,
"discounts": [],
"id": "---",
"invoice_item": null,
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1673292061,
"start": 1641756061
},
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 6500,
"amount_decimal": 6500,
"billing_scheme": "per_unit",
"created": 1598220248,
"currency": "eur",
"deleted": null,
"id": "---",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": null,
"object": "plan",
"product": "---",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"price": {
"active": true,
"billing_scheme": "per_unit",
"created": 1598220248,
"currency": "eur",
"deleted": null,
"id": "---",
"livemode": false,
"lookup_key": null,
"metadata": {},
"nickname": null,
"object": "price",
"product": "---",
"recurring": {
"aggregate_usage": null,
"interval": "year",
"interval_count": 1,
"trial_period_days": null,
"usage_type": "licensed"
},
"tiers": null,
"tiers_mode": null,
"transform_quantity": null,
"type": "recurring",
"unit_amount": 6500,
"unit_amount_decimal": 6500
},
"proration": false,
"quantity": 1,
"subscription": "---",
"subscription_item": "---",
"tax_amounts": [],
"tax_rates": [],
"type": "subscription",
"unified_proration": null
}
],
"has_more": false,
"object": "list",
"request_options": null,
"request_params": null,
"url": "---"
}
In short the invoice lines contain the following:
I believe this to be wrong. According to the documentation here the charge should be: 64.99 - 30 = 34.99 euros
Now if I go through with the actual subscription update the invoice that Stripe generates is indeed for 34.99 euros. So there seems to be something wrong with either how I call the upcoming invoice API or what it returns.
What am I missing? Am I supposed to deduct the price of the subscription from the amountDue myself?
Upvotes: 1
Views: 1411
Reputation: 337
Just wanted to extend on @Rich Harvey's answer in case anybody else runs into this issue.
The reason the actual invoice and the preview invoice are different, is because you set proration_behavior: "always_invoice"
when you actually apply the change to the subscription, thus creating an invoice right away with just the proration amounts.
However, in your preview, the change is being applied to the next invoice, thus charging the full price for the subscription + the proration amounts.
To fix this, simply set subscription_proration_behavior = 'always_invoice'
for the invoice preview:
InvoiceUpcomingParams params = InvoiceUpcomingParams.builder()
.setCustomer(userId)
.setSubscription(subscriptionId)
.addSubscriptionItem(
InvoiceUpcomingParams.SubscriptionItem.builder()
.setId(subscription.getItems().getData().get(0).getId())
.setPrice(priceId)
.build()
).setSubscriptionProrationDate(prorationDate)
.setSubscriptionProrationBehavior('always_invoice')
.build();
See the Documentation for .setSubscriptionProrationBehavior()
Upvotes: 4
Reputation: 13
Just hit the same issue. I managed to get the correct upcoming invoice (ie 2 lines one for the rebate and 1 for the new charge) by setting the proration_behavior to "always_invoice"
Upvotes: 1
Reputation: 581
I can see that the documentation example does indeed follow the same pattern. It contains 3 lines. 2 for the prorated charges and one for the actual item.
So the gist of this is that the upcoming invoice (on the subscription renew date) will include the prorated charges and the new installment charge.
So if I want to present my customer with what the upcoming invoice will look like if they upgrade/downgrade now I have to manually subtract the item price from the response.
The invoice generated is 34.99 because I am issuing the invoice roughly at the same time as the upcoming invoice preview modifying the subscription item's price.
Upvotes: 1
Reputation: 6485
This is expected behavior for the Upcoming Invoice endpoint. Have a look at the documentation for previewing a proration which shows the same thing you're seeing in the example result:
You can expand the example response below to see:
- The credit for unused time at the previous price on lines 36-38.
- The cost for time spent at the new price on lines 107-109.
- The new subtotal and total for the invoice on lines 276-279.
You're previewing the upcoming Invoice, which means it's going to Invoice for both the current period's change and the next period's regular amount. There are two line items for the change in the current period and one line item for the upcoming period.
Now if I go through with the actual subscription update the invoice that Stripe generates is indeed for 34.99 euros.
It sounds like you're making this change and then immediately generating an Invoice rather than waiting for the Invoice that would normally be generated as a result of the Subscription.
Upvotes: 0