<!-- x-generated: Generated by the Hyperscale artifact pipeline; do not edit by hand -->

# Sandbox testing

The Hyperscale sandbox runs the complete platform engine against deterministic test fixtures and an automated banking worker. Every mutation produces real ledger entries, audit trails, and webhook deliveries.

## Card lifecycles and payment testing

The platform does not provide a card simulator, card number fixtures, or test primary account numbers (PANs). Test credit card numbers do not exist in the Hyperscale API or sandbox.

Instead, card lifecycles are modeled as first-class instruments in your Product contract: `card`, `card_authorization`, `card_dispute`, `card_transaction`, and `cardholder`. Payment outcomes are tested by executing explicit contract actions on these instruments:

- `card_authorization.create`: Submit an authorization request with an amount, currency, and card reference.
- `card_authorization.approve`: Transition the authorization to approved, reserving the ledger funds.
- `card_authorization.decline`: Decline the authorization directly. Use this action to verify how your application handles declined card payments.
- `card_dispute.create`: Open a dispute against a settled card transaction to exercise chargeback and evidence handling.

This design ensures that your application tests against deterministic business state transitions rather than simulated network latency or card network magic numbers.

## Synthetic bank deposits

Queue synthetic bank credits using `sandbox_bank_credit.request` with `remittanceReference: "sandbox-credit"`. Supply an active `financialAddressId`, `amount`, `currency`, and an optional counterparty.

The sandbox bank worker runs on a five-second clock. When it ticks, it ingests queued credits, attributes the deposit through the standard attribution pipeline, records double-entry ledger evidence, and dispatches `deposit.attributed` webhooks.

## Payout decline sentinel

To test payout failures, supply `metadata.paymentReference: "sandbox-reject"` when calling `payout.create`.

The sandbox bank rejects the instruction automatically. The observation engine records the rejection, transitions the payout to failed, and releases the reserved ledger balance back to the funding account. Duplicate submissions with identical parameters remain rejected even with different references.

## Amount-based failure triggers

Standard-library instruments and custom money movements recognize amount-based failure sentinels during testing:

- Funding rejection (`amount: 99999997`): The funding transfer is refused before money moves (`ledger_transfer_rejected`). The instrument remains in its pre-funding lifecycle state.
- Release rejection (`amount: 99999998`): The release transfer is refused before money moves (`ledger_transfer_rejected`). The held balance remains locked in custody.

## KYC and identity verification rejection

Submit a national ID of `"2000000012"` to `entity.kyc.submit` or `entity.kyc.verification.start` to trigger a deterministic KYC verification rejection. All other valid national ID formats transition to verified in sandbox.

## Webhook failure simulation

Configure an endpoint URL of `"https://webhook-failure.sandbox.hyperscale.invalid/deliveries"` via `webhook.endpoint.create` or `webhook.endpoint.update`. Deliveries to this URL fail deterministically, allowing you to test retry backoff, dead-letter recording, and notification alarms.

## Platform actor operations

Call `POST /v1/sandbox/platform/fire` with header `x-hyperscale-environment: sandbox` and your Product API key to execute system-owned operations on demand. No operator credentials are required.

Supported platform operations:

- `billing_period.open`
- `billing_period.snapshot`
- `invoice.preview`
- `invoice.draft`
- `invoice.finalize`
- `api_key.rotate`

You can also fire authored HSX actions that declare a `due` clause to trigger scheduled lifecycle sweeps immediately.
