piesync / billbo

Easy to use billing service for Stripe with VAT support
MIT License
73 stars 3 forks source link

Handle VAT combined with coupons #59

Closed challengee closed 9 years ago

challengee commented 10 years ago

Problem

When we create a subscription for the first time, we need to add a VAT invoice item before creating the subscription in Stripe. When a discount is added to the generated invoice, this is suddenly much more difficult, as the coupon is applied after VAT instead of before.

Example

The customer has a coupon for $5. He creates a subscription on a plan of $10. Billbo calculates VAT on $10, for example $2 (20%). The total invoice amount will be $7, while it actually should be $6 ($5 + 20%).

Possible Solution

This could be solved by checking if the customer is eligible for a discount beforehand and calculate what the total amount would be, but this calculation would be brittle as it would have to be exactly like Stripe does it internally (like rounding).

Note

For percentage discounts, it's actually doable because the operations are commutative, ex: $10_0.9_0.8 = $10_0.8_0.9 (10% discount)

Does anyone have a clue on how to solve this elegantly? Is there a way to apply VAT after coupons?

matthewarkin commented 10 years ago

For dollar off coupons, an invoice object has a "Total" property which is the total after any discounts. You can just calculate VAT based on that add that as an invoice item.

For percent discounts, you'd want to calculate it based on the subtotal. (since the coupon will take the percent off the VAT invoice item).

You can check an invoice's discount object to see if its a percent or amount off.

challengee commented 10 years ago

@matthewarkin The method you describe would work for all invoices except the first. When you create a subscription in Stripe, an invoice will be immediately created and charged. You can't add anything anymore to this invoice after it is created (in contrast to the subsequent invoices of that subscription).

So the problem is that you can't know the total invoice amount because you do not have the invoice object yet because you did not create the subscription yet.

Is there a way to "preview" what the first invoice would be if a subscription is created?

/cc @russelldavis Is there any way to do this in the Stripe Ruby gem or with the Stripe API?

jimdanz commented 10 years ago

@challengee, jumping in for Russell here. Once a subscription is created, you can preview a customer's upcoming invoice: https://stripe.com/docs/api#retrieve_customer_invoice

Unfortunately, there isn't a way to ask about the invoice that would be created for a hypothetical subscription. I agree that the "check what discount the customer currently has" solution could work but may be brittle.

In cases where it's acceptable to have the subscription creation succeed unconditionally (even in the case of payment failure), a trick would be to create a subscription with otherwise normal parameters but with trial_end set to, eg, 1 minute in the future. This would mean that the subscription creation request would succeed and the only invoice that would be created would be the $0 invoice for the beginning of the trial period. And then asynchronously, Stripe would create the "actual" first invoice and that one would support adding invoice items.