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

ReasonDescription
insufficient_fundsCardholder balance too low
card_inactiveCard is not active
expired_cardCard has expired
fraud_suspectedFraud detection triggered
merchant_blockedMerchant is on blocklist
limit_exceededTransaction 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

  1. Use sandbox for all development and staging environments — never test against production
  2. Create separate sandbox apps for each developer or CI pipeline
  3. Test the full lifecycle — authorize, settle, refund, decline
  4. Verify webhook delivery — use sandbox to confirm your webhook handler processes events correctly
  5. Test error cases — use decline reasons to exercise error handling paths
  6. Reset sandbox state periodically to keep test data clean