=== ForthFocus SMS – OTP Verification, Order Notifications & Indian DLT for WooCommerce ===
Contributors: forthfocus, vgnavada
Tags: woocommerce, sms, otp, dlt, transactional-sms
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 1.0.7
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Indian DLT-compliant SMS for WooCommerce: order-status notifications, OTP at login / signup / checkout, full delivery logs.

== Description ==

ForthFocus SMS is built for Indian WooCommerce stores that need DLT-ready transactional SMS, order notifications, OTP verification, and operational visibility in one place. It sends order-status notifications to customers and adds phone-number OTP verification to important store touchpoints such as login, registration, cart, and checkout.

It is built for production: instant order-status sends with optional async queue, a custom log table with filtering, search, retry and CSV export, per-template DLT enforcement, real rate-limiting on OTP requests and verifications, segment-aware authoring with live variable-syntax linting, HTTP diagnostics for gateway communication, and a 3-step setup wizard so first-time configuration takes minutes instead of hours.

The plugin currently supports SMSGatewayHub, ForthFocus SMS Gateway, Gupshup, Fast2SMS, 2Factor, and MSG91. Additional providers (Twilio, Kaleyra) are on the roadmap. The architecture is provider-agnostic — the same templates, OTP flows, and logging continue to work as new providers are added.

= What makes it different =

Most SMS plugins focus only on sending a message or adding a basic OTP form. ForthFocus SMS is focused on the Indian WooCommerce + DLT workflow: every enabled template needs its own provider-specific template mapping, template syntax is checked before sending, customer OTP flows are rate-limited, gateway responses are logged, balance checks are available inside WordPress, and Diagnostics shows the actual WordPress HTTP request lifecycle for supported gateway communication.

= What it sends =

* **Order Processing: Online Payment** — when a non-COD order moves to Processing
* **Order Processing: Cash on Delivery** — when a COD order moves to Processing
* **Order Completed** — when an order is marked Completed
* **Order Cancelled** — when an order is cancelled
* **Order Refunded** — when a refund is issued
* **OTP for login** — alongside the standard email/password login
* **OTP for registration** — verify the phone number before account creation
* **OTP at checkout** — verify the phone before the customer hits "Place Order" (cuts down on fake / COD fraud orders)

= Why DLT compliance matters =

In India, every commercial SMS must use a sender ID and template registered on the DLT (Distributed Ledger Technology) portal of your telecom operator. Sending unregistered content gets rejected at the operator side, often silently. This plugin enforces DLT correctness at every layer:

* Each template requires its own DLT Template ID or MSG91 Flow ID before it can be enabled.
* The plugin refuses to send any template that has no active-provider mapping — and logs the attempt so you can see what was skipped and why.
* A live syntax linter catches the most common authoring mistakes (`{order_id)` instead of `{order_id}`, `{#var#}` placeholders pasted verbatim from the DLT portal) before they cause silent rejections.

= Privacy =

* The plugin sends data to the configured SMS gateway only when an SMS-related action is performed, such as sending an order notification, sending an OTP, testing a template, or refreshing the SMS balance where the selected provider supports a balance API.
* For SMS sending, the data sent to the selected gateway may include the recipient phone number, rendered SMS message body, sender ID/mask, route, channel, Entity ID/principalEntityId, DLT Template ID, provider credentials, and a unique provider message ID where supported.
* For balance checks, the plugin sends the required provider credentials to the selected gateway's balance endpoint where available. MSG91 does not currently provide a wallet balance API, so the plugin links to the MSG91 dashboard instead of calling a balance endpoint.
* Plugin scripts, styles, and images are loaded locally from the plugin folder. The plugin does NOT load anything from external CDNs or third-party servers on either admin or customer-facing pages.
* The plugin does NOT send usage analytics, telemetry, tracking events, or call-home data to ForthFocus.
* OTP codes are hashed (with a per-phone salt) before storage. Plaintext OTP codes are redacted from log entries.
* Store owners are responsible for ensuring that their SMS use complies with applicable consent, privacy, telecom, DLT, and customer communication rules.

== External services ==

