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
- Node.js
- Python
- Go
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;
}
import os
import requests
API_URL = os.environ["BANKING_API_URL"]
TENANT_ID = os.environ["BANKING_TENANT_ID"]
def banking_request(method, path, token, body=None):
res = requests.request(
method,
f"{API_URL}{path}",
headers={
"Authorization": f"Bearer {token}",
"X-Tenant-ID": TENANT_ID,
},
json=body,
)
data = res.json()
if not data["success"]:
raise BankingAPIError(data["code"], data["error"], res.status_code)
return data["data"]
func bankingRequest(method, path, token string, body io.Reader) (map[string]any, error) {
url := os.Getenv("BANKING_API_URL") + path
req, err := http.NewRequest(method, url, body)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("X-Tenant-ID", os.Getenv("BANKING_TENANT_ID"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result map[string]any
json.NewDecoder(resp.Body).Decode(&result)
return result, nil
}
Error Handling
The API returns a consistent error envelope. Map Banking API errors to your own HTTP responses:
- Node.js
- Python
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" });
});
class BankingAPIError(Exception):
def __init__(self, code, message, status):
self.code = code
self.message = message
self.status = status
# Flask error handler
@app.errorhandler(BankingAPIError)
def handle_banking_error(e):
return jsonify({"error": e.message, "code": e.code}), e.status
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-Remainingheaders and back off when approaching the limit.
Next Steps
- Webhooks — Receive real-time event notifications.
- Error Codes — Full error code reference.
- Sandbox Testing — Test your integration safely.