Testing & Sandbox
Use the PerfectPay sandbox environment to test your integration without processing real payments.
Sandbox Environment
| Surface | URL |
|---|---|
| Sandbox API | https://sandbox.perfectpay.ai |
| Dashboard | https://app.perfectpay.ai |
| Hosted Web SDK | https://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 Number | Brand | Behavior |
|---|---|---|
4242424242424242 | Visa | Always succeeds |
4111111111111111 | Visa | Always succeeds |
Example Card Details
{
"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:
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
- Create a payment with
"capture_method": "manual":
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
}'
-
Confirm the payment with a test card (status becomes
requires_capture). -
Capture the payment:
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
-
Complete a successful payment (see above).
-
Issue a partial refund:
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:
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:
- Switch your API base URL from
https://sandbox.perfectpay.aitohttps://api.perfectpay.ai - Replace sandbox API keys with production API keys from the dashboard
- Update your Web SDK initialization to point to the production backend URL
- Verify webhook endpoints are reachable from production