npm package: @glydeco/checkout-js
Description: Glyde Checkout SDK for JavaScript - Accept payments via modal checkout
Author: Glyde
Latest version: 1.0.3

# @glydeco/checkout-js

Official Glyde Checkout SDK for JavaScript. Accept payments via a beautiful modal checkout experience.

## Installation

### npm / yarn / pnpm

```bash
npm install @glydeco/checkout-js
# or
yarn add @glydeco/checkout-js
# or
pnpm add @glydeco/checkout-js
# or
bun add @glydeco/checkout-js
```

### CDN (Script Tag)

```html
<script src="https://unpkg.com/@glydeco/checkout-js/dist/index.umd.min.js"></script>
```

Or use jsDelivr:

```html
<script src="https://cdn.jsdelivr.net/npm/@glydeco/checkout-js/dist/index.umd.min.js"></script>
```

## Quick Start

### ES Modules / TypeScript

```typescript
import Glyde from '@glydeco/checkout-js';

// 1. Initialize the SDK
Glyde.init({
  publicKey: 'pk_live_xxxxxxxxxxxxxxxx',
  environment: 'production', // or 'sandbox' for testing
  onReady: () => {
    console.log('Glyde SDK is ready!');
  }
});

// 2. Open checkout when user clicks pay button
document.getElementById('pay-button').addEventListener('click', async () => {
  await Glyde.Checkout.open({
    amount: 5000,
    currency: 'NGN',
    reference: 'order_' + Date.now(),
    customer: {
      first_name: 'John',
      last_name: 'Doe',
      email: 'john@example.com',
      phone: '+2348012345678'
    },
    channels: ['card', 'transfer'],
    default_channel: 'card',
    onSuccess: (result) => {
      console.log('Payment successful!', result);
      // Redirect to success page
      window.location.href = '/success?ref=' + result.reference;
    },
    onClose: () => {
      console.log('Checkout closed');
    }
  });
});
```

### Script Tag (UMD)

```html
<!DOCTYPE html>
<html>
<head>
  <title>Checkout Example</title>
</head>
<body>
  <button id="pay-button">Pay Now</button>

  <script src="https://unpkg.com/@glydeco/checkout-js/dist/index.umd.min.js"></script>
  <script>
    // Initialize the SDK
    Glyde.default.init({
      publicKey: 'pk_live_xxxxxxxxxxxxxxxx',
      environment: 'production'
    });

    // Open checkout on button click
    document.getElementById('pay-button').addEventListener('click', function() {
      Glyde.default.Checkout.open({
        amount: 5000,
        currency: 'NGN',
        reference: 'order_' + Date.now(),
        customer: {
          first_name: 'John',
          last_name: 'Doe',
          email: 'john@example.com',
          phone: '+2348012345678'
        },
        channels: ['card', 'transfer'],
        default_channel: 'card',
        onSuccess: function(result) {
          console.log('Payment successful!', result);
          alert('Payment successful! Reference: ' + result.reference);
        },
        onClose: function() {
          console.log('Checkout closed');
        }
      });
    });
  </script>
</body>
</html>
```

## API Reference

### `Glyde.init(config)`

Initialize the SDK with your configuration.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `publicKey` | `string` | Yes | Your Glyde public key (`pk_*`) |
| `environment` | `'production' \| 'sandbox'` | No | Environment (default: `'production'`) |
| `theme` | `'light' \| 'dark'` | No | Checkout theme (default: `'light'`) |
| `logo` | `string` | No | URL of your logo to display in checkout |
| `onReady` | `() => void` | No | Callback when SDK is ready |
| `onError` | `(error: GlydeError) => void` | No | Callback on initialization error |

### `Glyde.Checkout.open(options)`

Open the checkout modal.

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `amount` | `number` | Yes | Payment amount |
| `currency` | `string` | Yes | Currency code (`'NGN'`, `'USD'`, etc.) |
| `reference` | `string` | Yes | Unique payment reference |
| `customer` | `CustomerDetails` | Yes | Customer information |
| `channels` | `PaymentChannel[]` | Yes | Available payment methods (`['card', 'transfer']`) |
| `default_channel` | `PaymentChannel` | Yes | Default selected channel |
| `meta` | `object` | No | Custom metadata (returned in webhooks) |
| `onSuccess` | `(result: PaymentResult) => void` | No | Callback on successful payment |
| `onClose` | `() => void` | No | Callback when checkout is closed |

