#Steven Gauerke - Discount Invoice
1 messages · Page 1 of 1 (latest)
When you say the discount code is wrong, what do you mean?
That the coupon does not exist?
yes
so I create a customer facing code
would I pass that code to discounts.discount?
No, a customer facing code is ...entered by the customer
right so how to I update an invoice to apply that
and thats apparently called a Promo Code
how do I get the promo_###### to update the invoice with?
In that case you'd want to make an. Update Invoice API request and specify the data in the discounts property:
https://stripe.com/docs/api/invoices/update?lang=cli#update_invoice-discounts
ok so I would have to do https://api.stripe.com/v1/promotion_codes with code = to what they entered. So that will return the ID of the promo code
so then im testing with Postman, how do I format the array for the discounts part?
Well promotion codes are just customer facing interfaces on top of Coupons. So if you're doing it in the API you'd use the coupon IDs
If you're implementing the Coupons interface on your end you'll need to have the "friendly" text mapped to the coupon code, OR, you could perform the lookup via the API:
https://stripe.com/docs/api/promotion_codes/retrieve
ok im beyond that part now. I have a promo_##### id. I'm trying to test this in Postman. But how do I test a promo code on an invoice?
A promo code is a friendly wrapper on a coupon. You just pass the coupon on the invoice
ok my problem is I have a promo_###### id. does that go under discounts.discount? or discounts.coupon?
The discounts that will apply to the invoice. Pass an empty string to remove previously-defined discounts.
Hide child parameters
discounts.coupon
optional
ID of the coupon to create a new discount for.
discounts.discount
optional
ID of an existing discount on the object (or one of its ancestors) to reuse.
I tried discounts.coupon but I get o such coupon: 'promo_1KeNyoAvXb0N1jioSO3lyni1'
but this is not a "coupon". its a promo"
ok nevermind
Nice, glad you figured it out. Any further questions on this at the moment?
yes
so this is still a problem
so calling promotionCodes -> all with the code and customer set I get
"data": [
{
"id": "promo_1KeNyoAvXb0N1jioSO3lyni1",
"object": "promotion_code",
"active": true,
"code": "steveng0317",
"coupon": {
"id": "qLZckqD2",
"object": "coupon",
"amount_off": null,
"created": 1647541401,
"currency": null,
"duration": "once",
"duration_in_months": null,
"livemode": false,
"max_redemptions": null,
"metadata": {},
"name": "Steven Gauerke",
"percent_off": 100.0,
"redeem_by": null,
"times_redeemed": 1,
"valid": true
},
"created": 1647541402,
"customer": "cus_LCXKhOi0cZdBXu",
"expires_at": null,
"livemode": false,
"max_redemptions": null,
"metadata": {},
"restrictions": {
"first_time_transaction": false,
"minimum_amount": null,
"minimum_amount_currency": null
},
"times_redeemed": 0
}
],
ok so for a subscription, If I wanted to apply this first one, I would use promotion_code = promo_1KeNyoAvXb0N1jioSO3lyni1
But to apply to an invoice, I would have to do discounts[][coupon] = qLZckqD2
the problem is that qLZckqD2 has more than one promo code on it. So what will happen when I apply that to an invoice?
I mean its only going to apply the amount or percent off set for the coupon qLZckqD2, but if each promo code has a set number of uses allowed, then when I attach that coupon to an invoice, which promo code gets affected?
I don't think any of the promo code counts will be affected if you use the actual ID to set this. Do you want one of the specific counts to go up when you apply the discount like this?
Well that's why the customer has a customer facing code. And if it's restricted to one time use, I need that specific code to now be inactive.
See I had created a coupon called comp service and I was just creating promo codes under it with specific codes and giving it to specific customers. But it appears that if I apply a discount to an invoice that I can only attach a coupon ID and not a promo ID
Hi there! Stepping in for @shell vortex here as he has to step away. Getting caught up.
I think we should step back for a moment and clarify that promotion codes are specifically designed to be input by your customer. You would not apply a promotion code to an invoice. If you are trying to provide a discount to a customer or on an invoice for a customer, you would use a coupon for that or you would use a discount if you are re-using a discount that had already been applied.
OK so lets actually look at it like this.....yes a promotion code is a customer facing code.....but where does a customer enter that? You could say hosted checkout pages. But I dont want to use checkout pages
What do you want to use for the UI with your customer?
Or what integration flow are you using?
im making my own using the stripe elements
you have an example in your documents on how to apply a promotion code to a subscription
and that documentation says you can apply to a subscription OR an invoice but there is no example for invoice
only thing I could find was update invoice and theres a discounts attribute
but that only takes a COUPON id. and not promo code id
I can take what the user enters and I get back the promo ID as well as the coupon ID but the coupon itself could have more than one promo code
the point is, you need to fix your api so you can pass a promo_XXXXXX OR a coupon ID
You are correct, we do not currently support passing promotion codes directly to invoices. I just checked, and there is a feature request in to get this added in the future. For now, if you want to use promotion codes with a single invoice then you would do as you stated and map the promotion code to the coupon and apply the coupon. Otherwise, you can apply the promotion code to the Customer object directly.
Yup. Thanks
so one last question then. When I create a subscription with the API, I get a latest_invoice which of course would get paid from the stripe Elements. So if they enter a promo code, would I apply that to the pending invoice they are about to pay? or to the subscription?
Hello! I'm taking over, give me a minute to get caught up. 🙂
you just need to read the last few as that was our solution
You can apply a promotion_code to the Subscription when you create it: https://stripe.com/docs/api/subscriptions/create#create_subscription-promotion_code
right. I was wondering if it would be better to apply to the subscription itself or to the invoice created. They would add a promo code AFTER a subscription is already created.
So if the promo code is for 1 time use only ($10 off) would that just apply to the next invoice only then?
even if I apply it to the subscription
The first Subscription of an Invoice is typically created and finalized before you can modify it, so adding the promotion code to the first Invoice after the Subscription has already been created is probably not viable.
You might be able to use default_incomplete for this, but let me confirm...
oh yes thats what i do
default_incomplete
so I can then use stripe elements to pay it
so the invoice created is still paid: false
and I get a payment intent to create the elements with it
Yeah, I don't think that will work. The Invoice is created with status set to open, not draft, so I don't think you'll be able to add the promotion code at that point.
hmm
The best way to do this would be to add the promotion code to the Subscription when you create it.
yeah see I can't do that yet
Why?
they select which subscription product they want first.
then I create the stripe elements. and stripe elements doesn't allow coupon codes
so I had to make something myself.
For that flow you'd need to move the promotion code field to the first screen where they select the Subscription.
so that middle product.....is a one time product.....so I create the invoice and then when they enter a coupon code after choosing the product, I can update that invoice because yes THAT invoice is in draft
hmm...I thought of that, but what if they forget to add promo code first?
then they are stuck
you are saying that once the stripe elements are generated, its too late to go back and add a promo or coupon code
Oh, this is the same screen, I didn't realize that.
ever been to the market and after fulling ringing up everything going "Oh wait, I have a coupon"
You can make the promo code field's Apply button create a new Subscription and trigger the creation of a new elements object with the new client secret, which you can in turn use to create a new Payment Element.
wouldnt that delete all the customers card info? The thought is right before they hit the button again....they remember a coupon code
people are dumb
i got to take that into consideration
It would remove the card info, yes.
ok i guess weighing in on the downsides....thats not so bad. they can get over it
The other option would be to not use the Payment Element.
ok so instead of payment element?
Are you familiar with the Card Element and Payment Request Button?
yes but the reason i used the payment elements was because I figured if they had a card on file, it would let them use those
does it not?
What do you mean?
ok so I dont know about Payment Request button. So let me tell you about my products. So this is for pay per view videos. They can either buy a subscription for unlimited or pay one time to watch. So I have either recurring or one time.
If they have issues, we might give them a coupon (customer facing code for ease of use) to get their next one discounted (or free)....Or we might set someone up on the recurring at lets say 50% off
But these customers would come back multiple times, so I wanted to use payment methods stored on file. Your system does that and I was hoping.....I wouldnt have to create my own selector for payment methods on file. I DO keep their customer ID. I actually create them as a stripe customer when they first sign up as they can't watch anything for free anyways
so I was assuming the Payment Elements included that if I passed the customer ID when creating
thats a whole other ball game I can deal with later
That's not correct. The Payment Element does not do that.
I just want to get coupons working
I think you might be thinking of Stripe Checkout, which does do that.
ok thats fine. I'll make my own selector for their stored payment methods'
I tried stripe checkout too but you can't use a coupon that gives an item for free
so a 100% off would come back invalid
Okay, so back to coupons/promotion codes. For the flow you want you can't do it with the Payment Element because you need a client secret to initialize the Payment Element. However, you can do what you want with the Card Element. The major downside is that you can only accept cards with the Card Element. What methods of payment do you need to accept?
all of them and yes I can use the client secret for the payment element. Thats how I'm doing it now
What does "all of them" mean?
google pay and apple pay
You can accept those with the Payment Request Button + the Card Element.
What else?
ok so whats returned when I create that subscription is under latest_invoice is a payment intent object
that has a client secret in it
and it appears to create the payment elements with it
No, sorry, we're talking about different things.
Let's take a step back.
You have a desired payment flow that is incompatible with the Payment Element.
I'm trying to explain an alternative approach that does not use the Payment Element at all.
i see
You have two choices: do you want to continue with the Payment Element even though you can't build exactly what you want with it, or do you want to explore the alternative?
lets see the alternative
i figured I could only get the Google Pay and Apply Pay with Payment Element
Okay, so we have the Card Element, which lets you accept credit card info, and we have the Payment Request Button, which lets you accept Apple Pay and Google Pay. These are both separate from the Payment Element.
Neither of them need to be initialized with a client secret.
https://stripe.com/docs/payments/accept-card-payments uses client secrets.....is that not what you mean?
You can create and add them to your page and have them produce a Payment Method. You can then use that Payment Method + the promotion code provided and whatnot to create the Subscription with the Promotion Code, then get the client secret from the Invoice's Payment Intent and confirm it client-side with the Payment Method, all in a single step.
Yeah, that is not what I mean.
The Card Element docs are here: https://stripe.com/docs/payments/accept-card-payments
The Payment Request Button docs are here: https://stripe.com/docs/stripe-js/elements/payment-request-button
thats the same link I just posted and yes it does require a client secret
Rather than sending the entire PaymentIntent object to the client, use its client secret from step 2. After you create the PaymentIntent, the API returns a unique client secret for it (the client secret is different from the secret key you use to make Stripe API requests).
This is the specific API to create a Payment Method using a Card Element is here, which does not require a client secret: https://stripe.com/docs/js/payment_methods/create_payment_method
You would not be using the specific approach in that guide.
This is the API you use to get a Payment Method from the Payment Request Button: https://stripe.com/docs/js/payment_request/events/on_paymentmethod
so you want me to create a payment method up front?
and before asking for coupon code?
No, not exactly.
ok so that modal pops up and they choose item they want. Then what should happen in the flow?
The flow I'm trying to help you build has your customer fill out the form entirely first, then they click submit/pay, and then you create the Subscription with the promotion code and confirm the first payment.
That's what you want, correct?
oh ok so then I would have to store the promo code data on my server too to calculate how its going to affect the price?
50% off or $10 off?
No.
theres no way to validate if its valid
Creating the Subscription will throw an error if you use an invalid promotion code.
but they also dont need to fill out card info if their coupon code is for 100% off
nor should they have to choose a pre-stored payment method
your customer fill out the form entirely first,
Is that including the promo code?
Yes.
Maybe I don't fully understand your desired flow.
Can you describe the ideal payment flow you want to build?
- Customer chooses product which could be subscription or one time.
- Fill out payment information
- Either before or after (and it needs to accomodate before OR after) enter a promotion code
- Click Submit
I wasn't showing the credit card fields until they chose a product and clicked Continue because I have to know what product we are selling. So that modal stays open but just adds the card elements after first Continue click
So lets try to break it down further
lets assume its always just a one time purchase
no subscriptions
I tried the hosted checkout page but you can't enter a coupon code for 100% off on those
so supposedly, I can create an invoice and the invoice can be $0 in the end and still finalize and marked as paid
But we can't assume we know the coupon code used ahead of time
Yeah, Stripe Checkout won't fit your use case for sure.
Okay, so for that flow in step #2 you would use the Card Element + Payment Request Button to allow them to enter payment information and produce a Payment Method.
I'm not clear on #3... before or after what?
before or after entering card data
so I will either know the coupon code BEFORE I create any payment intent or card elements.....or the card element is generated and then they want to apply a coupon
would be a perfect world if we knew it ahead of time, but that's not going to happen
Gotcha, yeah, that's very possible.
the reason I'm so pushing for this solution is because there have been MANY times I've had coupons for other merchants that use stripe and I miss my opportunity to enter my coupon code and I have to completely cancel my order and start over. I just dont want that for my customers
so with one time.....when the invoice gets updated and the new price is $0.00 then I just remove the card fields and do my backend stuff and mark that invoice as paid
The idea here is to gather up all the individual pieces of input you need, the user's selection, the Payment Method, the Promotion Code, and so on. Then, at the end of the process, use all of that information to either attempt a one-time payment or start a Subscription.
ok but theres an incovenience there
if they have a promo code that gives 100% off, we dont need to collect card info
Okay, so don't show the card input in that case.
but you are saying I need to collect all that BEFORE we process anything....so where is the validation and application of the promotion code?
thats at the END
You can fetch the Promotion Code from the Stripe API to see if it's valid or not: https://stripe.com/docs/api/promotion_codes/list#list_promotion_code-code
That can be done independently at any time.
ok but thats still assuming they entered the promotion code BEFORE anything else
No, you can do it whenever you want as an isolated step.
You can do it at the beginning, at the end, whenever works for you.
but how do I get the card elements and Payment Request buttons if nothing has been submitted to stripe yet?
I have to get a payment intent dont i?
That's what I've been trying to explain. You do not need a client secret to use the Card Element or the Payment Request Button.
No Payment Intent is required.
so how am I passing the card info to stripe?
you guys dont let me pass raw credit card data
When the user presses the submit button you use the payment information provided using one of those elements.
It's still sent directly to Stripe.
ok where is the documentation for Card Element that does NOT require a client secret
I dont see that anywhere
First you create an elements object without a client secret: https://stripe.com/docs/js/elements_object/create
Then you create a Card Element: https://stripe.com/docs/js/elements_object/create_element?type=card
Then you mount it: https://stripe.com/docs/js/element/mount
Then you create a Payment Method from it: https://stripe.com/docs/js/payment_methods/create_payment_method
clientSecret
REQUIRED
string
If you read the docs there it's only required for the Payment Element.
Required to use with the Payment Element.
Give it a try.
I see
ok so I follow those steps
so it creates a payment method on that customer
wait...how does it tie to a customer?
That's later.
It just creates a Payment Method.
That's all those steps do, nothing else.
Later, at the end, you use the Payment Method to do whatever you want to do based on their selections.
ok but I can save that payment method ID and attach it to a customer later?
Yep.
ok so we have a payment method to make a purchase with so whats next in the flow?
That depends on what they select, doesn't it?
You might be making a Subscription, you might be making a single payment?
correct. lets just do single payment right now
I need to make a purchase of that specific priceID
And you want to use an Invoice?
I dont have to. but I DO want to track how many of a specific item is sold
so the one time is an item and the subscriptions are separate items
and the reason is because we credit the schools based on which ones are bought
I originally tried to have 1 product and both recurring and one time price options but the client wanted segregation
You should keep track of how many are purchased on your end in your own database.
well the reason I wanted to do it in stripe was for stripe payouts to pay out commissions in the future
or does that all have to be calculated on my end?
example....im getting paid for continued support off each transaction....for each one time purchase, I'll get 30% but for subscriptions, I only get 10% of the sale
the schools themselves that provide these videos will get commission too
ok so ill track it on my end.
so whats your suggestion then
One thing to clarify, you will always either have a Customer object or create one for these one-time payments, and you want to save the payment info so it can be used later, correct?
yes
I really need to reference products in stripe for what is being purchased
even if i can't use it for reports. that is my database of the products and their pricing
Okay, so you would create an Invoice for the payment, then pass the client secret from its Payment Intent to your frontend code and use this API to confirm it client-side: https://stripe.com/docs/js/payment_intents/confirm_card_payment#stripe_confirm_card_payment-existing
ok so create elements, they enter card info, it returns a payment method ID like pm_1KeT1b2eZvKYlo2CU1KzpkHK
Yep.
then pass the paymethod ID to create Invoice. it returns a client secret
No.
just create an invoice by itself?
You create an Invoice. The Invoice will create a Payment Intent. The Payment Intent will have a client secret. You pass that client secret to your client-side code and use it + the Payment Method to confirm the payment.
Yes.
ok so to create the invoice, I have to create invoiceItems first and I need a customer ID there right
or is there a way to create an invoice with items already in it?
Yes, first you need a Customer. You can then do one of two things: you can either create an empty Invoice first and then add Invoice Items to it, or you can create Invoice Items on the Customer and then create an Invoice that will sweep up those Invoice Items.
ok that I can do
collection_method for invoice? what should it be set to?
I dont want to do charge_automatically because it would charge a default method if there already is one
or would I set auto_advance to false?
Probably auto_advance set to false, then you can explicitly assign the Payment Method.
ok give me a second. I'm almost done
ok so when do we apply the coupon?
before we confirm the payment?
and could I technically create the invoice first before anything else? It would be in draft mode so I can apply the coupon any time and then when the coupon updates the invoice, I'd update the payment Intent ID
then confirm at the very last step
You would apply the coupon to the Invoice.
I don't think you'd want to create the Invoice ahead of time as you may not need it. What if they select a Subscription option? Then you'd be creating a Subscription, not an Invoice.
correct....can I create the subscription with first payment pending until we do confirm card payment existing?
if invoice, we would run stripe.confirmCardPayment after we have all the pieces
Why do you want to do that instead of waiting until the end?
so I'd have a total
Yeah, if that works for the flow you want you could do it that way.
if they enter coupon code first.....what do I apply coupon code to if I dont have an invoice yet?
thats why I want to create invoice first
You would need to create the Invoice at that point if you wanted to get a total.
invoice created, coupon code inserted, and new total is zero....then skip the create card element part altogether
Yep.
invoice is created, no coupon code yet.....create card element. customer enters card data, then enters a coupon code.....so coupon code updates invoice and we see total is zero so we just skip confirmCard
so that way I can catch it before confirmCard or createElement
ok so subscription.....whats your thoughts on that?
taking over!
Is it possible a Subscription would be free forever and not require payment details at all?
what's your real question? Just asking for thoughts is a bit vague
yes.....more than likely free than discounted
The difference with Subs is that you can't modify the invoice the same way especially
but I Can just handle that on my end if its free. but they might offer 50% off indefinitely
So what's blocking you/what's the question?
so we figured out the one time versions....great. so now...using the flow rubeus shared....if a subscription needs to be % off....easiest is if it is a subscription, to just redirect to a hosted checkout page with promo codes enabled.
yes that works