Sahand – Unpaid Order SMS for WooCommerce

Description

Bring customers back to unpaid WooCommerce orders worldwide with SMS and email. Choose SMS, email, or both independently for customers and shop managers. Connect Twilio, any HTTP SMS API, the WP SMS plugin, another plugin through a developer hook, or Kavenegar for Iran. Email uses WordPress wp_mail, so it works with your SMTP or mail plugin.

How it works

  • X minutes or hours after an order is placed (you choose), if it is still unpaid, the customer gets the SMS and/or email you enabled. If the customer was active on the order in the last few minutes (for example just came back from the bank page to retry), the message waits a bit longer.
  • Optionally also when an order becomes Failed or Cancelled (after a short wait you choose, so a customer who retries right away is not bothered).
  • Each message can contain a personal one-time discount code (percent or fixed amount, optional free shipping, valid for the hours you choose).
  • And a one-click link back to checkout: if the order can still be paid, the customer lands on its payment page with the discount applied; if it was cancelled, the cart is rebuilt with the same products and variations, the discount and the billing details already filled in.
  • Shop managers (one or more phone numbers and email addresses) can receive SMS and/or email to follow up.
  • Each order is processed at most once for its enabled channels, and not at all if the customer has paid another order in the meantime.
  • A log of every message, test buttons, and a tool to run it for a single order.

SMS gateways and email

  • Twilio: send from a phone number or Messaging Service SID.
  • Custom HTTP API: connect providers such as MeliPayamak, FarazSMS/IPPanel, SMS.ir, Vonage and Plivo using their API URL, GET/POST, form/JSON parameters, optional headers and success text.
  • WP SMS plugin: use its configured provider when wp_sms_send is available.
  • Another plugin (developer hook): delegate to sahand_uos_send_sms.
  • Email: HTML messages wrapped in WooCommerce styling, sent through wp_mail with a clickable checkout link.
  • Kavenegar: pattern (verify/lookup) messages, which Iranian operators require for service SMS, and plain messages.
  • Test mode: SMS only goes to the log (including pattern previews). Enabled email channels still send real email.
  • Developers can add gateways with the sahand_uos_sms_gateways filter.

International phone numbers support + and 00 prefixes, Persian/Arabic digits, and a configurable default country code (98). New SMS gateways use E.164; Kavenegar retains Iranian mobile formatting.

Translation ready, with Persian translation sources included in the project. Compatible with WooCommerce High-Performance Order Storage (HPOS).

External services

The optional “Keep messages on time on cached sites” feature is enabled by default. Its browser tick only calls your own site’s WordPress AJAX endpoint and sends no personal data; its request contains only the action name. It does not contact an external service. It checks at most once every 5 minutes per browser, with a site-wide 60-second lock and up to 5 due rescue checks per request.

