Bora PesaBora Pesa

Adapters

Database adapters for the event store — SQLite, in-memory, and custom.

Added in v0.1.0

Adapters persist PaymentEvent entries to the event store. The default is in-memory (lost on restart) — swap to a persistent adapter for production.

Comparison

Memory (default)SQLiteCustom / Bring-your-own
Persists on restartDepends on your impl
Zero dependencies❌ (better-sqlite3)Depends
Dev / CI ready
Production ready

Available adapters

SQLite (@borapesa/sqlite)

Zero-config persistent storage powered by better-sqlite3. The database file is created automatically at the given path.

pnpm add @borapesa/sqlite
import { SQLiteAdapter } from '@borapesa/sqlite';

const pesa = createPesa({
  provider: new ClickPesaProvider({ ... }),
  db: new SQLiteAdapter('./pesa.db'),
});

WAL mode is enabled by default for concurrent read/write performance. See the @borapesa/sqlite API docs for full details.

@borapesa/sqlite is the only adapter package provided. For other databases, implement the interface yourself — the SQLiteAdapter source is the reference.

Writing your own

Implement PesaDatabaseAdapter — four methods:

import type { PesaDatabaseAdapter, PaymentEvent } from '@borapesa/pesa';

class MyAdapter implements PesaDatabaseAdapter {
  async saveEvent(event: PaymentEvent): Promise<void> {
    // Persist a verified PaymentEvent
  }

  async getEvent(id: string): Promise<PaymentEvent | null> {
    // Retrieve a single event by UUID
  }

  async getEventsByReference(reference: string): Promise<PaymentEvent[]> {
    // Retrieve all events for a merchant reference
  }

  async getEventsByOrderId(orderId: string): Promise<PaymentEvent[]> {
    // Retrieve all events for a provider order ID
  }
}

Pass your adapter via the db field in PesaConfig:

const pesa = createPesa({
  provider: new ClickPesaProvider({ ... }),
  db: new MyAdapter(),
});

See the Architecture page for how the event store fits into the webhook lifecycle.

On this page