renoki-co / jetstream-cashier-billing-portal

Cashierstream is a simple Spark alternative written for Laravel Jetstream, with the super-power of tracking plan quotas, like seats or projects number on a per-plan basis
Apache License 2.0
163 stars 20 forks source link

Any plans to support EU MOSS tax/vat regulations #4

Closed BKirev closed 3 years ago

BKirev commented 3 years ago

First of all, good work on the package. I love it! Saves a lot of time doing the boring stuff around Cashier.

But as the title says, I'm wondering if you're planning on adding support for all the EU MOSS/VAT stuff, since it's part of the boring process?

Maybe this could help: https://github.com/mpociot/vat-calculator, even though it's a bit dated.

Best regards!

rennokki commented 3 years ago

I'm not sure how to implement this since I never encountered this. Laravel Cashier already handles that, but I assume this package might be able to display some of the taxes or something?

BKirev commented 3 years ago

It does indeed support tax rates. I'm talking more about the frontend part and the link that connects the front with the tax rate logic(apply tax rate, don't, in case a valid VAT is entered, perhaps CRUD for tax rates, etc.).

If you need more information, just let me know.

rennokki commented 3 years ago

So I guess the products listed might need to have some taxes added to their price or perhaps if a VAT id is applied. I'll link this issue to a new issue created on https://github.com/renoki-co/cashier-register since it first has to be done there.

BKirev commented 3 years ago

Well, more like tax added on the total amount at the end(in case there's more than one product). If the customer is an individual, tax is always applied. If he's a company, but does not provide VAT ID, tax is applied. And if he's a company and provides a valid VAT ID, then there's no tax.

Also, each country may have different tax rates, that's why I mentioned CRUD for managing that, but it's not a huge deal, since tax rates can be added/modified/deleted in Stripe as well.

So the whole flow will look something like this:

  1. Countries list drop down/selector
  2. Check if selected country is in EU(or if there's tax rate added for the given country), where VAT/MOSS applies.
  3. Apply tax rate for the selected country 3.1 If VAT/MOSS applies, ask for VAT ID 3.2 Check if VAT ID is valid and if so, remove the applied tax

Hopefully I'm not missing something.

Do you want me to create the issue on https://github.com/renoki-co/cashier-register/issues?

rennokki commented 3 years ago

Hey @BKirev,

I come with an update after a while. Now that 4.x is released with more improvements with usual Jetstream-consistent code and easier customizations, do i miss something about the taxes? Can't this be fixed at the Stripe level?

BKirev commented 3 years ago

image

This is how it's done in Spark. They add VAT tax by default, I think and after you enter a valid VAT ID(checked by the package I sent above) AND your country is not the same as the business', then the VAT tax gets removed. If either of the above is not true, then the tax is sent to Stripe. It's also properly displayed on the receipt as VAT tax.

If I can help any further, let me know.

Keep up the good work! :)

rennokki commented 3 years ago

@BKirev Thanks for the explanation.

It's a bit different how Billing Portal handles this. Basically, new subscriptions are always sent to the Stripe Checkout page, and the filled-in data is strictly in Stripe, reducing the friction on the app level with migrations to store. This requires the webhooks to be set in order to work fine because catching webhooks is a must for checkout.

Also, the user gets redirected to the Stripe Checkout if it doesn't have a default payment method. At that time, I found it easier because it required less configuration in-package and make use of more of the already-built features from Stripe.

From what I know, Paddle also has a checkout page, so they can both be working well together on the same implementation.

It seems like Spark already handles this situation for you by not redirecting to the Checkout page and filling the form directly within the app. That's just more work to do instead of leveraging the already-mentioned Stripe and Paddle features. Of course, the whitelabel would look better and it won't require webhooks.

BKirev commented 3 years ago

Spark also works with webhooks. It does handle this part, yes. But it doesn't store sensitive information. This is all taken care of by Stripe. What it doesn't give you is flexibility in terms of modifying the UI. I was planning on using this package as a replacecment for Spark, but can't do because of the EU regulations features. Perhaps Stripe will add support for them in their Checkout at some point and it'll made life easier for all of us, but alas, it's not there yet.

You can have a look at Spark classic. Seems like they open sourced it: https://github.com/laravel/spark-aurelius

stale[bot] commented 3 years ago

This issue has been automatically closed because it has not had any recent activity. 😨