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

# Global-e Checkout

Global-e checkout runs in an iframe served from Global-e servers. SFCC sends the basket via **SendCartV2**, validates stock when the shopper places the order, creates a minimal SFCC order in the shopper session, then receives server-to-server updates with full international order data.

**Read order:** [Checkout flow](/checkout-flow-sfcc) (this page) → [Order lifecycle](/order-lifecycle-sfcc) (post-create updates) → [Failover and recovery](/failover-sfcc) (SOTM fallback when order create fails).

**See also:** [Configuration](/configuration-sfcc) · [Client JS SDK](/client-js-sdk-sfcc) · [Hooks → `globale.validateCart`](/hooks-sfcc) · [Metadata → Site Preferences](/metadata-sfcc)

Once the customer clicks the checkout CTA on the cart page, they are redirected to Global-e checkout (iframe served from Global-e servers).

Because checkout takes place outside SFCC, orders are created on Global-e first and then synchronized to SFCC through cartridge controller endpoints (`Globale-*`).

## Checkout journey

<Steps>
  <Step>
    **SendCartV2** — Before the iframe loads, SFCC calls the Global-e **SendCartV2** service (`Globale-SendCartV2`) with basket data, session identifiers (`dwsid` for SFRA/SiteGenesis, OCAPI/SCAPI JWT for headless), and merchant metadata. The response includes a **cart token** used by the Client JS SDK to render checkout.
  </Step>

  <Step>
    **Reserve inventory (optional)** — When site preference **`geEnableStockReservation`** is enabled, SFCC reserves basket inventory for **`geStockReservationTime`** minutes (default 30) before the Send Cart request. The **Globale-KeepAlive** endpoint keeps the SFCC session alive while the shopper is on checkout; it only creates a short (1-minute) reservation when none already exists — it does **not** extend the active SendCart reservation.
  </Step>

  <Step>
    **Show checkout** — The cartridge renders `globale/checkout/iframe.isml`, which hosts the Global-e checkout iframe using the cart token from SendCartV2.
  </Step>

  <Step>
    **Validate cart** — When the shopper clicks **Place order**, Global-e calls **`Globale-ValidateCart`** (server-to-server). SFCC runs the **`globale.validateCart`** hook (OOTB handler: `onGlobaleValidateCart.js` → `validateCartHelpers.js`). If a product is out of stock — or, when CAPI basket validation is enabled (`geEnableCartValidationCAPIBasket`, used for OCAPI/SCAPI/headless), the basket hash does not match — the shopper sees an error popup and is returned to the cart; no order is created on either side. (For the storefront default, the basket hash is enforced at order create rather than at `Globale-ValidateCart`.)
  </Step>

  <Step>
    **Order create** — After checkout completes on Global-e, SFCC must convert the basket to an order while bound to the original session (inventory reservation). Supported paths:

    * **`Globale-OrderCreate`** — legacy browser flow (Global-e SDK posts to SFCC from the container page).
    * **`Globale-OrderCreateV2`** — server-to-server order create (recommended; supports OCAPI/SCAPI session bridge for headless).

    Order create can fail due to session expiry, stock issues, or basket changes. Global-e may retry using stored basket data. On failure, the order-create response (both `Globale-OrderCreate` and `Globale-OrderCreateV2`) defaults to order number **`-1`** (`ORDER_CREATE_BYPASS_NO`) so Global-e can still send **Send Order To Merchant** (SOTM) — see [Failover and recovery](/failover-sfcc).
  </Step>

  <Step>
    **Send Order To Merchant (SOTM)** — Newly created SFCC orders start in status **Created** with minimal data. Global-e calls **`Globale-OrderSendToMerchant`** with the full international payload. The cartridge places the order (**New**), sets confirmation status to **Confirmed**, and writes Global-e attributes. When platform setting **`sfccPlaceOrderOnPaymentUpdate`** is enabled, place/confirm is deferred until payment update (step 7).
  </Step>

  <Step>
    **Perform payment** — After fraud checks pass, Global-e calls **`Globale-OrderPerformPayment`**. Payment status becomes **Paid** and export status **Ready for export** (and place/confirm runs here when **`sfccPlaceOrderOnPaymentUpdate`** is enabled).
  </Step>
</Steps>

## Checkout-phase SFCC endpoints

| Endpoint | Direction | Purpose |
| - | - | - |
| `Globale-CheckoutShow` | Storefront | Loads checkout iframe container |
| `Globale-SendCartV2` | SFCC → Global-e (service) | Sends basket; returns cart token |
| `Globale-KeepAlive` | Global-e → SFCC | Keeps SFCC session alive; creates a short reservation only if none exists |
| `Globale-ValidateCart` | Global-e → SFCC | Stock and basket validation at place order |
| `Globale-OrderCreate` | Global-e → SFCC (browser) | Legacy session-bound order create |
| `Globale-OrderCreateV2` | Global-e → SFCC (server) | Server-to-server order create |
| `Globale-ClearCart` | Global-e → SFCC | Clears basket after order confirmation |

