PostgreSQL adapter
Durable Lipila lifecycle state in PostgreSQL, coordinated safely across processes.
Lifecycle handling needs a durable store so payment creation and the eventual webhook, which happen in different requests and often different processes, agree on state. Use the PostgreSQL adapter.
import { lipila } from "@cozycodr/lipila";
import { postgresPaymentStore } from "@cozycodr/lipila-store-postgres";
const store = postgresPaymentStore({ connectionString, namespace });
await store.migrate();
const client = lipila({ apiKey, webhookSecret, lifecycle: { store, on } });Pass either connectionString or an existing pg.Pool, never both. close() closes only a pool the adapter created. Migrations are explicit, repeatable, and forward only, and never run during payment handling.
What it guarantees
- Atomic reservations. One
preparewins per reference, so concurrent creates cannot both dispatch. - Webhook leases. Each webhook is claimed, processed once, and completed only after the handler succeeds. Lease expiry is evaluated on the database clock.
- Idempotent projections. A settled payment is never overwritten by a late or out-of-order event.
Use a distinct namespace for every merchant and environment, for example lipila:production:merchant-123.
Test it against a real database
The suite skips unless LIPILA_POSTGRES_TEST_URL is set. It uses a unique namespace per run and deletes only its own rows.
LIPILA_POSTGRES_TEST_URL='postgresql://user:pass@127.0.0.1:5432/lipila_test' \
npm run test:integration -w @cozycodr/lipila-store-postgresIt runs the shared conformance suite plus lifecycle checks against your database.
PaymentLifecycleStore interface and validate it with the conformance suite.