This plugin connects to the SMS gateway selected by the site owner to send transactional SMS messages and fetch SMS balance information where the selected provider supports it. A gateway account, API key/Auth Key, approved sender ID/Header, Entity ID or provider-side DLT setup, and approved templates/flows are required for live SMS delivery.

The plugin currently supports the following gateway endpoints:

* `https://www.smsgatewayhub.com/api/mt/SendSMS` — used when the site owner sends an SMS through SMSGatewayHub, such as an order-status notification, OTP message, or template test. The plugin sends the recipient phone number, rendered message body, sender ID, route, channel, Entity ID, DLT Template ID, and the site's SMSGatewayHub API key.
* `https://www.smsgatewayhub.com/api/mt/GetBalance` — used when the dashboard or gateway settings page fetches the SMSGatewayHub balance. The plugin sends the site's SMSGatewayHub API key.
* `https://sms.forthfocus.com/api/mt/SendSMS` — used when the site owner sends an SMS through ForthFocus SMS Gateway, such as an order-status notification, OTP message, or template test. The plugin sends the recipient phone number, rendered message body, sender ID, route, channel, Entity ID, DLT Template ID, and the site's ForthFocus SMS Gateway API key.
* `https://sms.forthfocus.com/api/mt/GetBalance` — used when the dashboard or gateway settings page fetches the ForthFocus SMS Gateway balance. The plugin sends the site's ForthFocus SMS Gateway API key.
* `https://enterprise.smsgupshup.com/GatewayAPI/rest` — used when the site owner sends an SMS through Gupshup, such as an order-status notification, OTP message, or template test. The plugin sends the recipient phone number, rendered message body, approved sender ID/mask, Gupshup User ID, and Gupshup Password. For Gupshup, sender ID, entity, and DLT template mapping must be configured on the Gupshup account.
* `https://enterprise.smsgupshup.com/apps/apis/accInfo` — used when the dashboard or gateway settings page fetches the Gupshup balance. The plugin sends the site's Gupshup User ID and Password.
* `https://www.fast2sms.com/dev/bulkV2` — used when the site owner sends an SMS through Fast2SMS, such as an order-status notification, OTP message, or template test. The plugin sends the recipient phone number, rendered message body, Fast2SMS Authorization Key, DLT-approved sender ID, Entity ID, DLT Template ID, and the fixed `dlt_manual` route.
* `https://www.fast2sms.com/dev/wallet` — used when the dashboard or gateway settings page fetches the Fast2SMS wallet balance. The plugin sends the site's Fast2SMS Authorization Key.
* `https://2factor.in/API/R1/` — used when the site owner sends an SMS through 2Factor, such as an order-status notification, plugin-generated OTP message, or template test. The plugin sends the recipient phone number, rendered DLT-approved message body, 2Factor API Key, Sender ID/Header, PE ID, and DLT Template ID through the Transactional SMS API. The plugin does not use 2Factor's OTP generation or OTP verification APIs.
* `https://2factor.in/API/V1/{API_KEY}/ADDON_SERVICES/BAL/TRANSACTIONAL_SMS` — used when the dashboard or gateway settings page fetches the 2Factor Transactional SMS balance. The plugin places the site's 2Factor API Key in the endpoint path as required by the provider.
* `https://api.msg91.com/api/v5/flow/` — used when the site owner sends an SMS through MSG91 SMS Flow API, such as an order-status notification, plugin-generated OTP message, or template test. The plugin sends the recipient phone number, MSG91 Flow ID, Sender ID/Header, and variable values. The site's MSG91 Auth Key is sent in the request header. DLT Template ID, PE ID, approved content, and variable mapping must be configured inside the customer's MSG91 account and flow.
* MSG91 balance: MSG91 confirmed that no wallet balance API is currently available. For MSG91, the plugin does not call a balance endpoint and instead links the admin to the MSG91 dashboard.

SMS content and phone numbers are sent to the selected gateway only when the site owner enables the plugin and performs an SMS-related action or when a configured WooCommerce/OTP event triggers an SMS.

Service provider: SMSGatewayHub
Terms and Conditions: https://www.smsgatewayhub.com/terms-and-conditions
Privacy Policy: https://www.smsgatewayhub.com/privacy-policy
API Documentation: https://www.smsgatewayhub.com/free-sms-gateway-developer-api

