Skip to main content

Sandbox Environment

Test your integration thoroughly in our sandbox environment before going live. No real money, no risk. Our sandbox works exactly like production - same API, same behavior:
https://api.cheqpay.dev

Sandbox Features

No Real Money

Process test payments without financial risk

Test Cards & Accounts

Use pre-defined test cards and SPEI accounts

Full Feature Parity

All production features available in sandbox

Faster Processing

Instant processing for rapid testing

Test Cards

Use these cards to test different scenarios:

Successful Payments

Card NumberBrandBehavior
4000000000002503VisaSuccessful payment
5200000000002151MastercardSuccessful payment
For 3D Secure (3DS) testing, see the complete 3DS testing guide which includes specific test cards and amount thresholds for different 3DS scenarios.

Failed Payments

Card NumberBrandResult
4000000000000002VisaCard declined
4000000000000069VisaExpired card
4000000000000127VisaInvalid CVC
4000000000000119VisaProcessing error

Test Card Details

For all test cards:
  • Expiry Date: Any future date (e.g., 12/2025)
  • CVC: Any 3 digits (e.g., 123)
  • Billing Address: Any valid address
Test cards work only in sandbox. They will be rejected in production.

Test 3D Secure

Test the complete 3DS authentication flow using specific test cards and amount thresholds.

Trigger 3DS Challenge

Use amounts >= 100,000 cents (1,000 MXN) with the 3DS test card:
curl -X POST https://api.cheqpay.dev/payment-orders \
  -H "Authorization: Bearer YOUR_SANDBOX_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "test-3ds-001",
    "amount": 100000,
    "currency": "MXN",
    "paymentMethod": {
      "type": "card",
      "cardDetails": {
        "number": "4000000000002503",
        "expiryMonth": "12",
        "expiryYear": "25",
        "cvc": "123"
      }
    }
  }'
3DS Test Cards:
  • 4000000000002503 with amount >= 100,000 cents triggers full 3DS challenge
  • 4000000000002701 with amount >= 100,000 cents triggers frictionless 3DS
  • 4000000000002701 with amount < 100,000 cents skips 3DS entirely
See the complete 3DS testing guide for all scenarios.

Complete Authentication

When prompted for a verification code in sandbox, use:
123456
This simulates successful customer authentication.

Complete 3DS Guide

Learn how to implement 3D Secure authentication

Test Refunds

Refunds process instantly in sandbox (instead of 5-10 days in production):
# Create a successful payment
PAYMENT_ID=$(curl -X POST https://api.cheqpay.dev/payment-orders \
  -H "Authorization: Bearer YOUR_SANDBOX_KEY" \
  -d '{"externalId": "test-001", "amount": 10000, ...}' \
  | jq -r '.paymentOrder.id')

# Issue a refund
curl -X POST https://api.cheqpay.dev/payment-orders/$PAYMENT_ID/refund \
  -H "Authorization: Bearer YOUR_SANDBOX_KEY" \
  -d '{"reason": "Test refund"}'

Common Test Scenarios

Scenario 1: Successful Card Payment

curl -X POST https://api.cheqpay.dev/payment-orders \
  -H "Authorization: Bearer YOUR_SANDBOX_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "test-001",
    "customer": {
      "firstName": "Test",
      "lastName": "User",
      "email": "[email protected]"
    },
    "amount": 10000,
    "currency": "MXN",
    "paymentMethod": {
      "type": "card",
      "cardDetails": {
        "number": "4000000000002503",
        "expiryMonth": "12",
        "expiryYear": "25",
        "cvc": "123"
      }
    }
  }'
Expected: Status COMPLETED, payment successful.

Scenario 2: Declined Payment

Use declined card 4000000000000002:
curl -X POST https://api.cheqpay.dev/payment-orders \
  -H "Authorization: Bearer YOUR_SANDBOX_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "test-002",
    "amount": 10000,
    "currency": "MXN",
    "paymentMethod": {
      "type": "card",
      "cardDetails": {
        "number": "4000000000000002",
        "expiryMonth": "12",
        "expiryYear": "25",
        "cvc": "123"
      }
    }
  }'
