#anton-ach
1 messages · Page 1 of 1 (latest)
pi_3LZWqZASzn8WTmrl1dzbeLQe
did you do this step first? https://stripe.com/docs/payments/ach-debit/accept-a-payment?platform=web&ui=API#web-collect-details i.e. you need to call stripe.collectBankAccountForPayment to actually collect the bank details before you can call confirmUsBankAccountPayment
how can I get the data that the user entered for payment_method_data, if I use PaymentElement(react) maybe there is a built-in method for this?
any ideas? In all examples, this data is hardcoded. but I don't understand how to get them from stripe PaymentElement
you don't have to get it yourself, it's supposed to be automatic
sorry, missed your reply
but the way it works is the data is just stored in stripe.js and is available when the confirm method is called later on the same page. Since you're using React, it's likely a component hierachy problem where you are using multiple <Elements> or stripeProviders so the internal stripe.js state is not being persisted properly
i not understand.
what should I send to collectBankAccountForPayment. I have one Element
import React from 'react';
import { loadStripe } from '@stripe/stripe-js';
import { Elements } from '@stripe/react-stripe-js';
import { getClientSecretKey, isStripePopupShow } from '../../../../../selectors/payment.selectors';
import { useDispatch, useSelector } from 'react-redux';
import Popup from '../../../../Popup/Popup';
import StripeACHForm from './StripeACHForm';
import { showStripePopup } from '../../../../../actions/payment.actions';
import styled from 'styled-components';
const stripePromise = loadStripe(
'pk_test_51LD3ddawdawdawddKzWG87TkqPyngOo9m9Wy1UABhzeNof9j00LPbTneO5'
);
const popupOverlayStyle = {
backdropFilter: 'blur(3px)',
};
const popupStyle = {
width: 500,
background: undefined,
};
type AppearanceType = {
theme?: 'stripe' | 'night' | 'flat' | 'none' | undefined;
};
const StripeACH = () => {
const clientSecret = useSelector(getClientSecretKey);
const isShowStripePopup = useSelector(isStripePopupShow);
const dispatch = useDispatch();
const appearance: AppearanceType = {
theme: 'stripe',
};
const options = {
clientSecret,
appearance,
};
const handleClose = () => {
dispatch(showStripePopup(false));
};
if (!isShowStripePopup || !clientSecret) {
return null;
}
return (
<Popup
open={true}
defaultAnimation={false}
popupOverlayStyle={popupOverlayStyle}
popupStyle={popupStyle}
handleClose={handleClose}
closeOnDocumentClick={false}
closeIcon={true}
>
<Container>
<Elements options={options} stripe={stripePromise}>
<StripeACHForm clientSecret={clientSecret} />
</Elements>
</Container>
</Popup>
);
};
export default StripeACH;
import React, { useEffect, useState } from 'react';
import { PaymentElement, useStripe, useElements } from '@stripe/react-stripe-js';
type Props = {
clientSecret: string;
};
const StripeACHForm: React.FC<Props> = ({ clientSecret }) => {
const stripe = useStripe();
const elements = useElements();
const [message, setMessage] = useState('');
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
if (!stripe) {
return;
}
stripe.retrievePaymentIntent(clientSecret).then(({ paymentIntent }) => {
console.log('paymentIntent', paymentIntent);
switch (paymentIntent?.status) {
case 'succeeded':
setMessage('Payment succeeded!');
break;
case 'processing':
setMessage('Your payment is processing.');
break;
case 'requires_payment_method':
setMessage('Your payment was not successful, please try again.');
break;
default:
setMessage('Something went wrong.');
break;
}
});
}, [stripe, clientSecret]);
const handleSubmit = async e => {
e.preventDefault();
if (!stripe || !elements) {
return;
}
setIsLoading(true);
const result = await stripe.confirmUsBankAccountPayment(clientSecret);
if (result.error.type === 'card_error' || result.error.type === 'validation_error') {
setMessage(result.error.message);
} else {
setMessage('An unexpected error occurred.');
}
setIsLoading(false);
};
return (
<form onSubmit={handleSubmit}>
<PaymentElement />
<button disabled={isLoading || !stripe || !elements}>
<span id="button-text">Pay now</span>
</button>
{message && <div id="payment-message">{message}</div>}
</form>
);
};
export default StripeACHForm;
my code
if you're using PaymentElement then as far as I know you don't need to use collectBankAccountForPayment or confirmUsBankAccountPayment at all though
it's simply the same code as you use for cards, which is that you call stripe.confirmPayment
so what happens if you just change to using that?
i.e. instead of const result = await stripe.confirmUsBankAccountPayment(clientSecret); do const result = await stripe.confirmPayment(elements,confirmParams: {return_url:'https://example.com/order/123/complete', });. , exactly the same as in https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements&html-or-react=react#web-submit-payment .
the issue I think is you/I were looking at the docs for using ACH with a custom form, but if you're using the PaymentElement you don't need any of that, it just works the same as the regular PaymentElement guides.
Hey, taking over here. Let me know if there's any follow-up Qs I can answer!