fix payment method page element loading

this resolves the race condition issue when loading recurly payment element
and hence sometimes it wasn't showing
This commit is contained in:
Nuwan 2025-08-20 20:31:44 +05:30
parent a84a55f178
commit d424026f17
1 changed files with 36 additions and 106 deletions

View File

@ -16,7 +16,7 @@ import iconPaypalFull from '../../assets/img/icons/icon-paypal-full.png';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { updatePayment } from '../../helpers/rest'; import { updatePayment } from '../../helpers/rest';
import { useAuth } from '../../context/UserAuth'; import { useAuth } from '../../context/UserAuth';
import { getBillingInfo, updateBillingInfo, getUserDetail, getCountries } from '../../helpers/rest'; import { getBillingInfo, getUserDetail, getCountries } from '../../helpers/rest';
import { useForm, Controller } from 'react-hook-form'; import { useForm, Controller } from 'react-hook-form';
import Select from 'react-select'; import Select from 'react-select';
import { useResponsive } from '@farfetch/react-context-responsive'; import { useResponsive } from '@farfetch/react-context-responsive';
@ -30,7 +30,6 @@ const JKPaymentMethod = () => {
const [countries, setCountries] = useState([]); const [countries, setCountries] = useState([]);
const labelClassName = 'ls text-600 font-weight-semi-bold mb-0'; const labelClassName = 'ls text-600 font-weight-semi-bold mb-0';
const [submitting, setSubmitting] = useState(false); const [submitting, setSubmitting] = useState(false);
const [billingDataLoaded, setBillingDataLoaded] = useState(false);
const [isCardValid, setIsCardValid] = useState(false); const [isCardValid, setIsCardValid] = useState(false);
const { greaterThan } = useResponsive(); const { greaterThan } = useResponsive();
@ -74,7 +73,6 @@ const JKPaymentMethod = () => {
if (userData.has_recurly_account) { if (userData.has_recurly_account) {
setHasStoredCreditCard(userData['has_stored_credit_card?']); setHasStoredCreditCard(userData['has_stored_credit_card?']);
await populateBillingAddress(); await populateBillingAddress();
setBillingDataLoaded(true);
} }
} catch (error) { } catch (error) {
console.error('Failed to get user details:', error); console.error('Failed to get user details:', error);
@ -128,30 +126,19 @@ const JKPaymentMethod = () => {
setValue('country', selectedOption.value); setValue('country', selectedOption.value);
}; };
const recurlyContainerRef = useRef();
useEffect(() => { useEffect(() => {
if (!window.recurly) return; if (!recurlyContainerRef.current || !window.recurly || recurlyConfigured.current) return;
if (recurlyConfigured.current) return;
const interval = setInterval(() => {
const container = document.querySelector('#recurly-elements');
console.log('Checking for Recurly Elements container:', container);
if (container && window.recurly) {
console.log('Initializing Recurly Elements...');
window.recurly.configure({ publicKey: process.env.REACT_APP_RECURLY_PUBLIC_API_KEY }); window.recurly.configure({ publicKey: process.env.REACT_APP_RECURLY_PUBLIC_API_KEY });
const elements = window.recurly.Elements(); const elements = window.recurly.Elements();
const cardElement = elements.CardElement(); const cardElement = elements.CardElement();
cardElement.attach('#recurly-elements');
cardElement.attach(recurlyContainerRef.current);
cardElement.on('change', (event) => { cardElement.on('change', (event) => {
if (event.complete) { setIsCardValid(event.complete && !event.error);
setIsCardValid(true);
} else if (event.error) {
setIsCardValid(false);
} else {
setIsCardValid(false);
}
}); });
//then load paypal: //then load paypal:
@ -162,12 +149,13 @@ const JKPaymentMethod = () => {
elementsRef.current = elements; elementsRef.current = elements;
recurlyConfigured.current = true; recurlyConfigured.current = true;
clearInterval(interval);
}
}, 100);
return () => clearInterval(interval); return () => {
}, []); // Optional cleanup if the component unmounts
recurlyContainerRef.current.innerHTML = '';
recurlyConfigured.current = false;
};
}, [recurlyContainerRef.current]);
const onPayPalError = (error) => { const onPayPalError = (error) => {
console.error('PayPal Error:', error); console.error('PayPal Error:', error);
@ -196,67 +184,9 @@ const JKPaymentMethod = () => {
}); });
}; };
// const onSubmit = async (data) => {
// //first update billing address
// setSubmitting(true);
// const resp = await updateBillingInfo(data)
// if (!resp.ok) {
// setSubmitting(false);
// const errorData = await resp.json();
// console.error('Error updating billing info:', errorData);
// toast.error(errorData.message || t('payment_method.alerts.billing_update_error'));
// return;
// }
// if (paymentMethod === 'paypal') {
// handoverToPaypal();
// return;
// } else {
// if (!elementsRef.current) {
// console.error('Recurly elementsRef.current is not ready');
// setSubmitting(false);
// return;
// }
// if (!formRef.current) {
// console.error('formRef.current is not ready');
// setSubmitting(false);
// return;
// }
// // if (!isCardValid) {
// // console.error('Card is not valid');
// // toast.error(t('payment_method.validations.card.invalid'));
// // setSubmitting(false);
// // return;
// // }
// window.recurly.token(elementsRef.current, formRef.current, (err, token) => {
// if (err) {
// console.error('Recurly token error:', err);
// toast.error(err.message || t('payment_method.alerts.card_processing_error'));
// setSubmitting(false);
// } else {
// console.log('Recurly token:', token.id);
// // send token.id to backend
// handleUpdatePayment(token);
// }
// });
// }
// };
const onSubmit = async (data) => { const onSubmit = async (data) => {
//first update billing address
setSubmitting(true); setSubmitting(true);
// const resp = await updateBillingInfo(data) if (paymentMethod === 'paypal') { // PayPal payment method
// if (!resp.ok) {
// setSubmitting(false);
// const errorData = await resp.json();
// console.error('Error updating billing info:', errorData);
// toast.error(errorData.message || t('payment_method.alerts.billing_update_error'));
// return;
// }
if (paymentMethod === 'paypal') {
handoverToPaypal(); handoverToPaypal();
return; return;
} else { // Credit Card payment method } else { // Credit Card payment method
@ -490,7 +420,7 @@ const JKPaymentMethod = () => {
</Row> </Row>
<Row> <Row>
<Col sm={8}> <Col sm={8}>
<div id="recurly-elements"></div> <div id="recurly-elements" ref={recurlyContainerRef}></div>
{!isCardValid && errors.recurly && ( {!isCardValid && errors.recurly && (
<div className="text-danger"> <div className="text-danger">
<small>{errors.recurly.message}</small> <small>{errors.recurly.message}</small>