#mikesmith7748
1 messages ยท Page 1 of 1 (latest)
Hello mikesmith7748, we'll be with you shortly! Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
โข https://discord.com/channels/841573134531821608/1163914150813126737, 0 days ago, 19 messages
I messaged a little while ago about using the ElementsConsumer and how I needed the clientSecret && stripePromise to be able to render all payment methods without getting a cross origin error. I was directed to using the deferred flow (https://stripe.com/docs/payments/accept-a-payment-deferred?platform=web&type=payment) to get around needing the clientSecret before rendering a payment element.
I'm now trying use the deferred flow and it's changing my ACH form to a credit card form
It was this
Now it's this
Can you share the code you're using to create the element?
I changed the options to use what is in the docs:
appearance,
mode: 'payment',
amount: 1099,
currency: 'usd',
};```
Is there a way to specify using ACH?
I think you can set paymentMethodTypes to us_bank_account
https://stripe.com/docs/js/elements_object/create_without_intent#stripe_elements_no_intent-options-paymentMethodTypes
Here's the whole code block:
const clientSecret = props.clientSecret;
const stripePromise = props.stripePromise;
const appearance = {
variables: {
fontFamily: "montserrat, system-ui, sans-serif",
spacingGridRow: "20px"
}
};
const options = {
appearance,
mode: 'payment',
amount: 1099,
currency: 'usd',
};
return (
(<Elements stripe={stripePromise} options={options}>
<ElementsConsumer>
{({ stripe, elements }) => (
<ConnectedPaymentInfoStep
withAchProps={props.withAchProps}
stripe={stripe}
elements={elements}
{...props}
/>
)}
</ElementsConsumer>
</Elements>)
);
};
The issue there is that I have multiple payment methods available. One is for credit card and one is for ACH
The code as it is now throws a cross origin error
Can you share the error you're seeing?
But when I change it to clientSecret && stripePromise && (<Elements stripe={stripePromise} options={options}> it works
But I don't want to check for clientSecret before rendering the form
Here's the cross origin error
Huh that's weird, just adding paymentMethodTypes in options throws a cors error?
No, this will error: (<Elements stripe={stripePromise} options={options}>
But this will not: clientSecret && stripePromise && (<Elements stripe={stripePromise} options={options}>
That seems to be a bug in your project though. Seems like stripePromise isn't correctly being intialized before you pass it in to <Elements />
change it to stripePromise && (<Elements stripe={stripePromise} options={options}> and try?
The issue is that if one of the payment methods errors out, all payment methods won't render. I want it to still render other payment methods if one fails
Yeah still the same error with only stripePromise
Let's take a step back and solve one problem at a time.
The CORS error isn't really being thrown by the React Stripe.js code.
It's most likely coming from something else.
also we recommend using useElements hook for functional components
https://stripe.com/docs/stripe-js/react#useelements-hook
Any specific reason you're using ElementsConsumer?
Yeah it's a class component so we're using the HOC
I had the idea of using hooks but I'd have to rewrite the whole file which is huge
Gotcha. What does <ConnectedPaymentInfoStep /> do?
It's just wrapping all of the HOCs
const ConnectedPaymentInfoStep = injectT(withRouter(connector(PaymentInfoStep)));
PaymentInfoStep is the actual class name
And where are you adding <PaymentElement />?
It's in another component called <CheckoutForm/> that's being injected into the PaymentInfoStep component
Can you share that code too? Relevant parts
stripe={this.props.stripe}
elements={this.props.elements}
{...this.props} />```
Sorry formatting
You don't have a separate iframe that embedds PaymentElement, correct?
Inside that component:
useEffect(() => {
if (!stripe || !clientSecret) {
return;
}
}, [stripe]);
const handleSubmit = () => {
//API call
}
return (
<>
<form id="payment-form" onSubmit={handleSubmit}>
<PaymentElement id="payment-element" onChange={handleChange} />
<span>
<button className="checkout-flow-button place-order instant-ach-button" id="submit">
<T>{props.isOrderDetailsPage ? "Pay Balance" : "Place Order"}</T>
</button>
</span>
</Tooltip>
</form>
</>
);
}```
Gotcha. How are you importing/including Stripe.js?
Are you using an NPM package?
https://stripe.com/docs/stripe-js/react#setup
Or just including the <script> tag in the index.html?
I'm importing import { CardElement, Elements, ElementsConsumer } from '@stripe/react-stripe-js'; in the parent component
Yes, it's an npm package
package.json: "@stripe/stripe-js": "1.46.0",
if you remove
withAchProps={props.withAchProps}
stripe={stripe}
elements={elements}
{...props}
/>```
and directly implement `<PaymentElement />` in `InjectedCheckoutForm` does the error go away?
currently focusing on getting rid of the cors error, after that we can figure out the ACH/Card UI stuff
That causes a compile error
Oh you meant putting the payment element in there as a replacement
Yeah same cors error
Can you print out stripePromise when InjectedCheckoutForm HOC gets called?
Ah, had a different bug that caused the error. I had paymentMethodTypes: "us_bank_account" in the options
I removed it and the PaymentElement you told me to replace is now working
Ah interesting, I think the string we're setting it to is wrong
let me check something
yeah it said it has to be an array
ok that worked
now to replace the other ConnectedPaymentInfoStep and see if that works
Not seeing CORS anymore, correct?
correct
yeah it's a super weird edge case
so now i have:
const clientSecret = props.clientSecret;
const stripePromise = props.stripePromise;
const appearance = {
variables: {
fontFamily: "montserrat, system-ui, sans-serif",
spacingGridRow: "20px"
}
};
const options = {
appearance,
mode: 'payment',
amount: 1099,
currency: 'usd',
paymentMethodTypes: ["us_bank_account"]
};
return (
(<Elements stripe={stripePromise} options={options}>
<ElementsConsumer>
{({ stripe, elements }) => (
<ConnectedPaymentInfoStep
withAchProps={props.withAchProps}
stripe={stripe}
elements={elements}
{...props}
/>
)}
</ElementsConsumer>
</Elements>)
);
};```
without having clientSecret && stripePromise
and that works
but with the options specifying paymentMethodTypes: ["us_bank_account"] and i want to add another payment method like credit card, will that mess anything up?
if you remove that, you should see more payment methods show up
it pulls active payment methods from your account settings
so if i want credit card and ach, the options won't force both to be ach?
Not sure what you mean by that. Either you pass the payment methods you want to support manually by specifying in paymentMethodTypes OR you remove it & rely on automatic payment methods
i mean like on the checkout page, if i have an option for credit card, then below that an option for ACH, will the options paymentMethodTypes: ["us_bank_account"] force both options to be ACH?
Oh so you have two PaymentElements on one page?
ugh this is why it's complicated
so we have a CardElement from a long time ago
i know it's deprecated
and then this new PaymentElement
so both are on the same page
it seems to be working fine
Gotcha. The settings for the PaymentElement shouldn't affect CardElement.
You should really just merge them and use one PaymentElement instead
updating the CardElement would be a huge lift how they have it coded so i just left it there
It would allow you to enable more payment methods later on, when you're ready
NP! ๐
PaymentElement also supports accordian layout if that's what you need to make the transition pitch easier ๐
https://stripe.com/docs/payments/payment-element
so say i did update that to another PaymentElement, would i need to specify each one?
With two payment elements, thing would get quite messy and I'd highly recommend against it
But yeah, theoratically you could create two separate elements instances.
I haven't tried it myself and wouldn't recommend it either
so something like this
PaymentElement accordian layout can do it all