How to test PayPal and Braintree sandbox payments
PayPal and Braintree both give you a full sandbox, but they simulate failures in very different ways. PayPal uses special values in the name field and a mock-response header; Braintree uses the transaction amount and specific CVV and postal codes. This guide shows how to reproduce each outcome in both, with values taken from the official documentation.
Key takeaways
- PayPal card declines are triggered by typing a
CCREJECT-…value in the first name or name-on-card field, not by special card numbers. The values are case-sensitive. - In Braintree, the amount decides a transaction’s outcome and the card number decides a verification’s outcome. 2000.00–2999.99 returns a processor decline equal to the amount.
- Braintree CVV and postal code values (such as CVV 200 or postal code 20000) only reject transactions if AVS and CVV rules are enabled in the sandbox.
- Both sandboxes are separate from production: credentials, settings and test data never carry over, and test cards only work against the sandbox.
On this page
- Two sandboxes, two sets of credentials
- Set up the PayPal sandbox and test buyers
- Test card payments in PayPal Expanded Checkout
- Test 3D Secure in PayPal
- Test Braintree transactions with amounts
- Failed verifications, card types and fraud tools
- CVV and AVS rules in the Braintree sandbox
- Test 3D Secure 2 in Braintree
- A combined test matrix
- Frequently asked questions
PayPal and Braintree are often integrated side by side: PayPal Checkout for wallet payments and card fields, Braintree for merchants who want a full card gateway with vaulting and fraud tools. Both are PayPal services and both document their testing on developer.paypal.com, yet their sandboxes work differently. A test plan written for one won’t carry over to the other unchanged, so this guide treats them separately and then combines them into one test matrix.
Two sandboxes, two sets of credentials
The PayPal sandbox is, in PayPal’s words, a self-contained virtual testing environment that simulates the live production environment. You create an app in the developer dashboard, use its sandbox client ID and secret, and call the sandbox API endpoints (api-m.sandbox.paypal.com). Activity there creates mock transactions only.
The Braintree sandbox is a separate account with its own login, merchant ID and API keys. Braintree’s documentation is explicit that the sandbox is an entirely separate environment from production and that nothing created there — processing options, recurring billing settings — transfers to production. Plan to configure both environments independently and to keep their credentials in separate configuration entries.
| PayPal (Checkout / Expanded Checkout) | Braintree | |
|---|---|---|
| Credentials | Sandbox client ID and secret per app | Sandbox merchant ID, public key and private key |
| Wallet buyers | Sandbox personal accounts | Mocked PayPal flow inside the Braintree sandbox |
| Card declines | Name-field triggers (CCREJECT-…) | Transaction amount (2000.00–2999.99) |
| API error simulation | PayPal-Mock-Response header | Specific amounts (for example 3000.00, 5001.00) |
| 3D Secure | Country-specific 3DS test cards | 3DS 2 test cards, expiry 01 / current year + 3 |
Set up the PayPal sandbox and test buyers
You create and manage sandbox accounts from the sandbox Accounts page in the developer dashboard. Create at least one business account (the merchant receiving funds) and one personal account (the buyer). To pay with the PayPal wallet in your test checkout, log in to the PayPal pop-up with the personal account’s sandbox credentials. To see the result from the merchant side, log in to the sandbox site at sandbox.paypal.com with the business account and review the mock transactions.
Useful wallet scenarios to cover:
- The buyer approves the payment and your server captures the order.
- The buyer closes the pop-up or cancels — your page must leave the cart intact and allow a retry.
- The capture fails after approval — use negative testing (below) to force it and check that you don’t mark the order as paid.
Test card payments in PayPal Expanded Checkout
Expanded Checkout (also called advanced card payments) renders card fields on your page. In the sandbox, use PayPal’s static test cards with any future expiry date and a three-digit CVV (four digits for American Express). PayPal also offers a credit card generator on its developer site that produces more sandbox cards, which you can add to a sandbox account or use directly.
| Brand | Sandbox test card |
|---|---|
| Visa | 4012 8888 8888 1881 |
| Mastercard | 2223 0000 4840 0011 |
| American Express | 3714 496353 98431 |
| Maestro | 6304 0000 0000 0000 |
| UnionPay (CUP) | 6200 6800 0000 0004 |
PayPal lists its 3636… test cards under JCB, although numbers starting with 36 normally belong to Diners Club. If your own brand detection labels them differently, that is expected rather than a bug. More cards are on our PayPal test cards page.
Rejection triggers: forcing card declines
PayPal doesn’t use special card numbers for declines. Instead, enter a rejection trigger in the First Name or Name on Card field. PayPal suggests a Visa such as 4012 8888 8888 1881 with a future expiry and any CVV for these tests. The values are case-sensitive.
| Name on card | Scenario | Processor response |
|---|---|---|
CCREJECT-REFUSED | Card refused | 0500 DO_NOT_HONOR |
CCREJECT-IF | Insufficient funds | 5120 INSUFFICIENT_FUNDS |
CCREJECT-EC | Card expired | 5400 EXPIRED_CARD |
CCREJECT-CVV_F | CVC check fails | 00N7 CVV2_FAILURE_POSSIBLE_RETRY_WITH_CVV |
CCREJECT-IRC | Luhn check fails | 5180 INVALID_OR_RESTRICTED_CARD |
CCREJECT-IA | Card not valid | 1330 INVALID_ACCOUNT |
CCREJECT-SF | Fraudulent card | 9500 SUSPECTED_FRAUD |
CCREJECT-LS | Card lost or stolen | 9520 LOST_OR_STOLEN |
CCREJECT-BANK_ERROR | Card declined | 5100 GENERIC_DECLINE |
The important behavior to test: the order is still created, but the card payment comes back with the status DECLINED. Code that checks only for an HTTP error will treat these as successes. Read the capture status, and for codes such as SUSPECTED_FRAUD, INVALID_OR_RESTRICTED_CARD and LOST_OR_STOLEN — which PayPal marks “try using another card, do not retry the same card” — ask the buyer for a different payment method rather than offering a retry.
Negative testing with the mock-response header
For API-level errors that a card trigger can’t produce, PayPal’s negative testing lets you add a PayPal-Mock-Response header to a sandbox request. The header configures the sandbox to return the error code you name:
PayPal-Mock-Response: {"mock_application_codes": "DUPLICATE_INVOICE_ID"}PayPal’s own Expanded Checkout sample code includes commented-out mock headers for capture errors such as INSTRUMENT_DECLINED and TRANSACTION_REFUSED. Wire the header behind a test-only flag so it can never be sent from production code.
Test 3D Secure in PayPal
PayPal supports 3D Secure for card fields in countries with a PSD2 compliance mandate. Pass SCA_ALWAYS to trigger authentication on every transaction or SCA_WHEN_REQUIRED to authenticate only when a regional mandate such as PSD2 requires it. The approval callback returns a liability-shift value that your page uses to decide whether to capture.
PayPal’s US purchase-flow test cases include, for Visa:
| Card | Scenario | liability_shift |
|---|---|---|
| 4868 7191 9682 9038 | Successful frictionless authentication | POSSIBLE |
| 4868 7191 5813 0060 | Failed frictionless authentication | NO |
| 4868 7191 6610 1368 | Successful step-up (challenge) authentication | POSSIBLE |
| 4868 7191 8189 5556 | Failed step-up authentication | NO |
| 4868 7194 8865 1967 | Authentication not available on lookup | NO |
These cards work only for purchase flows, not for saving a payment method, and PayPal publishes separate cards for other issuing countries. Pick cards from the country you sell in.
Test Braintree transactions with amounts
Braintree’s sandbox works on a simple rule worth memorizing: transaction success is determined by the test amount; verification success is determined by the test card number. So 4111 1111 1111 1111 succeeds at 10.00 and is declined at 2001.00. Only documented test numbers are accepted — a random Luhn-valid number from a generator is not a Braintree test card.
| Amount | Authorization result | Settlement |
|---|---|---|
| 0.01 – 1999.99 | Authorized | Settled |
| 2000.00 – 2999.99 | Processor Declined, response code = amount | — |
| 3000.00 – 3000.99 | Failed with a 3000 processor response | — |
| 3001.00 – 4000.99 | Authorized | Settled |
| 4001.00 – 4001.99 | Authorized | Settlement Declined on certain transaction types |
| 5001.00 | Gateway Rejected (Application Incomplete) | — |
| 5002.00 and up | Authorized | Settled |
Because the response code equals the amount, a handful of amounts covers the declines most checkouts need to distinguish:
| Amount | Response | Type | What your UI should do |
|---|---|---|---|
| 2000.00 | 2000 Do Not Honor | Soft | Ask for another card or a retry later |
| 2001.00 | 2001 Insufficient Funds | Soft | Suggest another card |
| 2004.00 | 2004 Expired Card | Hard | Ask the buyer to check the expiry or use another card |
| 2010.00 | 2010 Card Issuer Declined CVV | Hard | Ask the buyer to re-enter the security code |
| 2099.00 | 2099 Cardholder Authentication Required | Soft | Run 3D Secure and retry |
| 3000.00 | 3000 Processor Network Unavailable | Soft | Retry later; alert your team if it persists |
import braintree, os
gateway = braintree.BraintreeGateway(braintree.Configuration(
braintree.Environment.Sandbox,
merchant_id=os.environ['BT_MERCHANT_ID'],
public_key=os.environ['BT_PUBLIC_KEY'],
private_key=os.environ['BT_PRIVATE_KEY'],
))
for amount in ('10.00', '2000.00', '2001.00', '2004.00', '3000.00'):
result = gateway.transaction.sale({
'amount': amount,
'payment_method_nonce': 'fake-valid-nonce', # documented test nonce: a valid card
'options': {'submit_for_settlement': True},
})
tx = result.transaction
print(amount, result.is_success, tx.processor_response_code if tx else result.message)Failed verifications, card types and fraud tools
When you vault a card with verification enabled, the card number decides the outcome. Braintree documents cards that make verification fail, such as 4000 1111 1111 1115 (Visa, processor declined) and 3566 0020 2036 0505 (JCB, failed with 3000). These numbers don’t change transaction outcomes, which still follow the amount.
Other test cards return specific card-type indicators, which is useful if your logic treats prepaid, debit or commercial cards differently:
4012 0043 3850 8385— prepaid “Yes” and debit “Yes”4009 0400 0000 0009— commercial “Yes”4012 0000 3333 0125— debit “Yes”
For Braintree’s fraud tools, 4000 1111 1111 1511 is gateway-rejected with the reason fraud, and 4111 1300 0000 0003 is rejected with risk_threshold. Braintree notes you can’t tweak sandbox settings to reject transactions; you use these specific values instead.
CVV and AVS rules in the Braintree sandbox
Security code and postal code values produce specific response codes, but they only trigger a rejection if you have AVS and CVV rules enabled in your sandbox. If a CVV test “does nothing”, check the rules before debugging your code.
| Field | Value | Response |
|---|---|---|
| CVV | 200 (CID 2000) | N — does not match |
| CVV | 201 (CID 2011) | U — not verified |
| CVV | 301 (CID 3011) | S — issuer does not participate |
| Postal code | 20000 | N — does not match |
| Postal code | 20001 | U — not verified |
| Postal code | 30000 | E — AVS system error |
| Postal code | 30001 | S — issuing bank does not support AVS |
Any other CVV or postal code returns M (matches). For background on what these codes check, see our guide to CVV, CVC and CID security codes.
Test 3D Secure 2 in Braintree
Braintree’s 3D Secure test cards have one strict requirement: the expiry month must be 01 and the year must be the current year + 3. Other dates won’t produce the documented results. Braintree also recommends disabling ad blockers during these tests, because they can block the device data collection 3D Secure relies on.
| Card | Scenario | Status |
|---|---|---|
| 4000 0000 0000 2701 | Successful no-challenge authentication | authenticate_successful |
| 4000 0000 0000 2925 | Failed no-challenge authentication | authenticate_frictionless_failed |
| 4000 0000 0000 2503 | Successful challenge authentication | authenticate_successful |
| 4000 0000 0000 2370 | Failed challenge authentication | challenge_required, then authenticate_failed |
| 4000 0000 0000 2446 | Error on lookup | lookup_error |
To test what happens when you skip authentication, create a sandbox transaction for 2099.00: it simulates the 2099 “Cardholder Authentication Required” soft decline that issuers send when 3D Secure wasn’t performed. The full list of 3DS cards is on our Braintree test cards page, and our 3-D Secure testing guide compares outcomes across gateways.
A combined test matrix
If your checkout offers both PayPal and Braintree, run the same business scenarios through each, using the mechanism each sandbox provides:
| Scenario | PayPal | Braintree |
|---|---|---|
| Card payment succeeds | Test card, normal name | Test card, amount 10.00 |
| Generic decline | CCREJECT-REFUSED | Amount 2000.00 |
| Insufficient funds | CCREJECT-IF | Amount 2001.00 |
| Expired card | CCREJECT-EC | Amount 2004.00 |
| CVV mismatch | CCREJECT-CVV_F | CVV 200 with CVV rules on |
| Processor / network error | PayPal-Mock-Response header | Amount 3000.00 |
| 3DS challenge passes | 4868 7191 6610 1368 | 4000 0000 0000 2503 |
| 3DS fails | 4868 7191 8189 5556 | 4000 0000 0000 2370 |
For every row, check the same three things: what the buyer sees, what your order record says, and what your logs contain. Logs should show the transaction ID and response code — never the full card number. Our guide to test data and PCI DSS explains how to keep real card data out of test systems entirely.
Frequently asked questions
What test card can I use in the PayPal sandbox?
PayPal lists static test cards per brand, for example 4012 8888 8888 1881 (Visa) or 2223 0000 4840 0011 (Mastercard), with any future expiry date and a three-digit CVV (four digits for American Express). Its developer site also has a card generator for more sandbox cards.
How do I make a PayPal sandbox card payment fail?
Enter a rejection trigger such as CCREJECT-REFUSED or CCREJECT-IF in the First Name or Name on Card field. The order is still created, but the card payment is declined with the matching processor response code.
How do I simulate a declined transaction in Braintree?
Use a valid test card and an amount between 2000.00 and 2999.99. The processor response code equals the amount, so 2001.00 returns 2001 Insufficient Funds and 2004.00 returns 2004 Expired Card.
Why does Braintree reject my card number in the sandbox?
The Braintree sandbox only accepts its documented test card numbers. A random number that passes the Luhn check is still not a test card. Use one of the numbers from the testing reference.
Can I use PayPal sandbox cards in production?
No. Sandbox cards only work against the sandbox endpoints with sandbox credentials. They are not valid payment cards in production.
Sources
- PayPal Developer — Sandbox testing guide
- PayPal Developer — Card testing (rejection triggers)
- PayPal Developer — Negative testing request headers
- PayPal Developer — Integrate Expanded Checkout
- PayPal Developer — 3D Secure test scenarios
- Braintree — Testing and go live
- Braintree — Authorization responses
- Braintree — 3D Secure testing
Tools used in this guide
Related guides
Written for developers, QA teams and merchants. Generated card numbers are test data: they are not real cards and cannot pay for anything.