#mayhul_api

1 messages ¡ Page 1 of 1 (latest)

chrome drumBOT
#

👋 Welcome to your new thread!

⏲️ We'll be here soon! We typically respond in a few minutes, but in some cases we might need a bit more time (e.g., server's busy, you've got a complex question, etc.).

⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can start a new thread if you have another question.

🔗 This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1259949913660325928

📝 Have more to share? Add details, code, screenshots, videos, etc. below.

worn haven
chrome stone
worn haven
#

Does this work for subscriptions?

#

Sometimes our checkout is for a subscription, and our current approach is to create the subscription & then grab the payment client sercret from subscription.latest_invoice. If we update the subscription with a promo code, would that update the underlying payment client secret?

chrome stone
#

It should as far as I am aware though I am not sure if you can get a discount on the subscription's first invoice if it is already finalized. Can you try applying that promo code to a finalized subscription invoice and let me know if that changes the payment intent amount on the first invoice?

#

If not, I have an idea for a workaround, but if that works then simply using fetchUpdates should work for your purposes

worn haven
#

Hm ok. I'll try that and report back

worn haven
#

From what I can see the subscription invoice does not get updated

chrome stone
#

As in we don't attempt to charge it? Or as in because the call errors we revert the subscription to what it was and don't issue the new invoice?

worn haven
#

I created an incomplete subscription that charged $100/yr and then I ran this:

await stripe.subscriptions.update(
    subID,
    {
      coupon: 'xuIVVL5s',
    },
    getStripeRequestOptions(accountID),
  );
  const sub = await stripe.subscriptions.retrieve(
    subID,
    {
      expand: ['latest_invoice.payment_intent'],
    },
    getStripeRequestOptions(accountID),
  );
  prettyPrint(sub);

Where the coupon is a 50% off coupon

#

And then I got back:

#
{
  "discount": {
    "id": "di_1PaNXFIEN4lWhEmZngG6NHnm",
    "object": "discount",
    "checkout_session": null,
    "coupon": {
      "id": "xuIVVL5s",
      "object": "coupon",
      "amount_off": null,
      "created": 1714104292,
      "currency": null,
      "duration": "forever",
      "duration_in_months": null,
      "livemode": false,
      "max_redemptions": null,
      "metadata": {
        
      },
      "name": "Half Off",
      "percent_off": 50,
      "redeem_by": null,
      "times_redeemed": 16,
      "valid": true
    },
    "customer": "cus_QRFy7d56HUhKed",
    "end": null,
    "invoice": null,
    "invoice_item": null,
    "promotion_code": null,
    "start": 1720468061,
    "subscription": "sub_1PaNSAIEN4lWhEmZD0jGRedg",
    "subscription_item": null
  },
  "discounts": [
    "di_1PaNXFIEN4lWhEmZngG6NHnm"
  ],
  "ended_at": null,
  "invoice_settings": {
    "account_tax_ids": null,
    "issuer": {
      "type": "self"
    }
  },
  "latest_invoice": {
    "id": "in_1PaNSAIEN4lWhEmZ5lsJOzVn",
    "object": "invoice",
    "account_country": "US",
    "account_name": "heartbeat.chat",
    "account_tax_ids": null,
    "amount_due": 10000,
    "amount_paid": 0,
    "amount_remaining": 10000,
    "amount_shipping": 0,
    "application": "ca_Jo54Jnkvy9KdCwW7nSYL9zYPiBFM9w1T",
    "application_fee_amount": 300,
    "attempt_count": 0,
    "attempted": false,
    "auto_advance": false,
    "automatic_tax": {
      "enabled": false,
      "liability": null,
      "status": null
    },
  }
}
#

So I see that the subscription has the discount applied, but latest_invoice still shows 10000

#

Lmk if that's not the right way to test this

chrome stone
#

My apologies, I mixed you up with another thread. It looks like the coupon did get applied, but won't retroactively take money off of the invoice that was already created. You could pass parameters to create a new invoice when applying that update, but it would create a new intent and therefore new client secret as you mentioned.
One workaround I can think of is that it is possible to render a Payment Element without a client-secret and then confirm the client-secret that you eventually create after the customer submits their payment details. So it would take changes to how your page currently works, but you could render the element, preview the invoice price with the upcoming invoice endpoint, and hold off on creating your subscription until the payment method details are actually submitted.
https://docs.stripe.com/payments/accept-a-payment-deferred?platform=web&type=subscription
https://docs.stripe.com/api/invoices/upcoming
https://docs.stripe.com/js/elements_object/update

#

I am unfortunately not aware of a way with your current setup to apply these coupons to your subscriptions in a way that doesn't require a client secret change

worn haven
#

I see, so if we use the mode parameter, we can render the payment element without the client secret. That seems like it would work pretty well for our case, are there are any downsides to this approach?

ex is the payment element able to optimize better when it has a payment client secret vs just a mode?

chrome stone
#

Nothing that I am immediately thinking of. Basically you would specify the mode, amount, currency and such and then could make that elements update call as you need to when the coupon or tax or whatever changes the price. I am not really thinking of anything that the deferred intent flow can't do that the client secret first method can

worn haven
#

great, thanks so much! I have another question re: collecting VAT. Should I start another thread or can I ask here?

chrome stone
#

Happy to continue in here

worn haven
#

So we're a connect platform & we allow our Connect accounts to collect VAT from their customers via our platform. Some of our customers are asking for a feature where if their customers are a business, that business can enter their business id to be exempt from VAT. I'm trying to figure out the best way for us to implement this feature

#

I'm thinking that our flow would be: Ask customer for business id => validate with stripe => if valid, then mark the customer as tax_exempt.

#

Does that make sense, or does Stripe have a more native way of handling this?

#

Also should we be telling our customers that we're not fully validating the ids, so it's on them to verify that the id actually lines up with the customer's name/address?

chrome stone
#

Good question. I am not sure how that works with customer tax IDs. I will consult my colleagues on this and get back to you

chrome stone
#

So what that doc is getting at is that we do evaluate AU, EU, and GB tax IDs against a business registry, but for IDs outside of that we don't support validating ourselves so that responsibility goes to you for the moment.

chrome stone
chrome drumBOT
worn haven
#

Gotcha, I guess what I'm wondering is what the typical protocol here is. Assuming we're outside of AU/EU/GB, should we allow end users to checkout tax-exempt with a potentially invalid tax id? And tell our connect users that they should double check these ids afterwards?

#

And for those in AU/EU/GB, is this the correct approach: Ask customer for business id => validate with stripe => if valid, then mark the customer as tax_exempt?

chrome stone
#

We haven't been able to find a solid answer on the invalid ID thing, though that sounds like a legal questions so my colleagues on our support team would be better to ask about this.
https://support.stripe.com/?contact=true