Skip to content

fintech-sdk/wise-sdk

Repository files navigation

wise-sdk

Production-grade TypeScript client for the Wise Platform API — all 42 API groups, zero runtime dependencies.

npm CI License: MIT


✨ Features

  • Full Wise API coverage (Profiles, Transfers, Cards, KYC, Webhooks, and more)
  • Multiple authentication modes
    • Personal Token
    • OAuth Client Credentials (auto-refresh)
    • OAuth User Token (custom refresh)
  • Built-in reliability
    • Retries with exponential backoff
    • Rate limiting (token bucket)
    • Circuit breaker support
  • Middleware hooks
    • Request hooks
    • Response hooks (logging, metrics)
  • Async pagination iterator
  • Webhook verification + routing
  • Zero external dependencies

📦 Installation

npm install wise-sdk

🚀 Quick Start

import { WiseClient } from "wise-sdk";

const client = new WiseClient({
  personalToken: process.env.WISE_API_TOKEN!,
  sandbox: true, // set false for production
});

async function main() {
  const profiles = await client.profiles.list();

  for (const p of profiles) {
    console.log(`Profile ${p.id} (${p.type})`);
  }
}

main();

🔐 Authentication

Personal Token

const client = new WiseClient({
  personalToken: process.env.WISE_API_TOKEN!,
});

OAuth — Client Credentials (Auto Refresh)

const client = new WiseClient({
  clientId: process.env.WISE_CLIENT_ID!,
  clientSecret: process.env.WISE_CLIENT_SECRET!,
});

OAuth — User Token (Custom Refresh)

const client = new WiseClient({
  accessToken: "access-token",
  refreshToken: "refresh-token",
  tokenExpiresAt: new Date(Date.now() + 3600_000),

  onTokenRefresh: async (refreshToken) => {
    return {
      accessToken: "new-access-token",
      refreshToken: "new-refresh-token",
      expiresAt: new Date(Date.now() + 3600_000),
    };
  },
});

🌍 Environments

import { PRODUCTION_BASE_URL, SANDBOX_BASE_URL } from "wise-sdk";

// Production (default)
const prod = new WiseClient({ personalToken: "token" });

// Sandbox
const sandbox = new WiseClient({
  personalToken: "token",
  sandbox: true,
});

💸 Sending Money

// 1. Create a quote
const quote = await client.quotes.create(profileId, {
  sourceCurrency: "USD",
  targetCurrency: "INR",
  sourceAmount: 1000,
});

// 2. Create a recipient
const recipient = await client.recipients.create({
  profile: profileId,
  accountHolderName: "Alice",
  currency: "INR",
  type: "ifsc",
  details: {
    ifsc: "HDFC0001234",
    accountNumber: "1234567890",
  },
});

// 3. Create transfer
const transfer = await client.transfers.create({
  targetAccount: recipient.id,
  quoteUuid: quote.id,
  customerTransactionId: "unique-id",
  details: { reference: "Invoice #42" },
});

// 4. Fund transfer
await client.transfers.fund(profileId, transfer.id);

⚠️ Error Handling

import {
  isNotFound,
  isRateLimited,
  isSCARequired,
  fieldErrors,
} from "wise-sdk";

try {
  await client.transfers.fund(profileId, transferId);
} catch (err) {
  if (isNotFound(err)) {
    console.log("Resource not found");
  } else if (isRateLimited(err)) {
    console.log("Rate limited");
  } else if (isSCARequired(err)) {
    console.log("SCA required");
  }

  for (const fe of fieldErrors(err)) {
    console.log(fe.field, fe.message);
  }
}

🔁 Pagination

import { AsyncIter } from "wise-sdk";

const iter = new AsyncIter(async (page) => {
  return client.transfers.list({
    profileId,
    ...page,
  });
});

for await (const transfer of iter) {
  console.log(transfer.id, transfer.status);
}

🔔 Webhooks

import {
  EventRouter,
  isTransferStateChangeEvent,
} from "wise-sdk";

const router = new EventRouter({
  secret: process.env.WISE_WEBHOOK_SECRET!,
});

router.on("transfers#state-change", async (event) => {
  if (isTransferStateChangeEvent(event)) {
    console.log(event.data.resource.id);
  }
});

⚙️ Advanced Configuration

import { TokenBucket, CircuitBreaker } from "wise-sdk";

const client = new WiseClient({
  personalToken: "token",

  timeoutMs: 30_000,

  retry: {
    maxAttempts: 3,
  },

  rateLimiter: TokenBucket.default(),

  circuitBreaker: new CircuitBreaker({
    failureThreshold: 5,
    timeout: 30_000,
  }),

  requestHooks: [
    async (req) => {
      req.headers.set("X-Custom", "value");
      return req;
    },
  ],

  responseHooks: [
    (req, res, latency) => {
      console.log(req.url, res.status, latency);
    },
  ],
});

🧪 Utilities

import { newIdempotencyKey, ptr } from "wise-sdk";

const idempotencyKey = newIdempotencyKey();
const amount = ptr(1000);

🩺 Health Check

await client.ping();

📚 API Coverage

Includes all major Wise services:

  • Profiles
  • Quotes
  • Transfers
  • Recipients
  • Balances
  • Cards & transactions
  • KYC & verification
  • Webhooks
  • OAuth & security
  • Batch payments
  • Multi-currency accounts
  • Disputes
  • Direct debits
  • And more

📜 License

MIT


❤️ Contributing

PRs and issues are welcome!

About

Production-grade TypeScript client for the Wise Platform API — all 42 API groups, zero runtime dependencies

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors