npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@havenpay/server

v1.0.2

Published

Server-side TypeScript SDK for Havenpay payment, project, webhook, and account APIs

Readme

@havenpay/server

Server-side TypeScript SDK for Havenpay.

@havenpay/server is the backend SDK for secret-key operations: PaymentIntent creation, project management, API key lifecycle, account lifecycle, provider account credential-reference management, refund requests, ledger-backed balance transaction reads, webhook endpoint management, event replay, and raw-body webhook signature verification.

Use it only from trusted backend infrastructure. Never bundle it into browsers, React Native apps, edge pages that expose client code, or public UI packages.

Install

bun add @havenpay/server
npm install @havenpay/server

Use it for

  • Creating PaymentIntents from a merchant server.
  • Returning a short-lived payment clientSecret to browser or mobile clients.
  • Managing projects, API keys, connected accounts, webhook endpoints, and events.
  • Verifying Havenpay webhook signatures against the exact raw request body.
  • Managing provider account encrypted credential references.
  • Reading balance transactions and creating refund requests through server-only APIs.

Quickstart

import { randomUUID } from 'node:crypto'
import { Havenpay } from '@havenpay/server'

const havenpay = new Havenpay({
  secretKey: process.env.HAVENPAY_SECRET_KEY,
  apiVersion: '2026-05-24.haven',
  retry: {
    maxAttempts: 3,
    initialDelayMs: 100,
    maxDelayMs: 2000,
  },
  timeoutMs: 30000,
})

const intent = await havenpay.paymentIntents.create({
  projectId: 'proj_...',
  amount: 1000,
  currency: 'usd',
  customer: {
    phone: '+263771234567',
  },
  mobileMoney: {
    provider: 'omari',
    phone: '+263771234567',
  },
  metadata: {
    orderId: 'order_123',
  },
  idempotencyKey: randomUUID(),
})

return Response.json({
  paymentIntentId: intent.id,
  clientSecret: intent.clientSecret,
})

Send clientSecret only to the client that is completing this one payment. Keep secretKey on the server.

Webhook verification

Webhook verification requires the exact raw body bytes sent by Havenpay. Do not parse JSON before signature verification.

import { Havenpay } from '@havenpay/server'

const havenpay = new Havenpay({
  secretKey: process.env.HAVENPAY_SECRET_KEY,
})

const event = havenpay.webhooks.constructEvent({
  rawBody,
  signature: request.headers.get('Havenpay-Signature') ?? '',
  secret: process.env.HAVENPAY_WEBHOOK_SECRET,
})

switch (event.type) {
  case 'payment_intent.succeeded':
    // Fulfil the order in an idempotent server-side transaction.
    break
  case 'payment_intent.failed':
    // Mark the order as failed only after validating the event payload.
    break
}

Main resources

havenpay.accounts.create(...)
havenpay.accounts.list(...)
havenpay.accounts.update(...)

havenpay.projects.create(...)
havenpay.projects.list(...)
havenpay.projects.update(...)
havenpay.projects.archive(...)
havenpay.projects.getConfig(...)

havenpay.apiKeys.create(...)
havenpay.apiKeys.list(...)
havenpay.apiKeys.revoke(...)

havenpay.paymentIntents.create(...)
havenpay.paymentIntents.retrieve(...)

havenpay.refunds.create(...)
havenpay.refunds.retrieve(...)
havenpay.refunds.list(...)

havenpay.providerAccounts.create(...)
havenpay.providerAccounts.list(...)
havenpay.providerAccounts.rotate(...)
havenpay.providerAccounts.revoke(...)

havenpay.balanceTransactions.list(...)

havenpay.webhookEndpoints.create(...)
havenpay.webhookEndpoints.list(...)
havenpay.webhookEndpoints.update(...)
havenpay.webhookEndpoints.rotateSecret(...)
havenpay.webhookEndpoints.delete(...)

havenpay.events.list(...)
havenpay.events.replay(...)

havenpay.webhooks.constructEvent(...)

Provider account credential references

Provider account APIs accept encrypted credential references and key fingerprints. They must not accept or return raw provider secret material.

await havenpay.providerAccounts.create({
  projectId: 'proj_...',
  provider: 'omari',
  encryptedCredentialRef: 'kms://havenpay/provider-credentials/...',
  keyFingerprint: 'fp_...',
  metadata: {
    label: 'Primary test credential',
  },
})

Live provider capability should be enabled only when the provider adapter, credentials, contract tests, and operational reconciliation path prove that lane.

Error handling

Non-2xx API responses throw HavenpayApiError.

import type { Havenpay } from '@havenpay/server'
import { HavenpayApiError } from '@havenpay/server'

async function _retrievePaymentIntent(havenpay: Havenpay) {
  try {
    return await havenpay.paymentIntents.retrieve('pi_...')
  }
  catch (error) {
    if (error instanceof HavenpayApiError) {
      console.error(error.status, error.code, error.requestId)
    }

    throw error
  }
}

Errors expose request IDs and typed API metadata when the API returns the standard error envelope. Do not log request bodies, API keys, idempotency keys, webhook secrets, provider credentials, or client secrets.

Retry and timeout policy

Retries are disabled unless retry is configured.

  • Network failures and HTTP 5xx responses may retry.
  • Safe reads may retry.
  • Mutating requests retry only when they include an Idempotency-Key.
  • Validation, authentication, authorization, tenant-scope, and not-found errors should not be retried without changing the request or credentials.
  • timeoutMs applies per request attempt.

Observability

onRequestEvent emits redacted server-side request lifecycle events.

const _havenpay = new Havenpay({
  secretKey: process.env.HAVENPAY_SECRET_KEY,
  onRequestEvent: (event) => {
    console.info({
      type: event.type,
      operationName: event.operationName,
      requestId: event.requestId,
      status: event.status,
    })
  },
})

Events include method, path, operation name, attempt number, status, error kind, and API response request ID only. They do not include headers, request bodies, API keys, idempotency keys, provider credentials, webhook secrets, or client secrets.

Security boundary

This is a server-only package. It may use Node/Bun server capabilities and secret-key authentication. It must never be imported by:

  • @havenpay/web
  • @havenpay/web-elements
  • @havenpay/react-native
  • browser bundles
  • mobile client bundles

Keep these values server-side:

  • HAVENPAY_SECRET_KEY
  • webhook signing secrets
  • provider credential references and fingerprints
  • account admin tokens
  • raw webhook request bodies
  • raw provider response payloads

Package boundaries

Use:

  • @havenpay/server for trusted backend operations.
  • @havenpay/web for browser payment-sheet flows.
  • @havenpay/web-elements for optional browser custom elements.
  • @havenpay/react-native for Expo and bare React Native payment flows.
  • @havenpay/core for shared public types.

Client apps should receive only a public projectId and the short-lived payment clientSecret required for one payment flow.

API-version pinning

Pass apiVersion to send X-Haven-API-Version with SDK requests:

const _havenpay = new Havenpay({
  secretKey: process.env.HAVENPAY_SECRET_KEY,
  apiVersion: '2026-05-24.haven',
})

Pinning keeps backend integrations explicit as Havenpay evolves.