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 Number | Scenario | Auth | Status | Description |
|---|---|---|---|---|
| 4539148800003010 | 3D Secure authentication | 3DS | REDIRECT | Triggers a 3D Secure flow. The API returns a redirect URL in the is3DS field. Send the customer to that URL to complete authentication. |
| 4539148800003011 | Successful payment (2D) | 2D | SUCCESS | Simulates a frictionless approval with no 3DS step. The transaction completes immediately with a SUCCESS status. |
| 4539148800003012 | Declined payment (2D) | 2D | FAILED | Simulates 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:
| Field | Value | Notes |
|---|---|---|
| cardExpiryMonth | 12 | Any valid future month (1–12) |
| cardExpiryYear | 2031 | Any valid future four-digit year |
| cvv | 123 | Any 3-digit CVV is accepted in sandbox |
| currency | USD | Supported 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.jsonRequest 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.