Card Payment Form
The card form is the last thing between a shopper and a sale, and every error message it shows costs conversions. It should catch obvious typos before anything is sent, explain exactly what is wrong and where, and never let a double click pay twice.
Build the card payment form for a $49.00 order.
Requirements
- Three fields labelled
Card number,Expiry (MM/YY)andCVC, and a submit buttonPay $49.00. - Formatting while typing:
- the card number keeps only digits (at most 19) and shows them in groups of four separated by spaces:
4242 4242 4242 4242; - the expiry keeps up to four digits and inserts a slash after the month: typing
1228shows12/28; - the CVC keeps only digits, at most four.
- the card number keeps only digits (at most 19) and shows them in groups of four separated by spaces:
- Validation on submit. Nothing is sent while any of these fail:
- the card number must have at least 13 digits and pass the Luhn checksum, otherwise
Enter a valid card number.; - the expiry must be
MM/YYwith a month from01to12, otherwiseEnter a valid expiry date.; - the CVC must have 3 digits, or 4 for American Express (numbers starting with
34or37), otherwiseEnter a valid security code.
- the card number must have at least 13 digits and pass the Luhn checksum, otherwise
- Each error is shown under its field; the field gets
aria-invalid="true"and anaria-describedbypointing at the error'sid. After a failed submit, focus moves to the first invalid field. - A valid submit sends
POST /api/paymentswith the JSON body{ "cardNumber": "<digits only>", "expMonth": <number>, "expYear": <number>, "cvc": "<digits>" }. While it is in flight the button readsProcessing...and is disabled. - On success show
Payment successful. On failure the server answers with{ "error": "<reason>" }: show that reason in an alert and enable the button again.
The setup
The files open on a skeleton. Build the behaviour the requirements describe.
- src/main.jsx
- src/App.jsx
- src/styles.css
The preview has no network. fetch is answered by this problem's API:
- POST /api/payments
Follow-up: Your company wants this form without its servers ever touching card numbers. What changes when the three inputs live in iframes served by the payment provider, and what can your page still validate itself?
- React with JavaScript and plain CSS; every file is editable. - Use a real `form` with `noValidate`, labelled `input`s and a submit `button`. - This is a practice exercise: the mock API never sees real card data, and production forms send card numbers to a payment provider's hosted fields instead.
- Views
- 2