DocsCharge · Test Cards
Sandbox Testing

Test Cards

Use these sandbox card numbers to simulate 3D Secure, successful, and declined payment flows before going live.

Important

Test cards are available only in the sandbox environment. They do not process real funds and must never be used in production. Send requests to /api/test/charge with your sandbox API key.

Quick Reference

Each test card is designed to produce a predictable outcome so you can validate your integration end to end — including redirects, webhooks, and error handling.

Card NumberScenarioAuthStatusDescription
45391488000030103D Secure authentication3DSREDIRECTTriggers a 3D Secure flow. The API returns a redirect URL in the is3DS field. Send the customer to that URL to complete authentication.
4539148800003011Successful payment (2D)2DSUCCESSSimulates a frictionless approval with no 3DS step. The transaction completes immediately with a SUCCESS status.
4539148800003012Declined payment (2D)2DFAILEDSimulates an issuer decline with no 3DS step. The API returns success: false with status FAILED, error.code DECLINED, message, and full data (merchantOrderId, transactionId, amount, currency, customer fields). The wire response remains encrypted.

Default Card Details

For all sandbox test cards, use the following supporting fields unless your integration requires otherwise:

FieldValueNotes
cardExpiryMonth12Any valid future month (1–12)
cardExpiryYear2031Any valid future four-digit year
cvv123Any 3-digit CVV is accepted in sandbox
currencyUSDSupported sandbox currencies per your merchant profile

Sample Sandbox Request

Replace card.number with any test card from the table above. All other fields use the same nested structure as the live charge endpoint.

POST /api/test/charge

curl -X POST https://api.payoflux.com/api/test/charge \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your_sandbox_api_key" \
  -d @request.json

Request Body

{
  "merchantOrderId": "ORD-SANDBOX-001",

  "payment": {
    "amount": 100,
    "currency": "USD"
  },

  "card": {
    "number": "4539148800003011",
    "expiryMonth": 12,
    "expiryYear": 2031,
    "cvv": "123",
    "holderName": "John Doe"
  },

  "customer": {
    "firstName": "John",
    "lastName": "Doe",
    "email": "john@example.com",
    "ip": "185.23.44.91"
  },

  "billing": {
    "addressLine1": "12, Hill",
    "city": "Nevada",
    "state": "Nevada",
    "country": "US",
    "postalCode": "12345"
  },

  "callback": {
    "webhookUrl": "https://your-domain.com/webhook",
    "returnUrl": "https://your-domain.com/payment/callback"
  }
}

Expected Responses by Card

3D Secure — 4539148800003010

Important

The response includes status: "REDIRECT" and an is3DS URL. Redirect the customer to that URL to complete authentication, then they will return to your returnUrl.

Wire format (from API)

{
  "success": true,
  "payload": "7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7:4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8"
}

After decryption

3DS redirect

200
{
  "success": true,
  "status": "REDIRECT",
  "data": {
    "amount": 100,
    "currency": "USD",
    "merchantOrderId": "ORD-SANDBOX-001",
    "transactionId": "FP2603YFGPKSWF0060",
    "firstName": "John",
    "lastName": "Doe",
    "address": "12, Hill",
    "city": "Nevada",
    "state": "Nevada",
    "country": "US",
    "email": "john@example.com",
    "webhookUrl": "https://your-domain.com/webhook"
  },
  "is3DS": "https://api.payoflux.com/payment/sandbox/card?transactionId=FP2603YFGPKSWF0060"
}

2D Success — 4539148800003011

Note

No is3DS field is returned. The transaction completes immediately with status: "SUCCESS".

Wire format (from API)

{
  "success": true,
  "payload": "7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7:4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8"
}

After decryption

2D success

200
{
  "success": true,
  "status": "SUCCESS",
  "data": {
    "amount": 100,
    "currency": "USD",
    "merchantOrderId": "ORD-SANDBOX-001",
    "transactionId": "FP2603YFGPKSWF0060",
    "firstName": "John",
    "lastName": "Doe",
    "address": "12, Hill",
    "city": "Nevada",
    "state": "Nevada",
    "country": "US",
    "email": "john@example.com",
    "webhookUrl": "https://your-domain.com/webhook"
  }
}

2D Declined — 4539148800003012

Note

The response returns success: false with status: "FAILED", a DECLINED error, and full data (merchantOrderId, transactionId, amount, etc.). No is3DS field is included. The wire response is still encrypted.

Wire format (from API)

{
  "success": true,
  "payload": "7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7:4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8"
}

After decryption

2D declined

200
{
  "success": false,
  "status": "FAILED",
  "message": "Transaction declined by issuer",
  "error": {
    "code": "DECLINED",
    "message": "Transaction declined by issuer"
  },
  "data": {
    "amount": 11,
    "currency": "USD",
    "merchantOrderId": "ORD-12345",
    "transactionId": "FP260231SJWKL80027",
    "firstName": "John",
    "lastName": "Doe",
    "address": "12, Hill",
    "city": "Nevada",
    "state": "Nevada",
    "country": "US",
    "email": "john@example.com",
    "webhookUrl": "https://your-domain.com/webhook"
  }
}

Testing Checklist

Before moving to production, confirm each flow behaves correctly in your application:

  • Successful 2D payment stores the transaction ID and shows confirmation to the customer.
  • 3DS card redirects to the is3DS URL and returns to your returnUrl after authentication.
  • Declined card surfaces the error message and does not mark the order as paid.
  • Webhook notifications are received and signature-verified for every outcome.
  • Sandbox API key is used exclusively — production keys are never sent to sandbox endpoints.