How to Send OTP with WordPress (2026)
WordPress OTP integration using StartMessaging. Custom plugin with REST API endpoints, options-page for the API key, and a shortcode-based login form. WooCommerce-friendly.
StartMessaging Team
Engineering
WordPress is still the dominant CMS in India. This tutorial shows how to wire StartMessaging as a custom plugin with REST endpoints and a shortcode form.
Overview
- Plugin file with a settings page for API key.
- Two REST routes:
/otp/send,/otp/verify. - Shortcode for the login form.
- WooCommerce checkout hook (optional).
Plugin Skeleton
<?php
/**
* Plugin Name: StartMessaging OTP
*/
defined('ABSPATH') || exit;
require_once __DIR__ . '/inc/options.php';
require_once __DIR__ . '/inc/rest.php';
require_once __DIR__ . '/inc/shortcode.php';Options Page
<?php
add_action('admin_menu', function () {
add_options_page('StartMessaging', 'StartMessaging', 'manage_options', 'sm', function () {
if (isset($_POST['sm_save'])) {
update_option('sm_api_key', sanitize_text_field($_POST['sm_api_key']));
echo '<div class="updated"><p>Saved.</p></div>';
}
$key = esc_attr(get_option('sm_api_key', ''));
echo "<form method='post'><h1>StartMessaging</h1><input name='sm_api_key' value='$key' size=60 /><button name='sm_save'>Save</button></form>";
});
});REST API Endpoints
<?php
add_action('rest_api_init', function () {
register_rest_route('sm/v1', '/send-otp', [
'methods' => 'POST',
'permission_callback' => '__return_true',
'callback' => function (WP_REST_Request $req) {
$phone = $req->get_param('phoneNumber');
$r = wp_remote_post('https://api.startmessaging.com/otp/send', [
'headers' => ['X-API-Key' => get_option('sm_api_key'), 'Content-Type' => 'application/json'],
'body' => json_encode(['phoneNumber' => $phone, 'idempotencyKey' => wp_generate_uuid4()]),
'timeout' => 10,
]);
$body = json_decode(wp_remote_retrieve_body($r), true);
if (wp_remote_retrieve_response_code($r) !== 200) return new WP_REST_Response($body, 502);
$data = $body['data'];
setcookie('sm_otp_req', $data['requestId'], time() + 900, '/', '', true, true);
return ['expiresAt' => $data['expiresAt']];
},
]);
register_rest_route('sm/v1', '/verify-otp', [
'methods' => 'POST',
'permission_callback' => '__return_true',
'callback' => function (WP_REST_Request $req) {
$code = $req->get_param('otpCode');
$rid = $_COOKIE['sm_otp_req'] ?? null;
if (!$rid) return new WP_REST_Response(['error' => 'no otp'], 400);
$r = wp_remote_post('https://api.startmessaging.com/otp/verify', [
'headers' => ['X-API-Key' => get_option('sm_api_key'), 'Content-Type' => 'application/json'],
'body' => json_encode(['requestId' => $rid, 'otpCode' => $code]),
]);
return wp_remote_retrieve_response_code($r) === 200
? ['verified' => true]
: new WP_REST_Response(['error' => 'invalid'], 401);
},
]);
});Login Shortcode
<?php
add_shortcode('sm_login', function () {
return '<form id="sm-phone"><input name="phoneNumber" /><button>Send OTP</button></form>
<form id="sm-otp" hidden><input name="otpCode" /><button>Verify</button></form>
<script>/* fetch /wp-json/sm/v1/send-otp etc */</script>';
});WooCommerce Notes
Hook into woocommerce_checkout_validation to require a verified phone before order placement. The same REST endpoints plug in.
FAQ
For Shopify equivalent see our Shopify guide.
Related Articles
Complete PHP tutorial for sending and verifying OTP via SMS using curl and Laravel HTTP client with the StartMessaging API. Includes service class and middleware patterns.
CodeIgniter 4 OTP tutorial using StartMessaging. Uses CURLRequest, Config files for keys, and Session for the request ID. Drop-in patterns for Indian dev shops.
Shopify OTP integration using StartMessaging. App-based pattern with App Proxy, customer metafields, signed cookies, and a checkout-extension flow for India COD verification.
Ready to Send OTPs?
Integrate StartMessaging in 5 minutes. No DLT registration required.