# Quickstart

This guide takes you from zero to a successful sandbox payment using **hosted checkout** — the simplest integration path. Fynex hosts the card form; you redirect the customer and verify the result. Plan for about 5 minutes.

> [!NOTE]
> All examples target the **staging** environment. Switch the base URL to `https://api.fynex.ai` when you are ready for production.

## Prerequisites

- A seller API token — mint your own from the dashboard **Integration** page, or via the API (see [Authentication](https://api.fynex.ai/payments-api/v2/docs#tag/authentication)).
- A seller account in **demo** mode. New accounts are created in `Demo` mode and activated automatically, so the sandbox calls below work right away. (If you ever get `403 seller account is not active`, the account isn't active — contact Fynex with your seller account ID. Going **live** for real-money payments requires KYB + a Fynex-assigned live terminal.)
- A terminal with `curl`, plus Node.js 20+ or Python 3.10+ if you prefer those snippets.

## Step-by-step

1. **Get a token and configure your environment**

   Get your token yourself from the dashboard: log in to `https://staging-dashboard.fynex.ai`, select your seller account, open the **Integration** page, reveal the token, and copy it (see [Authentication](https://api.fynex.ai/payments-api/v2/docs#tag/authentication) for details). Then export it:

   ```bash
   export FYNEX_API="https://staging-api.fynex.ai/payments-api/v1"
   export FYNEX_TOKEN="<the token you copied>"
   ```

2. **Create a hosted checkout session**

   Send a `POST /checkout` request with your order details. The `Idempotency-Key` header is mandatory — use a fresh UUID per request to prevent duplicate sessions.

#### curl

```bash
curl -sS -X POST "$FYNEX_API/checkout" \
  -H "Authorization: Bearer $FYNEX_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "externalOrderRef": "ORDER-DEMO-1",
    "amount": 19.99,
    "currencyCode": "GBP",
    "countryCode": "GB",
    "autoSettlement": true,
    "returnUrls": {
      "success": "https://example.com/success",
      "failure": "https://example.com/failure"
    }
  }'
```

#### JavaScript

```js
import { randomUUID } from 'node:crypto';

const res = await fetch(`${process.env.FYNEX_API}/checkout`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.FYNEX_TOKEN}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': randomUUID(),
  },
  body: JSON.stringify({
    externalOrderRef: 'ORDER-DEMO-1',
    amount: 19.99,
    currencyCode: 'GBP',
    countryCode: 'GB',
    autoSettlement: true,
    returnUrls: {
      success: 'https://example.com/success',
      failure: 'https://example.com/failure',
    },
  }),
});

const session = await res.json();
console.log(session.checkoutUrl); // redirect the customer here
```

#### Python

```python
import os, uuid, requests

res = requests.post(
    f"{os.environ['FYNEX_API']}/checkout",
    headers={
        "Authorization": f"Bearer {os.environ['FYNEX_TOKEN']}",
        "Content-Type": "application/json",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "externalOrderRef": "ORDER-DEMO-1",
        "amount": 19.99,
        "currencyCode": "GBP",
        "countryCode": "GB",
        "autoSettlement": True,
        "returnUrls": {
            "success": "https://example.com/success",
            "failure": "https://example.com/failure",
        },
    },
)
session = res.json()
print(session["checkoutUrl"])  # redirect the customer here
```

   A `201 Created` response returns:

   ```json
   {
     "sessionId": "6f9b84e1-3b83-4fb9-9f42-a8ac27d11d6b",
     "checkoutUrl": "https://staging-api.fynex.ai/checkout/6f9b84e1-3b83-4fb9-9f42-a8ac27d11d6b",
     "expiresAt": "2026-04-29T11:30:00Z"
   }
   ```

   ### Request field reference

   | Field | Type | Required | Notes |
   |-------|------|----------|-------|
   | `externalOrderRef` | string | Yes | Your order ID — must be unique per seller |
   | `amount` | float | Yes | Major units (e.g., `19.99` for £19.99) |
   | `currencyCode` | string | Yes | 3-letter ISO code (e.g., `GBP`). Unsupported currencies may be rejected when the payment is processed. |
   | `countryCode` | string | Yes | 2-letter ISO code (e.g., `GB`) |
   | `autoSettlement` | bool | No | `true` to auto-capture; `false` for manual capture later |
   | `returnUrls.success` | string | No | Customer redirected here on success; falls back to seller checkout settings, then the hosted checkout page |
   | `returnUrls.failure` | string | No | Customer redirected here on failure; falls back to seller checkout settings, then the hosted checkout page |
   | `sellerMerchantName` | string | No | Displayed on the checkout page |
   | `logoUrl` | string | No | Merchant logo URL shown on the checkout page |
   | `locale` | string | No | Falls back to seller account locale, then `"en"` |
   | `description` | string | No | Order description shown to the customer |

3. **Redirect the customer to the checkout URL**

   Take `checkoutUrl` from the response and redirect the customer's browser to it:

   ```
   HTTP/1.1 302 Found
   Location: https://staging-api.fynex.ai/checkout/6f9b84e1-3b83-4fb9-9f42-a8ac27d11d6b
   ```

   Fynex hosts the card entry form. Your server stays out of PCI scope.

4. **Complete the payment with a test card**

   On the hosted checkout page, enter:

   - **Card number:** `4111 1111 1111 1111`
   - **Expiry:** any future month/year
   - **CVV:** any 3 digits

> [!NOTE]
> This is a common sandbox test card. Confirm with your Fynex contact for the current set of accepted test cards and any outcome-specific numbers (decline, 3DS, etc.).

   Submit the form. The page will redirect to `returnUrls.success` on completion, or `returnUrls.failure` if the payment fails.

5. **Verify the result**

   Fynex delivers a `PaymentCompleted` webhook to the webhook URL(s) configured on your seller account (your receiver must return HTTP 200), and you can also poll for the payment status as a backstop. The simplest polling path for server-to-server backends is `GET /payments-api/v1/payments/{externalOrderRef}` — same bearer token you already have, returning the current Fynex `status`, amount, currency, payment method, timestamps, and any seller-safe failure summary. For browser/dashboard contexts the GraphQL `genericPayment` query or the SSE stream are also available. See the [Polling & SSE guide](https://api.fynex.ai/payments-api/v2/docs#tag/polling-sse) for the full verification pattern.

## What just happened

- Fynex created a draft payment tied to your seller account, returned a hosted page URL, and collected card details on its own domain — your integration never touches raw card data.
- `autoSettlement: true` means the payment was automatically captured when the card was charged. Set it to `false` if you want to capture manually later (see [Captures & Refunds](https://api.fynex.ai/payments-api/v2/docs#tag/captures-refunds)).
- The `Idempotency-Key` you sent guarantees that retrying the same request (e.g., after a network timeout) returns the **same session** instead of creating a duplicate.

## See also

- **[Authentication & Tokens](https://api.fynex.ai/payments-api/v2/docs#tag/authentication)** — How tokens work, how to rotate them, and what to do if one leaks.
- **[Hosted Checkout](https://api.fynex.ai/payments-api/v2/docs#tag/hosted-checkout)** — Full hosted checkout reference — optional fields, return URL handling, and more.
- **[Polling & SSE](https://api.fynex.ai/payments-api/v2/docs#tag/polling-sse)** — How to verify payment status without webhooks.
- **[Payment methods](https://api.fynex.ai/payments-api/v2/docs#tag/payment-methods)** — Discover what payment methods are enabled on your account.
