#afonso

1 messages · Page 1 of 1 (latest)

clever viperBOT
spark fable
#

Hi there, are you attaching a payment method to a customer directly?

hazy light
#

Hey, so I'm adopting the new flow where the payment element is mounted before the intent is created. And it's working wonderfully, but seems like this indian thing got in the way recently.

#

Yes, I'm attaching, but now I'm not anymore because I check if the card is indian or not.

#

However, then I get this second error when I try to create a subscription:

#

This is a piece of code to show you the logic:

#
                        await stripe.paymentMethods.attach(
                            payment_method_id,
                            { customer: company.stripe_customer_id },
                            { stripeAccount: jobboard.stripe_id }
                        );```
#
                        const subscription = await stripe.subscriptions.create(
                            {
                                customer: company.stripe_customer_id,
                                items: [{ price: plan.stripe_price_id }],
                                default_payment_method: payment_method_id,
                                default_tax_rates: jobboard.taxes_enabled ? [tax_rate.stripe_id] : [],
                                expand: ["latest_invoice.payment_intent"],
                                payment_behavior: "default_incomplete"
                            },
                            { stripeAccount: jobboard.stripe_id }
                        );```
#

That second block of code is outside the previous if.

spark fable
#

OK, so you are attaching a payment method directly.

hazy light
#

Yes, before creating the subscription.

#

But not anymore for indian cards.

#

But if I do that, I'll get the second error that I screenshotted.

spark fable
#

As mentioned in the error message, there's a limitation for Indian users where they can't attaching payment methods to customers directly.

#

You should use SetupIntent to collect payment methods instead.

hazy light
#

Yes, I'm aware, that's why I surrounded the attaching logic with an if-statement as you see.

spark fable
#

No, it's not about the card issuing country

hazy light
#

But I can't do that because the intent is created after the payment method is created.

#

Because I'm using the new flow where I mount the payment element (and create a payment method) without any payment intent.

spark fable
#

It's about the Stripe account itself. are you testing with a Indian Stripe account?

hazy light
#

I'm using this flow ^

#

Oh this is about stripe account, not indian card?

spark fable
hazy light
#

Just to clarify before I do that.

#

This indian regulation issue affects ALL payments within an indian stripe account, is that it?

#

It doesn't matter the country of the card that's used for payment?

spark fable
#

Yes you are right, that restriction is applied to all IN Stripe accounts.

hazy light
#

Ok, so we're a platform/website builder, that allows people to plug in their own stripe accounts.

#

We make this work through stripe connect, using on_behalf_off.

#

By inference, I'd assume all connect accounts that are indian will have this issue, am I correct?

spark fable
#

Yes you are right.

hazy light
#

Ok so that if-statement is pretty dumb.

#

What request ID are you referring to? The create subscription?

#

Where the error pops up, right?

#

Request ID is req_RUJutA9I7qHDqt.

#

This is the error if I don't attach the payment method to the customer.

#

Which I was doing before, but I came across the first error that I sent you.

#

After noticing that error, I removed the attachment, but now I get that error when creating subscriptions.

#

Am I making sense? Don't really want to waste your time.

spark fable
#

The error occured because a susbcription needed a payment_method. The solution here is to use SetupIntent to collect a payment method instead of creating one and attaching it to a customer.

hazy light
#

Yes I followed, but then again, we're collecting payment details before having the intent.

#

We're mounting the payment element way before we have any valid intent.

#

This is how we're doing it:

#
                amount: normalizeCurrency(this.price, currency),
                mode: this.isSubscription ? 'subscription' : 'payment',
                currency: this.currency.toLowerCase(),
                paymentMethodCreation: 'manual'
            });```
#
                const result = await stripe.createPaymentMethod({
                    elements: this.stripe.elements,
                    params: {
                        billing_details: {
                            email: this.billing.email,
                            name: this.billing.name,
                            address: {
                                line1: this.billing.address,
                                city: this.billing.city,
                                postal_code: this.billing.zip,
                                state: this.billing.state,
                                country: this.billing.country
                            }
                        }
                    }
                });```
#

And only then do we create the invoice/subscription, and get the intent from there.

#

And then,

                const payment_res = await stripe.confirmPayment({ clientSecret: invoice_res.client_secret, redirect: "if_required" });
#

We cannot create the intent before this, because that would imply that we would need to mount the element after that, and we can't do that.

spark fable
#

I don't think you are following the flow.

#

I'd suggest you to take a look at the doc that I sent earlier, it's about render a PaymentElement without creating a SetupIntent.

hazy light
#

I'm sorry it's not that flow, sent you the wrong link.

#

Let me find it, it's quite new.

spark fable
#

This is the follow that you should follow.

hazy light
#

No, we've tried that before and didn't work for our usecase.

spark fable
#

why?

hazy light
#

Let me find information on why, just a second, all of this is super complicated and has a lot of edge cases.

#

As you see we are using the manual payment method creation.

#

I'm trying to find the docs.

#

Ok actually I don't see how I'm doing it differently.

#

The payment intent is created automatically when you create a subscription.

