dayhaysoos / use-shopping-cart

Shopping cart state and logic for Stripe
MIT License
907 stars 118 forks source link

Support for Discount / Promo Codes #329

Closed minimatrix closed 1 year ago

minimatrix commented 1 year ago

👋 Hi I'm looking at using your package, I couldn't find anything in the source or documentation about having the ability to apply a discount / promo code at point of checkout.

Do you know if this is something that is already possible, or is it beyond the scope of this particular package?

dayhaysoos commented 1 year ago

Hey @minimatrix, discounts seem to be possible via Stripe API:

https://stripe.com/docs/api/discounts

This package in particular doesn't directly support discounts or coupons, but you should still be able to implement them with no issues on the server side:

https://stripe.com/docs/payments/checkout/discounts

As far as the UI goes, I suppose we can add a value to an item that says there's a discount being applied? I'd need to think about what ways USC can support it.

Do you have any ideas or does that sound ideal to you?

minimatrix commented 1 year ago

Thanks for responding so promptly, I haven't yet decided if I will be utilising stripes api for retrieving products or whether I'll be building them into my own api.

For those using stripe for their products I think your answer would certainly do the trick but if managing your own promo codes i think something else would be required perhaps a preCheckout hook where the dev can perform additional logic on the cart items (things like buy 2 get one half price for example) which then continues to the stripe checkout afterwards?

dayhaysoos commented 1 year ago

It's actually more secure to use Stripe's dashboard to create products. If you don't use Stripe's dashboard, I do have a helper function that helps with that aspect of security but at the end of the day it's on you to make sure it's secure, ya know? So I'd recommend the dashboard if you can.

With that being said, I think from the API docs, you can dynamically create one-time coupons like this:

const coupon = await stripe.coupons.create({
  percent_off: 20,
  duration: 'once',
});

And when you check out, include it in the serverless function like this:

const session = await stripe.checkout.sessions.create({
  line_items: [{
    price: '{{PRICE_ID}}',
    quantity: 1,
  }],
  mode: 'payment',
  discounts: [{
    coupon: '{{COUPON_ID}}',
  }],
  success_url: ['https://example.com/success'](https://example.com/success),
  cancel_url: ['https://example.com/cancel'](https://example.com/cancel),
});

You'll probably want to send some value that triggers a function to create a coupon that goes from client side to server.

It shouldn't be too difficult to apply some kind of UI logic for showing if there's a coupon applied or not, however, I think Stripe Checkout should show the discount there as well.

Lemme know if you have any questions!

minimatrix commented 1 year ago

Ah! I totally understand you now! I was missing the point, but it makes so much more sense to utilise the stripe api for the coupons!

And having the products on there too means nothing can be messed with client side.

Totally agree it's better to show them on the stripe checkout totals too.

Might as well close this now, thanks for your help it's much appreciated!

dayhaysoos commented 1 year ago

Thanks for asking your question, I never saw the coupon API so I learned something new!