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

# Promo Codes

> Validate promo codes at checkout

## `shop.checkout.validatePromo(params)`

Validates a promo code and returns the calculated discount amount. Call this when the customer applies a promo code — before placing the order.

```typescript theme={null}
const result = await shop.checkout.validatePromo({
  code: 'SAVE10',
  subtotal: 5000,
  cart_items: cart,
});

if (result.valid) {
  console.log(result.discount_amount); // e.g. 500
  console.log(result.message);         // e.g. "10% discount applied!"
} else {
  console.log(result.error);           // e.g. "This promo code has expired"
}
```

### Parameters

| Param        | Type         | Required | Description                                       |
| ------------ | ------------ | -------- | ------------------------------------------------- |
| `code`       | `string`     | ✅        | The promo code string entered by customer         |
| `subtotal`   | `number`     | ❌        | Cart subtotal — required for minimum order checks |
| `cart_items` | `CartItem[]` | ❌        | Required for product-specific promo codes         |

### Response

```typescript theme={null}
{
  valid: boolean;
  error?: string;         // present when valid is false
  message?: string;       // present when valid is true
  discount_amount?: number;
  promo_code?: {
    id: string;           // pass this to createOrder
    code: string;
    discount_type: 'percentage' | 'fixed';
    discount_value: number;
    applies_to: 'all' | 'specific';
  };
}
```

### Example — Promo code input UI

```typescript theme={null}
promoForm.addEventListener('submit', async (e) => {
  e.preventDefault();
  const code = promoInput.value.trim();
  if (!code) return;

  applyBtn.disabled = true;
  promoFeedback.textContent = 'Checking...';

  const subtotal = cart.reduce((s, i) => s + i.price * i.quantity, 0);

  const result = await shop.checkout.validatePromo({
    code,
    subtotal,
    cart_items: cart,
  });

  if (result.valid && result.discount_amount) {
    promoFeedback.className = 'success';
    promoFeedback.textContent = result.message ?? 'Promo applied!';

    // Show discount line in order summary
    discountLine.textContent = `-${formatPrice(result.discount_amount)}`;
    totalLine.textContent = formatPrice(subtotal - result.discount_amount);

    // Store for order creation
    appliedPromo = result;
  } else {
    promoFeedback.className = 'error';
    promoFeedback.textContent = result.error ?? 'Invalid promo code';
    appliedPromo = null;
  }

  applyBtn.disabled = false;
});
```

### Passing promo to createOrder

```typescript theme={null}
// After validatePromo succeeds, pass the ID and amount to createOrder
const order = await shop.checkout.createOrder({
  // ...other fields
  promo_code_id: appliedPromo.promo_code?.id,
  discount_amount: appliedPromo.discount_amount,
});
```

<Warning>
  Always pass both `promo_code_id` and `discount_amount` to `createOrder`. Passing only one will result in incorrect order totals.
</Warning>
