Short answer
There is no single PayPal test card number that works for everyone. PayPal generates test card numbers inside the Developer Dashboard, and each one belongs to a specific sandbox account. You pick or create a sandbox buyer account, generate its card, then use that number, expiry, and CVV when you test card payments against sandbox endpoints.
Where the number actually comes from
Sign in to the PayPal Developer Dashboard and open Sandbox > Accounts. Choose a personal (buyer) sandbox account or create a new one, then look for the option to generate a test card for it. What comes back is a card number, a future expiry date, and a CVV tied to that profile. Regenerate the card and the old values stop working, which is why copying a number out of an old forum post rarely gets you anywhere.
How sandbox cards behave
- They only work with sandbox credentials, such as calls to the sandbox REST host or the older sandbox NVP endpoint.
- Mixing a live client ID with a sandbox card produces an authentication failure, not a card decline, so read the error body before assuming the number is bad.
- Generated expiry dates sit in the future. If you need to test expired-card handling, that usually comes from negative testing settings rather than an old date.
- Not every decline reason can be triggered by typing a wrong digit. Some scenarios are produced by sandbox tooling or by the API request itself.
Testing the flow, not just the number
A card number on its own proves very little. I focus on the full path: create the order, confirm the buyer approval step, capture the payment, then check the webhook that fires and the transaction record it leaves behind. That is where real integration bugs show up, like a capture that succeeds while your order table still says pending.
Also worth exercising: an AVS or CVV mismatch to see how your UI handles a soft decline, a retry after a failed capture, and any 3D Secure or strong customer authentication prompt the sandbox throws at you. Keep your sandbox client ID and secret in environment variables so a stray live key never ends up in a test run.
Mistakes I see often
- Hardcoding a card number from a tutorial and assuming it still maps to your account.
- Testing with a real card, which breaks PCI rules and can get the account flagged.
- Ignoring the sandbox dashboard logs when a payment fails, then guessing at the cause.
- Rebuilding sandbox accounts without updating the test fixtures in the codebase.
Bottom line
Treat the sandbox card as a credential tied to one account, regenerate it when you rotate accounts, and spend your time on the surrounding flow instead of hunting for a magic number that does not exist.