=== Mocky M-Pesa STK Push ===
Contributors: mocky
Tags: mpesa, daraja, woocommerce, stk push, payments
Requires at least: 6.2
Tested up to: 6.7
Requires PHP: 7.4
Stable tag: 1.1.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Developer-ready Safaricom Daraja M-Pesa STK Push integration for WooCommerce products, services, downloads, and standalone WordPress payment forms.

== Description ==

Mocky M-Pesa STK Push lets WordPress developers add M-Pesa payments by entering Daraja credentials and copying the generated callback URL into Safaricom Daraja. It supports physical products, services, virtual products, digital downloads, invoices, and custom payment forms.

The plugin includes a free 24-hour domain trial, then annual paid access at KES 1,000 per domain per year. It includes annual license enforcement, WooCommerce checkout, shortcode checkout, callback handling, status polling, WP-Cron recovery, and an admin transaction log.

== Installation ==

1. Upload the plugin zip through WordPress admin (Plugins -> Add New -> Upload Plugin).
2. Activate the plugin.
3. Open Mocky M-Pesa from the admin menu.
4. Start the free 24-hour trial, buy the annual domain license, or activate an existing license.
5. Add Daraja credentials and select sandbox or production.
6. Copy the callback URL into the Daraja app.
7. Test Daraja authentication.
8. Enable the WooCommerce gateway for products/services/downloads or add the shortcode to a page.

== Licensing ==

Each domain can start one free 24-hour trial. Paid licenses are valid for one domain for one year. Renewals are paid through M-Pesa STK Push to Mocky's configured PayBill. Expired trials or licenses block new payment initiation until annual payment is confirmed.

== Shortcode ==

`[mocky_mpesa_checkout amount="1000" reference="INV-1001" description="Invoice payment"]`

Use the shortcode amount as the full payable price for services, downloads, products, invoices, or custom payments. WooCommerce checkout uses the full order total automatically.

== Security and Operations ==

* HMAC-signed license server responses (forged license responses are rejected).
* Per-phone cooldown and per-IP hourly cap on STK Push requests.
* Idempotent STK initiation prevents double prompts from double-submits.
* Callback authenticity defended in depth: token, optional Safaricom IP allowlist, and Daraja query reconciliation before crediting orders.
* HPOS (High-Performance Order Storage) declared compatible.
* WP-Cron based background recovery for stuck PENDING transactions with inter-process lock.
* Configurable data retention with daily pruning of standalone (non-WooCommerce) transactions.
* Auto-update via signed update metadata using the license key as the HMAC secret.

== Changelog ==

= 1.1.0 =
* Security: HMAC-signed license server responses (license, status, trial, purchase, renew).
* Security: rate limiting per-phone and per-IP on REST /initiate.
* Security: callback reconciliation by Daraja query before crediting WooCommerce orders.
* Security: optional Safaricom IP allowlist for production callbacks.
* Bugfix: apply_response no longer wipes license_key / expires_at on partial responses.
* Bugfix: idempotent STK initiation reuses a recent PENDING transaction within 90s window.
* Bugfix: replaced deprecated current_time('timestamp') with UTC time() comparisons.
* Bugfix: get_options no longer writes to the DB; callback token created in admin_init.
* Bugfix: cron query lock prevents concurrent processing of the same pending rows.
* Bugfix: payload encoding now consistent across create and update paths.
* Updates: gated on active license, no force-bypass on plugin View Details modal.
* Compat: declares HPOS compatibility for WooCommerce 8.2+.
* UX: full secret masking with placeholder + retention/uninstall settings.
* DB: schema versioning with auto-migration on plugins_loaded.
* Performance: license server timeout reduced to 10s; debug-log flag cached per request.

= 1.0.0 =
* Initial commercial release.
