#dash61_api

1 messages ยท Page 1 of 1 (latest)

grave jungleBOT
#

๐Ÿ‘‹ Welcome to your new thread!

โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always 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/1243198790345687091

๐Ÿ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

proven belfry
#

The confirm payment request id is req_pt5Ltof1qRq7zk.

#

I'm doing all this in test mode. I can show you the calls I make if you need that.

deep panther
#

Hi there ๐Ÿ‘‹ this does seem odd, I'm trying to think through what we need to look at here.

proven belfry
#

Ok, thanks

deep panther
#

Is this a new flow that you're building, or was this working before and then stopped?

proven belfry
#

I had another app that had payments, but not subscriptions, and I copied that project to this new one and started editing. That old project worked. Now I changed the old call from creating a payment to one creating a subscription and it is now failing.

deep panther
#

Hm, yeah, can we look at your code then. Let's start with the frontend code for the payment element, particularly how you're initializing elements.

proven belfry
#

Here is the basic flow:
import {PaymentElement, useStripe, useElements} from '@stripe/react-stripe-js';
...
function SignupPage() {
const stripe = useStripe();
const elements = useElements(); // need mode='subscription'

const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    ...
    const {error: submitError} = await elements.submit();
    ...
    const csParams: ICreateSubsParams = { id: customerId, metadata, priceId, plan: newPlan };
    // Call into the server to create the subs:
    const subsInfo = await callNetlify<ICreateSubsParams, ICreateSubsReturnType>("cs", csParams);
    (handle errors ...
    )

    const {error, paymentIntent} = await stripe.confirmPayment({
        elements,       // `Elements` instance that was used to create the Payment Element
        clientSecret: subsInfo.clientSecret,
        confirmParams: { return_url: SIGNUP_RETURN_URL },
        redirect: "if_required",
    });

}

inside a form:

    <PaymentElement onChange={(e) => handlePEType(e)} />  // options={{ fields: { billingDetails: "auto"}}}
#

Yeah, I had seen something about that mode but didn't know where it was set. I looked through my settings and also at the PaymentElement args, but didn't find it.

#

The PaymentElement doesn't have a mode option. I looked at that before. Perhaps I need to use Element instead, like that article you linked to did?

deep panther
#

Hm, for your payment flow, were you creating the intent first there too the way you're creating the Subscription first here?

proven belfry
#

No, I don't create a payment intent. I create the subscription, and it creates one and I return that to the client, though I don't use it when calling confirmPayment, just the client secret.

deep panther
#

Sorry, I was asking about the payment flow that you used as a starting point for this Subscription flow, but that's alright we can set that aside. I'm also stumbling a bit because this is react which I'm not as familiar with.

I see you shared the part that uses useElements, which looks like the path for using the Elements instance in other places:
https://docs.stripe.com/stripe-js/react#useelements-hook

Can you share how you're setting up the Elements provider?
https://docs.stripe.com/stripe-js/react#elements-provider

grave jungleBOT
proven belfry
#

Yeah in the old code I did create a payment intent. Just a sec on the elements provider.

#

I am basically doing this:
import {PaymentElement, useStripe, useElements} from '@stripe/react-stripe-js';

const CheckoutForm = () => {
const stripe = useStripe();
const elements = useElements(); // need mode='subscription'
return (
<form>
<PaymentElement />
<button>Submit</button>
</form>
);
};

export default CheckoutForm;

full anchor
#

Specifically when you initialize elements

#

calling useElements just uses the Elements provider that you initialize elsewhere

proven belfry
#

I don't initialize anything else. My code is just like in that link in the section "useStripe" or "useElements".

full anchor
#

Then where are you passing client secret

proven belfry
#

Oh ok, never mind, I found code in my main.txs where I initialize stripe - and there I have mode: 'payment' in the options.

#

That's what is wrong.

full anchor
#

AH yep

proven belfry
#

Let me get my code back to working state and try this out.

#

Ok, that worked. Thanks! Some of that original code I had written last year and forgotten about.

full anchor
#

Cool glad you got it working