Test Data
Card numbers, ACH routing numbers, AVS and CVV trigger codes for exercising every branch of your sandbox integration.
Sandbox runs the full moat stack against a simulated processor. Real card numbers will not authorize — you must use the test numbers below. Production is the opposite: test numbers are rejected as invalid.
The approval test numbers below are the standard Luhn-valid card numbers the card networks publish for developer testing. They work in moat's sandbox the same way they work in almost every other gateway sandbox.
Test cards — always approve
| Brand | Number | Expiration | CVC |
|---|---|---|---|
| Visa | 4111111111111111 | Any future | Any 3 digits |
| Visa (debit) | 4000056655665556 | Any future | Any 3 digits |
| Mastercard | 5555555555554444 | Any future | Any 3 digits |
| Mastercard (2-series) | 2223003122003222 | Any future | Any 3 digits |
| Mastercard (debit) | 5200828282828210 | Any future | Any 3 digits |
| American Express | 378282246310005 | Any future | Any 4 digits |
| American Express | 371449635398431 | Any future | Any 4 digits |
| Discover | 6011111111111117 | Any future | Any 3 digits |
| Diners Club | 30569309025904 | Any future | Any 3 digits |
| JCB | 3530111333300000 | Any future | Any 3 digits |
Any future expiration date is accepted (commonly 12/30 or 12/99). Any CVC of the correct length is accepted.
Triggering declines and specific outcomes
Sandbox simulates every non-approval outcome a real processor can return. There are two ways to trigger them:
- Use a dedicated decline card. moat publishes a set of card numbers that always produce a specific decline reason.
- Set the cents portion of
amount. With an approval card, the cents of the amount can be used as a trigger — useful when you want to exercise a specific path without swapping cards.
The specific card numbers and cents triggers that moat's sandbox accepts vary by processor configuration. The examples below are representative of the pattern — the exact numbers and triggers in effect for your account are listed in the Control Panel under Developer → Test Triggers.
Dedicated decline cards
| Number | Outcome |
|---|---|
4000000000000002 | Generic decline. |
4000000000009995 | Insufficient funds. |
4000000000000069 | Expired card. |
4000000000000127 | Incorrect CVC. |
4000000000000259 | Fraud suspected / high-risk. |
4000000000000119 | Processing error. |
4000000000000101 | Lost card — pick up. |
4000000000009987 | Stolen card — pick up. |
4000000000000051 | Partial approval — authorizes half the requested amount. |
Amount-based triggers
When you need to exercise a decline path but do not want to swap cards, vary the cents portion of the amount. Typical pattern:
| Amount ends in | Behavior |
|---|---|
| Any other value | Approve (baseline). |
.00 | Approve. |
.01 | Generic decline. |
.02 | Insufficient funds. |
.05 | Partial approval. |
.10 | Processor error / timeout. |
.20 | Authorize but hold for manual review. |
AVS triggers
AVS (Address Verification Service) results are driven by the billing address_line_1 and postal_code you submit. The sandbox looks for specific sentinel values:
| Street starts with | ZIP | AVS result |
|---|---|---|
888 | 77777 | Y — full match (street + ZIP). |
888 | Any other | A — street match only. |
| Any other | 77777 | Z — ZIP match only. |
| Any other | Any other | N — no match. |
| (omitted) | (omitted) | U — AVS unavailable. |
CVC triggers
| CVC value | Result |
|---|---|
Any 3- or 4-digit value (e.g. 123) | M — matches. |
999 | N — does not match. |
000 | U — issuer did not verify. |
| (omitted) | S — merchant did not request verification. |
ACH test accounts
ACH testing uses a combination of routing number and account number. The routing must be Luhn-valid (real routing numbers work); the account number is the trigger:
| Routing | Account | Outcome |
|---|---|---|
021000021 | 123456789 | Approves. |
021000021 | 000000002 | Declines — account closed. |
021000021 | 000000003 | Declines — insufficient funds. |
021000021 | 000000004 | Declines — invalid account. |
021000021 | 000000005 | Late return — simulates an ACH return 3 days after settlement. |
3D Secure test cards
Use these in the 3DS-with-Tokenizer flow or directly against the 3DS API. All numbers pass Luhn; the sandbox 3DS implementation branches on the last four digits.
| Number | Authentication flow |
|---|---|
4111111111111111 | Frictionless authentication. Returns an authenticated ECI directly. |
4000000000001091 | Challenge required. Sandbox challenge UI auto-approves after 2 seconds. |
4000000000001109 | Challenge required. Auto-fails — use to test your failure branch. |
4000000000001075 | Card not enrolled in 3DS. Returns "attempted" status. |
4000000000001018 | Authentication unavailable. Issuer or ACS offline. |
Recipes
Test a surcharge flow
- Enable a fee program on your sandbox account (see Fee Programs).
- Post a transaction with
base_amount: 10000using4111111111111111. BIN lookup marks it surchargeable — the response includes a calculated surcharge. - Repeat with the debit Visa
4000056655665556. Surcharge should be zero; debit cards are not surchargeable. - Repeat with
surcharge_exempt: true. Surcharge should be zero even on the credit card.
Test webhook signature verification
In the Control Panel, open any event in the webhook log and click Replay. moat resends the event to your endpoint with the same signing secret and signature — lets you verify your handler without triggering a real transaction.
Test partial captures
- POST a
type: "authorize"withamount: 1000. - POST
/api/transaction/{id}/capturewithamount: 400. - POST another capture with
amount: 600. - Verify the transaction is
capturedwith captured amount 1000.
Test a declined-then-resolved flow
- POST a transaction with
4000000000009995(insufficient funds). Expect decline. - POST a retry using
4111111111111111. Expect approval. - Confirm two transaction records exist — the first with
status: declined, the second withstatus: approved.
Test idempotent retry
- POST a transaction with an
idempotency_keyof your choice. - Immediately POST the identical body with the same
idempotency_key. - Both requests return the same transaction ID and response. The card is charged once.