Docs/Test Data

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.

Test PANs are industry-standard

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

BrandNumberExpirationCVC
Visa4111111111111111Any futureAny 3 digits
Visa (debit)4000056655665556Any futureAny 3 digits
Mastercard5555555555554444Any futureAny 3 digits
Mastercard (2-series)2223003122003222Any futureAny 3 digits
Mastercard (debit)5200828282828210Any futureAny 3 digits
American Express378282246310005Any futureAny 4 digits
American Express371449635398431Any futureAny 4 digits
Discover6011111111111117Any futureAny 3 digits
Diners Club30569309025904Any futureAny 3 digits
JCB3530111333300000Any futureAny 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:

  1. Use a dedicated decline card. moat publishes a set of card numbers that always produce a specific decline reason.
  2. 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.
Confirm these against your sandbox

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

NumberOutcome
4000000000000002Generic decline.
4000000000009995Insufficient funds.
4000000000000069Expired card.
4000000000000127Incorrect CVC.
4000000000000259Fraud suspected / high-risk.
4000000000000119Processing error.
4000000000000101Lost card — pick up.
4000000000009987Stolen card — pick up.
4000000000000051Partial 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 inBehavior
Any other valueApprove (baseline).
.00Approve.
.01Generic decline.
.02Insufficient funds.
.05Partial approval.
.10Processor error / timeout.
.20Authorize 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 withZIPAVS result
88877777Y — full match (street + ZIP).
888Any otherA — street match only.
Any other77777Z — ZIP match only.
Any otherAny otherN — no match.
(omitted)(omitted)U — AVS unavailable.

CVC triggers

CVC valueResult
Any 3- or 4-digit value (e.g. 123)M — matches.
999N — does not match.
000U — 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:

RoutingAccountOutcome
021000021123456789Approves.
021000021000000002Declines — account closed.
021000021000000003Declines — insufficient funds.
021000021000000004Declines — invalid account.
021000021000000005Late 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.

NumberAuthentication flow
4111111111111111Frictionless authentication. Returns an authenticated ECI directly.
4000000000001091Challenge required. Sandbox challenge UI auto-approves after 2 seconds.
4000000000001109Challenge required. Auto-fails — use to test your failure branch.
4000000000001075Card not enrolled in 3DS. Returns "attempted" status.
4000000000001018Authentication unavailable. Issuer or ACS offline.

Recipes

Test a surcharge flow

  1. Enable a fee program on your sandbox account (see Fee Programs).
  2. Post a transaction with base_amount: 10000 using 4111111111111111. BIN lookup marks it surchargeable — the response includes a calculated surcharge.
  3. Repeat with the debit Visa 4000056655665556. Surcharge should be zero; debit cards are not surchargeable.
  4. 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

  1. POST a type: "authorize" with amount: 1000.
  2. POST /api/transaction/{id}/capture with amount: 400.
  3. POST another capture with amount: 600.
  4. Verify the transaction is captured with captured amount 1000.

Test a declined-then-resolved flow

  1. POST a transaction with 4000000000009995 (insufficient funds). Expect decline.
  2. POST a retry using 4111111111111111. Expect approval.
  3. Confirm two transaction records exist — the first with status: declined, the second with status: approved.

Test idempotent retry

  1. POST a transaction with an idempotency_key of your choice.
  2. Immediately POST the identical body with the same idempotency_key.
  3. Both requests return the same transaction ID and response. The card is charged once.