=== CatCode Scalapay Payments for WooCommerce ===
Contributors: catcodestudio
Tags: scalapay, buy now pay later, installments, payment gateway, italy
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Scalapay for WooCommerce: pay in 3 or 4 interest-free instalments, captured on the server even if the buyer closes the tab, block checkout, HPOS.

== Description ==

A WooCommerce payment gateway for **Scalapay**, the Italian buy now, pay later service. Buyers pay in interest-free instalments on the Scalapay page, and you receive the full amount from Scalapay.

The plugin is built around one rule: an order is marked paid only when Scalapay itself says so, and a buyer who authorised the payment is charged even if they never come back to your site.

* **Captured on the server, not on the return page** — Scalapay charges nothing until the shop captures. The plugin captures on whichever path sees the authorisation first: the buyer's return, the Scalapay webhook, or the thank-you page. A buyer who closes the tab right after authorising is not lost, as long as the webhook is set up.
* **Orders confirmed by Scalapay, not by the browser** — after every payment the plugin reads the payment back from the Scalapay API with your own key. The webhook body is only a hint, and its HMAC signature is verified before anything happens.
* **Nothing charged by mistake** — the authorised amount and currency are compared with the order before the capture. If they differ, or the order was cancelled, or another attempt already paid it, or the buyer moved to another payment method, the money is simply not taken.
* **No double e-mails, no double stock reduction** — the webhook and the buyer's return can arrive in the same second; a database lock and a fresh read of the order apply each payment exactly once (HPOS order cache included). A capture that got no answer is retried with the same idempotency key, so it cannot charge twice.
* **Retries that just work** — every attempt is its own Scalapay order. When the buyer tries again, the previous attempt is closed first, so an old tab cannot authorise a second payment.
* **A buyer who cancels keeps the cart** — they land on the order page with a clear message and can try again or choose another method; the order shows "Failed" with a note.
* **Instalment widget** — Scalapay's own widget on the product page (it follows the chosen variation), the cart (classic and block) and the checkout, in the language of the page.
* **Shown only when it can work** — the method hides for currencies other than euro, for countries Scalapay does not serve, and for amounts outside your contract (read from Scalapay, cached).
* **"Re-check the Scalapay payment"** in the order actions — one click asks Scalapay and settles the order.
* **Test mode out of the box** — the public Scalapay sandbox key is built in, so you can try the whole flow before you have a contract. "Check connection" shows the plans and limits of your contract and tests that your webhook address answers.
* Phone numbers are sent in international form, virtual orders use the billing address as the shipping address Scalapay requires, coupons and fees are itemised.
* Classic and block checkout, HPOS compatible, "Processing" or "Completed" after payment, debug log without secrets. The live API key is stored encrypted.
// @pro-begin
* Translation included: Italian.
// @pro-end

// @pro-begin
= Pro =

