SpareSpare Docs
GuidesAPI Reference

TypeScript SDK

Install, configure, and use the @spare-technologies/spare-api npm package.

The TypeScript SDK targets Node.js 18+ and works with Bun. It is the recommended client for new integrations.

Now available (v1.0.0)

The TypeScript SDK is published on npm as @spare-technologies/spare-api. It currently targets the UAE tenant. The other language SDKs are still under review; until they ship, integrate those over the REST API.

Installation

Install

npm install @spare-technologies/spare-api

Configuration

import { Configuration, SpareApiClient } from "@spare-technologies/spare-api";

const config = new Configuration({
  appId: process.env.SPARE_APP_ID!,
  apiKey: process.env.SPARE_API_KEY!,
  tenant: "UAE",
  environment: "sandbox",
});

const client = new SpareApiClient({ authProvider: config });

Configuration caches access tokens and refreshes them before expiry.

End-to-end payment flow

The full happy path for a single payment: create a payment request, create a consent, hand the payer off to their bank, then read the result after the callback. Method names follow a resource.action pattern; each operation's fields are in the API Reference.

import { Configuration, SpareApiClient } from "@spare-technologies/spare-api";

const client = new SpareApiClient({
  authProvider: new Configuration({
    appId: process.env.SPARE_APP_ID!,
    apiKey: process.env.SPARE_API_KEY!,
    tenant: "UAE",
    environment: "sandbox",
  }),
});

// 1. Discover the providers (banks) available to the payer.
const providers = await client.providers.list();

// 2. Create the payment request.
const pr = await client.paymentRequests.create({
  amount: 150, // minor units (fils), 1.50 AED
  currency: "AED",
  description: "Invoice #12345",
  redirectUrl: "https://yourapp.com/payments/callback",
});
const paymentRequestId = pr.data.id;

// 3. Create a consent from the payment request; the response carries the URL
//    to send the payer to for bank authorization.
const consent = await client.paymentConsents.createFromPaymentRequest({
  paymentRequestId,
});
redirect(consent.data.authorizationUrl);

// 4. After the bank redirects back to your callback, read the payment status.
const payment = await client.payments.get({ paymentId: consent.data.paymentId });
console.log(payment.data.status);

Signed requests

POST /payment-requests requires an x-signature. For how the detached ES256 signature is built (if you sign requests yourself), see Request Signing.

Pagination

List endpoints are paginated with page (1-based) and perPage:

const firstPage = await client.paymentRequests.list({ page: 1, perPage: 20 });
for (const request of firstPage.data) {
  console.log(request.id, request.status);
}

Track the result

A payment's status advances as the payer authorizes and the bank settles. Read the latest state on demand:

const payment = await client.payments.get({ paymentId });
// payment.data.status, for example: New, AwaitingAuthorization, Authorized, Completed, Rejected

Prefer webhooks over polling for status changes. Register a subscription via POST /webhooks, then verify each signed delivery (a compact JWS) before acting on it. See Webhooks for an overview and Receive Events for the verification steps.

Error handling

import { SpareApiError, SpareApiTimeoutError } from "@spare-technologies/spare-api";

try {
  await client.paymentRequests.get({ paymentRequestId: "invalid" });
} catch (error) {
  if (error instanceof SpareApiError) {
    console.error(error.status, error.message);
  }
}

Types

Import types from the SpareApi namespace:

import type { SpareApi } from "@spare-technologies/spare-api";

Resources

On this page