#nykka

1 messages ยท Page 1 of 1 (latest)

analog summitBOT
haughty glen
#

Hello! Do you have a screenshot of the error you can share here?

arctic ruin
#

Sure

haughty glen
#

Interesting. And then they click on the pay button again and it works the second time?

arctic ruin
#

Yes

haughty glen
#

Can you share the code that's surfacing the "Please fill in your card details" message?

arctic ruin
#

What do you mean with the code that's surfacing the message?

haughty glen
#

The "Please fill in your card details" is being displayed by your integration, correct? I don't believe that's part of the Payment Element.

arctic ruin
#

I'm using the payment element, I'm pretty sure we are not validating the inputs but I'll check it and come back to you

haughty glen
#

Yeah, if you could share your Payment Element code, especially the error handling part, that would be helpful.

arctic ruin
#

Here's the code

#
<form
            id="payment-form"
            onSubmit={handleSubmit}
            aria-labelledby="payment-message"
        >
            <p className="font-adieu text-xs uppercase">payment method</p>
            <PaymentElement
                id="payment-element"
                onChange={(e) => handlePaymentChange(e)}
            />
            {/* Show any error or success messages */}
            {message && (
                <div
                    id="payment-message"
                    aria-live="polite"
                    className={`${messageColor[messageType]} mb-4 text-center`}
                >
                    {message}
                </div>
            )}
            <Button
                type="submit"
                className="my-4"
                id="button"
                isDisabled={isLoading || shouldBeDisabled || !paymentIsComplete}
                appearance="primary"
            >
                {isLoading ? "Processing..." : `Pay $${total}`}
            </Button>
            <PendingPayment isOpen={isLoading} />
        </form>
#

Here is how we handle errors

#
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        setIsLoading(true);

        if (!stripe || !elements) {
            // Stripe.js has not yet loaded.
            // Make sure to disable form submission until Stripe.js has loaded.
            return;
        }

        const { error } = await stripe.confirmSetup({
            elements,
            confirmParams: {
                return_url: `${window.location.origin}/confirm-payment/thank-you`,
            },
        });

        // This point will only be reached if there is an immediate error when
        // confirming the payment. Otherwise, your customer will be redirected to
        // your `return_url`. For some payment methods like iDEAL, your customer will
        // be redirected to an intermediate site first to authorize the payment, then
        // redirected to the `return_url`.
        if (error.type === "card_error" || error.type === "validation_error") {
            setMessage(error.message);
            setMessageType("error");
            setIsLoading(false);
            Bugsnag.notify(JSON.stringify(error));
        } else {
            setMessage("An unexpected error occurred.");
            setMessageType("error");
            setIsLoading(false);
            Bugsnag.notify(
                JSON.stringify("An unexpected error occurred with Stripe."),
            );
        }
    }; ```
haughty glen
#

Can you also share the handlePaymentChange() function code?

arctic ruin
#

Sure

#
const handlePaymentChange = (e: StripePaymentElementChangeEvent) => {
        setPaymentIsComplete(e.complete);
        setIsLoading(false);
    }; ```
haughty glen
#

Are you able to reproduce this issue on demand?

arctic ruin
#

I think so, let me check

#

I'm trying with the iOS simulator because I don't have an Iphone ๐Ÿฅฒ

haughty glen
#

If you can reproduce I would be interested to know what the full error object coming from stripe.confirmSetup looks like.

arctic ruin
#

I think I can check the logs on bugsnag

haughty glen
#

Just to confirm, you don't have multiple Payment Elements on the page or anything like that, right?

arctic ruin
#

Nope, just one

haughty glen
#

When this happens, in the payment sheet, does it change from "Amount Pending" to show the amount before it dismisses, or does it stay on "Amount Pending" the whole time?

arctic ruin
#

It says Amount Pending all the time

haughty glen
#

Hm. Can you share the code you're using to initialize Stripe Elements?

arctic ruin
#

Sure!

#

{checkoutState && checkoutState.data && checkoutState.data.intent_client_secret && ( <Elements options={{ clientSecret: checkoutState.data.intent_client_secret, appearance, }} stripe={stripePromise} > <div> {/* STRIPE ADDRESS ELEMENT */} <AddressForm handleShippingAddress={handleShippingAddress} initialValues={initialValues} isFetchingAddress={isFetchingAddress} submitAddressError={submitAddressError} cats={catsInStoreValues} lineItems={checkoutData.line_items} totalPrice={checkoutData.total_price} checkoutId={checkoutData.id} handleNavigateToPortal={handleNavigateToPortal} /> </div> {/* BILLING STEP */} <div> {/* STRIPE PAYMENT ELEMENT */} <CheckoutForm total={checkoutData.total_price} returnUrl={checkoutData.return_url} initialValues={initialValues} shouldBeDisabled={currentStep === CheckoutStep.Shipping} /> </div> </Elements> )}

