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

# Create a checkout

> Create an order in Hurry and get the checkout URL to redirect the buyer to.

This endpoint creates an order, picks your store's payment gateway and returns the checkout URL. Your website just needs to redirect the buyer to that URL.

* **Authentication:** not required. The store is identified by `shopUrl`.
* **Amounts:** in cents (the currency's minor unit). `2500` is €25.00.

> [!WARNING]
>
> Errors are returned as **HTTP 200 with `redirectUrl: null`**. Checking the HTTP code isn't enough: always make sure `redirectUrl` is set before redirecting.

***

## Request body

**externalId** `string` *required*

ID of the cart or order in your system. It makes the call idempotent: if you repeat it with the same value, you get the same order. See [Idempotency](#idempotency).

**shopUrl** `string` *required*

Store URL exactly as registered in Hurry. It must match an active store **exactly**, character for character. If it's missing or doesn't match, no order is created.

**items** `Item[]` *required*

Cart lines. Can't be empty.

**Item properties**

**name** `string` *required*

Product name.

**unitAmount** `integer` *required*

Unit price in cents.

**quantity** `integer` *required*

Units.

**taxAmount** `integer`

**Total tax for the line** in cents. It isn't multiplied by `quantity`.

**productId** `string`

Product ID in your system.

**sku** `string`

Product SKU.

**imageUrl** `string`

Product image shown at checkout.

**currency** `string` (default: USD)

Charge currency, in ISO 4217 format (`EUR`, `USD`…).

**showCurrency** `string`

Currency shown to the buyer. Only needed in multi-currency stores.

**shippingOptionId** `string`

Store shipping option. If you don't send it, the first active option is used.

**sourceUrl** `string`

URL of the page the buyer was on. Used as `event_source_url` in the pixels' server events.

**notes** `string`

Order notes.

**logoUrl** `string`

Checkout logo. Only used if the store doesn't have one configured.

### Tracking signals

All optional. Send them so your pixels' server events attribute the sale correctly.

**fbc** `string`

Meta `_fbc` cookie.

**fbp** `string`

Meta `_fbp` cookie.

**visitorId** `string`

Visitor ID (`hy_vid`). It's the same `external_id` the pixel sends from the browser.

**ttc** `string`

TikTok click ID.

**ttp** `string`

TikTok `_ttp` cookie.

**gclid** `string`

Google Ads click ID (`gclid`, `gcl_au` or `gcl_aw`).

**epik** `string`

Pinterest click ID (`_epik` cookie).

> [!NOTE]
>
> You don't need to send the buyer's IP or User-Agent: Hurry takes them from the request itself. Pixel IDs and the option to show your own terms are read from the store settings.

***

## Response

**redirectUrl** `string | null`

Checkout URL you must redirect the buyer to. It's `null` if the order couldn't be created.

**orderId** `string`

Order ID in Hurry.

**gateway** `string`

Gateway used (`STRIPE`, `SHOPIFY`…). Only present with some gateways, such as Shopify Payments.

**status** `string`

Payment status: `pending`, `paid`, `cancelled`, `refunded` or `fulfilled`. Only present with some gateways.

**checkoutUrl** `string`

Same as `redirectUrl`. Only present with some gateways.

**paymentSessionId** `string`

Payment session ID in Hurry. Only present with some gateways.

**externalPaymentSessionId** `string`

Payment session ID in the gateway. Only present with some gateways.

***

## Errors

The request responds **HTTP 200 with `redirectUrl: null`** when:

* `shopUrl` is missing, doesn't exist or the store is disabled.
* The account is suspended.
* Charges are paused because the daily cap of [volume routing](https://docs.hurrypayments.com/en/volume-routing.md) has been reached. They resume at 00:00.
* The store has no active payment gateway.
* The body isn't valid, for example with empty `items`.

The only request that returns an HTTP error is one that arrives **without `externalId`**.

***

## Idempotency

If you repeat the call with the same `externalId` (page reload, double click, retry), you get **the same order** as long as it can still be charged through its gateway.

If that gateway is no longer available (you've disabled it or the store no longer uses it), Hurry creates a new order routed with your current settings. Subsequent calls with the same `externalId` receive that new order.

***

## Amount calculation

```text Total theme={null}
total = Σ (unitAmount × quantity) + Σ taxAmount + shipping
```

In multi-currency stores, the amount is converted from `showCurrency` to `currency` at the day's exchange rate plus the surcharge you've set on the store.

***

## Order statuses

| Status | When |
| :- | :- |
| `PENDING` | When the order is created. |
| `IN_PROGRESS` | When the buyer opens the checkout page. |

```bash cURL theme={null}
curl -X POST https://app.hurrypayments.com/api/orders \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "CART-abc123-9f1e",
    "shopUrl": "mystore.com",
    "currency": "EUR",
    "sourceUrl": "https://mystore.com/cart",
    "items": [
      {
        "productId": "p1",
        "name": "T-shirt",
        "unitAmount": 2500,
        "quantity": 2,
        "imageUrl": "https://mystore.com/img/t-shirt.jpg"
      }
    ]
  }'
```

```javascript JavaScript theme={null}
const res = await fetch("https://app.hurrypayments.com/api/orders", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    externalId: "CART-abc123-9f1e",
    shopUrl: "mystore.com",
    currency: "EUR",
    items: [
      { productId: "p1", name: "T-shirt", unitAmount: 2500, quantity: 2 }
    ]
  })
});
const data = await res.json();

if (data.redirectUrl) {
  window.location.href = data.redirectUrl;
} else {
  // The checkout couldn't be created: show an error or go back to the cart
}
```

```json Order created theme={null}
{
  "redirectUrl": "https://app.hurrypayments.com/checkout/detail/v2?orderId=8f3c2a91-...",
  "orderId": "8f3c2a91-..."
}
```

```json Error theme={null}
{
  "redirectUrl": null,
  "orderId": null
}
```


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