# Inline Checkout SDK

Embed a payment modal directly on your website. No backend required — the SDK handles session creation, payment collection, and status polling using your public API key.

## Installation

### Script tag (recommended)

```html
<script src="https://js.zevpaycheckout.com/v1/inline.js"></script>
```

### npm

```bash
npm install @zevpay/inline
```

## Quick start

```html
<button id="pay-btn">Pay ₦5,000</button>

<script src="https://js.zevpaycheckout.com/v1/inline.js"></script>
<script>
  document.getElementById('pay-btn').addEventListener('click', function() {
    var checkout = new ZevPay.ZevPayCheckout();
    checkout.checkout({
      apiKey: 'pk_test_your_public_key',
      email: 'customer@example.com',
      amount: 500000, // ₦5,000 in kobo
      currency: 'NGN',
      reference: 'order_12345', // optional
      firstName: 'John', // optional
      lastName: 'Doe',   // optional
      onSuccess: function(reference) {
        console.log('Payment successful:', reference);
        // Verify payment on your server
      },
      onClose: function() {
        console.log('Checkout closed');
      },
    });
  });
</script>
```

## Configuration

### `checkout(options)`

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `apiKey` | string | Yes | Your public API key (`pk_test_...` or `pk_live_...`) |
| `email` | string | Yes | Customer's email address |
| `amount` | integer | Yes | Amount in kobo (e.g., `500000` = ₦5,000) |
| `currency` | string | No | Currency code. Default: `"NGN"` |
| `reference` | string | No | Your unique transaction reference. Auto-generated if not provided |
| `firstName` | string | No | Customer's first name — stored as `customer_name` in the session |
| `lastName` | string | No | Customer's last name — combined with `firstName` and displayed in dashboard |
| `metadata` | object | No | Custom data attached to the transaction |
| `paymentMethods` | string \| string[] | No | Payment methods to enable. Default: all methods |
| `onInitialize` | function | No | Called when session is created |
| `onSuccess` | function | No | Called when payment is confirmed |
| `onError` | function | No | Called when an error occurs |
| `onFailure` | function | No | Called when payment fails |
| `onExpired` | function | No | Called when session expires |
| `onClose` | function | No | Called when modal is closed |

### Payment methods

Control which payment methods are shown:

```js
// All methods (default)
paymentMethods: 'all'

// Specific methods
paymentMethods: ['bank', 'payid']

// Single method (auto-selects, skips method picker)
paymentMethods: ['bank']
```

| Method | Description |
|--------|-------------|
| `'bank'` | Bank transfer via virtual account |
| `'payid'` | ZevPay ID (P2P transfer) |
| `'card'` | Card payment (coming soon) |

::: info Auto-selection
When only one payment method is enabled (except `payid`), the SDK automatically selects it and skips the method picker screen.
:::

### Metadata

Attach custom data to the transaction. This data is returned in webhooks and the verify endpoint:

```js
checkout.checkout({
  // ...
  metadata: {
    orderId: 'order_12345',
    customerId: 'cust_789',
    cartItems: ['item_a', 'item_b'],
  },
});
```

## Callbacks

### `onInitialize()`

Called when the checkout session has been created and the modal is ready.

```js
onInitialize: function() {
  console.log('Checkout ready');
}
```

### `onSuccess(reference)`

Called when payment is confirmed. The `reference` is the ZevPay transaction reference.

```js
onSuccess: function(reference) {
  console.log('Paid! Reference:', reference);

  // IMPORTANT: Verify payment on your server
  fetch('/api/verify-payment', {
    method: 'POST',
    body: JSON.stringify({ reference }),
  });
}
```

::: warning Always verify
Never trust the client-side callback alone. Always verify the payment on your server using the [Verify Session](/api/verify-session) endpoint.
:::

### `onError(error)`

Called when an error occurs (validation, network, API errors).

```js
onError: function(error) {
  console.error('Checkout error:', error.message);
  // error.code is available for programmatic handling
}
```

**Error codes:**

