@borga/node
Official Node.js client for the Borga API: card payments, bank invoices (krafa), subscriptions and metered billing for the Icelandic market.
Installation
npm install @borga/node
Requires Node.js 18 or newer.
Usage
Authenticate with a secret API key (sk_test_… or sk_live_…) from the Borga dashboard under Developers. The key identifies your merchant, so no other header is needed.
import { Borga } from "@borga/node";
const borga = new Borga({ apiKey: process.env.BORGA_SECRET_KEY! });
// Create a hosted checkout session and redirect the payer to session.url
const session = await borga.paymentSessions.create({
amount: 24180, // whole krónur: 24.180 kr.
currency: "ISK",
return_url: "https://example.is/order/complete",
cancel_url: "https://example.is/cart",
external_reference: "order_1042",
});
An app acting for a merchant through a Borga OAuth grant passes the access token instead: new Borga({ accessToken }). Pass one credential, not both; defaultHeaders adds headers to every request but cannot set Authorization. The grant's scopes decide which calls succeed.
Embedded checkout
const session = await borga.paymentSessions.create({
amount: 24180,
currency: "ISK",
mode: "embedded",
origin: "https://example.is",
});
// Hand session.id and session.client_secret to the browser and open the
// modal with borga.js: new Borga(pk).checkout.open({ sessionId, clientSecret })
Usage events (metered billing)
await borga.usageEvents.create({
event_name: "api_call",
customer: "cus_…",
idempotency_key: "req_…",
metadata: { units: 1 },
});
Webhooks
import { verifyWebhookSignature } from "@borga/node";
const event = verifyWebhookSignature({
body: rawRequestBody, // the raw string or Buffer, not the parsed JSON
signature: req.headers["borga-signature"],
secret: process.env.BORGA_WEBHOOK_SECRET!,
});
switch (event.type) {
case "payment.succeeded":
// event.data is narrowed to the Payment object
break;
case "invoice.payment_failed":
// event.data.attempt, event.data.reason
break;
}
Behavior
- POST requests get an auto-generated
Idempotency-Key, so retries are safe. Pass your own with{ idempotencyKey }to make retries across processes safe too. - 5xx, 429 and network errors are retried with exponential backoff (3 retries by default).
- API errors throw
BorgaErrorwithtype,code,status,param,requestIdand the parsed body.
Documentation
Guides and the full API reference live at docs.borga.is. Every code sample there is typechecked against this package.