Skip to content

Bank Integration Guide

Join the OpenWave network as a payment partner. Once registered, your customers can pay and receive payments from any merchant or user in the ecosystem.

What a Bank Needs to Provide

OpenWave is a routing layer — it doesn't replace your core banking system. The gateway calls your core to:

  1. Verify customer identity (OTP or SCA)
  2. Debit the sending account
  3. Credit the destination account (if it's your bank)
  4. Query account details for Open Banking

You expose a bank core callback API that the gateway calls. The spec defines exactly what this interface must look like.

Step 1 — Register with a Gateway

Contact the gateway operator (or run your own — see Gateway Operators).

You'll need to provide:

  • Bank handle (e.g. andalus) — globally unique short identifier
  • Display name
  • Country (LY)
  • Core API base URL (your callback server)
  • Settlement IBAN (where net settlements are credited/debited)
  • Contact email

The gateway issues you a Bank API Key (owbk_...). Store it securely — it's shown once.

Step 2 — Implement the Core Callback Interface

The gateway calls your core at the core_base_url you registered. All endpoints receive X-OpenWave-Internal-Key for authentication. You must implement all of the following:

EndpointMethodCalled when
/send-otpPOSTCustomer selects OTP auth
/verify-otpPOSTCustomer submits OTP code
/send-pushPOSTCustomer selects push auth
/execute-transactionPOSTOTP/push verified — debit + route funds
/notify-creditPOSTCross-bank credit arrives (non-blocking)
/ob/accountsPOSTOpen Banking AISP account list
/ob/balancesPOSTOpen Banking AISP balance query
/ob/transactionsPOSTOpen Banking AISP transaction history
/ob/payment-ordersPOSTOpen Banking PISP payment initiation

Bank-agnostic routing

The gateway has one generic HTTP client for all banks. There is no bank-specific code in the gateway — your core_base_url is the sole routing target.

Send OTP Challenge

http
POST {core_base_url}/send-otp
X-OpenWave-Internal-Key: <shared-secret>

{
  "session_id": "ops_01HZGV...",
  "payer_iban": "LY83002700100099900001"
}

Your bank receives the payer IBAN, extracts the account number, looks up the customer in your CBS, and sends the OTP via SMS/email. Return:

json
{ "otp_token": "<reference>", "phone_masked": "091****12", "expires_in_seconds": 300 }

CBS customer IDs never leave your bank

The gateway passes only the IBAN — it never stores or transmits CBS-internal customer IDs. Your bank derives the customer from the IBAN internally. This is by design.

Verify OTP

http
POST {core_base_url}/verify-otp
X-OpenWave-Internal-Key: <shared-secret>

{ "session_id": "ops_01HZGV...", "otp_token": "<reference>", "otp_code": "123456" }

Return { "verified": true } or a 401.

Execute Transaction

Called once after OTP/push auth is confirmed. Handles both same-bank and cross-bank routing:

http
POST {core_base_url}/execute-transaction
X-OpenWave-Internal-Key: <shared-secret>

{
  "session_id": "ops_01HZGV...",
  "merchant_name": "My Store",
  "merchant_reference": "order_1042",
  "debtor_iban": "LY83002700100099900001",
  "creditor_iban": "LY83002700200099900002",
  "creditor_bank_handle": "bank-b",
  "creditor_bank_lypay_code": "002",
  "amount": 50000,
  "currency": "LYD",
  "description": "Order #1042",
  "route_type": "SAME_BANK"
}

route_type is either SAME_BANK (atomic CBS book transfer) or LYPAY_INITIATE (debtor bank initiates a CBL LyPay transfer). Return:

json
{ "transfer_ref": "TRF-20260424-001", "route_used": "SAME_BANK", "lypay_ref": null }

Notify Credit (cross-bank, non-blocking)

When a cross-bank payment credits the merchant's bank, the gateway calls the creditor bank to inform it:

http
POST {core_base_url}/notify-credit
X-OpenWave-Internal-Key: <shared-secret>

{
  "session_id": "ops_01HZGV...",
  "creditor_iban": "LY83002700200099900002",
  "amount": 50000,
  "currency": "LYD",
  "transfer_ref": "TRF-20260424-001"
}

Get Accounts (for Open Banking AISP)

http
POST {core_base_url}/ob/accounts
X-OpenWave-Internal-Key: <shared-secret>

{ "customer_id": "CUST-001", "consent_id": "con_01HZGV..." }

Returns list of accounts with IBAN, account name, currency, and type.

Get Balances (for Open Banking AISP)

http
POST {core_base_url}/ob/balances
X-OpenWave-Internal-Key: <shared-secret>

{ "customer_id": "CUST-001", "iban": "LY83...", "consent_id": "con_01HZGV..." }

Get Transactions (for Open Banking AISP)

http
POST {core_base_url}/ob/transactions
X-OpenWave-Internal-Key: <shared-secret>

{ "customer_id": "CUST-001", "iban": "LY83...", "from_date": "2026-01-01",
  "to_date": "2026-04-30", "page": 1, "limit": 50, "consent_id": "con_01HZGV..." }

Step 3 — Enroll Your Customers' Aliases

When a customer chooses their NPT handle in your app, your backend calls the Identity Registry:

http
POST /v1/identity/claim
X-OpenWave-Bank-Key: owbk_<your-bank-handle>_...

{
  "npt_handle": "mtellesy",
  "iban": "LY83002700100099900001",
  "customer_display_name": "Mohamed T.",
  "bank_customer_ref": "CUST-001"
}

If the handle is taken, the registry returns 409 Conflict.

Step 4 — Advertise Your Capabilities

Let TPPs know what Open Banking features you support:

http
PATCH /banks/{handle}
X-OpenWave-Bank-Key: owbk_andalus_...

{
  "ob_enabled": true,
  "ob_scopes_supported": ["accounts:read", "balances:read", "transactions:read", "payments:write"],
  "sca_exemption_limit": 5000,
  "max_consent_expiry_days": 365
}

Step 5 — Handle Settlements

The gateway batches net settlement amounts and calls your core once per settlement cycle (configurable: hourly, daily, etc.).

A settlement is a net credit or debit to your settlement_account_iban. The gateway handles individual customer debits and credits — settlement reconciles the net position between banks.

LyPay & NAD Integration

To participate in cross-bank OpenWave payments, your bank must be connected to CBL's National Payment Infrastructure:

NAD — National Alias Directory

NAD is the CBL-operated alias registry. Your bank must:

  1. Enroll your customers in NAD when they activate their alias (NPT handle) — this maps alias → IBAN + institution code
  2. Keep NAD in sync — deactivate entries when accounts are closed or aliases are released
  3. Expose the enrollment callback so the gateway can trigger NAD enrollment via your bank's OpenWave interface
http
POST /openwave/callbacks/v1/alias/enroll
{
  "alias": "mtellesy",
  "account_iban": "LY83002700100099900001",
  "customer_ref": "CUST-001"
}

LyPay — Outbound (Sending)

When your customer pays a merchant at another bank:

  1. Gateway instructs your bank to debit the customer
  2. Your bank CBS debits, then initiates a LyPay transfer to the creditor IBAN
  3. LyPay routes to the merchant's bank
  4. You receive a LyPay debit notice (your RRN) — store this for reconciliation

LyPay — Inbound (Receiving)

When your merchant customer receives a payment from another bank:

  1. CBL LyPay delivers a credit instruction to your bank
  2. Your CBS credits the merchant's account
  3. Your bank (or the gateway) fires the credit confirmation back to the gateway
  4. The gateway updates the session to COMPLETED and fires payment.completed to the merchant

Credit confirmation is mandatory

The gateway will not fire payment.completed to the merchant until it receives credit confirmation from your bank. Implement the credit callback promptly — delays here delay merchant fulfillment.

http
POST /openwave/callbacks/v1/payment/credit-confirmed
{
  "payment_reference": "LYPAY-REF-001",
  "session_id": "ops_01HZGV...",
  "creditor_iban": "LY83002700100099900001",
  "amount": 50000,
  "currency": "LYD",
  "rrn": "20260424-000123"
}

Security Requirements

RequirementDetail
All callback endpoints must be HTTPSTLS 1.2+ required
Validate X-OpenWave-Internal-Key on every callbackReject requests without valid key
IdempotencyUse the reference field to deduplicate — the gateway may retry on timeout
Response timeCore callbacks should respond within 10 seconds
Retry policyGateway retries with exponential backoff on 5xx responses

Rotate Your Bank Key

If your key is compromised:

http
POST /banks/{handle}/rotate-key
X-OpenWave-Bank-Key: owbk_<your-bank-handle>_...

New key is returned once. Update your systems immediately.