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

# Quickstart: your first sandbox payment

> Create a connection, send one payment with a test card in the Yuno sandbox, and see it in the dashboard.

Getting started

Tutorial · about 10 minutes

Yuno is the AI operating system for payments, and a payment is the first thing you run on it. You send your first sandbox payment in about 10 minutes once you have sandbox credentials.

Create a connection
Send one payment with a test card
See it in the dashboard

### 1. Get your sandbox credentials

Log in to the [Yuno dashboard](https://dashboard.y.uno/) and open **Developers** to find three values:

* **Account code**, shown as `account_id` in the dashboard
* **`public-api-key`**
* **`private-secret-key`**

Sandbox keys start with `sandbox_`. Production keys are different and start with `prod_`.

![Yuno dashboard log in page](https://mintcdn.com/yuno-3979e326/mqKc4056TZzyLssc/images/reference/step-1-set-up-your-account/image1.png?fit=max\&auto=format\&n=mqKc4056TZzyLssc\&q=85\&s=09be08d430f7f2e7af07821dd84f146f)

If you do not have an account yet, ask your Yuno contact or write to [sales@y.uno](mailto:sales@y.uno). There is no self-serve signup today.

### 2. Connect the Yuno Test Payment Gateway and publish a route

The Yuno Test Payment Gateway simulates a card provider. It works in sandbox only and needs no credentials.

1. Open [Connections](https://dashboard.y.uno/connections), search for **Yuno Test Payment Gateway**, click **Connect**, name the connection, and click **Save**.
2. Open [Routing](https://dashboard.y.uno/routing), open the **Not published** tab, find **Card**, and click **Set Up**.
3. Click **+ Create new route**, name it, and click **Save**.
4. Click the arrow, choose **Add step**, select **Yuno Test Payment Gateway**, and click **Publish**.
5. Open [Checkout builder](https://dashboard.y.uno/checkout-builder), turn on **Card**, and publish the settings.

### 3. Send the payment

**API**

> [!WARNING]
>
> Sending raw card numbers from your server is for sandbox testing. In production it requires PCI DSS scope. Otherwise use the Yuno SDK or Secure Fields to collect card data.

The API tab uses the `DIRECT` workflow, a back-to-back payment where your server sends the card data. Set your credentials as environment variables:

```bash Shell theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
export YUNO_PUBLIC_API_KEY="sandbox_..."
export YUNO_PRIVATE_SECRET_KEY="sandbox_..."
export YUNO_ACCOUNT_ID="your-account-code"
```

First, create a customer. The base URL is `https://api-sandbox.y.uno`.

```bash cURL theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
curl --request POST \
  --url https://api-sandbox.y.uno/v1/customers \
  --header "public-api-key: $YUNO_PUBLIC_API_KEY" \
  --header "private-secret-key: $YUNO_PRIVATE_SECRET_KEY" \
  --header "content-type: application/json" \
  --data '{
    "merchant_customer_id": "customer-0001",
    "first_name": "John",
    "last_name": "Doe",
    "email": "john.doe@example.com"
  }'
```

```javascript Node.js theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
const res = await fetch("https://api-sandbox.y.uno/v1/customers", {
  method: "POST",
  headers: {
    "public-api-key": process.env.YUNO_PUBLIC_API_KEY,
    "private-secret-key": process.env.YUNO_PRIVATE_SECRET_KEY,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    merchant_customer_id: "customer-0001",
    first_name: "John",
    last_name: "Doe",
    email: "john.doe@example.com",
  }),
});
const customer = await res.json();
console.log(customer.id);
```

```python Python theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
import os
import requests

res = requests.post(
    "https://api-sandbox.y.uno/v1/customers",
    headers={
        "public-api-key": os.environ["YUNO_PUBLIC_API_KEY"],
        "private-secret-key": os.environ["YUNO_PRIVATE_SECRET_KEY"],
    },
    json={
        "merchant_customer_id": "customer-0001",
        "first_name": "John",
        "last_name": "Doe",
        "email": "john.doe@example.com",
    },
)
print(res.json()["id"])
```

The response includes an `id`. Save it as `YUNO_CUSTOMER_ID` for the next call.

Then create the payment with a test card. Send a new `X-Idempotency-Key` with each payment.

```bash cURL theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
curl --request POST \
  --url https://api-sandbox.y.uno/v1/payments \
  --header "public-api-key: $YUNO_PUBLIC_API_KEY" \
  --header "private-secret-key: $YUNO_PRIVATE_SECRET_KEY" \
  --header "X-Idempotency-Key: $(uuidgen)" \
  --header "content-type: application/json" \
  --data '{
    "account_id": "'"$YUNO_ACCOUNT_ID"'",
    "merchant_order_id": "order-0001",
    "description": "First test payment",
    "country": "US",
    "amount": { "currency": "USD", "value": 25 },
    "workflow": "DIRECT",
    "customer_payer": { "id": "'"$YUNO_CUSTOMER_ID"'" },
    "payment_method": {
      "type": "CARD",
      "detail": { "card": { "card_data": {
        "number": "4507990000000002",
        "expiration_month": 11,
        "expiration_year": 28,
        "security_code": "123",
        "holder_name": "John Doe"
      } } }
    }
  }'
```

```javascript Node.js theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
const res = await fetch("https://api-sandbox.y.uno/v1/payments", {
  method: "POST",
  headers: {
    "public-api-key": process.env.YUNO_PUBLIC_API_KEY,
    "private-secret-key": process.env.YUNO_PRIVATE_SECRET_KEY,
    "X-Idempotency-Key": crypto.randomUUID(),
    "content-type": "application/json",
  },
  body: JSON.stringify({
    account_id: process.env.YUNO_ACCOUNT_ID,
    merchant_order_id: "order-0001",
    description: "First test payment",
    country: "US",
    amount: { currency: "USD", value: 25 },
    workflow: "DIRECT",
    customer_payer: { id: process.env.YUNO_CUSTOMER_ID },
    payment_method: {
      type: "CARD",
      detail: { card: { card_data: {
        number: "4507990000000002",
        expiration_month: 11,
        expiration_year: 28,
        security_code: "123",
        holder_name: "John Doe",
      } } },
    },
  }),
});
const payment = await res.json();
console.log(payment.status, payment.sub_status);
```

```python Python theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
import os
import uuid
import requests

res = requests.post(
    "https://api-sandbox.y.uno/v1/payments",
    headers={
        "public-api-key": os.environ["YUNO_PUBLIC_API_KEY"],
        "private-secret-key": os.environ["YUNO_PRIVATE_SECRET_KEY"],
        "X-Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "account_id": os.environ["YUNO_ACCOUNT_ID"],
        "merchant_order_id": "order-0001",
        "description": "First test payment",
        "country": "US",
        "amount": {"currency": "USD", "value": 25},
        "workflow": "DIRECT",
        "customer_payer": {"id": os.environ["YUNO_CUSTOMER_ID"]},
        "payment_method": {
            "type": "CARD",
            "detail": {"card": {"card_data": {
                "number": "4507990000000002",
                "expiration_month": 11,
                "expiration_year": 28,
                "security_code": "123",
                "holder_name": "John Doe",
            }}},
        },
    },
)
payment = res.json()
print(payment["status"], payment["sub_status"])
```

The payment succeeds when the response looks like this:

```json Response (trimmed) theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
{
  "id": "6c44ed29-cc51-4479-a5eb-108afdaadd50",
  "status": "SUCCEEDED",
  "sub_status": "APPROVED",
  "amount": { "currency": "USD", "value": 25 }
}
```

**Web SDK**

The Web SDK tab splits the work. Your server creates a checkout session, and the browser loads the SDK and starts the transaction.

**On your server**, create the checkout session. Use `workflow: "SDK_SEAMLESS"` so the SDK creates the payment for you. Without it the transaction ends in `INTERNAL_ERROR`.

```bash cURL theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
curl --request POST \
  --url https://api-sandbox.y.uno/v1/checkout/sessions \
  --header "public-api-key: $YUNO_PUBLIC_API_KEY" \
  --header "private-secret-key: $YUNO_PRIVATE_SECRET_KEY" \
  --header "content-type: application/json" \
  --data '{
    "account_id": "'"$YUNO_ACCOUNT_ID"'",
    "merchant_order_id": "order-0001",
    "payment_description": "First test payment",
    "country": "US",
    "amount": { "currency": "USD", "value": 25 },
    "workflow": "SDK_SEAMLESS"
  }'
```

```javascript Node.js theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
const res = await fetch("https://api-sandbox.y.uno/v1/checkout/sessions", {
  method: "POST",
  headers: {
    "public-api-key": process.env.YUNO_PUBLIC_API_KEY,
    "private-secret-key": process.env.YUNO_PRIVATE_SECRET_KEY,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    account_id: process.env.YUNO_ACCOUNT_ID,
    merchant_order_id: "order-0001",
    payment_description: "First test payment",
    country: "US",
    amount: { currency: "USD", value: 25 },
    workflow: "SDK_SEAMLESS",
  }),
});
const session = await res.json();
console.log(session.checkout_session);
```

```python Python theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
import os
import requests

res = requests.post(
    "https://api-sandbox.y.uno/v1/checkout/sessions",
    headers={
        "public-api-key": os.environ["YUNO_PUBLIC_API_KEY"],
        "private-secret-key": os.environ["YUNO_PRIVATE_SECRET_KEY"],
    },
    json={
        "account_id": os.environ["YUNO_ACCOUNT_ID"],
        "merchant_order_id": "order-0001",
        "payment_description": "First test payment",
        "country": "US",
        "amount": {"currency": "USD", "value": 25},
        "workflow": "SDK_SEAMLESS",
    },
)
print(res.json()["checkout_session"])
```

**In the browser**, load the SDK from the CDN, then start a transaction with the `checkout_session` value from your server.

```html Browser theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
<div id="payment-form"></div>
<script src="https://sdk-web.y.uno/v2.0.0/main.js"></script>
<script>
  async function startYuno() {
    const sdkPayments = await SdkPayments.initialize("your-public-api-key");
    const transaction = sdkPayments.transaction({
      checkoutSession: "checkout-session-from-your-server",
      countryCode: "US",
      elementSelector: "#payment-form",
      onStatus: (result) => console.log("Final status:", result.status),
    });
    await transaction.start({ paymentMethod: { type: "CARD" } });
  }

  if (window.SdkPayments) {
    startYuno();
  } else {
    window.addEventListener("sdk-payments-ready", startYuno);
  }
</script>
```

The form renders in `#payment-form`. Enter the test card **4507 9900 0000 0002**, expiry **11/28**, CVV **123**, name **John Doe**, then click Pay. The result arrives in `onStatus` with the status `SUCCEEDED`.

For iOS, Android, and every option, see the [SDK Get started](/docs/yuno-sdk/get-started.md).

### 4. See the result

* Check `status` and `sub_status` in the response. `SUCCEEDED` with `APPROVED` means the gateway approved the payment.
* Open [Payments](https://dashboard.y.uno/payments) in the dashboard, find your payment, and open it to see its details.
* To receive the result on your server, [configure a webhook](/docs/webhooks/configure-webhooks.md) and [verify its signature](/docs/webhooks/verify-webhook-signatures-hmac.md) (HMAC).

Payment statuses are listed in [Payment statuses](/reference/payments/status-and-response-codes/payment.md).

### 5. Pick your integration

Production uses the same objects and keys. Choose how much of the flow you own.

> **[Yuno SDK](/docs/yuno-sdk/get-started.md)**
>
> Tutorial
> Install the SDK on Web, iOS, or Android.

> **[Build your own UI](/docs/yuno-sdk/where-do-i-start.md)**
>
> Guide
> Choose the parameters and controllers for your own form.

> **[Direct API](/docs/direct-integration-use-cases/direct-flow.md)**
>
> Guide
> Own the whole flow from your backend.

> **[Agents and MCP](/setup-mcp.md)**
>
> Guide
> Let a coding agent call Yuno for you.

## Troubleshooting

> **The API returns 401**
>
> The `public-api-key` or `private-secret-key` header is missing or wrong. Sandbox and production use different keys, so check that you copied the sandbox keys from the dashboard in Test Mode. See [Authentication](/reference/getting-started/authentication.md).

> **The payment ends in INTERNAL\_ERROR**
>
> The `workflow` does not match your integration. Use `DIRECT` when your server sends the card, and `SDK_SEAMLESS` on the checkout session when the Web SDK creates the payment.

> **No provider processes the payment**
>
> Card has no published route. Open [Routing](https://dashboard.y.uno/routing) and check that the Card route with the Yuno Test Payment Gateway is under the **Published** tab, and that Card is turned on in the [Checkout builder](https://dashboard.y.uno/checkout-builder).

> **The card is declined**
>
> Test cards are specific to a provider. The cards in this Quickstart only work when your sandbox routes Card to the Yuno Test Payment Gateway. Other results are listed on the [Yuno Test Payment Gateway](/docs/direct-integration-use-cases/yuno-testing-gateway.md) page.

Stuck on a term? See the [Glossary](/docs/glossary.md). For URLs, keys, and specs see [Developers](/docs/developers.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.