=== OzuPay Payment Gateway for M-Pesa ===
Contributors: fearofbug
Tags: mpesa, woocommerce, payment gateway, kenya, safaricom
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 8.0
Stable tag: 5.1.23
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Accept M-Pesa STK Push payments in your WooCommerce store. Customers pay via their phone — no card required.

== Description ==

OzuPay accepts M-Pesa payments in WooCommerce. Customers enter their Safaricom number at checkout and receive a payment prompt on their phone.

= What's included in the free edition =

* **STK Push payments** — send a payment prompt directly to the customer's phone via the Daraja API
* **Payment waiting modal** — shows payment status in real time on the confirmation page
* **Retry support** — customers can resend the STK Push prompt up to 2 times if they missed it
* **Manual verification fallback** — if automation fails, customers can submit their M-Pesa transaction code for admin review
* **Paybill fallback matching** — matches an external Paybill payment by account reference
* **Transaction log** — every Daraja API request and callback is logged for easy troubleshooting
* **Sandbox testing panel** — test your Daraja credentials in the sandbox before going live
* **Health check** — instant feedback on missing credentials, SSL issues, and other common misconfigurations
* **Privacy tools integration** — supports WooCommerce personal-data export and erasure
* **HPOS compatible** — works with WooCommerce High-Performance Order Storage
* **Blocks compatible** — works with the WooCommerce Cart/Checkout Block editor

= What OzuPay Pro adds =

* **M-Pesa on Delivery (COD Deposit)** — deposit + balance on delivery gateway
* **C2B Buy Goods (Till) Reconciliation** — match Till payments made outside an STK prompt
* **B2C Automatic Refunds** — process WooCommerce refunds via the Daraja B2C API
* **Analytics Dashboard** — revenue, conversion, and payment path charts
* **Scheduled Email Reports** — daily, weekly, or monthly payment summary emails
* **POS REST API** — REST endpoints for the OzuPay Android cashier application
* **Webhook Enrichment** — add M-Pesa receipt data to WooCommerce webhook payloads