Service provider: ForthFocus SMS Gateway
Terms and Conditions: https://forthfocus.com/terms-and-conditions/
Privacy Policy: https://forthfocus.com/privacy-policy/
Website: https://forthfocus.com/

Service provider: Gupshup
Website: https://www.gupshup.ai/
Terms and Conditions: https://www.gupshup.ai/terms-and-conditions
Privacy Policy: https://www.gupshup.ai/privacy-policy

Service provider: Fast2SMS
Website: https://www.fast2sms.com/
Terms and Conditions: https://www.fast2sms.com/terms-conditions
API Documentation: https://docs.fast2sms.com/

Service provider: 2Factor
Website: https://2factor.in/
Terms and Privacy: https://2factor.in/v3/tos
API Documentation: https://documenter.getpostman.com/view/301893/TWDamFGh

Service provider: MSG91
Website: https://msg91.com/
API Documentation: https://docs.msg91.com/
Dashboard: https://control.msg91.com/

= Compatibility =

The plugin works on both classic (shortcode-based) and block-based WooCommerce checkout, but the depth of integration differs:

* **Classic checkout** (`[woocommerce_checkout]` shortcode, used by Storefront, Astra, GeneratePress, Flatsome, URNA, Dokan-style themes, and any site with the WC checkout shortcode) — full integration. The OTP gate renders above the checkout form, the billing phone field is automatically locked to the verified number once verification is complete, and the user uses a "Change phone" link if they need to switch numbers.
* **Block-based checkout** (the new WC Checkout Block, used by Twenty Twenty-Five and other FSE themes by default) — basic integration. The OTP gate renders above the checkout block. The billing phone field inside the React-managed block cannot be locked from outside the block API, so the user is technically able to edit it after verifying. However, the server-side Store API guard rejects order placement if the submitted phone does not match the verified number — so the verification is still enforced, just at submission rather than at the field level. Tightening this into a native checkout-block extension is on the v1.1 roadmap.

For the strictest UX and behavior (auto-locked phone field, no possibility of submitting a mismatched number), use the classic checkout. To switch from block-based to classic on a Twenty Twenty-Five site, edit the Checkout page and replace the "Checkout" block with the `[woocommerce_checkout]` shortcode.

= Setup wizard =

A 3-step setup wizard guides you through:

1. Gateway selection and credentials (provider-specific credentials such as API key, Fast2SMS Authorization Key, 2Factor API Key, or Gupshup User ID/Password, sender ID/mask, route/channel where applicable, and DLT details where applicable)
2. Notification templates (DLT ID + approved message body for each order event you want to notify on)
3. OTP verification (which flows to enable, and the OTP message templates)

You can re-run the wizard from the Dashboard at any time, or skip it entirely if you prefer to configure manually.

== Installation ==

1. Upload the plugin folder to `/wp-content/plugins/`, or install it through the WordPress Plugins screen.
2. Activate the plugin.
3. Go to **ForthFocus SMS → Dashboard** in the WordPress admin.
4. Click **Run Setup Wizard** and follow the 3-step flow.

== Frequently Asked Questions ==

= Does this work without WooCommerce? =

The plugin requires WooCommerce. The OTP module also works on the standard WordPress login (wp-login.php) regardless.

= What gateways are supported? =

The plugin currently supports SMSGatewayHub, ForthFocus SMS Gateway, Gupshup, Fast2SMS, 2Factor, and MSG91. Adapters for Twilio and Kaleyra are planned for upcoming releases. The plugin's architecture is provider-agnostic — once a new adapter is added, the same templates and OTP flows continue to work.

= Will this work with my existing SMS provider? =

Right now the plugin sends through SMSGatewayHub, ForthFocus SMS Gateway, Gupshup, Fast2SMS, 2Factor, or MSG91. If you have an account with a different provider (Twilio, Kaleyra, etc.), you have three options: (1) use one of the currently supported gateways, (2) wait for a future provider adapter, or (3) hook into our `ffsms_before_send` filter and dispatch to your own provider in custom code while still benefiting from our DLT enforcement, logging, and OTP machinery.

= I am getting error 0024 when sending — what does it mean? =