#### CustomerDetails

```typescript
interface CustomerDetails {
  first_name: string;
  last_name: string;
  email: string;
  phone: string;
}
```

#### PaymentResult

```typescript
interface PaymentResult {
  reference: string;
  transactionId: string;
  status: 'success';
  amount: number;
  currency: string;
}
```

### `Glyde.Checkout.close()`

Programmatically close the checkout modal.

```javascript
Glyde.Checkout.close();
```

### `Glyde.Checkout.isOpen()`

Check if the checkout modal is currently open.

```javascript
if (Glyde.Checkout.isOpen()) {
  console.log('Checkout is open');
}
```

### `Glyde.isReady()`

Check if the SDK has been initialized.

```javascript
if (Glyde.isReady()) {
  // SDK is ready
}
```

## Error Handling

The SDK throws `GlydeError` objects that contain a `code` and `message`.

```javascript
import Glyde, { isGlydeError } from '@glydeco/checkout-js';

try {
  await Glyde.Checkout.open({ /* ... */ });
} catch (error) {
  if (isGlydeError(error)) {
    console.error(`Error ${error.code}: ${error.message}`);

    switch (error.code) {
      case 'not_initialized':
        // SDK not initialized
        break;
      case 'missing_amount':
        // Amount is required
        break;
      case 'api_error':
        // API request failed
        break;
      // ... handle other errors
    }
  }
}
```

### Error Codes

| Code | Description |
|------|-------------|
| `not_initialized` | SDK not initialized. Call `Glyde.init()` first |
| `invalid_public_key` | Invalid public key format |
| `missing_amount` | Amount is required |
| `missing_currency` | Currency is required |
| `missing_reference` | Reference is required |
| `missing_customer` | Customer details are required |
| `missing_customer_email` | Customer email is required |
| `missing_customer_phone` | Customer phone is required |
| `missing_channels` | Payment channels are required |
| `api_error` | API request failed |
| `network_error` | Network error |
| `modal_already_open` | Checkout modal is already open |

## Modal Behavior

- **On Success**: Modal auto-closes and `onSuccess` callback is fired
- **On Error**: Modal stays open (errors are handled inside the iframe, user can retry)
- **On Close**: Modal closes and `onClose` callback is fired

The modal can be closed by:
- Clicking the X button
- Clicking the backdrop (desktop only)
- Pressing the Escape key
- Calling `Glyde.Checkout.close()` programmatically

## Browser Support

| Browser | Minimum Version |
|---------|-----------------|
| Chrome | 60+ |
| Firefox | 55+ |
| Safari | 11+ |
| Edge | 79+ |
| iOS Safari | 11+ |
| Android Chrome | 60+ |

## TypeScript Support

The SDK is written in TypeScript and includes full type definitions.

```typescript
import Glyde, {
  GlydeConfig,
  CheckoutOptions,
  PaymentResult,
  CustomerDetails,
  PaymentChannel
} from '@glydeco/checkout-js';

const config: GlydeConfig = {
  publicKey: 'pk_live_xxx',
  environment: 'production'
};

Glyde.init(config);
```

## Testing

Use sandbox mode for testing:

```javascript
Glyde.init({
  publicKey: 'pk_test_xxxxxxxx',
  environment: 'sandbox'
});
```

### Test Cards

| Card Number | Result |
|-------------|--------|
| `4242 4242 4242 4242` | Success |
| `4000 0000 0000 0002` | Declined |
| `4000 0000 0000 9995` | Insufficient funds |

## Security

- Card data is entered in a secure iframe hosted by Glyde
- Card data never touches your website
- PCI DSS compliant (SAQ-A eligible)
- Public keys are safe to use in client-side code

## Support

- Documentation: [https://docs.useglyde.co/checkout-sdk](https://docs.useglyde.co/checkout-sdk)
- Issues: [https://github.com/useglyde/checkout-js/issues](https://github.com/useglyde/checkout-js/issues)
- Email: support@useglyde.co

## License

MIT License - see [LICENSE](LICENSE) for details.