This plugin connects to the Kavenegar SMS API (https://api.kavenegar.com), an Iranian SMS gateway, to send the text messages. It is used only when you choose Kavenegar as the gateway and enter your own Kavenegar API key; in Test mode no SMS is sent.

What is sent, and when:

  • When an unpaid order is due for a reminder (after the delay you set, or when you press a test button or run the tool for one order): the recipient’s mobile number (the customer’s billing phone, or the shop manager numbers you entered), and the message content, which is either your template name plus its tokens (order number, discount code, the short code of the return link, the customer’s first name, the order total, etc.) or the plain message text with your sender line number, if you set one.
  • Your Kavenegar API key is part of the request URL, as required by the Kavenegar API.
  • The Kavenegar gateway sends no other data or requests to other services.

Service provider: Kavenegar (https://kavenegar.com). API documentation: https://kavenegar.com/rest.html
Terms of service: Kavenegar’s terms of use are shown and accepted when you create your Kavenegar account: https://panel.kavenegar.com/Client/Membership/Register
Privacy policy: Kavenegar does not publish a separate privacy policy page; their terms and contact page are at https://kavenegar.com/support/about

Twilio

When Twilio is selected and configured, the plugin sends the recipient phone number and message text to https://api.twilio.com when an unpaid order is due, or when an administrator sends a test or runs an order manually. Requests include your Account SID, Auth Token and From number or Messaging Service SID. Message text includes only the placeholders you choose.
Terms: https://www.twilio.com/en-us/legal/tos
Privacy: https://www.twilio.com/en-us/legal/privacy

Custom HTTP API

Requests are sent only to the public HTTP/HTTPS URL the administrator enters, when that gateway is selected and a reminder, test or manual send runs. Requests contain the configured parameters (including phone number and message text where placeholders are used) and headers, which may include API credentials. Redirects are not followed. Review your chosen provider’s terms and privacy policy before configuring it. Requests occur only for enabled SMS deliveries.

WP SMS, developer hooks and email

WP SMS and the developer hook pass the phone number and message text to the installed plugin you select or implement. The hook also receives the order ID and recipient role. That integration controls its external service usage. Email passes the recipient address, subject and message body to wp_mail, using your site’s mail transport or configured SMTP/mail plugin. No external email API is built into this plugin.

Hooks

  • sahand_uos_should_rescue (bool, WC_Order, reason): return false to skip an order.
  • sahand_uos_message_vars (array, WC_Order, coupon): add or change placeholders.
  • sahand_uos_rescued action (WC_Order, vars, reason): after messages were sent.
  • sahand_uos_send_sms (null, to, text, context): handle SMS through another plugin; return true or an array with ok for success.
  • sahand_uos_sms_gateways (array id => class): register gateways extending Sahand_UOS_Gateway.

Screenshots

Installation

  1. Upload the plugin and activate it (WooCommerce must be active).
  2. Go to WooCommerce > Unpaid Order SMS.
  3. Choose your SMS gateway and enter its credentials, or enable email. Set the default country code and each recipient’s channels. Existing SMS switches are preserved on upgrade; email starts disabled.
  4. Customize customer and manager messages using the same placeholders for SMS, email subjects and email bodies. Kavenegar users can also set approved patterns and tokens.
  5. Enter a test phone/email and use the test button for the recipient. Review the log, then tick “Enable”.

Example Kavenegar template for the customer (tokens: token = {order_id}, token2 = {coupon}, token3 = {link_code}, token10 = {first_name}):

%token10 عزیز، سفارش %token شما پرداخت نشد. کد تخفیف شما: %token2
تکمیل خرید: example.com/?suos=%token3

FAQ

How do I connect any HTTP SMS provider?

Choose “Custom HTTP API (any provider)” and copy the endpoint and authentication details from your provider’s API documentation. Enter one key=value parameter per line, for example:

apikey=YOUR_KEY
to={to}
text={message}

{to} is E.164 (for example +989120000000); {to_local} is the national form with a leading 0, based on your default country code. Parameters are substituted after parsing, then URL-encoded for GET/form or JSON-encoded without URL encoding for JSON. Optional headers use one Name: value per line. HTTP 2xx counts as success; set “Success text” if your provider also requires a specific response marker. The form supports flat key/value APIs; use the developer hook for APIs requiring nested payloads, signatures or another protocol.

How do I connect another SMS plugin with a hook?

Select “Another plugin (developer hook)”. Add the following five-line example to your integration plugin, replacing my_sms_plugin_send with its actual send function and adapting its success result:

add_filter( 'sahand_uos_send_sms', function ( $result, $to, $text, $context ) {
    if ( ! function_exists( 'my_sms_plugin_send' ) ) { return $result; }
    $sent = my_sms_plugin_send( $to, $text );
    return true === $sent;
}, 10, 4 );

The context contains order_id and recipient (customer/admin; test-customer/test-admin with order_id 0 for tests). Return true or an array with a truthy ok key for success. A null result means no plugin handled the filter. Only Kavenegar sends pre-approved patterns; the test gateway can preview them without sending.

Can I send only email?

Yes. Disable SMS and enable email independently for each recipient. Customer email uses the order’s billing email and is skipped when invalid. Manager addresses are entered separately. Email uses the WooCommerce wrapper and wp_mail, so your SMTP/mail plugin handles delivery. A successful log means the transport accepted the message; it does not guarantee inbox delivery.

My site uses page cache

Leave “Keep messages on time on cached sites” enabled in WooCommerce > Unpaid Order SMS, then clear your page cache so cached pages include the small browser tick. It runs due rescue checks during visits even when a full-page cache serves the page. Visitors must allow JavaScript and local storage; no visits means no browser ticks. For reliable timing even without visitors, configure a real server cron to call wp-cron.php every 5 minutes, then add define('DISABLE_WP_CRON', true); to wp-config.php. The plugin shows a notice with your site’s cron example if a check runs more than 15 minutes late.

Why are spaces in some tokens replaced with “_”?

Kavenegar accepts only one word in token, token2 and token3 (no spaces or half-spaces; it answers error 431). Put names and amounts in token10 or token20, which may contain spaces.

What if my delay is longer than WooCommerce’s “Hold stock” time?

The order is cancelled first; the message is still sent, and the link rebuilds the cart.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“Sahand – Unpaid Order SMS for WooCommerce” is open source software. The following people have contributed to this plugin.

Contributors

Changelog

1.2.0

  • Add independent customer and manager SMS/email channels with backward-compatible SMS setting migration.
  • Add Twilio, configurable HTTP APIs, WP SMS and a developer send hook; retain Kavenegar and log-only testing.
  • Add international phone normalization and a default country code, plus national-number placeholders for HTTP APIs.
  • Add WooCommerce-wrapped HTML email through wp_mail, email templates and multi-channel tests and logs.
  • Simplify settings with gateway-specific fields and update Persian translations and service disclosures.

1.1.0

  • Add the default-on “Keep messages on time on cached sites” setting and a lightweight browser tick that runs already-due rescue checks on cached sites.
  • Track late rescue checks without changing scheduled action arguments, and show shop managers a per-user dismissible notice with server cron guidance.
  • Document page-cache setup and the tick’s local-only, no-personal-data request.

1.0.0

  • First release.