The Central Bank of Nigeria's circular of 12 March 2026 on instant payments and mobile banking security requires multi-factor authentication for key account changes and limits mobile banking apps to one active device at a time, with implementation due by 1 July 2026. SMS OTP is not named as a required factor, but a code sent to the customer's registered number remains a common possession factor in device-binding and limit-change flows.

Last reviewed: 27 October 2026

This guide summarises what the circular is reported to require, where SMS OTP fits, and how to build the flows with eSMS Verify. It is a technical guide, not legal advice; confirm your design with your compliance team and the circular itself.

What the CBN circular requires

Based on summaries by Pavestones Legal (on Mondaq) and Global Law Experts, the circular sets these measures for financial institutions offering instant payments, with a 1 July 2026 implementation date:

  • MFA for changes: customers can opt in or out of instant payments at any time, subject to MFA, and changes to transaction limits take effect only after MFA.
  • One active device: mobile banking apps may run on only one device at a time. Moving to a new device deactivates the old one, and the new device must be reactivated and authenticated.
  • Enhanced MFA on a new device: the first internet banking login on a new device needs enhanced MFA.
  • New-device limits: for the first 24 hours after activation on a new device, outflows (and, for new account owners, inflows) are capped at NGN 20,000.
  • Onboarding checks: online account opening and reactivation need a liveness check and real-time BVN or NIN validation, and reactivation needs enhanced authentication such as biometrics or a token.
  • Fraud monitoring: enterprise-wide, real-time monitoring of inflows and outflows.

Where SMS OTP fits

MFA combines factors from different groups: something the customer knows (PIN, password), has (a phone, a token) or is (fingerprint, face). An SMS code sent to the customer's registered number proves possession of that SIM. It is not a complete answer on its own, but it is useful in specific moments:

FlowRole of SMS OTPPair it with
Binding a new deviceProves the customer holds the registered SIMPIN or biometric, plus liveness for reactivation where required
Raising a transfer limitConfirms the request came from the account ownerTransaction PIN
Opting in or out of instant paymentsSecond factor for the changePIN or in-app biometric
Old device deactivatedNot an OTP: a security notice to the registered numberHelpline to report fraud

The known weakness of SMS OTP is SIM swap: a fraudster who takes over the customer's number receives the codes. Device binding helps here, because a code alone is not enough to activate a device if you also require a PIN or biometric. Many teams also check for a recent SIM change before accepting an SMS factor where that signal is available.

Designing the device-binding flow

  1. Customer installs the app on a new phone and signs in with their credentials.
  2. The app shows the masked registered number and requests a code.
  3. Your backend calls Verify to start a verification for that number.
  4. Customer enters the code and a PIN or biometric.
  5. On approval, your backend deactivates the old device, activates the new one and applies the first-24-hour limit.
  6. Send a security notice to the registered number confirming the change.
// Device binding with eSMS Verify (Node 18+, Express-style handlers)
const ESMS = "https://sms.esmsafrica.io/v1/verify";
const headers = {
  "Authorization": "Bearer " + process.env.ESMS_API_KEY,
  "Content-Type": "application/json"
};

// 1. Customer signs in on a new device: send a code to the registered number
async function startDeviceBinding(customer, deviceId) {
  const res = await fetch(ESMS + "/start", {
    method: "POST",
    headers: { ...headers, "Idempotency-Key": "bind-" + customer.id + "-" + deviceId },
    body: JSON.stringify({ to: customer.phone, app_id: process.env.VERIFY_APP_ID })
  });
  if (res.status === 429) throw new Error("Too many code requests for this number");
  const v = await res.json();
  return v.verification_id; // store against the pending device
}

// 2. Customer enters the code: check it, then bind the device
async function confirmDeviceBinding(verificationId, code, customer, deviceId) {
  const res = await fetch(ESMS + "/check", {
    method: "POST",
    headers,
    body: JSON.stringify({ verification_id: verificationId, code })
  });
  const r = await res.json();
  if (r.status !== "approved") return { ok: false, status: r.status };
  // Second factor (PIN or biometric) is checked in the app before this point.
  await deactivateOtherDevices(customer.id);       // one active device
  await activateDevice(customer.id, deviceId);
  await applyNewDeviceLimits(customer.id);           // first-24-hour cap
  return { ok: true };
}

The security notice in step 6 is a plain transactional SMS:

curl -X POST https://sms.esmsafrica.io/api/messages/send \
  -H "Authorization: Bearer esms_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"to": "+2348031234567", "sender_id": "PayNa", "text": "PayNa: A new device was linked to your account at 14:02. Your old phone is now logged out. Not you? Call 0700 000 0000 now."}'

Rate limiting and abuse

Device binding is a target for attackers and for SMS pumping. Build in limits at several layers:

  • Per number: eSMS Verify returns 429 too_many_requests after five starts for one number in an hour and allows up to three resends per verification.
  • Per attempt: each wrong code consumes an attempt; after the cap the verification fails and a new one must be started.
  • Per device and IP: add your own limits on how often one device or IP can request codes for different numbers.
  • Idempotency: send an Idempotency-Key so network retries do not trigger a second SMS.

Delivery: making sure the code arrives

A strong MFA design fails if the code does not reach the customer. In Nigeria that means:

  • Use a sender ID approved for transactional traffic on MTN, Airtel, Glo and T2, so codes reach customers on DND.
  • Keep the OTP text free of promotional wording.
  • Watch delivery reports by network so a problem on one network is caught quickly.

Our OTP debugging checklist covers the common failure causes, and the NCC A2P licence explainer covers how traffic from platforms abroad reaches Nigerian networks.

Messages the customer should receive

Beyond the code itself, a well-designed flow keeps the customer informed at each step, which also helps them spot fraud early:

  • A code message when a new device or limit change is requested, stating what it is for: "Your PayNa code to link a new phone is ...".
  • A confirmation when the new device is active, naming the time and stating that the old device is logged out.
  • A notice when a limit change takes effect, with the new limit.
  • A warning if several wrong codes are entered, telling the customer to call the helpline if they did not start the request.

Naming the purpose in the code message matters. A customer who receives "code to link a new phone" when they have not changed phones knows something is wrong.

Cost planning

Each device binding or limit change sends at least one SMS, so estimate volumes from your device-change and limit-change rates. Verify pricing follows the Nigeria SMS rate, from NGN 9.1 ($0.0068) on the basic tier, with volume tiers on the pricing page. Failed Verify sends (502 otp_send_failed) are not charged.

Frequently asked questions

Does the CBN circular ban SMS OTP?

No. Public summaries describe MFA, device and limit requirements without naming or banning SMS. Whether SMS is an acceptable factor for a given flow is a decision for your institution's risk and compliance teams.

Should the old device get a notice?

Send the security notice to the registered number, which reaches the customer whichever device they hold. An in-app message on the old device is a useful addition before it is logged out.

Can we test the flow without sending real SMS?

Yes. With an esms_test_ key, Verify sends nothing, charges nothing and returns a sandbox_code; the code 000000 always passes check.

Does this apply to wallets as well as banks?

The circular is addressed to financial institutions offering instant payment services. Check with your compliance team whether and how it applies to your licence type.

Sources

Building device binding for a Nigerian bank or wallet? Read the fintech use-case guide and the eSMS Verify overview, then create an eSMS Africa account and test the full flow with a free test key.