import React, { useEffect, useState } from 'react';
const Checkout = () => {
const [paymentFormLoaded, updatePaymentFormLoaded] = useState(false);
const paymentForm = new SqPaymentForm({
applicationId: APPLICATION_ID,
inputClass: "sq-input",
autoBuild: false,
cardNumber: {
elementId: "sq-card-number",
placeholder: "Card Number"
},
cvv: {
elementId: "sq-cvv",
placeholder: "CVV"
},
expirationDate: {
elementId: "sq-expiration-date",
placeholder: "MM/YY"
},
postalCode: {
elementId: "sq-postal-code",
placeholder: "Postal"
},
callbacks: {
paymentFormLoaded: () => {
updatePaymentFormLoaded(true);
console.log('Form loaded.');
},
cardNonceResponseReceived: (errors, nonce, cardData) => {
if (errors) {
console.error(errors);
return;
}
console.log('Nonce received.');
}
}
});
useEffect(() => {
if (!paymentFormLoaded) {
console.log('Form loading...');
paymentForm.build();
}
});
return (
<>
<div id="form-container">
<div id="sq-card-number" />
<div className="third" id="sq-expiration-date" />
<div className="third" id="sq-cvv" />
<div className="third" id="sq-postal-code" />
</div>
{paymentFormLoaded && (
<button
className="sq-input"
onClick={() => {
console.log('Requesting nonce...');
paymentForm.requestCardNonce();
}}
>
Place your order
</button>
)}
</>
);
};
export default Checkout;
So far as I can tell, the logic is sound; however, clicking on the "Place your order" button produces this error in the browser's console:
Uncaught FormNotReadyError: Cannot call SqPaymentForm#requestCardNonce before the paymentFormLoaded() callback. See Step 4: https://developer.squareup.com/docs/payment-form/how-it-works#the-sqpaymentform-process-flow
This doesn't seem to make sense though, because the button wouldn't even be rendered if the form hadn't successfully loaded.