=== GenesisPay for WooCommerce ===
Contributors: genesispay
Tags: woocommerce, payments, usdc, stablecoin, crypto
Requires at least: 6.7
Tested up to: 7.1
Requires PHP: 8.1
Requires Plugins: woocommerce
Stable tag: 0.10.0
License: GPLv3 or later
License URI: https://www.gnu.org/licenses/gpl-3.0.html

Accept exact USDC payments through hosted GenesisPay checkout, with signed webhooks and fresh fulfillment verification.

== Description ==

GenesisPay for WooCommerce adds GenesisPay as a classic and Checkout Blocks payment method. Each WooCommerce order gets one exact, single-use hosted payment request. The order remains unpaid until a signed webhook is followed by a fresh server-to-server verification of the amount, asset, network, payout wallet, link, attempt and transaction evidence.

WooCommerce remains the source of truth for products, carts, inventory, shipping and orders. Eligible simple products and variations are synchronized as unlinked GenesisPay catalogue drafts so the merchant can manage one catalogue view. The plugin never gives a physical product a reusable base-price payment link: every payable checkout still starts from an exact WooCommerce order after shipping and tax are calculated. GenesisPay never asks the plugin to sign or custody buyer funds.

= Required external service =

This plugin requires the GenesisPay service. A merchant must connect a GenesisPay account and, for live payments, complete GenesisPay merchant eligibility and business verification.

When a shopper chooses GenesisPay, this store sends GenesisPay the order identifier, product names, variants, quantities, SKUs, public product image URLs, discounted line totals, shipping and fees, the exact order total, tax assertion, and return/cancel URLs. GenesisPay returns a hosted checkout URL and sends signed payment events back to the store. Payment and webhook evidence is retained for security, reconciliation and legal recordkeeping.

* Service: https://genesispay.finance/
* Privacy: https://genesispay.finance/privacy
* Terms: https://genesispay.finance/terms

= Current compatibility =

* WordPress 6.7 or newer
* WooCommerce 9.0 or newer
* PHP 8.1 or newer with OpenSSL
* Store currency: USD
* Settlement asset: USDC on Base
* WooCommerce-calculated tax is included in the frozen order snapshot
* Classic checkout, Checkout Blocks and High-Performance Order Storage

== Installation ==

1. Install and activate the plugin.
2. Open WooCommerce > Settings > Payments > GenesisPay.
3. Choose Test or Live, then select Connect GenesisPay.
4. Sign in to GenesisPay and approve the exact store and webhook shown.
5. The plugin encrypts the temporary connection token, returned webhook secret and locally generated final key with keys derived from the WordPress authentication salts, runs a real signed webhook test, and registers the final key only when activation succeeds.

Advanced operators may configure `GENESISPAY_WC_API_KEY`, `GENESISPAY_WC_EXPECTED_WALLET` and `GENESISPAY_WC_WEBHOOK_SECRET` in `wp-config.php` instead of using the managed connection.

== Frequently Asked Questions ==

= Does GenesisPay move money from my WordPress server? =

No. The plugin creates a hosted payment request. GenesisPay verifies buyer-signed settlement evidence; WordPress never holds a buyer private key.

= When is a WooCommerce order marked paid? =

Only after a valid signed webhook and a fresh authenticated fulfillment verification both match the immutable order contract. Returning to the thank-you page does not mark the order paid.

= Are test payments able to fulfill a live order? =

No. Test and Live use different hosts, keys, chains and stored order contracts. Simulated payments are explicitly refused for fulfillment.

= What is retained after uninstall? =

The local encrypted connection credential is deleted, every background job the plugin queued is cancelled, and the short-lived replay-protection table is dropped (on a multisite network, on every site). WooCommerce order metadata and the plugin's payment/webhook audit records are intentionally retained for reconciliation and security. Disconnect GenesisPay before uninstalling to revoke the remote managed credential.

= What happens to an AI-agent order that is never paid? =

It expires. WooCommerce does not cancel agent orders on its own, so the plugin gives each one a deadline: 60 minutes after it was placed by default (change it with the `genesispay_agent_order_unpaid_ttl_minutes` filter; 15 to 1440 minutes). At the deadline the plugin first archives the order's GenesisPay payment request, so it can no longer be paid, and only then cancels the order, which releases its stock. If the request was already paid, the order is left for the payment webhook. If a payment is still settling, the plugin tries again every five minutes for about an hour, then leaves a note instead of cancelling. Rarely, a payment the buyer had already sent on the blockchain is matched only after the order expired; it then completes the cancelled order, never ignored, and the order note asks you to check stock or refund the buyer. Orders from your normal checkout are not affected.

