Skip to main content
Version: Live

Testing

The Pay Theory sandbox simulates payment processing end to end. Approvals and declines depend on the card or bank account number you use. Settlements, ACH returns, and disputes don't happen on their own in sandbox. You trigger each one with a sandbox-only GraphQL mutation.

This guide covers:

  • Test card and bank account numbers, including the ones that fail
  • Settling transactions
  • Creating ACH returns
  • Creating disputes and moving them to won or lost

For webhook setup and payload examples, see Webhooks.


How Sandbox Processing Works​

When you tokenize a payment method or run a payment, the sandbox checks the card number or bank account number against a list of failure triggers.

  • If the number is on the list, the request fails with that entry's failure code.
  • Any other valid number succeeds.
  • The amount doesn't affect the result.
  • The sandbox checks the list when you create the payment method and again when you run a sale or authorization. So a failure number fails at tokenization, before you get a payment method token.
  • Captures, refunds, and voids always succeed.
Update your sandbox

Some older sandboxes still run payments through a processor's test environment instead of the Pay Theory sandbox. If the test numbers or sandbox mutations on this page don't work for you, your sandbox likely needs an update. Email Pay Theory support at support@paytheory.com and we'll update it for you.


Testing Card Payments​

Successful Cards​

Use any valid card number that isn't on the failure list. These numbers approve and show the matching card brand:

Card BrandTesting Number
Visa4835 0345 9845 7895
Discover6560 0545 6789 1235
MasterCard5560 9578 9456 1234
Amex3479 847894 56149

Use any future expiration date, any CVV, and any ZIP code.

Card Types​

Card TypeTesting Number
Business Credit4389 9414 7258 3697
Business Debit4472 7136 9258 1472
Credit Card4835 0325 8143 6793
Debit Card4398 8445 6789 1232
Prepaid Card4307 6415 9482 6375

Cards By Country​

CountryTesting Number
Canada4527 7111 5544 8861
USA4835 0345 9845 7895

Card Failures​

These card numbers fail with the listed failure code.

Failure CodeCard Number
GENERIC_DECLINE4000 0001 0000 0001
INSUFFICIENT_FUNDS4000 0002 0000 0000
INVALID_ACCOUNT_NUMBER4000 0003 0000 0009
EXPIRED_CARD4000 0004 0000 0008
INVALID_CVV4000 0005 0000 0007
DO_NOT_HONOR4000 0006 0000 0006
LOST_OR_STOLEN_CARD4000 0007 0000 0005
FRAUD_DETECTED4000 0008 0000 0004
CARD_NOT_SUPPORTED4000 0009 0000 0003
CALL_ISSUER4000 0010 0000 0000
PICK_UP_CARD4000 0011 0000 0009
RESTRICTED_CARD4000 0012 0000 0008
EXCEEDS_APPROVAL_LIMIT4000 0013 0000 0007
INVALID_TRANSACTION4000 0014 0000 0006
TRANSACTION_NOT_PERMITTED4000 0015 0000 0005
INACTIVE_CARD4000 0016 0000 0004
DUPLICATE_TRANSACTION4000 0017 0000 0003
SYSTEM_ERROR4000 0018 0000 0002
TIMEOUT4000 0019 0000 0001
COMMUNICATION_ERROR4000 0020 0000 0008
ADDRESS_VERIFICATION_FAILED_RISK_RULES4000 0021 0000 0007
CVV_FAILED_RISK_RULES4000 0022 0000 0006

For what each failure code means, see Failed Transactions.


Testing ACH Payments​

The sandbox ignores the routing number when it decides the outcome. Pass any valid routing number, such as 122105278.

Any account number not listed below succeeds. These account numbers fail with the listed failure code:

Failure CodeAccount Number
INVALID_BANK_ACCOUNT_NUMBER0000000001
BANK_ACCOUNT_CLOSED0000000002
NO_BANK_ACCOUNT_FOUND0000000003
BANK_ACCOUNT_FROZEN0000000004
GENERIC_DECLINE0000000005
NON_TRANSACTION_ACCOUNT0000000006
INVALID_ROUTING_NUMBER0000000007
PAYMENT_STOPPED0000000008

These failures happen right away, when you submit the payment. To test an ACH payment that succeeds and is returned later, settle it first and then create an ACH return.


Settling Transactions​

Sandbox transactions stay unsettled until you settle them. Settling a merchant takes two mutations:

  1. prepareSandboxSettlementBatch collects everything waiting to settle and calculates the totals.
  2. createSandboxSettlement creates the settlement from that batch.

You need settled transactions before you can create ACH returns or disputes, so you'll run these two mutations often.

1. Prepare the Batch​

Prepare Sandbox Settlement Batch
mutation {
prepareSandboxSettlementBatch(input: { merchant_uid: "your_merchant_uid" }) {
prep_id
debit_ids
reversal_ids
ach_return_ids
dispute_withdrawal_ids
dispute_deposit_ids
calculated_gross_amount
calculated_net_amount
}
}

The batch includes the merchant's unsettled:

  • PENDING payments
  • Refunds
  • ACH returns
  • Disputes that are open and haven't been withdrawn yet
  • Disputes that were won and haven't been deposited yet
  • Split payments

Preparing the batch captures those PENDING payments and moves them to SUCCEEDED, so you don't need to capture them yourself. The batch also charges the merchant's ACH return fee for each ACH return and the chargeback fee for each dispute withdrawal, based on the merchant's fee settings.

2. Create the Settlement​

