Documentation

Testing & Sandbox

Testing & Sandbox

Use the PerfectPay sandbox environment to test your integration without processing real payments.

Sandbox Environment

SurfaceURL
Sandbox APIhttps://sandbox.perfectpay.ai
Dashboardhttps://app.perfectpay.ai
Hosted Web SDKhttps://sdk.perfectpay.ai

All sandbox requests use the same authentication pattern as production: api-key: YOUR_SECRET_API_KEY. Your sandbox and production keys are different -- use the keys from your sandbox environment in the dashboard.

Test Cards

Use these card numbers with any future expiry date and any 3-digit CVC:

Card NumberBrandBehavior
4242424242424242VisaAlways succeeds
4111111111111111VisaAlways succeeds

Example Card Details

JSON
{
  "card_number": "4242424242424242",
  "card_exp_month": "10",
  "card_exp_year": "25",
  "card_cvc": "123",
  "card_holder_name": "Jane Doe"
}

Common Test Scenarios

Successful Payment

Create a payment, then confirm it with a test card:

GET //sandbox.perfectpay.ai/payments
curl https://sandbox.perfectpay.ai/payments \
  -X POST \
  -H "api-key: YOUR_SECRET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 4999,
    "currency": "USD",
    "confirm": true,
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": {
      "card": {
        "card_number": "4242424242424242",
        "card_exp_month": "10",
        "card_exp_year": "25",
        "card_cvc": "123",
        "card_holder_name": "Jane Doe"
      }
    },
    "return_url": "https://example.com/checkout/complete"
  }'

Expected response status: succeeded

Manual Capture Flow

  1. Create a payment with "capture_method": "manual":
GET //sandbox.perfectpay.ai/payments
curl https://sandbox.perfectpay.ai/payments \
  -X POST \
  -H "api-key: YOUR_SECRET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 4999,
    "currency": "USD",
    "capture_method": "manual",
    "confirm": false
  }'
  1. Confirm the payment with a test card (status becomes requires_capture).

  2. Capture the payment:

GET //sandbox.perfectpay.ai/payments/{payment_id}/capture
curl https://sandbox.perfectpay.ai/payments/{payment_id}/capture \
  -X POST \
  -H "api-key: YOUR_SECRET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount_to_capture": 4999}'

Partial Refund

  1. Complete a successful payment (see above).

  2. Issue a partial refund:

GET //sandbox.perfectpay.ai/refunds
curl https://sandbox.perfectpay.ai/refunds \
  -X POST \
  -H "api-key: YOUR_SECRET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_id": "{payment_id}",
    "amount": 1500,
    "reason": "Partial refund test"
  }'

3DS Authentication Flow

Create a payment with "authentication_type": "three_ds" and confirm it. The payment will move to requires_customer_action with a next_action containing a redirect URL or 3DS challenge.

Cancel a Payment

Create a payment without confirming, then cancel it:

GET //sandbox.perfectpay.ai/payments/{payment_id}/cancel
curl https://sandbox.perfectpay.ai/payments/{payment_id}/cancel \
  -X POST \
  -H "api-key: YOUR_SECRET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"cancellation_reason": "requested_by_customer"}'

Verifying Webhooks in Sandbox

Webhook events fire in sandbox the same way they do in production. Configure a webhook URL in the dashboard and use a tool like ngrok or a RequestBin to inspect payloads during development.

Moving to Production

When you are ready to go live:

  1. Switch your API base URL from https://sandbox.perfectpay.ai to https://api.perfectpay.ai
  2. Replace sandbox API keys with production API keys from the dashboard
  3. Update your Web SDK initialization to point to the production backend URL
  4. Verify webhook endpoints are reachable from production