Short answer
A Square test card is a fake card number that only works against Square's sandbox. It runs through the same authorization flow as a live card, comes back with a realistic response, and moves exactly zero dollars. You paste it into your checkout, hit your server, and read the response. No bank, no settlement, no real money.
The numbers I keep in a snippet
Square publishes a short list of card numbers that always approve in sandbox. These are the ones I reach for first:
- Visa: 4111 1111 1111 1111
- Mastercard: 5105 1051 0510 5100
- American Express: 3400 000000 00009
- Discover: 6011 1111 1111 1117
- JCB: 3569 9900 1009 5841
For everything else on the form, use any future expiration date, any 3-digit CVC (4 digits on Amex), and any postal code. One trap worth knowing: the sandbox still runs the Luhn check. If you fat-finger a digit, the request dies before authorization and the error you get looks nothing like a decline. That has cost me half an hour more than once.
Testing the failure paths
Approvals are the easy half of integration work. The half that ships bugs is everything after the charge succeeds, so I spend most of my sandbox time trying to make payments fail on purpose.
Square's sandbox includes test values wired to specific failure modes, which is how you exercise the code that handles an insufficient funds message or an expired card without hunting for a real card that misbehaves. The exact numbers change from time to time, so I pull them from Square's developer docs each time rather than trusting my memory or an old Stack Overflow answer. The categories you can usually force:
- Generic card decline
- Insufficient funds
- Expired card
- CVC mismatch
- Address or postal code mismatch, useful for AVS logic
- Processing or network error
I keep a second browser profile logged into a buyer account and a merchant dashboard side by side. Watching the payment land in the seller's transaction list in real time is the only way to be sure a webhook actually fired and my handler did the right thing with it.
Sandbox and production do not mix
Test numbers return an error in production, and a real card returns an error in sandbox. If a charge fails in live mode with a message that mentions a test card, you almost certainly shipped sandbox credentials alongside a test card. Check your application ID and access token before you debug anything else.
Two other habits that save time: reset the sandbox when your test data gets messy instead of patching it by hand, and log the full response object, not just the boolean success flag. The decline reason code is the part you actually need.
A word about real card data
Test cards exist so you never have to touch a real one during development. Card industry rules, and PCI DSS specifically, forbid storing the CVC after an authorization, and buying or selling live card numbers is card fraud regardless of how it is labeled. If a script or a vendor is feeding you full card data to test with, that is not a test environment. Square's sandbox is free, documented, and does the job.