Create Sandbox Settlement
mutation {
createSandboxSettlement(input: { merchant_uid: "your_merchant_uid" }) {
success
}
}

Once the batch is prepared, create the settlement. Every item in the batch moves to SETTLED, and a settlement batch is created for the merchant.

Captures run in the background

If the batch included PENDING payments, the captures may still be running when you call createSandboxSettlement. In that case it returns Captures not yet complete. Wait a few seconds and try again.

A few rules to keep in mind:

  • A merchant can have only one prepared batch waiting at a time. If you call prepareSandboxSettlementBatch again before you create the settlement, it returns Existing settlement batch prep has not been reconciled.
  • If there is nothing to settle, prepareSandboxSettlementBatch returns No settlement items found for merchant.
  • Both mutations queue their work and return right away. Settlement records can take a few seconds to appear in queries. See Query Settlement Data.

Triggering ACH Returns​

Use createSandboxAchReturn to return an ACH payment or refund. The transaction must be:

  • An ACH payment or an ACH refund
  • Settled. A PENDING or SUCCEEDED transaction is rejected, so settle it first.
Create Sandbox ACH Return
mutation {
createSandboxAchReturn(
input: { transaction_id: "your_transaction_id", return_code: R01 }
) {
success
ach_return_transaction_id
return_code
}
}

return_code accepts any standard NACHA return code from R01 to R85. The code you pick is recorded on the transaction. Every code behaves the same way in sandbox. See the create sandbox ACH return reference for the full list.

When the return goes through:

  • The original transaction changes to RETURNED and its ach_return_details hold the return code.
  • A new ACH_RETURN transaction is created for the full amount, with the original transaction as its parent. Its ID is the ach_return_transaction_id in the response.
  • Returning a payment takes the money back from the merchant. Returning a refund gives it back to the merchant.
  • The next settlement includes the return and charges the merchant's ACH return fee.

You can request one return per transaction. A second request for the same transaction returns ACH return already requested.


Triggering Disputes​

A sandbox dispute takes three settlements to go from payment to resolution:

  1. Settle the card payment.
  2. Create the dispute, then settle again. This settlement withdraws the disputed amount and the chargeback fee from the merchant.
  3. Mark the dispute won or lost. If it's won, settle again to deposit the amount back to the merchant.

Create a Dispute​

The transaction must be a settled card payment. Refunds and ACH payments can't be disputed.

Create Sandbox Dispute
mutation {
createSandboxDispute(
input: { transaction_id: "your_transaction_id", reason: FRAUD }
) {
success
dispute_id
transaction_id
}
}
Keytypedescription
transaction_idStringThe settled card payment to dispute.
reasonDisputeReasonOne of CLERICAL, FRAUD, INQUIRY, QUALITY, or TECHNICAL.

The dispute:

  • Covers the full payment amount.
  • Starts in PENDING, whatever reason you pass.
  • Has a respond-by date seven days out.

A transaction can have only one open dispute at a time.

Resolve a Dispute​

Before you can close a dispute, a settlement has to withdraw the disputed amount. Run both settlement mutations after you create the dispute. The batch lists the dispute in dispute_withdrawal_ids.

Then move the dispute to WON or LOST:

Update Sandbox Dispute Status
mutation {
updateSandboxDisputeStatus(
input: { dispute_id: "your_dispute_id", status: WON }
) {
success
}
}
  • LOST closes the dispute. The merchant already paid the amount in the earlier settlement, so nothing else moves.
  • WON closes the dispute in the merchant's favor. The next settlement deposits the amount back to the merchant and lists the dispute in dispute_deposit_ids.

WON and LOST are final. A closed dispute can't change status again.


Testing Merchant Onboarding​

New sandbox merchants are boarded and ready to take payments as soon as you create them. To test the onboarding flow instead, include "onboarding" anywhere in the merchant name, such as Acme Onboarding Test. Case doesn't matter.

Create an Onboarding Merchant
mutation {
createMerchant(merchant_name: "Acme Onboarding Test") {
merchant_uid
}
}

A merchant with "onboarding" in its name:

  • Starts with card and ACH processing turned off.
  • Shows in the portal as a merchant who still needs to fill out the onboarding form.
  • Is approved automatically as soon as you submit the form in sandbox.

Testing Barcode Payments​

To simulate a customer paying a cash barcode, call createBarcodePaymentSandbox with the barcode ID and the amount paid in cents. The amount must match the barcode's amount. See the create sandbox barcode payment reference for the full request and response.


Common Errors​

Settlements​

  • No settlement items found for merchant: the merchant has nothing waiting to settle.
  • Existing settlement batch prep has not been reconciled: you already prepared a batch. Call createSandboxSettlement before you prepare another one.
  • No pending settlement prep found: call prepareSandboxSettlementBatch first.
  • Captures not yet complete: wait a few seconds and call createSandboxSettlement again.

ACH Returns and Disputes​

  • Transaction cannot be pending or succeeded: the transaction hasn't settled yet. Settle it, then retry.
  • Transaction is not ACH: you called createSandboxAchReturn on a card payment.
  • Transaction is not a card payment: you called createSandboxDispute on an ACH payment.
  • Transaction already has an active dispute: the transaction already has an open dispute.
  • Dispute must be part of a settlement withdrawal batch before closing: settle the merchant after you create the dispute, then update the status.

Any Sandbox Mutation​

  • Merchant is not using an allowed processor: your sandbox needs an update. Email support@paytheory.com and we'll update it for you.