#cardouken

1 messages ยท Page 1 of 1 (latest)

reef lavaBOT
terse elk
burnt dove
#

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?

terse elk
#

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

burnt dove
#

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)
burnt dove
#

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

terse elk
#

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

#

I am admittedly fuzzy on how this would work, I will ask a colleague for help here

burnt dove
#

sure, i'll check the docs in the meanwhile

dusty dust
#

Hi there ๐Ÿ‘‹ catching up on the discussion.

burnt dove
#

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

dusty dust
#

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.

burnt dove
#

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

dusty dust
#

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.

dusty dust
burnt dove
#

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:

  1. create a coupon in our backend
  2. create that coupon in stripe
  3. apply the coupon on quote creation which applies a discount with whatever conditions were applied to the coupon
  4. 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

dusty dust
#

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.

burnt dove
#

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

#

it feels like that's where you'd insert either a coupon or promotion code id at least

dusty dust
#

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.

burnt dove
#

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

dusty dust
#

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.

burnt dove
#

no worries at all, it's not an issue to do it ourselves, just glad we didn't spend multiple days on trying to implement it with promotion codes before realizing it didn't work, so your help was much appreciated

#

thanks again and have a good night!