Sandbox Testing
Test payments end-to-end without real money using the sandbox processor
Time: \~10 minutes | Difficulty: Beginner
The sandbox processor lets you test the full payment flow — checkout, payment processing, order creation, webhooks — without connecting a real payment gateway or charging real cards.
How the Sandbox Processor Works
The sandbox processor simulates a payment gateway. When a customer submits payment on a checkout that uses a sandbox processor:
- The payment is always approved (no real card validation)
- An order is created in AsherPay
- Webhooks fire as if a real payment occurred
- Subscriptions are created and can be billed
This makes it perfect for:
- Testing your checkout flow end-to-end
- Verifying webhook integrations
- Testing subscription billing cycles
- QA before going live with a real processor
Step 1: Create a Sandbox Processor
const { processor } = await tagada.processors.create({
processor: {
name: 'Test Sandbox',
type: 'sandbox',
enabled: true,
supportedCurrencies: ['USD', 'EUR', 'GBP'],
baseCurrency: 'USD',
options: {
testMode: true,
},
},
});
console.log('Sandbox processor:', processor.id);
```
bash theme={null}
curl -X POST https://app.tagadapay.com/api/public/v1/processors/create \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{
"processor": {
"name": "Test Sandbox",
"type": "sandbox",
"enabled": true,
"supportedCurrencies": ["USD", "EUR", "GBP"],
"baseCurrency": "USD",
"options": { "testMode": true }
}
}'
Step 2: Create a Payment Flow
Create a payment flow that routes all traffic to your sandbox processor:
```ts theme={null} const flow = await tagada.paymentFlows.create({ data: { name: 'Sandbox Flow', strategy: 'simple', fallbackMode: false, maxFallbackRetries: 0, threeDsEnabled: false, stickyProcessorEnabled: false, pickProcessorStrategy: 'weighted', processorConfigs: [ { processorId: processor.id, weight: 100, disabled: false, nonStickable: false, }, ], fallbackProcessorConfigs: [], abuseDetectionConfig: null, }, });
***
## Step 3: Assign to Your Store
Assign the sandbox payment flow to your store. You can pass it at store creation:
```ts theme={null}
const store = await tagada.stores.create({
name: 'Test Store',
baseCurrency: 'USD',
presentmentCurrencies: ['USD', 'EUR'],
chargeCurrencies: ['USD'],
selectedPaymentFlowId: flow.id,
});
Or if your store already exists, assign it via the dashboard: Store Settings → Payments → Select Payment Flow.
Step 4: Complete the Setup
Follow the Merchant Quick Start to create a product and funnel. Once your checkout is live, any payment submitted will go through the sandbox processor.
Testing Payments
On the Checkout Page
- Open your checkout URL in a browser
- Fill in any email and shipping details
- Enter any card number — the sandbox accepts everything:
4242 4242 4242 4242(or any 16 digits)- Any future expiry date
- Any 3-digit CVC
- Submit payment
- The order is created and you're redirected to the thank you page
Via the Headless API
You can also create a checkout session programmatically and share the link:
```ts theme={null} const session = await tagada.checkout.createSession({ storeId: store.id, items: [{ variantId: 'variant_...', quantity: 1 }], currency: 'USD', checkoutUrl: 'https://your-funnel-checkout-url.cdn.tagadapay.com/checkout', });
console.log('Test checkout:', session.redirectUrl);
***
## Verifying Results
After a sandbox payment, verify everything worked:
### Check Orders
```ts theme={null}
const orders = await tagada.orders.list({
storeId: store.id,
page: 1,
per_page: 5,
});
console.log('Latest orders:', orders.data);
Check Payments
```ts theme={null} const payments = await tagada.payments.list({ pagination: { page: 1, pageSize: 5 }, filters: { storeIds: [store.id] }, }); console.log('Latest payments:', payments.data);
### Check Webhooks
If you've configured webhooks, they fire for sandbox payments exactly as they would for real ones:
```ts theme={null}
const webhooks = await tagada.webhooks.list(store.id);
console.log('Configured webhooks:', webhooks);
Testing Subscriptions
The sandbox processor fully supports subscription billing. Create a recurring product and test the billing cycle:
```ts theme={null} // Create a subscription product await tagada.products.create({ storeId: store.id, name: 'Monthly Membership', active: true, variants: [{ name: 'Standard', sku: 'membership-monthly', grams: 0, price: 1999, compareAtPrice: 0, active: true, default: true, prices: [{ currencyOptions: { USD: { amount: 1999 } }, recurring: true, interval: 'month', intervalCount: 1, billingTiming: 'in_advance', default: true, }], }], });
When a customer subscribes through the checkout:
* The initial payment is processed through the sandbox
* The subscription is created in AsherPay
* Rebilling occurs on schedule (processed through the sandbox)
* You can manage the subscription via the API or dashboard
***
## Sandbox vs Production
| Behavior | Sandbox | Production |
| --------------- | ------------------ | -------------------- |
| Card validation | Accepts any card | Real card validation |
| Charges | No real money | Real charges |
| Orders | Created normally | Created normally |
| Webhooks | Fire normally | Fire normally |
| Subscriptions | Created and billed | Created and billed |
| 3D Secure | Skipped | Enforced if enabled |
| Refunds | Simulated | Real refunds |
***
## Going Live
When you're ready for production:
1. Create a real processor (Stripe, NMI, Adyen, etc.) with production credentials
2. Create a new payment flow using the real processor
3. Update your store's payment flow assignment
4. Your checkout now processes real payments
```ts theme={null}
// 1. Real processor
const { processor: stripeProcessor } = await tagada.processors.create({
processor: {
name: 'Stripe Production',
type: 'stripe',
enabled: true,
supportedCurrencies: ['USD', 'EUR'],
baseCurrency: 'USD',
options: {
secretKey: 'sk_live_...',
publicKey: 'pk_live_...',
webhookSecret: 'whsec_...',
},
},
});
// 2. Production flow
const prodFlow = await tagada.paymentFlows.create({
data: {
name: 'Production Flow',
strategy: 'simple',
fallbackMode: false,
maxFallbackRetries: 0,
threeDsEnabled: true,
stickyProcessorEnabled: false,
pickProcessorStrategy: 'weighted',
processorConfigs: [
{ processorId: stripeProcessor.id, weight: 100, disabled: false, nonStickable: false },
],
fallbackProcessorConfigs: [],
abuseDetectionConfig: null,
},
});
// 3. To switch a store's payment flow, update it in the dashboard
// or recreate the store with the new flow ID
Cleanup
When done testing, archive the sandbox processor:
ts theme={null}
await tagada.processors.del([processor.id]);