The Pro version is sold on [catcode.com.ua](https://catcode.com.ua/modules/catcode-scalapay-payments-for-woocommerce/), with a 7-day trial that never starts by itself:

* **Refunds from the order screen** — full or partial, through the Scalapay refund API; partial refunds are counted, so Scalapay is never asked for more than the payment still holds.
* **Delayed capture** — authorise at checkout and charge when the order ships: automatically when the order reaches the status you choose, or from the order actions. Cancelling the order releases the authorisation. Delayed capture has to be part of your Scalapay contract.
* **Payment watchdog** — every 15 minutes the plugin re-checks the unpaid Scalapay orders of the last 48 hours, so an authorisation whose webhook was blocked still gets captured. Held payments are followed too: you get a warning a day before the authorisation ends.
* **Exclude categories** — no Scalapay and no widget for the products you choose.
* **Payment journal** — every Scalapay payment with order token, plan, amount, refunds, held payments and when they run out, and a one-click re-check.

The licence runs for 1-5 years and includes updates and support for that term; a purchased licence keeps its Pro features after the term ends.
// @pro-end

Scalapay is a trademark of its owner. This plugin is an independent integration made by CatCode; it is not the official Scalapay plugin and is not affiliated with or endorsed by Scalapay.

== Installation ==

1. Upload the plugin and activate it.
2. WooCommerce → Settings → Payments → **Scalapay (CatCode)**: enable the method. Test mode is on by default and needs no key.
3. Press "Check connection" and place a test order with your own mobile number (see the FAQ).
4. To go live, switch test mode off, paste the live API key and the merchant token from the Scalapay Merchant Portal (section Developer) and save.
5. Paste the webhook address shown in the settings into the Scalapay Partner Portal, section Developers, field Webhook Url.

== Frequently Asked Questions ==

= Do I need a Scalapay contract? =
For live payments, yes. Test mode works without one.

= How do I test? =
With test mode on, place an order with your own mobile number: Scalapay sends a real login code by SMS even in the sandbox. Pay with Scalapay's test card 5200 8282 8282 8210 (any CVV, any date); card 4000 0000 0000 0341 tests a failed payment. Scalapay may also send reminders about the test instalments to that number and e-mail; nothing is really charged.

= Which countries and currencies? =
Euro only. The countries are those Scalapay lists for its WooCommerce integration: Austria, Belgium, Finland, France, French Guiana, Germany, Guadeloupe, Italy, Martinique, Mayotte, the Netherlands, Portugal, Réunion and Spain. Developers can narrow the list with the `catcode_scalapay_countries` filter.

= I use the official Scalapay plugin. =
Deactivate it before enabling this one, so the checkout does not show Scalapay twice. Orders it started stay with it.

= An order stayed "Pending payment" although the buyer paid. =
Open the order and pick "Re-check the Scalapay payment" in Order actions. To avoid it, set up the webhook: it is what reaches your shop when the buyer closes the tab.
// @pro-begin
The Pro watchdog re-checks such orders by itself.
// @pro-end

= Why is the method missing at checkout? =
The shop currency is not euro, the billing country is not served by Scalapay, the total is outside your contract, or test mode is off and no live key is saved. "Check connection" shows the limits.

= The widget does not appear. =
In live mode it needs the merchant token. It also hides for amounts your contract does not cover. It loads from cdn.scalapay.com, so a strict Content-Security-Policy has to allow that address.

= How do refunds work? =
// @pro-begin
With a Pro licence, Refund → "Refund via Scalapay" on the order screen. Without it, and for refunds made in the portal:
// @pro-end
Refund the payment in the Scalapay Merchant Portal, then record the refund on the order in WooCommerce: a refund made in the portal does not change the order by itself, the plugin only adds a note.

== External services ==

This plugin connects to Scalapay, the payment service the shop owner chooses:

* Scalapay API (api.scalapay.com, in test mode integration.api.scalapay.com) — when a buyer chooses Scalapay, to create the payment: the order total, tax, shipping, discounts and items (name, category, SKU, quantity, price, product and image address), the buyer's name, e-mail, phone, billing and shipping address, the order number and the shop's return addresses. Afterwards to read the payment back and capture it, and, when you press "Check connection", to read the plans and limits of your contract.
* Scalapay widget (cdn.scalapay.com) — loaded on product, cart and checkout pages unless switched off in the settings; it shows the instalment amount. It receives the amount, the page language and your merchant token. Buyers' browsers load it from Scalapay.
// @pro-begin
* CatCode licence server (catcode.com.ua) — only when the owner activates a key or starts the trial, and periodically while a key is stored: the key and the site address are sent (plus the e-mail typed for a trial). Updates are checked there with the same key. Privacy policy: https://catcode.com.ua/privacy/
// @pro-end

Scalapay terms: https://cdn.scalapay.com/terms-and-conditions/it-IT/Scalapay%20-%20Terms_and_Conditions.pdf — Scalapay privacy policy: https://www.scalapay.com/privacy

== Changelog ==

= 1.0.0 =
* First release: Scalapay order per attempt with redirect to the Scalapay page, capture on the buyer's return, the webhook or the thank-you page, payments read back from the API, HMAC-checked webhook, amount and currency checks before the capture, payment lock, idempotent capture, contract limits, instalment widget on product, cart and checkout, "Re-check the Scalapay payment" order action, connection check, test mode with the public sandbox key, block checkout, HPOS.
// @pro-begin
* Pro: refunds from the order screen, delayed capture, payment watchdog, excluded categories, payment journal, updates from catcode.com.ua.
// @pro-end