0024 means your message body does not match the DLT-approved template registered with your operator. The most common causes are: extra text outside what was registered, wrong punctuation, malformed variable syntax (use `{curly_braces}` not `{round_braces}` or `{#var#}`), or emojis that the operator does not accept. The plugin's live linter catches most of these as you type.

= Does this support OTP only for COD orders? =

Per-payment-method OTP gating is planned for the next release. In the current version, OTP at the cart page applies to all payment methods. You can also wire it via custom code using the `ffsms_before_send` filter.

= How does the plugin handle DND (Do Not Disturb) numbers? =

DND handling is enforced at the operator side, not in the plugin. If you send to a DND-registered number using a template approved under the "Promotional" or "Explicit" category, the operator returns code 640-659 and the plugin marks the send as failed with the operator's reason. To deliver to DND numbers, get your template approved under the "Service" or "Implicit" category on the DLT portal.

= Can I send promotional SMS / campaigns / cart abandonment? =

Not in the free version. Those features are planned for the upcoming Pro tier.

= Where are OTP codes stored? =

OTP codes are stored in a dedicated `wp_ffsms_otp` database table, hashed with a per-phone salt and a per-site secret. Plaintext OTP values never persist. Codes have a configurable expiry (default 10 minutes) and a resend cooldown (default 30 seconds). The plugin enforces a max-attempts lockout to prevent brute-forcing.

= Will this work with international phone numbers? =

Phone numbers are normalized to E.164-style digits (country code + national number, no `+`). The default country code is configurable in Gateway settings. If your DLT registration covers Indian numbers only, sends to non-Indian numbers may be rejected by the operator — that is a DLT/operator policy, not a plugin restriction.

= Does the plugin work with the new WooCommerce Checkout Block? =

Partially, with a documented limitation. The OTP verification gate renders above the Checkout Block on Twenty Twenty-Five and other FSE themes that use it, and the server-side guard rejects orders where the submitted phone does not match the verified number. However, because the Checkout Block's phone input is managed by React inside the block, it cannot be auto-locked from outside the block API — the user can technically type a different number after verifying. Verification is still enforced (at order submission), but the experience is tighter on the classic shortcode-based checkout where the phone field can be locked at the field level. Native checkout-block integration is on the v1.1 roadmap. For the strictest behavior in the meantime, use the classic checkout shortcode.



The plugin declares compatibility with WooCommerce's High-Performance Order Storage (HPOS) and the Cart/Checkout Block APIs. All order-related operations use the HPOS-safe `WC_Order` API rather than legacy postmeta queries.

= How do I extend the plugin? =

Three filters and one action are exposed:

* `apply_filters('ffsms_render_message', $message, $template_id, $vars, $opts)` — modify the rendered body before send
* `apply_filters('ffsms_before_send', $params)` — modify dispatch parameters (phone, message, dlt_template_id) just before the gateway call. Returning empty cancels the send.
* `do_action('ffsms_after_send', $result, $phone, $message, $template_id)` — observer hook fired after the gateway responds
* `do_action('ffsms_dispatch_sms', $phone, $template_id, $vars)` — programmatic send: routes through Sender::send_template with full DLT enforcement, logging, and dedupe. Note: this hook is intentionally named `ffsms_dispatch_sms` (not `ffsms_send_sms`) to avoid colliding with the plugin's internal Action Scheduler queue hook.

= How do I report a security vulnerability? =

Please email security details to support@forthfocus.com (or open a private message via forthfocus.com) instead of posting to the public .org support forum or opening a public GitHub issue. We aim to acknowledge reports within 2 business days and ship a coordinated fix before any public disclosure. Include a clear reproduction, plugin version, WordPress version, WooCommerce version, and any logs that demonstrate the issue.

= Is this plugin DLT compliant? =

Yes. India's Telecom Regulatory Authority (TRAI) requires all commercial SMS to be sent under DLT (Distributed Ledger Technology) registration, with a registered Header (sender ID), an approved Entity ID, and an approved DLT Template ID for every message body. The plugin enforces this end-to-end: every template requires a DLT Template ID before it can be enabled, the placeholder syntax is validated against DLT-style variable rules, and the gateway request sends the required DLT details for gateways that require API-level DLT pass-through. For Gupshup, the sender ID, entity, and templates must be mapped on the Gupshup account. Templates without a DLT ID are blocked from sending.

