Built for Drupal agencies and site builders
If you build and maintain Drupal Commerce sites for clients, a payment integration has to meet a few unwritten rules: it should use Commerce's own plugin types, store configuration where Drupal expects it, log to the places site admins already check, and survive a core update without surprises.
The commerce_payfim module is written that way. It provides a single off-site payment gateway plugin built on OffsitePaymentGatewayBase, so it is configured as a normal payment gateway config entity, works with gateway Conditions, and receives notifications on Commerce's standard /payment/notify/[gateway] route. There is no custom checkout pane to maintain and no extra route to open in your firewall.
What your client gets is a crypto option that pays into wallets they control, through a self-hosted Payfim Gateway on their own hosting. Payfim takes no transaction fees and holds no funds, which usually makes the conversation about processor contracts very short.
How payments map to Commerce entities
At the payment step, the module creates the crypto invoice on the server from $order->getTotalPrice() and redirects the customer to the gateway. The browser never carries the amount. When the gateway reports a status change, the module verifies the webhook, re-reads the invoice, compares amount and currency with the order total, and then acts:
| Payfim status | What happens in Commerce |
|---|---|
| Paid | One payment in state Completed, remote ID = Payfim invoice ID; the order is placed if the customer never came back to the site |
| Underpaid | A payment in state Authorization that does not count toward the order balance |
| Confirming | A note in the order data and activity log |
| Expired / cancelled | Cancels a placed, unpaid order if its workflow allows Cancel and Payfim is still the order's gateway; draft orders stay in checkout |
Because the remote ID is the Payfim invoice, the same payment entity is updated as an invoice goes from underpaid to paid, and a repeated webhook finds the existing payment instead of creating a second one. Processing runs inside a per-order lock and reloads the order unchanged before touching it.
The transaction hash lives in the order data and, with the Commerce Log module enabled, in the order's activity stream along with the coin and amount received.
Underpayments: Capture or Void, your call
An underpayment is the most common exception in crypto checkout, typically caused by an exchange subtracting its withdrawal fee. Rather than inventing a custom state, the module uses Commerce's own authorization model. The short payment appears on the order's Payments tab as an Authorization:
- Capture accepts it. Commerce lets you enter the lower amount actually received.
- Void rejects it, after which you refund the customer from the wallet.
Nothing is marked paid automatically when the amount is short. See how to handle crypto underpayments and refunds for a policy you can hand to your client's support team.
Configuration, secrets and deployment
The gateway form has a Gateway URL field, a password-type API key field that is never sent back to the browser (leave it empty to keep the saved key), a Description shown under the option at checkout, a debug switch and an AJAX Test connection button that works with unsaved values.
One thing to plan for in a config-managed workflow: like every Commerce gateway, the API key is stored in the payment gateway configuration entity, so it ends up in your config exports. Keep exported configuration out of public repositories and treat it as a secret.
Outbound calls use Drupal's own Guzzle http_client with certificate verification on, redirects off and short timeouts. Errors go to the commerce_payfim logger channel, visible under Reports → Recent log messages; the API key is never logged. For the wider security model, see our security overview.
Testing before you hand the site over
A crypto integration is easy to test on a staging copy, provided the gateway can reach it over HTTPS. A sensible go-live checklist:
- Run Test connection on the gateway form. It reports the store name, the gateway version and whether the license is valid.
- Use the test payment feature in the Payfim gateway admin to confirm the gateway itself sees your wallets and coins.
- Place a real low-value order with a cheap coin and check the order's Payments tab and activity.
- Open the Webhooks page in the Payfim dashboard: every delivery shows the HTTP status your site returned.
- If something fails, switch on Debug logging and filter Recent log messages by the
commerce_payfimtype.
Make sure the gateway's cron job runs every minute on the client's hosting; it keeps blockchain checks and webhook retries on schedule.
Requirements
| Drupal core | 10.1 - 11 |
|---|---|
| Drupal Commerce | 2.x and 3.x (requires the Commerce Payment submodule) |
| PHP | 8.1 - 8.4 |
| Plugin type | Off-site payment gateway with authorization support |
| Optional | Commerce Log, for crypto events in the order activity |
| Gateway | Payfim Gateway 3.0+ on HTTPS (included in your download) |
The module is distributed as a zip for modules/custom rather than through drupal.org, and is licensed GPL-2.0-or-later like Drupal itself.
One gateway, several client sites
Each Drupal site needs its own module license for its domain, but the Payfim Gateway is a separate application. An agency can run one gateway per client, which keeps wallets and invoices separated, and connect any other platform that client uses. Building something that is not Drupal at all? The PHP & Laravel SDK talks to the same gateway API.
Two add-ons are useful for agency work. White-label removes the "Powered by Payfim" line from the checkout, so the payment page carries only your client's brand. The installation service covers setting up the gateway if your team would rather not.
How to install the Drupal Commerce crypto payment gateway
- Prepare the gateway. Install the Payfim Gateway on the client's hosting (for example
pay.clientsite.com) and add their receiving addresses. See Install the Payfim gateway. - Add the module. Unzip
commerce_payfim.zipintomodules/custom/(web/modules/custom/on Composer-based sites), then enable Commerce Payfim (Crypto payments) under Extend, or rundrush en commerce_payfim. - Create the payment gateway. Go to Commerce → Configuration → Payment → Payment gateways, click Add payment gateway, give it a name and select the Payfim plugin.
- Connect and enable. Enter the Gateway URL and the API key from the gateway's Integrations page, click Test connection, set Status to Enabled and save. No webhook URL needs to be copied anywhere.
- Check the checkout flow. Make sure your checkout flow contains the Payment information and Payment process panes, then place a test order. The Drupal Commerce setup guide has troubleshooting tips.
