POST /sandbox/test-purchases

Sandbox only: the production API does not serve this operation. Buys the named listings of the authenticated seller as Snapcaster's sandbox buyer, through the same checkout a buyer uses, and pays in Stripe test mode. The capture then creates the order and sends the usual signed order.created webhook, or inventory.adjusted for an inventory subscription. The buyer, its contact details, its address and the card are Snapcaster's; send only the lines and, optionally, a shipping option. A purchase takes at most 5 lines of at most 10 cards each, totals at most 25000 cents before tax and fees, and a platform may start 20 an hour. Retrying with the same Idempotency-Key and body returns the same test_purchase_ref and never pays twice. Poll GET /sandbox/test-purchases/{ref} until status is succeeded or failed. The sandbox catalog holds product 86 as SKUs 14602 (NM), 363348 (LP), 316074 (DM); list two of them to file a substitution.

Example

These examples send requests to the sandbox.

cURL request - Sandbox: One card
curl --request POST \
  --url 'https://api-sandbox.snapcaster.ca/api/v1/marketplace/sandbox/test-purchases' \
  --header "Authorization: Bearer $MARKETPLACE_API_KEY" \
  --header "Idempotency-Key: $(uuidgen)" \
  --header 'Content-Type: application/json' \
  --data '{
  "lines": [
    {
      "skuId": 14602,
      "quantity": 1
    }
  ]
}'

$(uuidgen) makes a new Idempotency-Key each time you run the command. To retry a command after a lost response, send the key from the first attempt.

Response 202: Paid, order pending
{
  "success": true,
  "data": {
    "test_purchase_ref": "tpr_3f2c0b9d8e7a6f5c4b3a29180f7e6d5c",
    "checkout_id": "chk_4e1f7a2b9c3d",
    "status": "processing",
    "order_ids": [],
    "failure": null
  }
}

Endpoint

EnvironmentURL
Sandboxhttps://api-sandbox.snapcaster.ca/api/v1/marketplace/sandbox/test-purchases
Authentication
  • marketplaceApiKey - http bearer. Send the seller's marketplace API key as Authorization: Bearer mp_{sellerCode}_{hex}. The mp_{sellerCode}_ prefix identifies the seller; the trailing hex is the secret. The seller generates the key and supplies it to your platform.

Request

Headers

Idempotency-Key string required

Keep this UUID when retrying the same order operation and body. Keys remain valid for the lifetime of the order. Changed contents return 409 IDEMPOTENCY_CONFLICT; a concurrent attempt returns 409 REQUEST_IN_PROGRESS with Retry-After.

Constraints: format: uuid Example f04e4a96-3c99-44dc-abce-5b6862c589c9

X-Snapcaster-Api-Version string

Override the platform pin for this request only. Webhook versions and the platform pin do not change.

Constraints: allowed values: 2026-10 Example 2026-10

Request body

lines array of object required

The line items in this request, response, or event.

Constraints: minimum items: 1; maximum items: 5

Show child fieldsHide child fields
lines[].skuId integer required

A SKU of one of the authenticated seller's listings.

Constraints: exclusive minimum: 0 Example 14602

lines[].quantity integer required

The number of units.

Constraints: minimum: 1; maximum: 10 Example 1

shippingOptionId integer

One of the seller's shipping options. Omit it to use the cheapest option that carries every card in the purchase.

Constraints: exclusive minimum: 0

Response

202

The test purchase, paid and waiting for its order, or failed.

Response body: SandboxTestPurchaseResponse

success boolean required

Whether the operation completed as requested.

Constraints: allowed values: true Example true

data SandboxTestPurchase required

The operation or event payload.

Show child fieldsHide child fields
data.test_purchase_ref string required

Stable for the Idempotency-Key that started the purchase.

Example tpr_3f2c0b9d8e7a6f5c4b3a29180f7e6d5c

data.checkout_id string required

The checkout the sandbox buyer paid through.

Example chk_4e1f7a2b9c3d

data.status string required

processing until the payment is captured and the order exists, then succeeded. failed when the payment did not complete.

Constraints: allowed values: processing, succeeded, failed Example processing

data.order_ids array of string required

The orders the purchase created, as order_id values. Empty until succeeded.

Field example[]
data.failure object or null required

Why the purchase failed, or null.

Show child fieldsHide child fields
data.failure.code string required

The stable machine-readable code for this result.

Constraints: allowed values: TEST_PAYMENT_FAILED, TEST_PURCHASE_NOT_AVAILABLE

data.failure.message string required

A human-readable explanation of the result.

Errors

Errors return a MarketplaceError body, except HTTP 413, 500 (ApiError). Error codes explains both error bodies and lists every code.

  • 400 INVALID_REQUEST IDEMPOTENCY_KEY_REQUIRED UNSUPPORTED_API_VERSION

    Invalid command body or missing/invalid UUID Idempotency-Key. Unknown or retired API-version override (UNSUPPORTED_API_VERSION).

    Do this: Correct the request fields and supply a UUID Idempotency-Key. Keep the same key when retrying the same command. For UNSUPPORTED_API_VERSION, choose a supported version from the API versioning guide.

  • 401 UNAUTHORIZED

    Missing or invalid marketplace API key (UNAUTHORIZED).

    Do this: Send the marketplace API key for this seller as a Bearer token, then retry.

  • 409 IDEMPOTENCY_CONFLICT REQUEST_IN_PROGRESS INSUFFICIENT_STOCK

    IDEMPOTENCY_CONFLICT when the key was used with a different body, REQUEST_IN_PROGRESS while another request with this key runs, or INSUFFICIENT_STOCK when a line asks for more than the listing has available.

    Do this: For REQUEST_IN_PROGRESS, wait Retry-After seconds and retry the same key and body. For IDEMPOTENCY_CONFLICT, reuse the original body or a new UUID. For INSUFFICIENT_STOCK, push more on-hand or ask for fewer cards.

  • 413 PAYLOAD_TOO_LARGE

    The body is larger than this route accepts (PAYLOAD_TOO_LARGE).

    Do this: Send a smaller body and retry.

  • 422 TEST_LISTING_NOT_BROWSABLE SHIPPING_OPTION_INVALID TEST_PURCHASE_LIMIT_EXCEEDED

    TEST_LISTING_NOT_BROWSABLE when a SKU has no browsable listing for this seller, SHIPPING_OPTION_INVALID when the shipping option is not the seller's or cannot carry the cards, or TEST_PURCHASE_LIMIT_EXCEEDED when merchandise and shipping total more than 25000 cents.

    Do this: Check the listing with GET /listings until it reads browsable, omit shippingOptionId to use the cheapest option that fits, or buy fewer or cheaper cards.

  • 429 RATE_LIMITED

    More than 20 test purchases in the last hour for this platform (RATE_LIMITED).

    Do this: Wait the Retry-After duration in seconds, then retry.

  • 500 INTERNAL_ERROR

    An unexpected failure (INTERNAL_ERROR).

    Do this: Retry with bounded retries and jitter. If the failure persists, contact Snapcaster with the X-Correlation-ID response header.

  • 503 TEST_PURCHASE_NOT_AVAILABLE

    This deployment cannot run a test purchase right now (TEST_PURCHASE_NOT_AVAILABLE): it is not the sandbox, its payments are not in test mode, or its sandbox buyer is missing.

    Do this: Call the sandbox API. If this persists there, contact Snapcaster with the X-Correlation-ID response header.