OTP Login (mdn.academy)
WordPress plugin bridging the Digits login plugin to Melipayamak's pattern-based SMS API, enabling reliable OTP login without depending on a rotating sender line.
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/naznaveh/otp-login/archive/refs/heads/master.zipReadme
OTP Login Bridge for Melipayamak (WordPress)
A WordPress plugin that enables SMS one-time-password (OTP) login for existing users on MDN Academy, by bridging the Digits login plugin to Melipayamak's pattern-based SMS API — solving a reliability problem that the standard integration doesn't handle.
The problem
Melipayamak (a major Iranian SMS gateway) offers OTP delivery two ways:
- Shared sender line — the number you'd normally put in a "Sender ID" field. This line rotates on a schedule (weekly, in this account's case) for anti-spam/operator compliance reasons. Any integration expecting a fixed sender number (which is how most WordPress OTP plugins, including Digits' built-in Melipayamak gateway, are built) breaks silently the moment the line rotates.
- Dedicated line — fixed and reliable, but requires a paid "advertising → service line" conversion process with paperwork — overkill for this use case.
- Pattern-based API (
SendByBaseNumber2/ bodyId) — sends via a pre-approved message template, with Melipayamak handling line selection internally. No sender number needed, no rotation problem. This is the same mechanism the site already used reliably for license-key delivery SMS.
The solution
Rather than fighting with Digits' built-in gateway config (which only supports the fragile sender-number method), this plugin:
- Exposes a small REST bridge endpoint (
/wp-json/vx-otp/v1/bridge) that accepts a phone number + code - Internally calls Melipayamak's pattern-based API instead of the rotating-line method
- Is registered in Digits as a Custom Gateway, so Digits' existing OTP UI (tabs, code entry, resend timer) keeps working — only the actual SMS transport changes
Digits (UI + user lookup)
→ Custom Gateway URL → this plugin's REST bridge
→ Melipayamak SendByBaseNumber2 (pattern/bodyId — stable, no sender rotation)
A standalone login form ([otp_login] shortcode) with password/OTP tabs is also included for use outside Digits' native flow, with its own request → verify → wp_set_auth_cookie() cycle and a 30-second resend cooldown.
Requirements
- A Melipayamak account with an approved SMS pattern containing one variable placeholder (e.g.
{0}) for the code — same system used for transactional SMS like license delivery. - Existing users' phone numbers stored in a lookup-able user meta field (defaults check
digits_phone, WooCommerce'sbilling_phone, and a genericphonefield, in that order).
Structure
otp-login/
├── otp-login.php # Bootstrap, REST bridge route, shortcode
├── includes/
│ ├── class-otp-settings.php # Admin settings (Melipayamak creds, bodyId, code TTL)
│ ├── class-otp-sender.php # Pattern-based SMS sending + phone normalization
│ └── class-otp-handler.php # AJAX (request/verify/password-login) + REST bridge
├── templates/login-form.php
└── assets/otp-login.js / .css
License
MIT