#cardouken
1 messages ยท Page 1 of 1 (latest)
If you need a promotion-code specific feature, you can create the promotion code and then pass its ID in to the subscriptions API on your backend https://stripe.com/docs/api/subscriptions/update#update_subscription-promotion_code
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
hey
it's not quite what we're trying to achieve, basically i'm only looking to use the max redemptions per customer feature, so far we've just been using coupon id-s to create a quote
and i'm not sure if the quote discount params are that or how they work together with coupon ids and promotion code id-s
mind if i share a code snippet on how we're using it now just to illustrate what i mean?
Sounds good, happy to take a look
Interesting, I do see that the Quotes API does not have a promotion code parameter. I wonder if you need to apply the promotion code to the customer or something and then provide the discount ID https://stripe.com/docs/api/quotes/create#create_quote-discounts
https://stripe.com/docs/api/customers/update#update_customer-promotion_code
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
alright i'll cut off some irrelevant parts that can probably be inferred but:
fun purchase(customerId: String, prices: List<StripePurchaseWrapper>, couponId: String?): Quote {
val lineItems = prices.map {
QuoteCreateParams.LineItem.builder()
.setPrice(it.price.id)
.setQuantity(it.quantity)
.build()
}
val quoteCreateParamsBuilder = QuoteCreateParams.builder()
.setCustomer(customerId)
.addAllLineItem(lineItems)
.setCollectionMethod(CHARGE_AUTOMATICALLY)
if (couponId != null) {
quoteCreateParamsBuilder.addDiscount(QuoteCreateParams.Discount.builder().setCoupon(couponId).build())
}
var quote = stripeClient.quoteCreate(quoteCreateParamsBuilder.build())
quote = stripeClient.quoteFinalize(quote)
val quoteAcceptParams = QuoteAcceptParams.builder()
.addExpand("subscription")
.addExpand("invoice")
.build()
quote = stripeClient.quoteAccept(quote, quoteAcceptParams)
ok yeah that's the part i'm wondering about
so right now we're applying the coupon id to the quote on creation, then we accept, finalize, do other stuff with it etc
i saw the setDiscount method but wasn't sure if that's what was meant to accept the promotion code
or what would happen if you attempted to apply both, e.g.
val quoteDiscountBuilder = QuoteCreateParams.Discount.builder()
if (couponId != null) {
quoteDiscountBuilder.setCoupon(couponId)
}
if (promotionCodeId != null) {
quoteDiscountBuilder.setDiscount(promotionCodeId)
}
quoteCreateParamsBuilder.build()
the reason i'm even asking this is because we've integrated and coupled the way coupons work pretty tightly into our backend billing so this is a legitimate issue we might have. i can of course happy path test this but there's probably 200 ways in which i can't think or manage to verify it. but if setDiscount(promotionCodeId) is definitely the correct way to apply them, then we can probably switch to just using promotion codes only
because the stripe sdk docs are confusing me slightly:
/** ID of an existing discount on the object (or one of its ancestors) to reuse. */
so assuming there's a coupon with id FREE123 as well as a promotion code FREE123 which is applied to the coupon, is it going to first assume it's a promotion code or the ancestor (coupon) given they'd have the same id essentially
I think setDiscount(promotionCodeId) would be expecting the ID of a Discount object (di_123)
The way that I can think of getting this to work API-wise would be to update the customer and pass in the promotion code to them. I think that would create a discount object that would show up on their discount property. Then that ID could be passed in to setDiscount on the Quotes API
https://stripe.com/docs/api/customers/update#update_customer-promotion_code
https://stripe.com/docs/api/customers/object#customer_object-discount
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
I am admittedly fuzzy on how this would work, I will ask a colleague for help here
sure, i'll check the docs in the meanwhile
Hi there ๐ catching up on the discussion.
yeah i'm afraid updating the customer isn't going to help since this would just be to apply a one-time discount on a one-off purchase the same way you would use a coupon. i'm just trying to set it so that one customer could only redeem a specific coupon once and not change anything else
i have a feeling it might be easier to actually just implement it in our backend without using customer facing coupon codes but obviously using customer facing codes would be preferable overall
It doesn't seem like Promotion Codes would be a good fit here, they're only accepted by our hosted checkout flows such as Checkout Sessions.
It's likely going to be best for you to model the restrictions you want to add around the user of Coupons on your side. Then you can control whether or not your code passes the Coupon in your requests to Stripe.
alright that's kind of a shame. but mind explaining a bit on how setDiscount() works for quote creation in that case or is that not at all for coupon/promotion code id-s?
if not then feel free to skip the explanation lol
only asking because as per the docs:
A discount represents the actual application of a coupon or promotion code. It contains information about when the discount began, when it will end, and what it is applied to.
which in turn has a promotion_code attribute
My understanding is that field is for passing in a reference to an already existing Discount object, let me take a closer look at quotes with discounts to see if I can piece together when it would make sense to use that approach.
Yes, it's a reference from the Discount object back to the Promotion Code object that caused the Discount to be created, if it came from a Promotion Code. I'd expect that field to be null for Discounts created directly from Coupons.
mm, ok, but then it kinda sounds like our usecase after all unless i'm missing something here. right now our workflow is more or less like this:
- create a coupon in our backend
- create that coupon in stripe
- apply the coupon on quote creation which applies a discount with whatever conditions were applied to the coupon
- that's it
my understanding was that you could then also create promotion codes that would be attached to this coupon that could be used in the same way as coupons, so instead of redeeming a discount via a coupon id you could just do that via a promotion code that is linked to a coupon
so step 1 and 2 would additionally just create a promotion code for a specific coupon after the coupon has been created
Most of that is right!
The concern is with this part:
that could be used in the same way as coupons,
Promotion Codes and Coupons are used in different ways. Coupon IDs are used by your integration when creating objects. So your steps are right, your code would pass the ID of a Coupon when creating a Quote. Promotion Codes on the other hand do not get used by your code, those are intended to be used directly by end-customers on Stripe-hosted checkout UIs.
alright makes sense. i don't want to keep you forever, so one last question just so i'm crystal clear on everything:
/**
* ID of the coupon to create a new discount for.
*/
@SerializedName("coupon")
String coupon;
/**
* ID of an existing discount on the object (or one of its ancestors) to reuse.
*/
@SerializedName("discount")
String discount;
so here the id of an existing discount on an object could be what? i understand coupons, but to me it seems like a coupon is sort of the underlying item as a discount for anything
https://stripe.com/docs/billing/subscriptions/coupons from here as well
it feels like that's where you'd insert either a coupon or promotion code id at least
A Discount object is a specific instance of an object being discounted.
https://stripe.com/docs/api/discounts
Looking at the Quote object as an example. You can provide a Coupon when creating the Quote:
https://stripe.com/docs/api/quotes/create#create_quote-discounts-coupon
However the resulting Quote object doesn't have a discount.coupon field, it instead has the discounts array:
https://stripe.com/docs/api/quotes/object#quote_object-discounts
The Coupon that was provided, is used to create a Discount object, and that Discount object's ID is then placed in the discounts array on the Quote object.
The discount field that you're referring to, is used to pass in the ID of one of those existing Discount objects, but offhand I'm not sure when that would be the right flow to use.
It is not the field where Promotion Codes are entered, that is in our Checkout Session UI:
I think that's why Promotion Codes have additional functionality around them, because they're accepted on surfaces that you don't control. So without those additional features you wouldn't have any control over them. Since you're creating the Quotes directly though, you can include your coupon logic in your server-side code, and only provide Coupon IDs when your system determines that is the right thing to do.
alright thanks. sorry for the long questions, I get it mostly now, just seemed like it'd be possible to use them on the backend as well (or in our custom checkout flow in the app) but if not, then that's fine
we'll just work around it and implement it ourselves but i do really appreciate you taking the time to help me out with this
No worries, we're always happy to help! Sorry the advice wasn't quite what you were hoping for this time, but I'm glad to have been able to help clear things up. I can definitely understand how reusing behavior that already exists for promotion codes would be beneficial here though, so I'll be sure to capture this feedback for our teams to take into consideration as they're thinking about future improvements that can be made.