P2Flux for WooCommerce
WooCommerce orders and subscriptions paid in USDC on Base, settling directly to your own wallet. What the plugin does, what it refuses, and what every outcome means.
A WooCommerce order becomes a P2Flux payment. The customer pays from their own wallet, the money lands in yours in the same transaction, and WooCommerce marks the order paid only after the plugin has verified that transaction on chain. For subscriptions, WooCommerce Subscriptions decides when a renewal is due and the plugin collects it; for P2Flux Native Subscriptions the plugin itself owns that schedule. Either way, P2Flux the service schedules nothing.
Overview
The plugin adds one payment method, P2Flux, to WooCommerce → Settings → Payments. It handles one-time orders and recurring products — simple fixed subscriptions through P2Flux Native Subscriptions, and everything WooCommerce Subscriptions offers through its adapter. Both environments are supported: Base Sepolia for testing with faucet money, and Base Mainnet for real USDC.
Non-custodial means exactly what it says. P2Flux never holds your revenue and cannot move it; there is no balance to withdraw and no payout step. The transaction the customer sends pays your wallet directly, with the P2Flux fee split out inside it.
Requirements
Installation
- Download p2flux-for-woocommerce-1.0.0.zip from the latest release on GitHub.
- In WordPress, open Plugins → Add New → Upload Plugin, upload that ZIP and activate it. The plugin requires WooCommerce and declares that requirement to WordPress.
- Open WooCommerce → Settings → Payments and enable P2Flux.
- Open its settings, enter your payout wallet, choose the environment, and save.
Install the ZIP attached to the release, not GitHub’s “Download ZIP” of the source tree: that archive unpacks under the wrong folder name and carries development-only test fixtures which can shorten billing periods. The plugin is also submitted to the WordPress.org plugin directory and is awaiting review there; until it is published, GitHub is where it comes from.
The method appears at checkout once it is enabled, has a valid payout wallet, and can price the cart — which for a subscription means the cart shape below is one it can honour.
Configuration
Changing the environment or the payout wallet affects new payments and new subscriptions. Existing subscriptions keep paying the wallet the customer authorized, on the environment they were created in — including when they are re-authorized. See Changing settings later.
Test mode
With the environment set to Test, the plugin talks to api-test.p2flux.com and opens pay-test.p2flux.com. Payments settle on Base Sepolia in faucet USDC — the same contracts, the same signatures and the same failure modes as production, with nothing at stake. The checkout and the admin both say “Test mode” so nobody mistakes a test order for revenue.
Faucets: Base Sepolia ETH for gas and Circle for USDC (choose Base Sepolia).
One-time checkout
The customer chooses P2Flux at checkout and places the order. A small P2Flux window opens from that same click, and the order’s pay screen loads behind it, showing the amount in USDC (and the conversion, for a non-USD store) and the progress. Where a browser refuses the window, the pay screen offers one button, Pay with your wallet, that opens it on demand.
If the window closes early — the customer shut it, the browser crashed — the pay screen does not offer to pay again, because the payment may already be on its way. It offers I already paid — check my payment, which asks P2Flux whether the money arrived. The store also asks on its own, at a few points over the next two days, so a payment whose confirmation was lost still marks its order paid without anyone doing anything.
Native Simple Subscriptions
Simple recurring products can use P2Flux Native Subscriptions without any separate subscription extension: WooCommerce plus this plugin is enough. Tick “P2Flux recurring subscription” on an ordinary simple product, choose daily, weekly, monthly or yearly, and the product’s price is the recurring amount. The plugin creates a renewal order each period, collects it, and shows the subscription under My Account → USDC subscriptions and WooCommerce → P2Flux Subscriptions.
Fixed-price, non-taxable virtual products, priced in US dollars, bought one at a time and on their own. Taxes, coupons, shipping, free trials, sign-up fees and variable subscriptions are not supported in native mode. Native mode intentionally supports fewer features than WooCommerce Subscriptions.
Paid through P2Flux only. P2Flux Native Subscription products cannot be paid with other WooCommerce gateways; the checkout offers P2Flux alone for such a cart and refuses anything else server-side. Normal WooCommerce products continue using your existing payment gateways — the P2Flux-only requirement applies only to products using P2Flux Native Subscriptions, not to WooCommerce Subscriptions products.
Activation. The first payment must complete shortly after the customer authorizes it. If the setup expires before payment completes, the subscription is marked expired: it never activated, and it will never charge automatically later. The customer starts a new order. An expired signup keeps its unused wallet authorization on record so the customer can revoke it from My Account.
Renewals and misses. Each renewal is bound to its own billing period. If it cannot be collected, the renewal order is marked failed, the subscription goes on hold, and the customer is emailed what to do. A period that passes unpaid is never collected later — no catch-up billing, no surprise bulk charges after downtime; at most one payment, the current one, is attempted when the store comes back. Missed renewals put the subscription on hold rather than cancelling it; only the customer or the store cancels.
Privacy. The plugin stores no name, address, email, wallet address or IP of its own — those stay in WooCommerce’s records and follow WooCommerce’s personal-data export and erasure. It keeps the financial history of each subscription (amounts, periods, public blockchain identifiers, the encrypted authorization needed for refunds) and registers its own exporter and eraser: erasure unlinks the subscription from the customer and cancels it; the financial rows are retained, as they are on uninstall unless the store opts into destructive removal.
Price changes. An existing subscriber keeps the amount they authorized; a new price applies to new customers only. Disabling the recurring option or trashing the product stops new sales and leaves existing subscriptions running from their stored terms until cancelled.
WooCommerce Subscriptions
With WooCommerce Subscriptions installed, recurring products can be paid with P2Flux. The customer authorizes once, in their wallet, and is never asked again; the store collects each renewal when WooCommerce Subscriptions says it is due.
P2Flux does not schedule charges. WooCommerce Subscriptions decides when a renewal is due, creates the renewal order and asks the plugin to collect it; the plugin asks P2Flux to execute that one charge. The amount, the wallet it pays and the billing period are fixed by what the customer signed — a store cannot change them afterwards.
What the plugin can honour in this version, and what it refuses at the cart rather than sells:
A cart that breaks one of these does not see P2Flux at checkout — in the block checkout the decision travels with the cart itself, so adding or removing an item updates it at once. That is deliberate: a subscription sold under terms the authorization cannot express is a checkout that succeeds and a renewal that can never collect.
Recurring authorization
At signup the pay screen’s button reads Authorize with your wallet. The hosted checkout asks the customer for two things, once: a standard USDC approval (an on-chain transaction, so it costs a little ETH for gas) and a signature over the exact terms — amount, period, your wallet. The signature is not a transaction and costs nothing.
The result is a standing permission the store holds. It is stored encrypted, on your server, and it can only ever pay the wallet the customer authorized — it is not something that could be used to pay anyone else. It never appears in a page, a URL, an email or a log. Before it is stored, the plugin reads the subscription’s own terms from the chain and checks them against the order, so a permission for somebody else’s cheaper plan cannot be attached to this one.
The first payment is collected immediately after authorization, and the checkout window shows the result. If the store’s page is closed before that finishes, nothing is lost: reopening the same authorization link resumes the same subscription rather than creating a second one.
Renewal outcomes
Every renewal ends in one of these, and the order note says which.
Insufficient USDC balance
The authorization is fine; the wallet just does not hold enough. The renewal order is marked failed, WooCommerce Subscriptions puts the subscription on hold, and the customer is told to top up. The store then retries once a day for three days. On the customer’s account page, under the subscription, a Try the payment again button collects immediately once they have topped up, so nobody waits a day for the next scheduled attempt.
If none of that works, the renewal can also be paid by hand from its pay screen like any one-off order. When it is, the plugin cancels the pending automatic collection for that renewal so it cannot be charged twice.
Restore USDC approval
A wallet grants P2Flux’s recurring contract a standing approval to move USDC. If that approval runs short — the customer lowered it, or a wallet tool reset it — renewals fail with “insufficient approval”. The authorization itself is untouched, so the fix is small: one new approval, not a new subscription.
The customer’s account page shows Restore USDC approval. It opens a hosted P2Flux screen that asks their wallet for exactly one approval and nothing else — no signature, no new subscription — and then the store collects the outstanding renewal straight away. The link the store hands the browser for this can approve and can do nothing else: it cannot charge, cancel or refund.
Re-authorization
A new authorization is needed when the old one can no longer be used: the customer revoked it, it passed its end date, or the subscription’s terms changed — a price change, for instance. The plugin never charges an old authorization for new terms: if WooCommerce’s amount or period no longer matches what the customer signed, the renewal is stopped with a note saying so, and nothing is collected.
For changed terms, the customer’s account page explains the new amount and offers Re-authorize: one signature, and the outstanding renewal is collected at once. The old authorization stays on record, so the payments it made remain refundable. A re-authorization keeps that subscription’s original payout wallet and environment, whatever the store’s current settings say — the customer is authorizing the same arrangement at new terms, not a different one.
A revoked or expired authorization ends the subscription; the customer subscribes again.
Cancellation
There are two layers, and the plugin keeps them distinct.
When a subscription is cancelled, the customer’s account page keeps offering Revoke wallet authorization, with a plain explanation that the permission stays in their wallet until they remove it. The store’s side is already done; this is the customer’s cleanup, and it is theirs to decide.
Suspension and reactivation
WooCommerce Subscriptions puts a subscription on hold for two opposite reasons: itself, moments before collecting a renewal, and a person suspending it. The plugin tells them apart and records why.
- A subscription you or the customer suspended is never charged, whatever is queued. Reactivating it resumes the normal schedule; nothing is collected on reactivation and no missed period is caught up.
- A subscription on hold because a renewal failed — insufficient balance, say — may be retried, but only for that renewal and only within the bounded schedule above.
Refunds
A P2Flux refund is a USDC transfer from your own wallet back to the wallet that paid. No server can send money out of your wallet, so WooCommerce’s usual refund button is not offered for P2Flux orders. The order screen has a P2Flux box instead.
Version 1 refunds a payment in full, once. Partial refunds are not offered: the protocol allows exactly one refund per payment, and a partial one would silently use it up. If the wallet window closed before confirmation, the box offers Re-check refund — never a second transfer.
Payment recovery
Money can move while the confirmation gets lost — a closed window, a timed-out request. The plugin treats every such case the same way: it never assumes, and it never asks the customer to pay again while a payment might exist.
Changing settings later
Both the payout wallet and the environment are written into each order and subscription when it is created, and never rewritten.
Supported in v1
Troubleshooting
Security model
- P2Flux never holds your money. Every payment goes from the customer’s wallet to yours in one transaction.
- A message from the checkout window never marks an order paid. Your store verifies every transaction with P2Flux, server-side, against the exact payment it created.
- The recurring permission stays on your server, encrypted. It never reaches a page, a URL, an email or a log, and it can only ever pay the wallet the customer authorized.
- One period pays one order. If WooCommerce ever produces two renewal orders for the same billing period, the second is refused before anything is sent.
- Nothing is paid without a transaction. An order is marked paid only for a settlement the plugin can name, which is what makes it refundable.
For a stronger key than the one the plugin generates, add P2FLUX_WC_ENCRYPTION_KEY to wp-config.php. The plugin’s own documentation describes the key model and how to rotate it.