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

# Checkout API

> Redirect customers to secure hosted checkout

The Checkout API redirects customers to Shoppex's hosted checkout page. The checkout is fully hosted by Shoppex for PCI compliance.

## checkout

Redirects the customer to the checkout page with their cart contents.

```javascript theme={"system"}
await shoppex.checkout();
```

### Parameters

<ParamField path="coupon" type="string">
  Pre-applied coupon code
</ParamField>

<ParamField path="options" type="CheckoutOptions">
  <Expandable title="CheckoutOptions">
    <ParamField path="autoRedirect" type="boolean" default="true">
      Automatically redirect to checkout page
    </ParamField>

    <ParamField path="locale" type="string">
      Override checkout language
    </ParamField>
  </Expandable>
</ParamField>

### Example: Checkout with Coupon

```javascript theme={"system"}
const couponCode = document.getElementById('coupon-input').value;

if (couponCode) {
  // Validate coupon first
  const { data } = await shoppex.validateCoupon(couponCode);

  if (!data.valid) {
    alert('Invalid coupon code');
    return;
  }
}

// Proceed to checkout
await shoppex.checkout(couponCode);
```

## buildCheckoutUrl

Builds the checkout URL without redirecting. Useful for opening in a new tab or iframe.

```javascript theme={"system"}
const checkoutUrl = await shoppex.buildCheckoutUrl('SAVE10', { locale: 'de' });
console.log(checkoutUrl);
// https://yourstore.shoppex.io/checkout?coupon=SAVE10&locale=de&cart=...
```

### Parameters

<ParamField path="coupon" type="string">
  Coupon code to pre-apply
</ParamField>

<ParamField path="locale" type="string">
  Checkout language (e.g., 'en', 'de', 'fr')
</ParamField>

### Example: Open Checkout in New Tab

```javascript theme={"system"}
async function openCheckoutInNewTab() {
  const url = await shoppex.buildCheckoutUrl();
  window.open(url, '_blank');
}
```

## buildCheckoutUrlSync (Deprecated)

<Warning>
  `buildCheckoutUrlSync` is deprecated and throws immediately. Use `buildCheckoutUrl()` instead — it handles both default and custom domains.
</Warning>

## Coupons

### validateCoupon

Validates a coupon code before checkout. Affiliate/referral codes are separate from coupons and should use `validateAffiliateCode` or `applyAffiliateCode`.

```javascript theme={"system"}
const { data } = await shoppex.validateCoupon('SAVE10', {
  productId: 'prod_abc123',
  variantId: 'variant_lifetime',
});

if (data.valid) {
  console.log('Discount:', data.discount, data.discount_type);
  // 10, "percentage" → 10% off
  // 5.00, "fixed" → $5 off
} else {
  console.log('Invalid or expired coupon');
}
```

### Parameters

<ParamField path="code" type="string" required>
  Coupon code to validate
</ParamField>

<ParamField path="options.productId" type="string">
  Product ID to check product-specific coupons
</ParamField>

<ParamField path="options.variantId" type="string">
  Selected variant ID to check variant-specific coupons. Requires `options.productId`.
</ParamField>

### Response

<ResponseField name="data" type="CouponValidation">
  <Expandable title="CouponValidation">
    <ResponseField name="valid" type="boolean">
      Whether the coupon is valid
    </ResponseField>

    <ResponseField name="discount" type="number">
      Discount amount
    </ResponseField>

    <ResponseField name="discount_type" type="string">
      Either "percentage" or "fixed"
    </ResponseField>

    <ResponseField name="product_restricted" type="boolean">
      Whether the coupon is restricted to selected products
    </ResponseField>

    <ResponseField name="variant_restricted" type="boolean">
      Whether the coupon is restricted to selected variants
    </ResponseField>

    <ResponseField name="restriction_scope" type="string">
      One of "all", "products", "variants", or "products\_and\_variants"
    </ResponseField>

    <ResponseField name="allowed_product_ids" type="string[]">
      Public product IDs the coupon can apply to
    </ResponseField>

    <ResponseField name="allowed_variant_ids" type="string[]">
      Variant IDs the coupon can apply to
    </ResponseField>
  </Expandable>
</ResponseField>

## Affiliate Codes

### validateAffiliateCode

Validates an affiliate/referral code without storing it.

```javascript theme={"system"}
const result = await shoppex.validateAffiliateCode('creator10');

if (result.success && result.data.valid) {
  console.log(result.data.affiliate_code);
} else if (result.data?.program_enabled === false) {
  console.log('Affiliate program is disabled for this shop');
}
```

### applyAffiliateCode

Validates and stores the normalized affiliate code. `checkout()` sends the stored code as `affiliate_code`.

```javascript theme={"system"}
const affiliate = await shoppex.applyAffiliateCode('creator10');

await shoppex.checkout({
  coupon: 'SAVE10',
  affiliateCode: affiliate.data?.affiliate_code,
});
```

### Example: Coupon Input with Validation

```html theme={"system"}
<div class="coupon-form">
  <input type="text" id="coupon-input" placeholder="Enter coupon code">
  <button onclick="applyCoupon()">Apply</button>
  <span id="coupon-status"></span>
</div>

<script>
let appliedCoupon = null;

async function applyCoupon() {
  const code = document.getElementById('coupon-input').value.trim();
  const status = document.getElementById('coupon-status');

  if (!code) {
    status.textContent = '';
    return;
  }

  const { data } = await shoppex.validateCoupon(code);

  if (data.valid) {
    appliedCoupon = code;
    if (data.discount_type === 'percentage') {
      status.textContent = `${data.discount}% off applied!`;
    } else {
      status.textContent = `$${data.discount} off applied!`;
    }
    status.className = 'success';
  } else {
    appliedCoupon = null;
    status.textContent = 'Invalid coupon';
    status.className = 'error';
  }
}

async function goToCheckout() {
  await shoppex.checkout(appliedCoupon);
}
</script>
```

## Checkout Flow

```
┌─────────────────────────────────────────────────────────────────┐
│                        Your Website                             │
├─────────────────────────────────────────────────────────────────┤
│  1. Customer browses products                                   │
│  2. Adds items to cart (SDK stores in localStorage)            │
│  3. Clicks "Checkout"                                          │
│  4. SDK calls shoppex.checkout()                      │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                     Shoppex Checkout                            │
│                   (yourstore.shoppex.io)                        │
├─────────────────────────────────────────────────────────────────┤
│  5. Customer enters email, billing info                        │
│  6. Selects payment method (Stripe, PayPal, Crypto)           │
│  7. Completes payment                                          │
│  8. Receives confirmation + delivery                           │
└─────────────────────────────────────────────────────────────────┘
```

## After Checkout

After successful checkout, the cart is automatically cleared. If you need to handle the return:

```javascript theme={"system"}
// Check URL for order confirmation
const urlParams = new URLSearchParams(window.location.search);
const orderId = urlParams.get('order');

if (orderId) {
  // Customer returned from successful checkout
  showOrderConfirmation(orderId);
}
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Cart API" icon="cart-shopping" href="/sdk/api/cart">
    Manage shopping cart items before checkout
  </Card>

  <Card title="Webhooks Guide" icon="bell" href="/guides/webhooks">
    Get notified when orders are paid or cancelled
  </Card>
</CardGroup>