| Code | Description |
|------|-------------|
| `MISSING_FIELD` | Required field not provided |
| `INVALID_INPUT` | Invalid parameter value |
| `INVALID_CREDENTIALS` | Invalid API key |
| `FORBIDDEN` | Origin not allowed |
| `EXPIRED_SESSION` | Session has expired |
| `SERVICE_UNAVAILABLE` | API is temporarily unavailable |
| `TOO_MANY_REQUESTS` | Rate limit exceeded |

### `onFailure(error)`

Called when the payment itself fails (after method selection).

```js
onFailure: function(error) {
  console.error('Payment failed:', error?.message);
}
```

### `onExpired()`

Called when the session expires (30-minute timeout).

```js
onExpired: function() {
  alert('Session expired. Please try again.');
}
```

### `onClose()`

Called when the user closes the checkout modal.

```js
onClose: function() {
  console.log('User closed checkout');
}
```

## Full example

```html
<!DOCTYPE html>
<html>
<head>
  <title>ZevPay Inline Checkout Example</title>
</head>
<body>
  <h1>Order Summary</h1>
  <p>Total: ₦5,000.00</p>
  <button id="pay-btn">Pay Now</button>

  <script src="https://js.zevpaycheckout.com/v1/inline.js"></script>
  <script>
    document.getElementById('pay-btn').addEventListener('click', function() {
      var checkout = new ZevPay.ZevPayCheckout();

      checkout.checkout({
        apiKey: 'pk_test_your_public_key',
        email: 'customer@example.com',
        amount: 500000,
        currency: 'NGN',
        reference: 'order_' + Date.now(),
        firstName: 'John',
        lastName: 'Doe',
        metadata: {
          orderId: '12345',
          product: 'Premium Plan',
        },
        paymentMethods: ['bank', 'payid'],
        onInitialize: function() {
          console.log('Checkout initialized');
        },
        onSuccess: function(reference) {
          alert('Payment successful! Reference: ' + reference);
          // Verify on your server
          window.location.href = '/order/success?ref=' + reference;
        },
        onError: function(error) {
          console.error('Error:', error.message);
        },
        onFailure: function(error) {
          alert('Payment failed. Please try again.');
        },
        onExpired: function() {
          alert('Session expired. Please try again.');
        },
        onClose: function() {
          console.log('Checkout closed');
        },
      });
    });
  </script>
</body>
</html>
```

## How it works

1. User clicks your pay button
2. SDK creates a checkout session via the API using your **public key** — no backend server needed
3. Modal renders with available payment methods
4. User selects a method and sees payment details (e.g., bank account number)
5. User completes the transfer externally
6. SDK polls for confirmation every 5 seconds
7. Once confirmed, `onSuccess` fires with the transaction reference
8. Modal auto-closes after 3 seconds

## Domain whitelisting

The inline SDK sends your public key from the browser. To prevent unauthorized websites from using your key, configure **allowed domains** on your API key in the [Dashboard](https://business.zevpay.ng).

When `allowedDomains` is configured, the API validates the origin of each request:

- **Exact match**: `mystore.com` — only allows requests from `mystore.com`
- **Wildcard**: `*.mystore.com` — allows `shop.mystore.com`, `mystore.com`, etc.

See [Domain Whitelisting](/guide/authentication#domain-whitelisting) for full details.

::: tip Production recommendation
Always configure `allowedDomains` on your live public keys to prevent unauthorized usage.
:::

## Validation

The SDK validates inputs before making any API calls:

| Rule | Error |
|------|-------|
| `apiKey` is required | `MissingRequiredField` |
| `email` is required | `MissingRequiredField` |
| `amount` is required | `MissingRequiredField` |
| `amount` must be ≥ 10,000 kobo (₦100) | `InvalidInput` |
| `currency` must be `"NGN"` if provided | `InvalidInput` |

## Resources

- [API Reference](/api/overview) — Full endpoint documentation
- [Standard Checkout](/sdks/standard) — Redirect-based alternative
- [Webhook Events](/webhooks/events) — All event types
- [npm](https://www.npmjs.com/package/@zevpay/inline) — Package registry
