Skip to main content

Server Integration

This guide shows how to integrate the Digital Banking API from your backend — authenticating users, forwarding tenant context, handling errors, and verifying webhook signatures.

Architecture Overview

┌────────────┐     ┌────────────────┐     ┌──────────────────┐
│ Your Client│────▶│ Your Backend │────▶│ Banking API │
│ (mobile/ │ │ (proxy layer) │ │ api.korastratum │
│ web app) │ │ │ │ .com/banking │
└────────────┘ └────────────────┘ └──────────────────┘

Your backend acts as a proxy between client apps and the Banking API. This keeps API credentials server-side and lets you add your own business logic (e.g. approval flows, audit logs).

Setup

Store your tenant credentials as environment variables:

BANKING_API_URL=https://api.korastratum.com/api/v1/banking
BANKING_TENANT_ID=fmfb

Making Authenticated Requests

async function bankingRequest(method, path, token, body = null) {
const res = await fetch(`${process.env.BANKING_API_URL}${path}`, {
method,
headers: {
Authorization: `Bearer ${token}`,
"X-Tenant-ID": process.env.BANKING_TENANT_ID,
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : undefined,
});

const data = await res.json();

if (!data.success) {
throw new BankingAPIError(data.code, data.error, res.status);
}

return data.data;
}

Error Handling

The API returns a consistent error envelope. Map Banking API errors to your own HTTP responses:

class BankingAPIError extends Error {
constructor(code, message, status) {
super(message);
this.code = code;
this.status = status;
}
}

// Express error handler
app.use((err, req, res, next) => {
if (err instanceof BankingAPIError) {
return res.status(err.status).json({
error: err.message,
code: err.code,
});
}
res.status(500).json({ error: "Internal server error" });
});

Retry Logic

Retry on transient errors (503 Service Unavailable, network timeouts) with exponential backoff:

async function withRetry(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (err) {
if (err.status === 503 && i < maxRetries - 1) {
await new Promise((r) => setTimeout(r, 1000 * Math.pow(2, i)));
continue;
}
throw err;
}
}
}

Token Management

Store user tokens securely on your backend. Refresh them before they expire:

async function getValidToken(userId) {
const session = await db.getUserSession(userId);

// Refresh if expiring within 5 minutes
if (session.expiresAt - Date.now() < 5 * 60 * 1000) {
const data = await bankingRequest("POST", "/api/v1/auth/refresh", null, {
refreshToken: session.refreshToken,
});
await db.updateSession(userId, data.tokens);
return data.tokens.accessToken;
}

return session.accessToken;
}

Security Best Practices

  • Never expose tokens to the client — Proxy all Banking API calls through your backend.
  • Validate input — Check amounts, account numbers, and other fields before forwarding to the API.
  • Log all transactions — Keep an audit trail of every transfer, loan, and bill payment.
  • Use HTTPS — All communication with the Banking API must be over TLS.
  • Rotate secrets — Periodically rotate your tenant credentials and JWT secrets.
  • Handle rate limits — Check RateLimit-Remaining headers and back off when approaching the limit.

Next Steps