=== GoWakit OTP Authentication & Notifications for WooCommerce ===
Contributors: gowakit
Tags: whatsapp, woocommerce, otp, order notifications, login
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 2.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Connect your site to Wakit in one click, then send WhatsApp order updates and let customers sign in with a code.

== Description ==

Press **Connect to Wakit** and a window opens on Wakit. Put in your mobile
number, confirm the code that arrives on WhatsApp — an account is created there
and then if you do not have one — and choose which workspace pays for messages
and which approved template this site may send on. Approve, and the window
closes on your WordPress screen with the workspace, the balance and the template
already filled in.

Then:

* **Templates.** See every template you can send on, write a new one, and watch
  it move from review to approved without leaving WordPress.
* **Order notifications.** When an order moves to Processing, Completed or any
  other status, the customer gets a WhatsApp message. Each status picks its own
  template and its own variables, built from merge tags like `{full_name}` and
  `{order_number}`.
* **Sign in with WhatsApp.** A `[wakit_otp_login]` form takes a mobile number,
  sends a code, and signs the matching account in. It also appears under the
  usual login box on `wp-login.php` when wp-admin sign-in is switched on.
* **Sign in to wp-admin with a mobile number.** Switch on wp-admin sign-in and
  administrators and shop managers can use the same form: number, code from
  WhatsApp, straight to the screen they were asking for. Each of those accounts
  puts its number on its own profile, under **Sign in with WhatsApp**.
* **Your WhatsApp numbers.** The dashboard shows the Cloud API numbers on your
  Wakit workspace, which one your customers see the message arrive from, and
  whether it can send today. Connect a new one on Wakit — the button gets you
  there already signed in — and it appears here on the next look.
* **Send log.** Every attempt, successful or not, with what Meta said about
  the failures.

= Two kinds of account, and why the screens differ =

**You have your own WhatsApp Business number.** You own that account, so every
template on it is yours, and a new one goes straight to WhatsApp for approval.

**You are on Wakit's shared number.** You send from a number other businesses
also send from, so you use the templates Wakit has assigned to you — never
anybody else's, and nobody else ever sees yours. A template you write is read by
Wakit before WhatsApp is shown it: on a shared number, WhatsApp holds everyone
to what any one of them sends.

= What the site can and cannot do =

This site can only send templates the workspace already has. Naming anything
else is refused by Wakit, not by the plugin — so a compromised WordPress install
cannot invent a message to send, and a plugin added here never widens what may
go out from a workspace.

The API key is swapped for on the server, never travels through a browser, and
is stored encrypted with a key that lives in `wp-config.php`. A database dump on
its own is not a working credential.

== External services ==

