=== CatCode Revolut Payments for WooCommerce ===
Contributors: catcodestudio
Tags: revolut, revolut pay, payment gateway, credit card, woocommerce
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

Revolut Merchant payments for WooCommerce: cards and Revolut Pay on the Revolut page, orders confirmed by a signed webhook plus a server check.

== Description ==

A WooCommerce payment gateway for **Revolut Merchant**, built around one rule: an order is marked paid only when Revolut itself says so, never because a browser reached the thank-you page.

* **The methods of your Revolut account** on the secure Revolut Hosted Checkout Page: cards, Revolut Pay, and Apple Pay, Google Pay or Pay by Bank where Revolut offers them to you. The buyer's card details never touch your server.
* **One field to fill in** — paste the secret key; the plugin registers its webhook at Revolut through the API, with the events it needs and its signing secret. Nothing to copy by hand.
* **Webhooks verified** — HMAC-SHA256 signature with the signing secret and a five-minute timestamp limit. A forged request cannot reach an order.
* **Orders confirmed by Revolut, not by the browser** — after a webhook the plugin reads the order back from the Revolut API with your own key, and only a completed payment for the right amount and currency marks the order paid. Anything else puts it on hold with a note.
* **No order left "pending payment" after a successful payment** — the webhook is handled on the spot (no background queue that waits for WP-Cron), and if it never arrives, the buyer's return and the thank-you page ask Revolut themselves. A thank-you page that is still waiting watches the status and updates by itself.
* **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).
* **Refused attempts in plain words** — the Revolut page lets the buyer try again; the order keeps waiting, and its notes say why each attempt was refused.
* **No payment for a dead order** — when WooCommerce cancels an order, its Revolut page is cancelled too. When the order total changes, the old Revolut order is cancelled first, so it cannot be paid in another tab.
* **Late payments are not lost** — an order WooCommerce cancelled for being unpaid is marked paid again when Revolut confirms its payment afterwards, with a note to check the stock.
* **Refunds made in Revolut Business** reach the order with "Re-check the Revolut payment": a full refund makes it "Refunded", a partial one leaves a note.
* **"Re-check the Revolut payment"** in the order actions — one click asks Revolut and settles the order.
* **"Check connection"** in the settings tests your key (sandbox or live), registers the webhook and tests that your webhook address answers.
* Classic and block checkout, HPOS compatible, 27 currencies with the right minor units (JPY and ISK have none), "Processing" or "Completed" after payment, debug log without secrets, key and signing secret stored encrypted.
// @pro-begin
* Translation included: German.
// @pro-end

// @pro-begin
= Pro =

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

* **Refunds from the order screen** — full or partial, through the Revolut API. Partial refunds are counted, so Revolut is never asked for more than the payment still holds; an idempotency key means a repeated click cannot pay twice; a refund Revolut fails later is taken back out of the count and told in the order notes.
* **Authorise now, capture later** — the money is held and the order waits on hold. Moving the order to Processing or Completed captures it, and so does an order action; cancelling the order releases it.
* **Payment watchdog** — every 15 minutes the plugin re-checks the unpaid Revolut orders of the last 48 hours, so a payment whose webhook was blocked by a firewall or arrived during maintenance still settles its order without anyone pressing a button.
* **Payment journal** — every Revolut payment with how it was paid, the amount, refunds, sandbox or live, and a one-click re-check.
// @pro-end

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

== Installation ==

1. Upload the plugin and activate it.
2. In Revolut Business open Merchant → ⋯ → Merchant API and copy the secret key (press Generate the first time).
3. WooCommerce → Settings → Payments → **Revolut (CatCode)**: paste the key, choose the environment and press "Check connection". The webhook is registered at this moment.
4. Enable the method and make a test payment.

== Frequently Asked Questions ==

= Do I need a Revolut account? =
Yes, a Revolut Business account with Merchant enabled. For tests, Revolut has a free sandbox with its own account and keys: sandbox-business.revolut.com.

= How do I test? =
Choose "Sandbox" and paste the secret key of the sandbox account. Only Revolut's test cards work there; Revolut lists them in its documentation under "Test cards".

= I used the official Revolut plugin before. =
Deactivate it before enabling this one, so the checkout does not show Revolut twice. Each plugin answers for the orders it created.

= An order stayed "Pending payment" although the buyer paid. =
Open the order and pick "Re-check the Revolut payment" in Order actions. If it happens again, press "Check connection" in the settings: it tells whether the site answers its own webhook address. Security plugins and firewalls that block POST requests are the usual cause.
// @pro-begin
The Pro watchdog re-checks such orders by itself.
// @pro-end

= Why is the method missing at checkout? =
The order currency is one Revolut does not take, or the secret key is empty.

= The connection check says the webhook could not be registered. =
Revolut takes webhooks only at a public domain, so a site on localhost or a bare IP address cannot have one, and an account can hold at most 10 webhooks. Payments are still confirmed when the buyer returns.

= Can the card form be on my checkout page? =
Not in this version: the buyer pays on the Revolut page.

== External services ==

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

* Revolut Merchant API (merchant.revolut.com, or sandbox-merchant.revolut.com in the sandbox) — with your secret key: to create an order when a buyer pays (order total and currency, a description with the order number and the shop name, an order reference, the buyer's name, e-mail and phone, and the shop's return address); to read the order after the payment; to cancel an order WooCommerce no longer needs; and to list and register the shop's webhook address when you save the key or press "Check connection".
* Revolut Hosted Checkout Page (checkout.revolut.com, or the sandbox equivalent) — the buyer is sent there to pay.
// @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

Revolut terms: https://www.revolut.com/legal/terms/ — Revolut privacy notice: https://www.revolut.com/legal/business-customer-privacy-notice

== Changelog ==

= 1.0.0 =
* First release: payments on the Revolut Hosted Checkout Page, webhook registered through the API and verified by signature, orders confirmed by reading them from the Revolut API, amount and currency checks, one Revolut order per attempt, payment lock, restored late payments, refunds from Revolut Business reaching the order, "Re-check the Revolut payment" order action, connection check, block checkout, HPOS.
// @pro-begin
* Pro: refunds from the order screen, authorise now and capture later, payment watchdog, payment journal, updates from catcode.com.ua.
// @pro-end