= Can I use this for COD (Cash on Delivery) order verification? =

Yes — the cart-page and checkout-page OTP gates are designed exactly for this. Verifying the customer's phone number before "Place Order" cuts down on fake / abandoned COD orders that would otherwise generate failed deliveries and return-shipping costs. Per-payment-method gating (e.g. require OTP only for COD orders, skip for prepaid) is on the roadmap.

= What is the difference between transactional and promotional SMS in India? =

Transactional SMS (channel 2 in our gateway settings) is for order confirmations, OTPs, delivery updates, and other essential service messages. It is delivered 24/7 even to DND-registered numbers. Promotional SMS (channel 1) is for marketing campaigns and offers — it is restricted to 9am–9pm and is blocked for DND numbers. The plugin defaults to transactional channel for all order and OTP templates because that is the appropriate category for the messages it sends. Make sure your DLT template registration matches the channel you select.

= Can I use my existing SMSGatewayHub account? =

Yes. Select SMSGatewayHub in the setup wizard, then paste your SMSGatewayHub API key, sender ID, Entity ID, and the DLT Template IDs you've already registered. There's nothing to migrate — the plugin works on top of your existing account and SMS credit balance. The Dashboard shows your live SMS balance via the gateway's GetBalance API.

= Can I use my Gupshup Enterprise SMS account? =

Yes. Select Gupshup in the setup wizard, then enter the Gupshup API User ID, API Password, and approved sender ID / mask provided by Gupshup. These API credentials may be different from your portal login credentials. The sender ID, entity, and templates must be approved and mapped on your Gupshup account. Per-template DLT Template IDs are still maintained inside the plugin for template readiness. The plugin uses Gupshup's normal SendMessage API for both order notifications and OTP delivery; OTP generation and verification remain inside the plugin.

= Can I use my existing Fast2SMS account? =

Yes. Select Fast2SMS in the setup wizard, then enter your Fast2SMS Authorization Key, DLT-approved sender ID, and Entity ID. The plugin uses Fast2SMS DLT Manual API with the fixed `dlt_manual` route, so your per-template DLT Template IDs remain configured inside the plugin. OTP generation and verification remain inside the plugin; Fast2SMS is used only for SMS delivery and wallet balance checks.

= Can I use my existing 2Factor account? =

Yes. Select 2Factor in the setup wizard, then enter your 2Factor API Key, DLT-approved Sender ID/Header, and PE ID. The plugin sends order notifications and plugin-generated OTP messages through 2Factor's Transactional SMS API using each template's DLT Template ID. OTP generation and verification remain entirely inside the plugin; 2Factor's OTP APIs are not used.

= Can I use my existing MSG91 account? =

Yes. Select MSG91 in the setup wizard, then enter your MSG91 Auth Key and DLT-approved Sender ID/Header. Create an approved template/flow inside your MSG91 account for each plugin notification type, then paste the matching MSG91 Flow ID into the plugin template settings. OTP generation and verification remain inside the plugin; MSG91 is used only for SMS delivery through the SMS Flow API. MSG91 does not currently provide a wallet balance API, so balance must be checked from the MSG91 dashboard.

= How much does SMS cost in India? =

SMS is billed per segment, not per message. Indian transactional SMS pricing typically ranges from ₹0.10 to ₹0.30 per segment depending on your gateway provider and volume tier. A "segment" is 160 characters for plain English (GSM-7 encoding) or 70 characters for Unicode (Kannada, Hindi, Marathi, Tamil, etc.). Multi-segment messages count as multiple sends. The plugin shows a live segment counter in the template editor so you can see exactly how many segments each message will use before sending. Long DLT-registered templates with personalization variables can easily span 2–3 segments — worth checking before bulk sends.

== Screenshots ==

1. Dashboard with SMS balance/status, active gateway logo, status checklist, and quick actions
2. Gateway settings — credentials, master switches, and a "test an approved template" panel
3. Notification templates page — provider-mapped template management with live segment counter and variable linter
4. OTP configuration — module switches and per-flow OTP message templates
5. Logs page — filterable, searchable, with detail modal and CSV export
6. Setup wizard — 3-step flow for first-time configuration