Expected: Status FAILED, error code DECLINED.

Scenario 3: 3DS Authentication Flow

  1. Create payment with 3DS card
  2. Receive PAYER_AUTHENTICATION_CHALLENGE_REQUIRED status
  3. Display authentication challenge
  4. Customer enters code 123456
  5. Validate authentication
  6. Payment completes

Scenario 4: Save & Reuse Card

# 1. Save card during payment
curl -X POST https://api.cheqpay.dev/payment-orders \
  -H "Authorization: Bearer YOUR_SANDBOX_KEY" \
  -d '{
    "externalId": "test-003",
    "amount": 10000,
    "currency": "MXN",
    "paymentMethod": {
      "type": "card",
      "cardDetails": {
        "number": "4000000000002503",
        "expiryMonth": "12",
        "expiryYear": "25",
        "cvc": "123"
      },
      "persist": true
    }
  }'

# 2. Get paymentMethodId from response
# 3. Use saved card for next payment
curl -X POST https://api.cheqpay.dev/payment-orders \
  -H "Authorization: Bearer YOUR_SANDBOX_KEY" \
  -d '{
    "externalId": "test-004",
    "amount": 5000,
    "currency": "MXN",
    "paymentMethod": {
      "type": "payment_method_id",
      "paymentMethodId": "pm_xxx",
      "cvc": "123"
    }
  }'

Scenario 5: Idempotency Test

Send the same request twice with same externalId:
# First request
curl -X POST https://api.cheqpay.dev/payment-orders \
  -H "Authorization: Bearer YOUR_SANDBOX_KEY" \
  -d '{"externalId": "test-005", "amount": 10000, ...}'

# Second request (duplicate)
curl -X POST https://api.cheqpay.dev/payment-orders \
  -H "Authorization: Bearer YOUR_SANDBOX_KEY" \
  -d '{"externalId": "test-005", "amount": 10000, ...}'
Expected: Both requests return the same payment. No duplicate charge.

Integration Testing Checklist

Test these scenarios before going live:
  • ✅ Successful payment with Visa
  • ✅ Successful payment with Mastercard
  • ✅ Successful payment with Amex
  • ✅ Declined payment handling
  • ✅ Expired card error
  • ✅ Invalid CVC error
  • ✅ Trigger 3DS challenge
  • ✅ Display authentication iframe
  • ✅ Handle successful authentication
  • ✅ Handle failed authentication
  • ✅ Handle authentication timeout
  • ✅ Save card during payment
  • ✅ Charge saved card
  • ✅ Handle expired saved card
  • ✅ Update saved card
  • ✅ Full refund
  • ✅ Partial refund
  • ✅ Multiple partial refunds
  • ✅ Handle refund errors
  • ✅ Network errors
  • ✅ Validation errors
  • ✅ Declined payments
  • ✅ Rate limiting
  • ✅ Retry logic

Performance Testing

Test your integration under load:
// Example: Load test with 100 concurrent payments
const promises = [];
for (let i = 0; i < 100; i++) {
  promises.push(
    createPayment({
      externalId: `load-test-${i}`,
      amount: 10000,
      currency: 'MXN',
      // ...
    })
  );
}

const results = await Promise.allSettled(promises);
const successful = results.filter(r => r.status === 'fulfilled').length;
const failed = results.filter(r => r.status === 'rejected').length;

console.log(`Successful: ${successful}, Failed: ${failed}`);

Go Live Checklist

Ready to switch to production?
1

Get Production Credentials

Contact [email protected] for live API keys.
2

Update Base URL

Change from sandbox.cheqpay.com to api.cheqpay.com.
3

Register Production Webhooks

Provide your production webhook URL to support.
4

Secure Your Keys

Use environment variables, never hardcode keys.
5

Set Up Monitoring

Track payments, errors, and webhook delivery.
6

Test in Production

Process a small test transaction to verify everything works.

Going Live Guide

Complete production readiness checklist

Need Help?