Upgrade at [ozupay.com](https://ozupay.com/#pricing)

= Requirements =

* **WooCommerce is required** — OzuPay is a WooCommerce payment gateway and does not run without it
* A Safaricom Daraja developer account (free at [developer.safaricom.co.ke](https://developer.safaricom.co.ke))
* Store currency must be set to **KES (Kenyan Shilling)**
* A public HTTPS URL for Daraja callbacks (required for production; not needed for sandbox testing)

== Installation ==

1. Upload the `ozupay-payment-gateway` folder to the `/wp-content/plugins/` directory, or install directly through the WordPress plugins screen.
2. Activate the plugin through the **Plugins** screen in WordPress.
3. Go to **OzuPay → Settings** and enter your Daraja credentials.
4. Go to **WooCommerce → Payments** and enable the **M-Pesa** gateway.
5. Configure the gateway title and description under **WooCommerce → Payments → M-Pesa → Manage**.
6. Test with the Sandbox Testing panel before going live.

= Getting your Daraja credentials =

1. Create a free developer account at [developer.safaricom.co.ke](https://developer.safaricom.co.ke)
2. Create an app under **My Apps** and add the **Lipa Na M-Pesa** product
3. Copy the **Consumer Key** and **Consumer Secret** from the Keys tab
4. Copy the **STK Passkey** from the sandbox credentials section
5. Use shortcode **174379** and passkey from the test credentials page for sandbox testing

== Frequently Asked Questions ==

= What is the test phone number for sandbox STK Push? =

Safaricom's official sandbox test phone is **254708374149**. Any STK Push to this number in sandbox mode will succeed. You can change this in the Sandbox Testing panel.

= What are the sandbox credentials? =

Shortcode: 174379
Passkey: bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919

These are public Safaricom test credentials. The plugin's Sandbox Testing panel can pre-fill these automatically.

= Why is the gateway not showing at checkout? =

The most common reasons:
1. The store currency is not set to KES — go to WooCommerce → Settings → General
2. The gateway is not enabled — go to WooCommerce → Payments and enable M-Pesa
3. Consumer Key, Consumer Secret, Shortcode, or Passkey is missing — go to OzuPay → Settings
4. The Health Check panel (OzuPay → Settings → Health Check) will tell you exactly what is missing

= Why is "Invalid TransactionType" returned by Daraja? =

Your Shortcode Type setting does not match the type registered in Daraja. Paybill numbers use **CustomerPayBillOnline** and Till numbers use **CustomerBuyGoodsOnline**. The sandbox shortcode 174379 is a Paybill — set the type to Paybill.

= Do callbacks work on localhost, and is HTTPS required? =

Daraja requires a publicly accessible HTTPS callback URL. For local testing, use a secure tunnel such as [ngrok](https://ngrok.com), then confirm delivery with the Sandbox Testing panel.

= Can I upgrade to Pro later without losing data? =

Yes. The free and Pro editions use the same database tables and option names (`ozupay_mpesa_settings`, `wp_ozupay_mpesa_transactions`). Upgrading to Pro or switching back to free never deletes your data.

= Where are API credentials stored? =

Consumer Key, Consumer Secret, and STK Passkey are stored AES-256-GCM encrypted in the WordPress options table. The encryption key is derived from your site's `AUTH_KEY` and `SECURE_AUTH_KEY` constants. They are never stored in plain text.

= Does this plugin phone home or send usage data? =

Payment processing uses Daraja. Optional OzuPay diagnostics are **off by default** and run only after you opt in. The report includes your hostname and is not anonymous. Details follow.

== External services ==

This plugin relies on the following external services. Nothing else is contacted.

**1. Safaricom Daraja API (required)**

The plugin connects to Daraja to send STK Push prompts and receive payment results. This core service is required.

Endpoints: `https://api.safaricom.co.ke` (production) and `https://sandbox.safaricom.co.ke` (sandbox, used only when you select Sandbox mode in settings).

What is sent, and when:

* When a customer places an order with the M-Pesa gateway: the customer's Safaricom phone number, the order amount, your store's Paybill/Till shortcode, the order number as the payment reference, and your site's callback URL.
* When the plugin needs an API token (before each request batch): your Daraja Consumer Key and Consumer Secret.
* While a customer is on the payment-waiting page and their payment hasn't confirmed after 15 seconds: your store's Paybill/Till shortcode and the CheckoutRequestID for that specific payment, to proactively check whether Daraja already has an outcome (rate-limited to once every 30 seconds per order).
* Safaricom sends results back to your site's callback URL; nothing is sent by the plugin in that direction.

You supply your own Daraja credentials, so your store's relationship is directly with Safaricom.

Safaricom Daraja API terms and conditions: https://developer.safaricom.co.ke/terms
Safaricom data privacy statement: https://www.safaricom.co.ke/dataprivacystatement/

**2. OzuPay diagnostics (optional, disabled by default)**

If you enable "Share optional diagnostic telemetry" in OzuPay → Settings → Advanced, the plugin sends a daily report to `https://ozupay.com/wp-json/ozls/v1/telemetry`. It also sends once immediately after opt-in. Fresh installs default to off.

What is sent, and when: once per day (and once immediately after you enable it) — your site's hostname, the plugin/PHP/WordPress/WooCommerce version numbers, store locale and country, whether the site is a WordPress multisite install, whether the site is in sandbox or production mode, whether HPOS and block checkout are in use, whether your M-Pesa shortcode is a Paybill or Till, boolean configuration-health flags (for example "credentials configured: yes/no", "callback URL reachable: yes/no"), install and last-active dates, daily aggregate payment counts (initiated, confirmed, failed, retried), and error type slugs with their frequency.

What is never sent: customer names, phone numbers, emails, addresses, order IDs, order contents, payment amounts, M-Pesa receipt numbers, or your Daraja API credentials.

OzuPay terms of service: https://ozupay.com/terms
OzuPay privacy policy: https://ozupay.com/privacy

== Screenshots ==

1. The M-Pesa payment option at WooCommerce checkout.
2. Settings — Credentials tab, with sandbox testing tools and a live Daraja health check.
3. Dashboard — payment activity at a glance.
4. Settings — Checkout Settings tab, controlling the checkout-page fields customers see.
5. Settings — Features tab, showing what's included in the free edition.

== Changelog ==

= 5.1.23 =
* Change: Declared and verified WooCommerce 11.1 compatibility.

= 5.1.22 =
* Change: The classic (non-Blocks) checkout's M-Pesa gateway now defaults its title to "M-Pesa Pay Now" instead of plain "M-Pesa", matching the block-based checkout. Only affects new installs; a saved custom title is untouched.

For the full version history, see changelog.txt in the plugin package.
