Skip to content

Getting Started

Requirements

Dependency Version
PHP ≥ 7.4
WordPress ≥ 6.0
WPGraphQL (optional) ≥ 1.14
wp-graphql-headless-login / AxeWP (optional) any

WPGraphQL and AxeWP are only required for the headless/GraphQL flow. The plugin works as a pure WordPress OTP replacement without them.


Installation

The plugin is a Composer package. Install it into a WordPress project that manages its plugins via Composer (e.g. Bedrock or a custom root composer.json).

Via Packagist (production)

composer require subscribed/wp-otp

Via path repository (local development)

// composer.json in your WordPress project root
{
  "repositories": [
    {
      "type": "path",
      "url": "../../plugins/package-wp-otp"
    }
  ],
  "require": {
    "subscribed/wp-otp": "*"
  }
}
composer install

Composer (with composer/installers) installs the plugin to wp-content/plugins/wp-otp/ automatically because composer.json declares "type": "wordpress-plugin".

After installation

Activate the plugin in WP Admin → Plugins, or via WP-CLI:

wp plugin activate wp-otp

Configuration

Settings are managed under Settings → WP OTP in the WordPress admin.

Setting Default Description
Token duration 5 minutes How long a code remains valid before expiring
Code length 6 Number of characters in the generated code (4–12)
Character set numeric numeric, alpha, or alphanumeric — see below
Max failed attempts 5 Token is revoked after this many wrong codes, forcing the user to request a new one
Email logo URL (empty) URL to the logo shown at the top of the OTP email. Leave empty to use the site name as text
Email logo max height 50 px Maximum height of the logo image in the email (20–500 px)

Character sets

Value Example Notes
numeric 483920 Digits only. Best for SMS-style entry; mobile shows numeric keyboard
alpha xkqmbt Lowercase letters only
alphanumeric x4k9mq Lowercase letters + digits

Note: If wp-graphql-headless-login (AxeWP) is not installed, the settings page under Settings → WP OTP is always visible. When AxeWP is installed the same settings page is still the single source of truth — AxeWP's own settings panel is not used for OTP settings.


WordPress login vs GraphQL login

The plugin supports two independent login flows that can run side by side:

  1. Traditional WP login (wp-login.php) — replaces the password form with an OTP flow. All users (admins, shop managers, editors, etc.) are affected.
  2. GraphQL / headless login — exposes a requestOtp mutation and integrates with AxeWP's login mutation. Used by Nuxt or other headless frontends.

Both flows share the same OtpStore (WordPress Transients) and OtpSettings.