=== SpicePay for WooCommerce ===
Contributors: spicepay
Tags: payments, woocommerce, payment gateway, checkout, hosted-payment
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 7.4
WC requires at least: 8.0
WC tested up to: 10.9
Stable tag: 1.2.0
License: MIT
License URI: https://opensource.org/licenses/MIT

Take WooCommerce payments through SpicePay's hosted checkout. One click to connect, one payment method per row under WooCommerce → Payments.

== Description ==

SpicePay for WooCommerce is a payment gateway. WooCommerce keeps the cart, the checkout page, taxes, shipping, coupons, emails, the thank-you page and the order status machine; this plugin contributes payment methods and nothing else.

**Licensing note:** only this plugin — the WooCommerce integration code — is open source (MIT). The SpicePay platform itself (the payment service, hosted checkout and APIs it connects to) is a proprietary commercial service operated by SpicePay. A SpicePay merchant account is required.

= How it works =

* The buyer picks a SpicePay payment method on WooCommerce's own checkout — the block checkout or the classic shortcode checkout.
* WooCommerce creates the order and the plugin creates a payment at SpicePay, then sends the buyer **off-site** to SpicePay's hosted checkout. No card data ever touches your server.
* The buyer returns to WooCommerce's order-received page. SpicePay's signed webhook marks the order paid; the plugin also verifies the payment against the SpicePay API when the buyer lands back, so the thank-you page is right even if the webhook is a second late.
* Refunds issued from the WooCommerce order screen are sent to SpicePay. Refunds issued from the SpicePay dashboard are mirrored as WooCommerce refunds.
* Every payment, refund and dispute event leaves a note on the order.

= Features =

* **One-click Connect to SpicePay** — sign in to the SpicePay control center from WooCommerce → Settings → SpicePay; the API key, webhook secret and webhook registration are provisioned for you. A manual credentials fallback is there for browsers that block popups.
* **One gateway per payment method** — "SpicePay" offers every method your account has enabled on one hosted checkout; the other entries (card, Apple Pay, Google Pay, PayPal, Klarna, SEPA, iDEAL, Bancontact, crypto and more) restrict the hosted checkout to that single method so the buyer gets what they picked. Each is its own row under WooCommerce → Settings → Payments with WooCommerce's native enable toggle, title, description and icon.
* **Express redirect** per method — skip the method picker on the hosted checkout.
* **Signed webhooks** — HMAC-SHA512, verified in constant time before any state change, replay-safe.
* **Refunds** from the WooCommerce order screen, full or partial.
* **HPOS compatible**, block checkout compatible.
* **Connection health** — the plugin checks that SpicePay still accepts your API key and warns you on every admin screen if it does not. Logs go to WooCommerce → Status → Logs (source "spicepay"), secrets redacted.
* **No custom tables, no extra admin menu.** Settings live in WooCommerce's settings; orders are WooCommerce orders.

= Running alongside the SpicePay storefront plugin =

If the standalone SpicePay plugin (slug `spicepay`) is also installed and connected, this plugin offers to reuse its connection with one click. The two plugins share no option keys and no class names, and each processes a payment event at most once.

== Installation ==

1. Install and activate WooCommerce.
2. Upload the `spicepay-woocommerce` folder to `/wp-content/plugins/` and activate the plugin.
3. Go to WooCommerce → Settings → SpicePay and click **Connect to SpicePay**.
4. Under WooCommerce → Settings → SpicePay → Payment methods, pick the methods to offer.
5. Enable each method under WooCommerce → Settings → Payments.

== Frequently Asked Questions ==

= Does the buyer pay on my site? =

No. The buyer is redirected to SpicePay's hosted checkout and returns to your order-received page afterwards. Card data never reaches your server.

= Which order statuses does the plugin set? =

`processing`/`completed` (via WooCommerce's `payment_complete`) when the payment is captured, `on-hold` when it is authorized but not yet captured or still processing, `failed` when it fails, `cancelled` when it is cancelled or expires. A captured amount that does not match the order total puts the order on hold with a note instead of marking it paid.

= Can I use it with HPOS? =

Yes. The plugin declares HPOS compatibility and uses the WooCommerce CRUD API exclusively.

== Changelog ==

= 1.2.0 =
* The payment now carries the WooCommerce order key as its own `payment_id`, so an order and its SpicePay payment share one identifier instead of being correlated through metadata. A retry on the same order reuses that payment when it is still chargeable for the same amount, and falls back to a SpicePay-generated id otherwise, so a buyer is never left unable to pay.
* Registered customers are sent as `customer_id`, scoped to the site so two stores sharing one SpicePay shop cannot merge two shoppers into one customer. Guests are unaffected.
* Line-item attributes (variation attributes, or a simple product's own visible attributes) are sent as payment metadata under their own names — an attribute called "tshirtsize" arrives as `"tshirtsize": "L"`. A name already used by the plugin's own metadata, or repeated across lines with a different value, gets the line number appended rather than overwriting anything.


= 1.1.0 =
* Payment method presentation is now editable from WooCommerce → Settings → SpicePay → Payment methods: icon, title and description per method, next to the enable status. The icon is picked from the media library, with one click back to the icon the plugin ships or to no icon at all.
* New "Show at checkout" setting per method — title and description, title only, or nothing at all. With "nothing" the payment step disappears and Place order takes the buyer straight to the SpicePay hosted checkout. It applies only while SpicePay is the store's one available method; with a second method on the page it falls back to showing the title, so the buyer is never asked to choose between unlabelled options.

= 1.0.0 =
* Initial release.
