---
title: "Quickstart"
description: "See each step of a sandbox order with real responses, then place your first order from your own server in five minutes."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.cardzone.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

This page helps you place your first order in the **sandbox**. The sandbox is a test mode: it returns fixed answers and spends no money.

First you see each request and its real sandbox response: list products, place an order, and poll it until it reaches a final status. **Polling** means asking the API for the order again until its status changes. Then you send the same requests from your terminal with your own API key.

## Before you start

- A Cardzone store. Sign in at `cardzone.ai/b2b`.
- A **Sandbox** API key. Create it on the **Developers** page in the dashboard. Sandbox API keys work right away. You don't need business verification first.

> **Note**
>
> You can follow along without an API key, because the examples below show real sandbox responses. Use **Copy cURL** to copy any request. The copied request uses `$CARDZONE_API_KEY`, so you can run it with your own API key.

## Steps

1. **List the catalog**

   The catalog is the list of products you can sell. Each product is one item at one fixed amount. To order a product, send its `id` as `product_id`. With a sandbox API key, each product `id` gives a fixed test result, called a scenario.
2. **Create an order**

   Send the product, a quantity, and your own `merchant_order_ref`. `merchant_order_ref` is your own ID for the order. It makes retries safe: if you send the same `merchant_order_ref` again, you get `409` and no second order is created. Pick a scenario to see its response.
3. **Poll until the status is final**

   `processing` and `action_required` are not final. Keep polling until the status is `fulfilled`, `failed`, or `canceled`. In the example above, the **Poll** button switches to this request.
4. **Call it from your server**

   Save your sandbox API key in the `CARDZONE_API_KEY` environment variable. Then copy any example request with **Copy cURL**, or start from these samples:

   ```bash
   # Replace this value with your own sandbox API key.
   export CARDZONE_API_KEY=cz_your_sandbox_key

   curl -X POST https://cardzone.ai/api/b2b/v1/orders \
     -H "Authorization: Bearer $CARDZONE_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"product_id":"018f0000-0000-7000-8000-000000000001","quantity":1,"merchant_order_ref":"shop-order-1001"}'
   ```

   ```js
   const response = await fetch("https://cardzone.ai/api/b2b/v1/orders", {
     method: "POST",
     headers: {
       Authorization: `Bearer ${process.env.CARDZONE_API_KEY}`,
       "Content-Type": "application/json",
     },
     body: JSON.stringify({
       product_id: "018f0000-0000-7000-8000-000000000001",
       quantity: 1,
       merchant_order_ref: "shop-order-1001",
     }),
   });
   const order = await response.json();
   console.log(response.status, order.order_id, order.status);
   ```

   ```python
   import os
   import requests

   response = requests.post(
       "https://cardzone.ai/api/b2b/v1/orders",
       headers={"Authorization": f"Bearer {os.environ['CARDZONE_API_KEY']}"},
       json={
           "product_id": "018f0000-0000-7000-8000-000000000001",
           "quantity": 1,
           "merchant_order_ref": "shop-order-1001",
       },
       timeout=30,
   )
   order = response.json()
   print(response.status_code, order["order_id"], order["status"])
   ```

   ```ruby
   require "net/http"
   require "json"

   uri = URI("https://cardzone.ai/api/b2b/v1/orders")
   request = Net::HTTP::Post.new(uri, "Authorization" => "Bearer #{ENV.fetch("CARDZONE_API_KEY")}", "Content-Type" => "application/json")
   request.body = {product_id: "018f0000-0000-7000-8000-000000000001", quantity: 1, merchant_order_ref: "shop-order-1001"}.to_json
   response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
   order = JSON.parse(response.body)
   puts response.code, order["order_id"], order["status"]
   ```

## Check the result

You get a `201 Created` response. Its `status` is `fulfilled`, and `codes` holds `SANDBOX-CODE-123`:

```json
{
  "order_id": "1CAYVN8V9qVvrLwnnSZsPE",
  "merchant_order_ref": "shop-order-1001",
  "product_code": "sandbox-success-voucher",
  "status": "fulfilled",
  "code": "SANDBOX-CODE-123",
  "codes": ["SANDBOX-CODE-123"],
  "actions": []
}
```

Sandbox orders return their final status at once. A live order (a real order made with a live API key) can return `processing` first and reach its final status later. That is why you poll or listen for webhooks.

## Next steps

- [Order lifecycle](https://docs.cardzone.ai/concepts/order-lifecycle/): what each status means and what to do.
- [Catalog and recipients](https://docs.cardzone.ai/concepts/catalog-and-recipients/): build the checkout form for top-ups.
- [Webhooks](https://docs.cardzone.ai/guides/webhooks/): get updates sent to you, so you don't poll on a timer.

Source: https://docs.cardzone.ai/quickstart/index.mdx