This plugin connects your site to Wakit (https://wakit.in), which is the service
that actually delivers the WhatsApp messages. Without a Wakit account the plugin
cannot send anything, so using this plugin means using that service.

Everything below is sent from your server to `https://wakit.in/api/v1` over
HTTPS, signed with the API key this site was given when you connected it.

* **Connecting the site.** Pressing "Connect to Wakit" opens
  `https://wakit.in/connect/authorize` in a window and gives it this site's
  wp-admin address to come back to. When you approve there, the one-time code
  that comes back is exchanged at `/connect/exchange` for an API key. Nothing
  about your WordPress users is part of this step.
* **Sending a WhatsApp message.** When an order reaches a status you have
  switched on, the plugin posts to `/messages/template`: the customer's mobile
  number in international format, the name of the approved template to send, and
  the values you mapped into that template's variables — usually the customer's
  name and the order's number, total and status. A test send does the same with
  the number you type in.
* **Signing in with a code.** The sign-in form posts the mobile number typed
  into it to `/otp/send`, then that send's id together with the code the visitor
  typed to `/otp/verify`.
* **Reading your account.** The admin screens fetch `/account`, `/connect/me`,
  `/numbers` and `/templates` for your wallet balance, the WhatsApp numbers on
  your workspace and the templates you may send on. Writing a template posts its
  name, language, category and text to `/templates`. Opening Wakit from a button
  in wp-admin asks `/connect/sso` for a one-time signed-in link.

Nothing is sent anywhere until you connect the site, and no customer data is
sent until you switch on a feature that needs it.

* **Tracked button links.** When a template's link button is
  `https://2xurl.com/{{1}}`, each send posts the destination (the order page,
  the cart link or the campaign link — never the customer's number) to
  `/short-links`. Wakit makes that recipient's own short link on 2xurl
  (https://2xurl.com), which counts the clicks; the log reads the counts back
  from `/short-links`. A customer who taps the button passes through 2xurl.com
  on the way to your page.
* **Your own 2xurl account (optional).** If you paste your own 2xurl.com API
  key on the Short links screen, this site sends each link's destination and
  title straight to the 2xurl API (https://2xurl.com/api/v1) with that key,
  instead of through Wakit, and reads click counts back from it. The key is
  stored encrypted on this site and is never sent to Wakit.

Wakit's terms of service: https://wakit.in/terms
Wakit's privacy policy: https://wakit.in/privacy
2xurl's terms of service: https://2xurl.com/terms
2xurl's privacy policy: https://2xurl.com/privacy

== Installation ==

1. Upload the `gowakit-otp-authentication-notifications-for-woocommerce` folder to
   `/wp-content/plugins/`, or install the zip from
   **Plugins → Add New → Upload**.
2. Activate it.
3. Go to **Wakit** and press **Connect to Wakit**.

Your site must be on HTTPS. Wakit refuses to send the connect code back over
plain http, where it would travel in clear text — the one exception is a site
running on `localhost` for development.

To point at a self-hosted Wakit, define this in `wp-config.php` before the
plugin loads:

`define( 'WAKIT_BASE_URL', 'https://wakit.example.com' );`

== Frequently Asked Questions ==

= Nothing arrives, but the log says "Sent". =

"Sent" means Meta accepted the message. Delivery after that depends on the
number having WhatsApp and not having blocked the sender. Open the Wakit
dashboard to follow a specific message.

= A send fails with "template name does not exist". =

The template was approved on a different WhatsApp number than the one the
workspace now sends from. Reconnect from the Wakit screen and pick it again.

= Sends fail after I changed the number of variables. =

Meta counts the variables and rejects a mismatch. The template decides how many
there are — fill in exactly that many rows and leave the rest blank.

= Can an administrator sign in to wp-admin with a code? =

Yes, but two things have to be true, and neither happens on its own. Tick
**wp-admin sign-in** under **Wakit → OTP sign-in**, and put the mobile number on
the account itself — **Users → Profile → Sign in with WhatsApp**. An
administrator usually has no billing address, so without that field there is no
number to match and the form will say no account uses it.

It is off by default for a reason. A phone number that reaches an account which
can edit the whole site is a much bigger thing to hand over than one that
reaches a customer account: whoever holds that SIM, or can have it reissued,
holds the site.

= I signed in with a code and landed on the shop's account page, not wp-admin. =

Fixed in 1.1.0. The form now carries the page you were sent to the login screen
from, and anyone who can edit posts or orders is taken to wp-admin by default.
The destination is checked on the server, so a link cannot use the login form to
bounce you off to another site.

= Two accounts have the same mobile number. =

Only one can keep it. The profile field refuses a number that already signs in
another account, and names the account holding it — the sign-in form has to be
able to say which account a code belongs to.

= A customer's number keeps changing back after checkout. =

A number typed on the profile screen is fixed to the account and a later
checkout no longer moves it. A number that was only ever copied from the billing
address still follows the billing address; the profile screen says which of the
two you are looking at. Clear the field to go back to following billing.

= Someone could spam the sign-in form and spend my balance. =

An unknown number is turned away before anything is sent, and each number and
each address is capped per hour. Switching on "create an account for a number
that does not have one" removes the first of those protections, which is why it
is off by default.

= I deleted the plugin. Is the key gone? =

The copy stored here is deleted on uninstall. The key itself stays live on
Wakit until you revoke it there, under API keys.

= Where did my template go? =

Check **Templates**. "Waiting for Wakit" means it is in their review queue;
"With WhatsApp" means it has been passed on and they are reading it. A refusal
from either shows the reason on the row.

= I wrote "order_update" but the list shows something longer. =

On Wakit's shared number a name is claimed once for everyone, so your account
name goes in front of yours. Nobody else can then take it, and you can tell your
templates apart from the rest at a glance.

== Screenshots ==

1. The Wakit dashboard: wallet balance, the WhatsApp number your messages leave from, and the last few sends.
2. Connecting the site — mobile number, WhatsApp code, workspace and template, in one window.
3. Order notifications: one WooCommerce status at a time, each with its own template and variables.
4. Templates, from "waiting for Wakit" through "with WhatsApp" to approved.
5. Sign in with WhatsApp, under the usual login box on wp-login.php.
6. The send log, with what Meta said about anything that failed.

== Changelog ==

= 2.0.0 =
* Short links screen: every tracked link the workspace has, with clicks and
  unique visitors, search, and a filter for links made by hand vs. links in
  messages. Make a new short link and copy it in one click. Links made here
  count toward the plan's monthly short-link allowance (shown on the screen
  with what is left); the per-customer links in order messages and campaigns
  never do.
* Order notifications: each status row on the dashboard gets a "Button link"
  when its template has a link to fill. A tracked 2xurl.com button opens the
  URL set there (tags allowed, the order page by default). A button on the
  shop's own URL ending in {{1}} now gets its tail filled — the Button link,
  or the order id — instead of being refused by WhatsApp; a send whose button
  would come out empty is stopped and noted on the order.
* Your own 2xurl account: paste a 2xurl.com API key on the Short links screen
  and every link — by hand or in messages — is made on that account straight
  from this site (never through Wakit), on its own short domain if it has
  one, with no Wakit allowance. Switching back keeps the click counts of
  links sent before.
* Fixed: the dashboard suggested the wrong template for some statuses —
  "Order placed" got gowakit_order_cancelled, "Completed" got
  gowakit_delivery_delayed, "Failed" got gowakit_delivery_failed. Each status
  now has its own shelf template by name; word matching is only the fallback.
* Fixed: cart reminders on a template that takes the cart link in its text
  were refused by WhatsApp (a text variable may be 30 characters; the cart
  link is about 70). The cart and stop links now go out as short links.
* Fixed: a full refund sent "Refund issued" and "Refunded" both; the partial
  refund message now waits for refunds that leave something unrefunded.
* Templates screen lists only this plugin's templates: the shared number's
  WordPress shelf (gowakit_* and the OTP templates Wakit assigns) and
  templates written from this site. A workspace's other templates no longer
  crowd it.
* Template names show without the internal "gowakit_" prefix on every Wakit
  screen ("order_shipped"); stored and sent names are unchanged.
* Every checkbox on Wakit screens now has the same rounded box with a tick
  (some showed as a solid square). Logs: a clearer "Send log" bar with an
  on/off switch, and Messages / Sent / Failed / Success rate / Spent numbers.
* "When to Send WhatsApp Messages?": every status row shows its template's
  full button URL (prefix included) and a live example of the link a
  customer taps, following the template picked and the Button link typed.
* Dashboard: when messages leave from Wakit's shared number rather than the
  number shown (the shelf templates are approved there), the card says so.
* Fixed: with the send log switched off, form, cart and integration messages
  lost their "already sent" check and the same event could go out twice.
* New shelf templates (in WhatsApp review): cart reminders 1–3, a campaign
  template, booking confirmed / reminder / cancelled, course enrolled /
  completed, membership activated / renewed / expired / payment failed.
  Cart reminders and the learning, membership and booking events pick them
  up by themselves once approved, unless another template is chosen.
* Integrations: new "Booking reminder" event for WooCommerce Bookings, on the
  reminder it schedules before each booking.
* "Templates on my number": a shop with its own WhatsApp number copies every
  shelf template onto it — edit the wording, header, footer or button text
  first if it likes — and sends them all to WhatsApp in one go. Each copy
  takes over, from the shop's own number, once approved; until then the
  shelf one keeps sending. Opened from the dashboard note or Templates.
* Plan: a new tab with the Wakit plan, its price and renewal date, every
  allowance as used / allowed / left (numbers, team, contacts, broadcasts,
  flows, AI credits, short links) and what the plan includes; the dashboard
  shows the current plan under the WhatsApp connection.
* Tighter spacing under the top bar on every Wakit screen; the dashboard's
  three columns line up.
* Fixed: the "translation loading was triggered too early" notice on every
  request (cart recovery read its translated default before WordPress had
  loaded translations).
* New tags {order_id} and {order_key}.
* Links to Wakit screens open signed in through Wakit itself, so they follow
  wherever the dashboard is hosted.
* Tracked button links: a template whose link button is
  `https://2xurl.com/{{1}}` now gets every recipient their own short link —
  order page for order updates, cart link for cart reminders, the campaign's
  link for campaigns, the home page otherwise. Clicks show in the log (a new
  "Link clicks" column and on each message), and campaigns show how many
  people clicked.
* Templates: a "Button link" column says whether each template's link button
  is tracked; "Make tracked copy" submits a copy (`<name>_tl`) with the button
  rewritten to the tracked link, leaving the approved original sending until
  the copy is approved. The template view now lists its buttons.
* Campaigns: a "Button link" field for where a tracked button opens.
* Templates whose header is "{{1}} | ..." now get the shop's name filled in;
  before, WhatsApp refused those sends for the missing header value.
* Forms: separate customer and admin alert templates, picked automatically
  (gowakit_form_customer_ack / gowakit_form_admin_alert) once approved; the
  admin alert's button opens the form plugin's entries screen.
* Order links in the message body are now 2xurl links too.
* New since 1.4.2: WhatsApp two-step sign-in for wp-admin, abandoned cart
  reminders, campaigns with opt-outs, form submissions and plugin
  integrations, all sent through one queue that drops duplicates and retries
  network failures.
* Uninstall with WAKIT_REMOVE_ALL_DATA now also removes the cart,
  campaign and opt-out tables and the newer settings.

= 1.5.2 =
* Templates page redesign: summary cards (total, per-category, pending,
  rejected) from real counts, a segmented category control, a toolbar with
  search plus new status and language filters, and a polished table — full
  1px borders, tinted category badges, green/amber/red status badges and a
  styled empty state. Live search, preview and test-send work as before,
  and unused CSS left with the old design.
* The OTP sign-in pickers (dashboard and Settings) list every approved
  template, verification-shaped ones first: a shop with no verification
  template still gets to pick one and send the code through its variables.
  The code and the text fill the first two variables, so a two-variable
  template reads as written.

= 1.5.1 =
* Template lists no longer narrow by name: the API answer is already scoped
  to what the workspace may send on — its own rows on its own number, only
  the rows assigned to it on Wakit's shared number — so a shared shop's
  "<slug>_order_update" rows show up on Templates, Verification and every
  picker instead of hiding behind an All (0). An empty wordpress group falls
  back to the sendable list on an own-number site.
* The OTP sign-in pickers (dashboard and Settings) list every approved
  template, verification-shaped ones first: a shop with no verification
  template still gets to pick one and send the code through its variables.
  The code and the text fill the first two variables, so a two-variable
  template reads as written.

= 1.5.0 =
* Dashboard "When to Send WhatsApp Messages?" is now one row per order
  status instead of one row per template: tick a status and the order's
  message goes out on that template when the order reaches it. Ticking them
  all covers pending, processing, on-hold, completed, cancelled, refunded
  and failed. Previously several rows guessed the same status and only the
  last ticked one survived the save, so ticks silently went missing.
* Saving that card with any status ticked switches order notifications back
  on, and each status offers the template written for it. Variables stay
  owned by Settings → Order notifications and are carried through untouched.
* The card needs WooCommerce now: without it there are no orders, so it says
  so instead of rendering, and its save refuses rather than storing ticks
  that could never send.
* OTP sign-in and Admin WhatsApp Login stay in step with the Verification
  tab: switching them on also opens the Login/Signup event rows that sends
  actually check, so wp-login.php no longer reports "switched off" with both
  switches on. A site that never opened the Verification tab sends through
  the auto-detected template instead of failing on a blank choice.

= 1.4.2 =
* Connected sites: connecting now registers this domain, site name, WP user
  and webhook URL with the workspace, so the Wakit dashboard lists every
  connected WordPress site with who connected it. Disconnecting removes it.
* Webhook autofill: the Webhook URL fills itself with this site's own
  receiver on connect, and incoming delivery pushes (signed, timestamped)
  update the send log's status, error and cost by themselves.
* The update checker now reads Wakit's real answer (`/wordpress/update`).
* Order notifications: each WooCommerce status now offers the template whose
  name is that status's, instead of whichever template Meta's list happened to
  put first — "Pending payment" no longer opens on a template written for a
  different status. A choice already saved that reads as another status's
  template is kept in the list and replaced by Wakit's pick, with a line under
  the dropdown saying so.

= 1.4.1 =
* One-click updates: the Plugins screen now shows "a new version is
  available / update now" for GoWakit like it does for any wordpress.org
  plugin, and the Wakit dashboard's version card has an "Update to X"
  button plus "Check for updates". Releases are read from Wakit
  (`GET /api/v1/wordpress/latest`, cached 12 hours); for testing, define
  `WAKIT_LATEST_VERSION` (and optionally `WAKIT_LATEST_PACKAGE`) in
  `wp-config.php`.

= 1.4.0 =
* Templates is now AJAX: click any row to open a live panel with variable
  boxes, a WhatsApp-style chat preview that refills on every keystroke, and
  a Send Test button that sends without leaving the page. Search, category,
  language and Refresh also update the list and counts in place, no reload.
  The old page-reload View links stay as the no-JS fallback.

= 1.3.3 =
* New admin design: Dashboard, Settings, Templates, Logs and Help & Support
  are five menu pages — stat cards, category tabs with search, a template
  details panel with variables, filtered logs with a message details panel
  and CSV export, and an FAQ accordion.
* The simple OTP option (Settings → OTP Sign-in): pick the template from
  your wordpress group on Wakit, with its variables shown, plus code expiry
  and length. A new server endpoint, GET /api/v1/templates/groups, serves
  one group per connected app plus the category shelf.
* One verification template, six events: Login, Signup, Checkout, COD,
  Password Reset and Phone Verification share a single approved template and
  differ only in text. Checkout blocks the order until verified, COD
  confirms on the thank-you page.
* Dashboard shows the wallet balance; old submenu URLs redirect to their
  new pages instead of going blank.

= 1.3.2 =
* Templates has a Verification inner tab: one approved template
  (`OTP Code: {{code}}…for {{text}}…`) shared by 6 events — Login, Signup,
  Checkout, COD, Password Reset, Phone Verification. Each event only sets
  {{text}} as "{domain} {event}", with a per-site domain name, on/off switch,
  override text and live preview.
* All 6 events actually send through that template now: the code is minted
  locally (6 digits, hashed, single-use, 10 minutes, 5 guesses) and verified
  on the site. Login/Signup reuse the same sign-in and registration rules as
  before; Checkout blocks the order until the billing number is verified;
  COD confirms on the thank-you page; `[wakit_password_reset]` and
  `[wakit_phone_verify]` cover the last two.
* Dashboard shows a Wallet Balance card with a Recharge button, so the
  balance no longer lives only on the Settings tab. It reads every balance
  shape the API may return, and says why when it cannot load one.
* Old submenu URLs (Templates, Order notifications, OTP sign-in, Send log)
  now redirect to their tab even when the site is not connected. Previously
  they were only registered after connecting, so opening one on a
  disconnected site showed a blank admin page.

= 1.3.1 =
* The name now starts with GoWakit — "GoWakit OTP Authentication &
  Notifications for WooCommerce". Same plugin, same people behind it; a site
  that had the old plugin installed keeps its connection, its templates and
  its send log.

= 1.3.0 =
* The name now starts with Twakit — "Twakit OTP Authentication &
  Notifications for WooCommerce". Same plugin, same people behind it; a site
  that had the old plugin installed keeps its connection, its templates and
  its send log.

= 1.2.9 =
* The admin screen is now a tabbed layout — Dashboard, Settings, Templates,
  Logs, Help & Support — with a three-column card grid, so each feature has a
  screen of its own and one look across the plugin.
* The real Wakit logo and icon are bundled with the plugin rather than pulled
  from the site, and buttons, inputs, checkboxes and focus rings across every
  screen use the same modern set. Nothing about how connections, templates or
  sends work has changed.

= 1.2.8 =
* A mobile number can only become an account on a site that is open to new
  accounts. "Create an account for a number that does not have one" now does
  nothing on its own: WordPress's own Settings → General → Membership → Anyone
  can register has to be ticked as well, so this plugin cannot become a second
  way in past a door the site has shut.
* The roles that setting may create an account in are now decided by what a
  role is allowed to do rather than by what it is not. Only a role that grants
  nothing beyond reading the site — what a subscriber and a WooCommerce
  customer have — is offered, so a role added by another plugin cannot slip
  through on a capability this plugin had not heard of.

= 1.2.7 =
* The name now starts with Fastkit — "Fastkit OTP Authentication &
  Notifications for WooCommerce" — so that it names a particular plugin rather
  than describing a category of them. Same plugin, same people behind it.

= 1.2.6 =
* The plugin is no longer called "Wakit". Nothing about how it works has
  changed, and it is still built and run by Wakit — the name is the one the
  WordPress plugin directory will list it under. A site that had the old plugin
  installed keeps its connection, its templates and its send log: the settings
  live in the database, not in the folder the plugin sits in.

= 1.2.5 =
* A mobile number can no longer become an account that can change the site.
  "Role for new accounts" now offers only roles that cannot write, upload or
  administer anything, and the role is checked again at the moment the account
  is created — so a site that had picked something more powerful stops handing
  it out.
* The page that closes the connect popup takes its styles and its script from
  files like every other screen, rather than printing them into the page.

= 1.2.4 =
* First release on the WordPress plugin directory. On the Plugins screen the
  plugin is now simply "Wakit", and updates come from wordpress.org the same
  way they do for every other plugin there.
* The readme now sets out exactly what this site sends to Wakit, when, and
  under whose terms — see "External services".

= 1.2.3 =
* Updates arrive the ordinary way. WordPress offers a new Wakit release on the
  Plugins screen with "update now", a changelog behind View details, and
  auto-updates if the site has them on — no more downloading a zip and
  uploading it by hand.

= 1.2.2 =
* Order notifications is one status at a time. The statuses are a list down the
  side, each marked when it is switched on, and only the one being edited is
  open — rather than eight cards stacked into a page nobody could see the end
  of. Nothing is hidden from the save: every status still posts, so switching
  between them never loses what was typed.
* Template variables sit two or three across instead of one per row, and the
  merge tags are two short columns rather than one long table.

= 1.2.1 =
* Fixes an install that failed on activation with "Plugin file does not exist."
  The 1.2.0 zip was packed with the wrong path separator, so WordPress unpacked
  it into files it could not then find. Nothing inside the plugin changed.
* The plugin's own screens are now Wakit green rather than WordPress blue, so
  they match the Wakit tab the connect button opens. The WhatsApp sign-in form
  is painted to match too, on wp-login.php and wherever the shortcode is used.
* Templates now says what to do about it when you are on Wakit's shared number:
  add your own WhatsApp Business number, get the business behind it verified,
  and write templates in your own words. The button that starts it is on the
  screen rather than somewhere on Wakit you have to go looking for.

= 1.2.0 =
* The dashboard now shows the WhatsApp Cloud API numbers on your Wakit
  workspace, which one your messages actually leave from, and whether it may
  send today. Connect a number on Wakit and it appears here on the next look —
  nothing to copy across.
* Every link out to Wakit signs you in on the way: the dashboard, your numbers,
  connecting a new number, and recharging are each one click, with no second
  sign-in.

= 1.1.0 =
* Sign in to wp-admin with a mobile number and a WhatsApp code.
* A mobile number on the user profile, so an account with no billing address —
  every administrator — can be reached by the sign-in form. It is fixed to the
  account: a later checkout no longer moves it, and no two accounts may share
  one.
* Signing in now returns to the page you came from, and sends anyone who works
  on the site to wp-admin rather than the shop's account page.

= 1.0.0 =
* One-click connect: mobile number, WhatsApp code, workspace and template.
* Write your own templates and follow them through review to approved.
* WooCommerce order notifications, a template and variables per status.
* Sign in to WordPress with a WhatsApp code.
* Send log, test send, and a one-time link into the Wakit dashboard.
