Sandbox Guide
The mCards sandbox environment lets you test your integration without affecting production data. Sandbox mode provides simulated transaction processing, isolated data, and predictable responses for automated testing.
Setting Up the Sandbox
Step 1: Create a Sandbox OAuth Application
Sandbox applications are created with the sandbox: true flag and automatically get a sandbox_mcp_* prefix on their client ID.
typescript
import { McardsSdk } from '@mcards/sdk';
const client = new McardsSdk({
apiKey: process.env.MCARDS_API_KEY,
apiSecret: process.env.MCARDS_API_SECRET,
});
const { data: app } = await client.oauth.createApplication(
'My Sandbox App',
'partner:read wallets:read cards:read sandbox:write',
true // sandbox = true
);
console.log(app.client_id); // sandbox_mcp_abc123...
console.log(app.client_secret);Step 2: Get a Sandbox Bearer Token
typescript
const { data: token } = await client.oauth.createToken(
app.client_id,
app.client_secret,
);
client.setBearerToken(token.access_token);Step 3: Verify Sandbox Mode
All sandbox requests include the X-Sandbox-Mode: true response header.
typescript
const { data: info } = await client.sandbox.getEnvironment();
// { environment: "sandbox", features: [...], limits: {...} }Transaction Simulation
The sandbox provides a full transaction lifecycle: authorize, settle, refund, and decline.
Authorize a Transaction
typescript
const { data: txn } = await client.sandbox.authorize({
amount: 42.50,
currency: 'USD',
merchant_name: 'Coffee Shop',
merchant_category_code: '5812',
});
// { transaction_id: "txn_sandbox_abc123", status: "authorized", ... }Settle a Transaction
typescript
const { data: settled } = await client.sandbox.settle({
transaction_id: txn.transaction_id,
amount: 42.50, // optional: partial settlement supported
});Refund a Transaction
typescript
const { data: refund } = await client.sandbox.refund({
transaction_id: txn.transaction_id,
amount: 10.00, // partial refund
});Decline a Transaction
typescript
const { data: declined } = await client.sandbox.decline({
amount: 100.00,
currency: 'USD',
merchant_name: 'Risky Merchant',
reason: 'insufficient_funds',
});Decline Reasons
| Reason | Description |
|---|---|
insufficient_funds | Cardholder balance too low |
card_inactive | Card is not active |
expired_card | Card has expired |
fraud_suspected | Fraud detection triggered |
merchant_blocked | Merchant is on blocklist |
limit_exceeded | Transaction exceeds card limit |
Python Sandbox Example
python
import os
from mcards_sdk import McardsSdk
with McardsSdk(
api_key=os.environ["MCARDS_API_KEY"],
api_secret=os.environ["MCARDS_API_SECRET"],
) as client:
# Create sandbox app + token
app = client.oauth.create_application(
name="Python Sandbox Test",
scopes="sandbox:write partner:read",
sandbox=True,
)
token = client.oauth.create_token(
client_id=app.data["client_id"],
client_secret=app.data["client_secret"],
)
client.set_bearer_token(token.data["access_token"])
# Authorize
txn = client.sandbox.authorize(
amount=99.99,
currency="USD",
merchant_name="Test Merchant",
)
print(f"Authorized: {txn.data['transaction_id']}")
# Settle
settled = client.sandbox.settle(
transaction_id=txn.data["transaction_id"],
)
print(f"Settled: {settled.data['status']}")Best Practices
- Use sandbox for all development and staging environments — never test against production
- Create separate sandbox apps for each developer or CI pipeline
- Test the full lifecycle — authorize, settle, refund, decline
- Verify webhook delivery — use sandbox to confirm your webhook handler processes events correctly
- Test error cases — use decline reasons to exercise error handling paths
- Reset sandbox state periodically to keep test data clean