#

Or when you create an invoice.

#

Which is what we're doing, right?

#
                        const subscription = await stripe.subscriptions.create(
                            {
                                customer: company.stripe_customer_id,
                                items: [{ price: plan.stripe_price_id }], 
                                default_payment_method: payment_method_id,
                                default_tax_rates: jobboard.taxes_enabled ? [tax_rate.stripe_id] : [],
                                expand: ["latest_invoice.payment_intent"],
                                payment_behavior: "default_incomplete"
                            },
                            { stripeAccount: jobboard.stripe_id }
                        );````
#

And we get the payment intent through

                            client_secret: subscription.latest_invoice.payment_intent.client_secret 
                        };```
#

But this only works if customer has the payment method attached, which won't work for indian accounts.

spark fable
hazy light
#

Yes I'm doing that, look at the code is the same.

#

But it only works if I attach the customer to the payment method before.

#

I get the same error:

#

Request ID - req_RUJutA9I7qHDqt.

spark fable
#

No, you are still not follwing the follow.

hazy light
#

I'm confused, why do you say that?

spark fable
#

You get the this error because you set a default_payment_method and this payment_method is not yet attached to the customer.

hazy light
#

What am I missing

#

Ok I removed the default payment method

#

Same error

spark fable
#

Please remove default_payment_method

#

request ID?

hazy light
#
                        const subscription = await stripe.subscriptions.create(
                            {
                                customer: company.stripe_customer_id,
                                items: [{ price: plan.stripe_price_id }], 
                                //default_payment_method: payment_method_id,
                                payment_settings: { save_default_payment_method: '' },
                                default_tax_rates: jobboard.taxes_enabled ? [tax_rate.stripe_id] : [],
                                expand: ["latest_invoice.payment_intent"],
                                payment_behavior: "default_incomplete"
                            },
                            { stripeAccount: jobboard.stripe_id }
                        );```
#

wait now I get

#

"message": "You cannot confirm this PaymentIntent because it's missing a payment method. To confirm the PaymentIntent with cus_NsexwjMGfiHmNK, specify a payment method attached to this customer along with the customer ID.",

spark fable
#

request ID please.

hazy light
#

req_j3OzqZmPI4HJk3

#

Maybe I can do this

                            receipt_email: company.email,
                            description: plan.name,
                            payment_method: payment_method_id
                        }, { stripeAccount: jobboard.stripe_id });```
#

Let me try

#

nice this worked!!!!!

#

hurray

#

please keep this open let me test it in a few other scenarios

#

so there is no point to attach the payment method to the customer after all right?

#

at least in our flow

spark fable
#

That's the limitation for IN users. And I'd recommend using SetupIntent flow since it's universally supported in all accounts

hazy light
#

I know we tried that and failed, cannot remember why though.

#

But this is good enough for now, thanks.

#

How can I know if the stripe connect account is indian?

spark fable
hazy light
#

just to be clear

#

having the information that I gave you

#

being the only way we process $

#

why would we need to attach a payment method to a customer?

#

is there a valid reason?

#

we're saving the payment_method_id on our database and we use it afterwards

spark fable
#

You need to attach a payment method to a customer to make it reusable.

hazy light
#

reusable in what sense?

#

reusable in the sense that I can use the payment method id again?

spark fable
#

Reusbale means you can use the same payment method to charge the customer in the future.

hazy light
#

in case of subscriptions, does this apply?

#

because subscriptions by definition charge customers multiple times

spark fable
#

Yes, you are going to use the same payment method for recurring payments right?

hazy light
#

can you clarify that recurring payments = subscriptions?

#

if the customer purchases a subscription

#

he's going to be charged every 30 days

#

is that a problem if the payment method hasn't been attached to his customer object?

#

also, is there a way to test these indian edge cases within test mode? how so?

spark fable
#

OK, subscription for Indian users have its own restrictions

hazy light
#

these indians 🤦‍♂️

spark fable
#

It's very complicated, and I'll strongly recommend you to use Checkout Sessions APIs instead.

hazy light
#

yeah right :p

#

is there a way to simulate all these restrictions in test mode?

#

is there a way to somehow make my connect account test mode indian to see if it works?

spark fable
hazy light
#

ok worked

#

good enough!

#

thanks

#

i just need one last clarification

#

because you weren't very assertive on this

#

does attaching a payment method to a customer matter at all in a subscription flow?

#

why would i need to do it? right now I feel like it's pointless

spark fable
#

OK, let's go back to this question. it depends on whether the susbcription requires a payment when it's created/

hazy light
#

also that doesnt allow me to test it properly, since I'm doing this and ofc the account is always the same country

#

i need to test this with an actual indian account

spark fable
#

If a subscription doesn't requires payment (i.e., trial or payment_behavoiur is allow_incomplete), then you can create a subscription with a customer who doesn't have a payment_method.

hazy light
#

payment_behavior: "default_incomplete"

#

this is what we have

#

so no attaching needed, correct?

spark fable
#

Yes

hazy light
#

awesome thank you so much\

#

you saved us on doing business with india today