haughty glen
#

The thing that's really throwing me for a loop is that it works the second time. ๐Ÿ˜…

arctic ruin
#

hahaha

#

Yeah, that's weird

haughty glen
#

The fact that it's throwing the "Please fill in your card details" error when Apple Pay is selected is also very strange. That should only come up when Card is selected.

arctic ruin
#

Not sure how to proceed :/

haughty glen
#

Yeah, I'm looking at your code again for anything I might have missed...

#

Oh, you didn't find anything useful in BugSnag?

arctic ruin
#

I couldn't find any record but I'm asking a co worker (who owns an Iphone) to reproduce the error so I can check on today's logs

haughty glen
#

Do you happen to have one of the Setup Intent IDs involved when the error happened?

arctic ruin
#

Let me see if I can get it

analog summitBOT
haughty glen
#

Thanks! I'm heading out for now, but there's someone else jumping in who will hopefully see something I missed. ๐Ÿ™‚

arctic ruin
#

seti_1MwQlHIm407W2EQ5uKvzJPYg

sour hull
#

Thank you for the ID. Checking in to that

#

Also to be clear was this ever working on iOS safari or has it been like this since it has been used?

arctic ruin
#

Good question. I'll ask!

#

So, it is working on staging but we get that error on prod

sour hull
#

Very helpful to know. Can you get a diff of this code between your prod and staging environments?

arctic ruin
#

The code should be exactly the same, but let me double check

sour hull
#

Can you try logging your client secret before it is confirmed? My colleague has a theory that these may be two different setup intents being confirmed between the two times

arctic ruin
#

I'm adding @primal gale to the thread, he's the backend dev for this project

#

How can I do that?

#

I mean, logging the client's secret

#

btw, I made a diff between main (prod) and develop (staging) and they are exactly the same

#

Sorry, now I get what you meant

analog summitBOT
bronze kettle
#

๐Ÿ‘‹

#

Did you log the client secret here before confirming @arctic ruin ?

arctic ruin
#

Yes, and it seems to be always the same. Have in mind i'm testing it in my local env with a credit card. I'm thinking about using the ipad to test it with Apple Pay but I need to do some steps before I can do it.

bronze kettle
#

Yeah if it is always the same then that is likely the issue here

#

Let's back up a second.

#

It looks like you are creating a Subscription with a trial here, correct?

arctic ruin
#

I'm charging the customer with a trial and then creating a subcription for the next upcoming boxes

bronze kettle
#

Hmm what do you mean exactly by "charging the customer with a trial"?

#

Like the trial is part of the Subscription, yes?

#

Based on the SetupIntent you provided above, it looks to me like you create a SetupIntent and then create a trialing Subscription.

#

Is that correct?

arctic ruin
#

Yes

bronze kettle
#

So you don't actually want to be creating a SetupIntent ahead of time here

#

You want to just create the Subscription and expand the pending_setup_intent

#

Then you pass that SetupIntent's client_secret to your frontend to render Payment Element

arctic ruin
#

What we do is we change the customer for a trial/sampler for the first time, and after they get that trial/sampler they are automatically subscribed to the service. The trial is not part of the subscription, because it's just a sampler of our products.

#

Does that make sense?

bronze kettle
#

Hmm so you are just collecting a payment method (and providing a sample to the customer when you do that), then later on you create a Subscription?

arctic ruin
#

Exactly

bronze kettle
#

Why not just create a trialing Subscription when you collect the payment method?

arctic ruin
#

Well, I'm sure the back end dev had their reasons to make it like that

#

We have been sharing the complete flow with Stripe via email and they agreed it was ok for our business needs.

bronze kettle
#

Gotcha

#

Well in that case you want to check on the client secret that you use to render Payment Element

arctic ruin
#

Thanks! What should I be checking on?

bronze kettle
#

You want to log out the actual client secret that was used to confirm when you saw the error

arctic ruin
#

Ok, i'll do that but It will take me some time to do it lol

#

I'll get back to you as soon as I get something

bronze kettle
#

๐Ÿ‘

arctic ruin
#

Thank you all!