= Can a customer cancel an order or pay for it later? =

Yes. While an order awaits GenesisPay payment, the customer can cancel it from their account page. To pay later, the Pay button in their account and the link on the order confirmation page open the same exact GenesisPay payment request; no other payment method is offered for that order, so the buyer cannot pay twice by different means. A payment that still arrives after cancellation is verified and completes the order, so money is never ignored; the order note asks the merchant to check stock or refund the buyer.

= Can GenesisPay help resolve an agent purchase dispute? =

Version 0.9.0 (commerce RPC 3) supplies signed original-order observations and frozen product/return-policy terms to GenesisPay's Disputes tab. The merchant can accept a cancellation request after confirming the order has not been handed to a carrier. A verified payment arriving later is recorded, but does not automatically fulfill an order cancelled through this dispute workflow. Cancellation does not return money: send any agreed refund from the original receiving wallet, then record its transaction in GenesisPay for verification. Add return-policy text through the `genesispay_agent_return_policy` filter; no carrier verification is implied.

= Does it support taxes and currencies other than USD? =

Version 0.9.0 supports USD orders and preserves WooCommerce-calculated tax in the exact order snapshot. Zero-tax orders retain the merchant-selected zero-tax treatment. Settlement is USDC on Base; other store currencies are not yet supported.

== Changelog ==

