npm package: @paygate/node
Description: Official PayGate Node.js SDK for payment processing in Ghana
Author: Ebenezer Sakyi
Latest version: 0.1.0

# PayGate Node.js SDK

Official Node.js SDK for the PayGate payment gateway. Accept Mobile Money payments in Ghana.

## Installation

```bash
npm install paygate
```

## Quick Start

```typescript
import PayGate from 'paygate';

const paygate = new PayGate('sk_live_your_secret_key');

// Create a payment
const payment = await paygate.payments.create({
  amount: 100.00, // GHS
  payment_method: {
    type: 'mobile_money',
    phone_number: '0241234567',
  },
  description: 'Order #1234',
});

console.log(payment.id); // pay_xxx
console.log(payment.status); // 'pending'
```

## Usage

### Initialize the Client

```typescript
import PayGate from 'paygate';

// Live mode
const paygate = new PayGate('sk_live_xxx');

// Test mode
const testPaygate = new PayGate('sk_test_xxx');
```

### Payments

#### Create a Payment

```typescript
const payment = await paygate.payments.create({
  amount: 50.00,
  currency: 'GHS', // optional, defaults to GHS
  payment_method: {
    type: 'mobile_money',
    phone_number: '0241234567',
    provider: 'mtn', // optional, auto-detected from number
  },
  description: 'Order payment',
  metadata: {
    order_id: '12345',
  },
});
```

#### Retrieve a Payment

```typescript
const payment = await paygate.payments.retrieve('pay_xxx');
```

#### List Payments

```typescript
const payments = await paygate.payments.list({
  limit: 10,
  status: 'completed',
});

for (const payment of payments.data) {
  console.log(payment.id, payment.amount);
}

// Pagination
if (payments.has_more) {
  const nextPage = await paygate.payments.list({
    starting_after: payments.data[payments.data.length - 1].id,
  });
}
```

### Payouts

#### Create a Payout

```typescript
const payout = await paygate.payouts.create({
  amount: 100.00,
  destination: {
    type: 'mobile_money',
    phone_number: '0241234567',
    account_name: 'John Doe',
  },
  description: 'Withdrawal',
});
```

#### Retrieve a Payout

```typescript
const payout = await paygate.payouts.retrieve('po_xxx');
```

### Idempotency

Use idempotency keys to safely retry requests:

```typescript
const payment = await paygate.payments.create(
  {
    amount: 100.00,
    payment_method: {
      type: 'mobile_money',
      phone_number: '0241234567',
    },
  },
  'unique-idempotency-key'
);
```

### Webhook Endpoints

#### Create a Webhook Endpoint

```typescript
const webhook = await paygate.webhookEndpoints.create({
  url: 'https://your-site.com/webhooks',
  events: ['payment.completed', 'payment.failed', 'payout.completed'],
});

console.log(webhook.secret); // whsec_xxx - Save this!
```

#### List Webhook Endpoints

```typescript
const webhooks = await paygate.webhookEndpoints.list();
```

#### Update a Webhook Endpoint

```typescript
const updated = await paygate.webhookEndpoints.update('we_xxx', {
  events: ['payment.completed', 'payment.failed'],
  is_active: true,
});
```

#### Delete a Webhook Endpoint

```typescript
await paygate.webhookEndpoints.delete('we_xxx');
```

### Handling Webhooks

```typescript
import express from 'express';
import { constructEvent } from 'paygate';

const app = express();

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['paygate-signature'] as string;

  try {
    const event = constructEvent(req.body, signature, 'whsec_xxx');

    switch (event.type) {
      case 'payment.completed':
        const payment = event.data;
        console.log('Payment completed:', payment.id);
        // Fulfill order
        break;
      case 'payment.failed':
        console.log('Payment failed:', event.data.failure_reason);
        break;
      case 'payout.completed':
        console.log('Payout completed:', event.data.id);
        break;
    }

    res.json({ received: true });
  } catch (err) {
    console.error('Webhook error:', err.message);
    res.status(400).send(`Webhook Error: ${err.message}`);
  }
});
```

### Refunds

#### Create a Refund

```typescript
const refund = await paygate.refunds.create({
  payment_id: 'pay_xxx',
  amount: 25.00, // optional, defaults to full amount
  reason: 'Customer request',
});
```

#### Retrieve a Refund

```typescript
const refund = await paygate.refunds.retrieve('ref_xxx');
```

#### List Refunds

```typescript
// All refunds
const refunds = await paygate.refunds.list();

// Refunds for a specific payment
const paymentRefunds = await paygate.refunds.list({
  payment_id: 'pay_xxx',
});
```

### Account

#### Get Merchant Profile

```typescript
const merchant = await paygate.account.retrieve();

console.log(merchant.business_name);
console.log(merchant.status); // 'active'
console.log(merchant.tier); // 'starter' | 'growth' | 'enterprise'
```

#### Get Account Balance

```typescript
const balance = await paygate.account.balance();

console.log(balance.available.amount); // Available to withdraw
console.log(balance.pending_incoming.amount); // Pending payments
console.log(balance.pending_outgoing.amount); // Pending payouts
```

#### List API Keys

```typescript
const apiKeys = await paygate.account.listApiKeys();

for (const key of apiKeys.data) {
  console.log(key.key_prefix, key.type, key.environment);
}
```

### Error Handling

```typescript
import PayGate, { PayGateAPIError, PayGateAuthenticationError } from 'paygate';

try {
  const payment = await paygate.payments.create({ ... });
} catch (error) {
  if (error instanceof PayGateAuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof PayGateAPIError) {
    console.error('API error:', error.message);
    console.error('Error code:', error.code);
    console.error('Status:', error.statusCode);
  } else {
    console.error('Unknown error:', error);
  }
}
```

## Payment Statuses

| Status | Description |
|--------|-------------|
| `created` | Payment created, not yet submitted |
| `pending` | Awaiting customer authorization |
| `processing` | Being processed by provider |
| `completed` | Successfully completed |
| `failed` | Payment failed |
| `refunded` | Fully refunded |
| `cancelled` | Cancelled before completion |

## Supported Providers

- MTN Mobile Money
- Telecel (Vodafone) Cash
- AirtelTigo Money

## Requirements

- Node.js 14 or higher
- PayGate API keys (get them at https://dashboard.paygate.com)

## Support

- Documentation: https://docs.paygate.com
- Email: support@paygate.com