npm package: @payoza/sdk
Description: Official JavaScript/TypeScript SDK for Payoza crypto payments
Latest version: 0.1.0

# @payoza/sdk

Official JavaScript/TypeScript SDK for the [Payoza](https://payoza.io) crypto payments API.

Works in Node.js 18+, Deno, Bun, and modern browsers (uses `fetch` and `crypto.subtle`).

## Installation

```bash
npm install @payoza/sdk
```

## Quick Start

```typescript
import { Payoza } from '@payoza/sdk'

const payoza = new Payoza('sk_live_xxx')
```

Or with full configuration:

```typescript
const payoza = new Payoza({
  apiKey: 'sk_live_xxx',
  baseUrl: 'https://api.payoza.io',  // default
  timeout: 30000,                     // ms, default
  maxRetries: 2,                      // retries on 429/5xx, default
})
```

## Payment Links

```typescript
// Create
const link = await payoza.paymentLinks.create({
  name: 'Premium Plan',
  amount: '29.99',
  currency: 'USDC',
  accepted_networks: ['solana'],
  accepted_tokens: ['USDC', 'SOL'],
})

// List (paginated)
const { data: links, meta } = await payoza.paymentLinks.list({ page: 1, per_page: 20 })

// Get
const link = await payoza.paymentLinks.get('pl_xxx')

// Update
await payoza.paymentLinks.update('pl_xxx', { name: 'Updated Name' })

// Delete
await payoza.paymentLinks.delete('pl_xxx')
```

## Checkout Sessions

```typescript
const session = await payoza.checkout.create({
  payment_link_id: 'pl_xxx',
  amount: '29.99',
  currency: 'USDC',
  chain: 'solana',
})

const session = await payoza.checkout.get('cs_xxx')
```

## Customers

```typescript
const customer = await payoza.customers.create({
  external_id: 'user_123',
  email: 'user@example.com',
})

const { data: customers } = await payoza.customers.list()
const customer = await payoza.customers.get('cus_xxx')
await payoza.customers.update('cus_xxx', { email: 'new@example.com' })
```

## Transactions

```typescript
const { data: txns, meta } = await payoza.transactions.list({ page: 1 })
const tx = await payoza.transactions.get('tx_xxx')
```

## Subscriptions

```typescript
const { data: subs } = await payoza.subscriptions.list({ page: 1 })
const sub = await payoza.subscriptions.get('sub_xxx')
await payoza.subscriptions.pause('sub_xxx')
await payoza.subscriptions.resume('sub_xxx')
await payoza.subscriptions.cancel('sub_xxx')
```

## Balance

```typescript
const balances = await payoza.balance.list()
const { data: ledger } = await payoza.balance.listLedger({ page: 1 })
```

## Settlements

```typescript
const { data: settlements } = await payoza.settlements.list({ page: 1 })
```

## Addresses

```typescript
const addresses = await payoza.addresses.list()
const address = await payoza.addresses.create({ chain: 'solana' })
```

## Prices

```typescript
// Single rate
const { rate } = await payoza.prices.getRate('SOL', 'USD')

// Multiple tokens
const prices = await payoza.prices.getMultiple(['SOL', 'ETH', 'BTC'], 'USD')
```

## Webhooks

```typescript
const webhook = await payoza.webhooks.create({
  url: 'https://example.com/webhook',
  events: ['payment.confirmed', 'payment.failed'],
})

const webhooks = await payoza.webhooks.list()
await payoza.webhooks.update('wh_xxx', { events: ['payment.confirmed'] })
await payoza.webhooks.delete('wh_xxx')

// List delivery events
const { data: events } = await payoza.webhooks.listEvents('wh_xxx')
```

## Analytics

```typescript
const revenue = await payoza.analytics.revenue({ start_date: '2026-01-01', end_date: '2026-03-10' })
const fees = await payoza.analytics.platformFees({ start_date: '2026-01-01' })
```

## Notifications

```typescript
const { data: notifs } = await payoza.notifications.list({ page: 1 })
const { count } = await payoza.notifications.unreadCount()
await payoza.notifications.markRead('notif_xxx')
await payoza.notifications.markAllRead()
await payoza.notifications.delete('notif_xxx')
```

## Team Members

```typescript
const members = await payoza.team.listMembers()
await payoza.team.inviteMember({ email: 'alice@example.com', role: 'admin' })
await payoza.team.updateMember('mem_xxx', { role: 'member' })
await payoza.team.removeMember('mem_xxx')
```

## API Keys

```typescript
const keys = await payoza.apiKeys.list()
const key = await payoza.apiKeys.create({ name: 'Production' })
console.log(key.key) // full key, only shown once
await payoza.apiKeys.updatePermissions('key_xxx', ['read', 'write'])
await payoza.apiKeys.delete('key_xxx')
```

## Webhook Signature Verification

Verify incoming webhook payloads on your server:

```typescript
import { verifyWebhookSignature } from '@payoza/sdk'

// In your webhook handler (e.g., Express)
app.post('/webhook', async (req, res) => {
  const signature = req.headers['x-payoza-signature'] as string
  const isValid = await verifyWebhookSignature(req.body, signature, 'whsec_xxx')

  if (!isValid) {
    return res.status(401).send('Invalid signature')
  }

  // Process the event
  const event = JSON.parse(req.body)
  console.log('Received event:', event.type)
  res.sendStatus(200)
})
```

## Error Handling

All API errors throw a `PayozaError` with `code`, `status`, and `message`:

```typescript
import { Payoza, PayozaError } from '@payoza/sdk'

try {
  await payoza.paymentLinks.create({ name: '', currency: 'USDC' })
} catch (e) {
  if (e instanceof PayozaError) {
    console.log(e.status)   // 400
    console.log(e.code)     // "VALIDATION_ERROR"
    console.log(e.message)  // "Name is required"
  }
}
```

## Automatic Retries

The SDK automatically retries requests on HTTP 429 (rate limited) and 5xx (server errors), up to `maxRetries` times (default: 2). It respects the `Retry-After` header when present, otherwise uses exponential backoff.

## Supported Chains

`solana` · `ethereum` · `base` · `polygon` · `bsc` · `arbitrum` · `avalanche`

## License

MIT