== Changelog ==

= 1.0.7 =

Added:
* Added MSG91 as the sixth supported SMS gateway provider using the SMS Flow API.
* Added MSG91 Auth Key and Sender ID settings in Gateway settings and the setup wizard.
* Added per-template MSG91 Flow ID mapping for order notifications and OTP templates.
* Added the supplied MSG91 logo to the dashboard Active Gateway card with wide-logo sizing.
* Added MSG91-specific balance messaging with a dashboard link because MSG91 does not currently provide a wallet balance API.
* Added MSG91 delivery report and API-failed webhook URLs so plugin logs can update submitted MSG91 requests to delivered or failed after MSG91 reports final status.
* Added validation to block DLT Template IDs from being saved in the MSG91 Flow ID field.

Compatibility:
* OTP generation and verification remain inside the plugin. The MSG91 OTP APIs are not used.
* MSG91 DLT Template ID, PE ID, approved message content, and variables are managed inside each customer's MSG91 account and flow.
* Preserved existing gateway selection, credentials, templates, OTP flows, WooCommerce hooks, balance checks, and notification behaviour for SMSGatewayHub, ForthFocus SMS Gateway, Gupshup, Fast2SMS, and 2Factor users.

= 1.0.6 =

Added:
* Added 2Factor as the fifth supported SMS gateway provider using the Transactional SMS API.
* Added separate 2Factor API Key, Sender ID/Header, and PE ID settings in Gateway settings and the setup wizard.
* Added 2Factor Transactional SMS balance support over HTTPS.
* Added provider-aware 2Factor request metadata and credential redaction for diagnostics.
* Added the official 2Factor logo to the dashboard Active Gateway card with square-logo sizing.
* Expanded the eligible review request across wp-admin and replaced its mark with the supplied ForthFocus symbol artwork.
* Split Processing notifications into separate Online Payment and Cash on Delivery templates, each with its own message, enable switch, and DLT Template ID.

Fixed:
* Registered the WooCommerce Processing status listener so real online-payment and Cash on Delivery orders trigger the correct Processing notification.
* Prevented ordinary admin edits to existing orders from re-sending status notifications, while retaining a one-time fallback for newly created admin orders whose status or payment method is not yet available.
* Ensured the 1.0.6 settings migration also runs when the plugin is upgraded while deactivated, preserving the existing Order Processing template as Order Processing: Online Payment.
* Removed review-request state during uninstall.

Compatibility:
* OTP generation and verification remain inside the plugin. The 2Factor OTP Send and Verify APIs are not used.
* Preserved existing gateway selection, credentials, templates, OTP flows, and WooCommerce notification behaviour for SMSGatewayHub, ForthFocus SMS Gateway, Gupshup, and Fast2SMS users.
* Existing Order Processing template settings are migrated to Order Processing: Online Payment. The new Cash on Delivery template starts disabled until configured with its own DLT-approved message and Template ID.

= 1.0.5 =

Added:
* Added Fast2SMS as a supported SMS gateway provider using the DLT Manual API.
* Added Fast2SMS Authorization Key, Sender ID, and DLT Entity ID fields in Gateway settings and the setup wizard.
* Added Fast2SMS wallet balance support.
* Added provider-aware Fast2SMS request metadata in logs without storing secrets, full phone numbers, or message bodies.

Compatibility:
* Preserved existing gateway selection and credentials for current SMSGatewayHub, ForthFocus SMS Gateway, and Gupshup users.

= 1.0.4 =

Fixed:
* Fixed provider logo sizing in the dashboard Active Gateway card.
* Fixed fresh setup so no SMS gateway is auto-selected before the user chooses a provider.

Compatibility:
* Preserved existing gateway selection and credentials for current SMSGatewayHub, ForthFocus SMS Gateway, and Gupshup users.

= 1.0.3 =

Added:
* Added Gupshup as a supported SMS gateway provider with provider-mapped DLT support.
* Added Gupshup balance check support.
* Added Gupshup API credential guidance because API credentials may differ from portal login credentials.
* Added provider logos to the dashboard Active Gateway card.

