WooCommerce
Futa Payments for WooCommerce adds Futa as a payment method under WooCommerce’s payment settings, in the classic checkout and in the Cart and Checkout Blocks. At checkout the customer is sent to Futa’s hosted checkout to pay by mobile money or bank, then comes back to the order-received page. The order is marked paid only when Futa says so, by its signed webhook or a status read, never by the customer’s return.
Before you install
Section titled “Before you install”- Versions. PHP 8.1 or later, WordPress 7.0 or later and WooCommerce 11.0 or later; tested on PHP 8.1 and 8.4 with WordPress 7.1.3 and WooCommerce 11.2.1. Compatible with WooCommerce’s order tables (HPOS).
- Where it comes from. The plugin is not yet listed in any marketplace, WordPress.org’s directory included. Its
folder,
futa-payments-for-woocommerce, is in Futa-payer-web underplugins/woocommerce/: for sandbox testing, by those Futa has given access to Futa-payer-web, copy it into the shop’swp-content/plugins/and activate it beside WooCommerce, which it requires. - Licence. MIT is its intended licence, a placeholder that grants nothing until Futa rules on it; until then the code is all rights reserved.
- Sandbox only. Futa’s merchant API takes sandbox keys only for now, and the plugin refuses any other.
Settings
Section titled “Settings”- Enter a sandbox merchant key (
sk_test_…) for this shop only, with six permissions:payments:read,payments:write,refunds:readandrefunds:writefor payments and refunds, andwebhooks:readandwebhooks:managefor the subscription in step 2. In the developer console only an Owner or an Admin can delegate the refund permissions. Then enter the webhook signing secret (whsec_test_…) and the API base: by defaulthttp://host.docker.internal:18130, the local sandbox’s merchant API as a shop in a container reaches its host; for the hosted sandbox,https://api.sandbox.futa-app.com. - Register the receiver address the settings show, WordPress’s REST route
futa/v1/webhooks, as your Futa webhook endpoint. In the local sandbox, Futa delivers only tohttp://127.0.0.1on ports from 18161 to 18169: use this shop’s address on such a port with the same path. In the hosted sandbox no delivery reaches the shop: Futa delivers only to its own test receiver, which answers them and keeps nothing, so the plugin learns each outcome from its background checks, the sweep of your approved payments included. The subscription below reads your endpoint and is refused without one, so add it first in the developer console, on the test receiver,http://127.0.0.1:18161/sandbox/webhooks, or leave the subscription out there. Then press “Subscribe your Futa endpoint to these events”: it reads your endpoint and chooses its events, the payment events, every refund event andobligation.collected, including those Futa leaves off by default, and a key withoutwebhooks:readandwebhooks:manageis refused. Without that subscription, or the same events chosen in the endpoint’s configuration,refund.pending_approval,refund.rejected,refund.expiredandobligation.collectednever arrive, and the plugin learns of those changes only through its background checks. - Serve the shop over https: Futa returns customers only to an https address, and the method is not offered otherwise.
The key and the secret stay on the server: they are never shown again after saving, sent to a browser, answered by
WooCommerce’s REST API or written to the log. Futa’s checkout address is never logged or stored. The receiver checks
Futa-Signature on the raw body and answers 400 to a delivery it refuses, and 503 while the order is busy, so
Futa delivers it again.
Amounts
Section titled “Amounts”US dollars (USD) and Congolese francs (CDF) only, sent in integer minor units without rounding. A CDF total with
centimes, or a total finer than two decimals, is refused before the customer leaves the shop: set the shop’s prices
to zero decimals for CDF.
How it handles money
Section titled “How it handles money”- One payment at a time. A customer who comes back to an unpaid order is sent back to that payment’s own page on
Futa while it is
CREATED. While a payment waits for the customer’s approval or is uncertain, the order stays on hold, and WooCommerce’s stock hold does not cancel it. - The wait after a decline or an expiry. A declined or expired payment can still be completed on Futa’s page for a while, so the order waits, on hold, and no new payment is asked for until Futa confirms the payment can no longer be collected: its time limit has passed, by five minutes on the shop’s clock, with nothing open on Futa’s page. Meanwhile the customer is told when they can try again, or that a payment is still being confirmed. If Futa has still not confirmed it 24 hours past the time limit, an admin notice names the order.
- Duplicates held for your review. The order’s first collection pays it, once, however its approval arrives. A payment approved for an order that no longer awaits payment (cancelled, in the trash or already paid), or for another amount or currency, is held for your review with a note and an admin notice: never fulfilled twice, never refunded automatically. It stays flagged until you dismiss it on the order screen, once you have refunded it in the Futa portal or decided; dismissing clears the flag alone: it pays and refunds nothing, needs the right to edit orders and is noted on the order with your name. Its refunds, as Futa lists them, are shown beside the flag, never as refunds of the order.
- Refunds recorded once completed. Refunds are asked from the order screen and go through Futa, from the payment that paid the order. A refund is recorded on the order only once Futa completes it: until then the order notes say where it stands, including when a person must approve it in the Futa portal. Refunds made in the Futa portal are recorded on the order when they complete.
- One refund in flight. At most one Futa refund is in flight per order: while one is pending, waiting for approval, uncertain, unanswered or about to be sent, the order screen shows it and no other is sent. The same refund, of the same amount and items, asked again after the first ended is answered with its outcome and never sent twice; to send another refund of the same amount, first choose “Confirm a new Futa refund of the same amount” in the order’s actions and update the order.
- Four background checks. Four separate checks are due every minute, within at most 10 requests a minute in fixed
shares and 50 orders a run for each: the open payments and held orders (3 requests); the pending refunds and the
refund requests whose answer was lost, sent again (2); the refunds of the orders it paid, within Futa’s 180-day
refund window, and of the held payments (2); and a sweep of your approved payments, each matched to its order by
the payment id the order stores, else by its order number, for one a lost webhook left behind (3). A share counts
per clock minute, the minute a check’s run starts in, so by send time a check can make up to twice its share in 60
seconds across a minute’s turn. They are WordPress scheduled events, so they run only when a request reaches
WordPress: on a quiet shop they wait for the next visitor. For them to run on time, set
DISABLE_WP_CRONand callwp-cron.phpevery minute from the server’s cron. One shop per merchant key: those 10 requests are planned for one shop on the merchant’s quota.
What it sends to Futa
Section titled “What it sends to Futa”- When a customer pays: the order number, its amount and currency, a description made of the order number and the shop’s name, the order-received address and an expiry.
- When a payment is read, from the order-received page, a returning customer or the background checks: the payment’s id, to read it, its obligation or its refunds, or to cancel it with the unpaid order.
- When the sweep lists approved payments: the state and the earliest date of the payments to list.
- When you refund: the payment’s id, the amount and your reason.
- When you subscribe the endpoint: the list of events.
No customer name, address, e-mail or phone number is sent.