Post-create endpoints (`Globale-OrderSendToMerchant`, `Globale-OrderPerformPayment`, and others) are documented in [Order lifecycle](/order-lifecycle-sfcc).

<h2 id="session-identifiers-in-sendcartv2-sfra--sitegenesis">
  Session identifiers in SendCartV2 (SFRA / SiteGenesis)
</h2>

<Note>
  **Mandatory for SFRA and SiteGenesis:** the shopper `dwsid` cookie must be present in the SendCartV2 `UrlParameters` (inside the `ClientCookie` entry). `getUrlParameters` collects it automatically from the storefront request, so it is only ever missing when SendCartV2 is triggered without the shopper's browser cookies (for example a misconfigured proxy/CDN that strips `dwsid`, or a custom flow that calls SendCartV2 outside the shopper request).
</Note>

On SFRA and SiteGenesis, Global-e replays the cookies it received in `ClientCookie` when it calls back server-to-server. SFCC uses the `dwsid` to re-bind to the **shopper session** and its current basket. Without it:

* **`Globale-Coupon`** cannot resolve `BasketMgr.getCurrentBasket()` for the shopper, so coupon and checkout-discount voucher apply/remove fail (`IsVoucherValid: false`).
* **`Globale-OrderCreate` / `Globale-OrderCreateV2`** cannot re-bind to the original session (inventory reservation, session-scoped promotions), so session-bound order create fails and Global-e falls back to SOTM — see [Failover and recovery](/failover-sfcc).

Headless (`int_globale_headless`) does not depend on `dwsid`: it authenticates the same server-to-server calls with the OCAPI/SCAPI JWT (`AuthToken`) instead.

## Stock validation

Out of the box, stock validation checks SFCC inventory when the shopper clicks **Place order** on Global-e checkout. Merchants can customize validation through the **`globale.validateCart`** hook — see [Hooks](/hooks-sfcc).

### Site preferences

| Preference ID | Display name | Role |
| - | - | - |
| `geEnableStockReservation` | Enable Stock Reservation | Reserve basket inventory before Send Cart |
| `geStockReservationTime` | Stock reservation time | Reservation duration in minutes (default 30) |

When **`geEnableStockReservation`** is enabled, reservation runs in `SendCartOperation` before the SendCartV2 call. **`Globale-ValidateCart`** runs again at place order.

### Releasing a reservation

When Global-e needs to release a reservation it has taken (for example, the shopper abandons checkout or the reservation expires), it calls the **`Globale-VoidInventoryReservation`** endpoint with `OrderId` and `ReservationRequestId`. This endpoint is implemented in `int_globale_sfra` only — it is not registered in the SiteGenesis controller.

Because reservation storage is merchant-specific, the cartridge ships no out-of-the-box handler. Release is implemented through the **`globale.onAfterVoidReservation`** hook — see [Hooks](/hooks-sfcc#globaleonaftervoidreservation). The hook must return a boolean indicating whether the release was applied:

1. The endpoint invokes the hook **synchronously**. If it returns `true`, processing ends there.
2. If it returns anything falsy — including when no handler is registered — SFCC stores a `GLOBALE_INVENTORY_NOTIFICATION` custom object (`geNotificationType` = `VoidReservation`) so the release can be retried asynchronously.
3. The **`custom.GlobaleInventoryVoidReservation`** job step drains those custom objects in creation order, re-invoking the same hook for each and deleting the object once the hook returns `true`.

The step type ships with the cartridge but is **not** included in the default `metadata/jobs.xml`. Create a Business Manager job for it only if you implement `globale.onAfterVoidReservation` and want the asynchronous retry path. It accepts the standard `geDisableJobStep` parameter and runs in site context.

With no handler registered, the custom objects are still written but nothing consumes them; they expire under the type's 7-day retention.

### Validation enabled vs disabled

When cart validation is **enabled** on the Global-e side, **`Globale-ValidateCart`** runs at place order. Out-of-stock products trigger a checkout popup and redirect back to the cart.

When validation is **disabled**, the shopper may reach confirmation, but SFCC order create can still fail on inventory. Global-e may create a failed order while SFCC logs show missing inventory.

When validation succeeds, the SFCC order is created with status **Created** and Global-e proceeds with checkout completion.

### Third-party inventory checks

Implement custom logic in the **`globale.validateCart`** hook handler (`int_globale_sfra` or `int_globale_sitegenesis` → `scripts/hooks/checkout/onGlobaleValidateCart.js`). Do not override `validateCartHelpers.js` in `int_globale` directly.

## Test Global-e Checkout

To pass fraud checks automatically on SFCC sandbox, development, or staging environments, use the test phone number and card numbers provided by your Global-e account or project manager (not published in this guide for security).

Use valid, realistic billing and shipping addresses in test orders.