Improved:
* Improved gateway setup flow for multiple providers.
* Improved diagnostics with safer redaction and clearer provider request metadata.
* Improved admin asset cache-busting to avoid stale CSS/JS after updates.
* Improved template test dropdown so only enabled templates with both a valid message body and DLT Template ID are shown.
* Improved setup wizard notice behavior and mobile layout.
* Improved DLT Template ID validation wording and handling.
* Simplified gateway selection helper text for better scalability across multiple providers.

Fixed:
* Fixed duplicate SMS risk by adding atomic send-attempt claiming for concurrent hooks, scheduled actions, and overlapping workers.
* Fixed cases where partially configured templates could appear in the template test dropdown.
* Fixed Gupshup balance display when the provider returns plain-text balance responses.

Compatibility:
* Preserved backward compatibility for existing SMSGatewayHub and ForthFocus SMS Gateway users.

= 1.0.2 =
* Added ForthFocus SMS Gateway as a separate provider with its own provider path.
* Added gateway selection to the setup wizard and Gateway settings page.
* Made SMS sending, balance checks, and diagnostics provider-aware.
* Improved diagnostics with gateway labels, response summaries, collapsible developer traces, and a more readable responsive table layout.
* Fixed skip_dedupe so OTP and template-test sends can bypass Sender-level dedupe when intended.
* Marked DLT Entity ID as a required gateway readiness field.
* Added server-side validation so individual templates cannot be saved without a DLT Template ID.
* Improved OTP settings UX so child OTP options are inactive unless the master OTP module is enabled, without wiping saved selections.
* Added ffsms_http_audit cleanup to uninstall.
* Added clearer WordPress Playground guidance for live SMS tests where external API requests may behave differently from hosted WordPress.

= 1.0.1 =
* Confirmed compatibility with WordPress 7.0.
* Added WordPress Playground preview support.
* Improved Playground testing guidance for temporary browser-based environments.
* Improved SMSGatewayHub-compatible request headers.

= 1.0.0 =
* First public release.

== Upgrade Notice ==

= 1.0.7 =
Adds MSG91 SMS Flow API support with Auth Key/Sender ID settings, per-template Flow IDs, plugin-managed OTP delivery through MSG91 flows, delivery-report/API-failed webhook status updates, MSG91 dashboard balance guidance, and the supplied MSG91 provider logo.

= 1.0.6 =
Adds 2Factor Transactional SMS support, HTTPS balance checks, separate provider credentials, provider-safe diagnostics, and separate Processing templates for online-payment and Cash on Delivery orders.

= 1.0.5 =
Adds Fast2SMS DLT Manual API support, Fast2SMS wallet balance checks, and provider-specific Fast2SMS settings while preserving existing provider credentials.

= 1.0.4 =
Fixes dashboard provider logo sizing and keeps fresh setup neutral until a gateway provider is selected.

= 1.0.3 =
Adds Gupshup gateway support, provider logos, stronger duplicate-send protection, improved diagnostics, Gupshup balance handling, and setup UI refinements.

= 1.0.2 =
Adds ForthFocus SMS Gateway support, provider-aware routing, diagnostics improvements, DLT Template ID validation, and OTP settings UX fixes while preserving existing SMSGatewayHub settings.

= 1.0.1 =
Compatibility update for WordPress 7.0 with WordPress Playground preview support.

= 1.0.0 =
First public release.

== Trademark Notice ==

ForthFocus is a trademark of FORTHFOCUS GROUP.

WordPress, WooCommerce, and Woo are trademarks of their respective owners. This plugin is not affiliated with, endorsed by, sponsored by, or officially associated with the WordPress Foundation, Automattic Inc., WooCommerce, or Woo.

SMSGatewayHub, MSG91, Gupshup, Fast2SMS, 2Factor, Twilio, and Kaleyra are trademarks or brands of their respective owners. This plugin currently integrates with SMSGatewayHub, ForthFocus SMS Gateway, Gupshup, Fast2SMS, 2Factor, and MSG91. Twilio and Kaleyra are referenced only as examples of additional providers planned for future releases. The plugin is not officially endorsed by or affiliated with third-party gateway brands unless stated through a formal partnership.