= 0.10.0 =
* Invoices: each order line now carries the tax rate WooCommerce applied to it, and the tax is sent as one line per rate instead of one combined total, so GenesisPay's invoice prints the rate and quantity of every line and the tax per rate. A line taxed at several rates (compound tax), or a rate that basis points cannot express exactly, is sent without a rate; if the per-rate rows do not add up exactly to the order's tax, the plugin keeps the single combined tax line.
* Invoices: new setting **Delivery period (days)**. When set, the payment request states the expected delivery period (order date to that many days later, in the store's timezone) as the invoice's date of supply. Shops with a per-order delivery date can supply it through the `genesispay_supply_period` filter. Left empty, the invoice states that no delivery date was given.

= 0.9.4 =
* Catalogue sync: stays under GenesisPay's seller API rate limit on large stores. Catalogue requests are paced store-wide to one per second (half the limit, so checkouts on the same key always have room), a full sync queues only products that actually changed, and the next page waits for the current one. A refusal with HTTP 429 pauses every catalogue request until the Retry-After time, then retries; nothing is dropped.
* Catalogue sync: the duplicate cleanup of **Sync catalogue now** reads the GenesisPay catalogue once per sync instead of once per page of 50 products, and retries after a 429 instead of giving up. A product whose archive was refused retries only the revisions still left.

= 0.9.3 =
* Catalogue sync: rapid edits to one product no longer leave duplicate listings in the GenesisPay catalogue. Each content edit (name, description, image, product page or price) creates a new GenesisPay catalogue draft and archives the previous one; two syncs of the same product could run at once, both archive the same old draft and leave one new draft listed for good. Syncs of one product now run one at a time, and a sync that finds the product busy runs again five minutes later.
* Catalogue sync: **Sync catalogue now** also archives drafts left behind by that race, keeping only the product's current draft. Drafts you created yourself in GenesisPay, and drafts of other stores, are never touched.

= 0.9.2 =
* Signed agent-commerce responses now name the plugin version (`GENESISPAY-Plugin-Version`), so GenesisPay can tell stores that refuse replayed requests from older ones. Unsigned refusals never carry it.
* Install: the replay-protection and agent-order tables are created on activation and, after an in-place update, on the next page load. If the database refuses a create, the plugin logs it to the WooCommerce `genesispay` log and retries every five minutes instead of on every page load. Before, a failed agent-order table create was never retried, so agent orders kept failing until the plugin was reactivated.
* Multisite: uninstalling from a network now removes the plugin's options, queued jobs and replay-protection table on every site, not only the main site.

= 0.9.1 =
* Security: refuse a replayed agent-commerce request. A signed quote, order or dispute request from GenesisPay is now accepted once; a captured copy sent again while its signature is still valid (signed time plus or minus five minutes) is refused like an invalid signature (401 `invalid_signature`). GenesisPay signs every request and every retry with a new nonce, so normal retries are unaffected. Each accepted nonce is kept, hashed, until six minutes after its signed time in a new `genesispay_commerce_nonces` table (created automatically after the update, dropped on uninstall). If that table cannot be written, signed agent-commerce requests are refused and the reason is logged to the WooCommerce `genesispay` log.

= 0.9.0 =
* Commerce RPC3 supplies frozen product description and optional merchant return-policy filter.
* Signed original-order evidence and seller-attested idempotent cancellation.
* Shared order lock and fresh reread fence cancellation against delayed verified fulfillment.
* Cancellation does not refund money; GenesisPay records external refund proof separately.


= 0.8.1 =

* Expire unpaid AI-agent orders. WooCommerce never cancels an order an agent placed through GenesisPay, so its stock stayed held forever. Each agent order now gets a deadline (60 minutes by default, `genesispay_agent_order_unpaid_ttl_minutes`, 15 to 1440 minutes). At the deadline the plugin archives the order's GenesisPay payment request first and cancels the order (releasing its stock) only once GenesisPay confirms the request can no longer be paid. A paid request is never cancelled; a settling payment is retried, then left with a merchant note. Orders from your normal checkout are not affected.
* Cancelling an expired order does not ask GenesisPay to archive the request a second time.
* Uninstall now cancels the plugin's queued background jobs.

= 0.8.0 =

* When WooCommerce cancels or fails an order an AI agent placed through GenesisPay, archive that order's single-use GenesisPay payment request at once, so a stale link can never be paid. Retries run in the background if GenesisPay is unreachable or a payment is still settling. A request that was already paid is never archived; the order gets a note instead. Orders from your normal checkout are not affected.
* Tell GenesisPay which agent-commerce version this plugin supports, right after connecting and once after an upgrade, and inside each signed agent quote. GenesisPay lists products to AI agents and accepts their purchases only from stores that run this version or later.
* Keep the 0.7.2 quote and order behaviour unchanged, including the temporary in-memory session.

= 0.7.2 =

* Fix agent quotes and orders for products that need shipping: on a plain REST request WooCommerce starts no session, and its shipping calculation failed without one. The plugin now uses a temporary in-memory session for the calculation only (no cookie, nothing stored).
* Total every shipping option with that option selected, so each option's shipping, tax and total are exact. If another extension overrides the selected method, that option is left out instead of being quoted at another method's price.
* Offer agents delivery rates only, including when an extension registers its own pickup method. Local pickup is taxed at the store address in the cart but at the buyer's address on the order, so a pickup quote could never be ordered.
* Log unexpected agent quote/order failures to the WooCommerce "genesispay" log with the error type, throw site and product, never the error message, the buyer's address or contact.

= 0.7.1 =

* Complete managed connection by recognizing GenesisPay's signed provisioning marker inside the standard webhook data envelope.
* Normalize WooCommerce's higher-precision stored components to the store's USD precision while preserving the exact gross, subtotal and tax contract.
* Reconcile only bounded currency-rounding residue; larger order mismatches still fail before a payment request is created.

= 0.7.0 =

* Add a signed agent order endpoint that recalculates stock, shipping and tax before creating anything.
* Keep durable idempotency records in GenesisPay and WordPress so retries return the same WooCommerce order and single-use payment request.
* Transmit buyer destination/contact only to the connected merchant store; GenesisPay retains keyed digests rather than that personal data.

= 0.6.0 =

* Add the signed, read-only GenesisPay agent quote endpoint.
* Calculate destination tax and available shipping methods with WooCommerce's live cart engine.
* Return exact six-decimal integer-minor USD/USDC totals and a five-minute destination-bound quote token without creating an order.

= 0.5.0 =

* Synchronize the canonical WooCommerce product-page URL with each eligible catalogue draft.
* Let human GenesisPay Explore pages show those products and hand buyers to WooCommerce for address-bound shipping, tax, availability and final total.
* Keep storefront-only products out of agent Discovery and MCP until an exact payable WooCommerce order exists.

= 0.4.1 =

* Support taxed WooCommerce orders by freezing WooCommerce's exact tax total beside the net product, shipping and fee lines.
* Refuse checkout locally if the frozen line snapshot does not add up exactly to the gross order total.
* Record the GenesisPay API status and stable error code in private WooCommerce logs without exposing it to the buyer.

= 0.4.0 =

* Synchronize eligible WooCommerce simple products and variations into GenesisPay as unlinked catalogue drafts, with background retries and archive-on-unpublish/out-of-stock behavior.
* Add a manual **Sync catalogue now** action and queue the initial sync after a managed connection is activated.
* Keep agent-facing reusable links disabled for physical products until WooCommerce has created the exact order with quantity, address, shipping and tax.
* Return WooCommerce's required failure result from Checkout Blocks errors instead of causing a critical checkout error.

= 0.3.1 =

* Keep a verified payment retrying until WooCommerce has actually completed the order, instead of leaving a paid order unpaid.
* Let customers cancel an order awaiting payment, or reopen the same GenesisPay payment request from their account page or order confirmation.
* Stop WooCommerce's internal stock bookkeeping from blocking a retry of an unchanged order.
* Hold an order for manual review when its products changed after checkout, even if the total stayed the same. Catalog edits to SKUs, images or attribute names no longer count as a change.
* Flag a GenesisPay payment that arrives for an order already paid by other means, or after cancellation, so the merchant can refund the buyer or check stock.

= 0.3.0 =

* Add one-click, PKCE-bound GenesisPay account connection.
* Preserve any working connection during setup, encrypt managed credentials locally and register the final key only after verifying the exact webhook.
* Add explicit privacy and external-service disclosures.
* Safely acknowledge valid webhook events belonging to another WooCommerce site.

= 0.2.1 =

* Add GenesisPay provider branding to classic checkout, Checkout Blocks and Payments settings.
* Send frozen product, variant, SKU, image, shipping and fee snapshots to hosted checkout.

== Upgrade Notice ==

= 0.10.0 =

Invoices show each line's tax rate and quantity. Set **Delivery period (days)** in the GenesisPay settings so invoices state a date of supply. Needs the GenesisPay release from October 2026 or later.

= 0.9.4 =

Makes **Sync catalogue now** and its duplicate cleanup work on large stores without being throttled by GenesisPay. After updating, click **Sync catalogue now** once; on a store with thousands of products it takes about an hour to finish in the background.

= 0.9.3 =

Fixes duplicate catalogue listings after rapid product edits. After updating, click **Sync catalogue now** once to archive existing duplicates.

= 0.9.2 =

Security update; strongly recommended for every store, and required to close the agent-commerce replay gap on 0.9.0 and older. Until you update, a captured signed request from GenesisPay could be sent to your store again for up to five minutes. No reconnect is required; the replay-protection table is created automatically.

= 0.9.1 =

Security update: a captured agent-commerce request can no longer be replayed. Superseded by 0.9.2; install 0.9.2 instead.

= 0.8.1 =

Recommended if AI agents buy from your store: unpaid agent orders now expire after 60 minutes and release their stock. No reconnect is required. Agent orders placed before the upgrade get no deadline; cancel any stale ones by hand (the plugin still archives their payment request).

= 0.8.0 =

Required for AI-agent purchases: GenesisPay refuses agent quotes and orders from stores on older versions. No reconnect is required; the plugin reports its version automatically after the upgrade.

= 0.7.2 =

Upgrade if AI agents buy from your store: agent quotes for shipped products failed with "quote unavailable" on 0.7.1. No reconnect is required.

= 0.7.1 =

Upgrade before connecting or reconnecting GenesisPay. Existing connections remain valid; this release also fixes checkout for WooCommerce orders whose stored components have more precision than the displayed USD total.

= 0.7.0 =

Reconnect is not required. The plugin creates its agent-order idempotency table automatically during upgrade.

= 0.6.0 =

Reconnect is not required. Connected stores can answer signed agent quotes after upgrading; order creation remains disabled until durable retry idempotency ships.

= 0.5.0 =

Run **Sync catalogue now** after upgrading so eligible products receive their merchant product-page URL. Existing checkout and fulfillment behavior is unchanged.

= 0.4.1 =

Taxed USD orders can now use GenesisPay checkout. WooCommerce remains the tax authority; GenesisPay charges the exact gross total and does not recalculate tax.

= 0.4.0 =

Eligible products are synchronized automatically after GenesisPay is connected. They remain non-payable drafts; normal WooCommerce checkout is still the only way to create the exact hosted payment request.

= 0.3.1 =

Fixes a case where a verified payment could leave the order unpaid, lets customers cancel or pay later for orders awaiting payment, and rechecks the ordered products before completing an order. Orders created with 0.3.0 are checked with the 0.3.0 rules: if a product's SKU, image or attribute names changed since checkout, or another plugin stored private item data at checkout, the order is held for manual review instead of being marked paid.

= 0.3.0 =

Existing manual settings continue to work. Use Connect GenesisPay to replace manual secret copying with a managed, revocable store connection.
