What is the best crypto payment plugin for Magento 2?
Key takeaways
- Judge any module on six checks: where the money settles, what marks an order paid, how it handles duplicate webhooks, whether it survives production mode, which coins and networks it takes, and whether you can read the code.
- No card fields on your checkout. Payzum's module loads no third-party script on the Magento checkout and sends the buyer to a hosted page. It adds nothing to the script inventory that PCI DSS requirement 6.4.3 has demanded since 31 March 2025.
- The webhook decides, inside a database lock. A Magento invoice is created only when a signed HMAC-SHA-512 notification arrives and its amount and currency match the order. The order row is locked first, so a retried delivery can never invoice it twice.
- Install in four commands, configure on one screen. Unzip the release into
app/code/(or use Composer), run the usualbin/magentocommands, then fill in Stores → Configuration → Sales → Payment Methods. There is no webhook URL to paste anywhere. - Know the limits: it ships a renderer for Magento's standard Luma checkout, not Hyvä Checkout or a headless front end. It doesn't handle admin-created or multi-address orders, and refunds are sent from your wallet.
Payzum is a non-custodial, stablecoin-first crypto payment processor: payments settle directly to wallets the merchant controls. Its Magento 2 crypto payment plugin is the module Payzum_CryptoPayments (Composer package payzum/module-crypto-payments), open source under OSL-3.0 at github.com/payzum-dev/magento2-payzum. This guide gives you a neutral way to compare any crypto module for Magento, then walks through version 1.2.0, whose release zip was published on 28 September 2026: install, configuration, and what happens to the order at every step of a USDC or USDT payment.
Why Magento stores add USDC and USDT at checkout
Magento isn't the biggest cart by count. W3Techs puts Adobe Commerce (Magento) on 0.3% of all websites and 1.6% of sites with a known e-commerce system (1 October 2026). But it is the cart merchants choose for complex selling: B2B price lists, several store views and currencies, large catalogs and integrations with ERP and warehouse systems. Those stores sell across borders, and cross-border is where cards cost the most.
Take PayPal Braintree's published US pricing (checked 1 October 2026): 2.89% + $0.29 per card transaction, an extra 1% when the card was issued outside the US, another 1% when the sale is in a currency other than the dollar, and $15 per chargeback. A euro sale paid with a foreign card costs 4.89% + $0.29 before anything ships. And the money is still reversible for months.
Magento merchants carry a second card cost that rarely shows up on a fee schedule: the checkout page itself is a target. In summer 2024, attackers exploited CosmicSting (CVE-2024-34102), a flaw Adobe patched on 11 June 2024. Sansec reported on 1 October 2024 that seven groups had hacked 4,275 stores, and that five percent of all Adobe Commerce and Magento stores ended up with a payment skimmer on their checkout page. A skimmer only pays if buyers type card numbers into your site.
Then there are the buyers who don't want a card at all: trade customers who settle large invoices in USDT, shoppers whose card is declined abroad, crypto-native communities. For them, a checkout without a stablecoin option is an abandoned cart, or a wire transfer that takes days to arrive.
What a badly built crypto module costs a Magento store
Adding crypto doesn't remove risk on its own. Payment modules fail in Magento-specific ways, and each failure costs money or a weekend:
- Orders nobody can pay. Many offsite payment methods create the external invoice in a second browser request, fired after Magento places the order. If the confirmation email throws, the request times out or the buyer closes the tab in between, the order exists and the invoice doesn't. It sits in Pending forever, and nothing flags it.
- Orders marked paid by the success page. If the module trusts the buyer landing on
checkout/onepage/success, anyone can load that URL without paying. Crypto confirmation is asynchronous, and the browser is the wrong witness. - Two invoices for one payment. Providers retry webhooks. Two deliveries that arrive together can both read a not-yet-invoiced order and both invoice it. In Magento's books, that is the same as charging the buyer twice.
- Underpayments invoiced in full. A buyer sends $1,800 against a $2,000 order. A module that only reads "status: finished" creates the invoice anyway, and the shipment follows.
- Paid orders cancelled late. An "expired" notice can arrive after the invoice was paid. Cancelling a Magento order returns its items to stock, so a late notice can undo a sale that already happened.
- A method that is configured and still invisible. A payment method can be enabled, available and registered and still be filtered out of checkout, with nothing logged. Another classic: a module that reads its encrypted API key without decrypting it gets a 401 on every call, which looks exactly like an attack.
- Breakage in production mode. A module that only works in developer mode fails at
setup:di:compile, usually during a deploy, which is the worst time to find out. - Funds parked in someone else's balance. Custodial crypto gateways collect your sales in their wallet and pay you later, on their schedule, minimums and freeze policy.
Why card gateways and custodial crypto modules fall short on Magento
Card modules are mature, but the rail sets the terms. The acquirer holds the funds, decides when they settle and can pull them back through a dispute. And every card field on your checkout is in scope for PCI DSS 4.0.1. Since 31 March 2025, requirements 6.4.3 and 11.6.1 make you inventory and authorize every script that runs on a payment page and detect tampering at least weekly. Adobe added Content Security Policy restrict mode and Subresource Integrity on payment pages in Magento 2.4.7 (9 April 2024) to help with exactly that.
Custodial crypto modules fix acceptance but not custody. The buyer pays the gateway's address, the gateway credits a balance, and you withdraw when it allows. That balance is exactly what a provider can freeze, or lose if it shuts down.
The DIY route keeps custody and drops everything else. A wallet address in the order email gives you no unique amount per order, no underpayment detection, no Magento invoice and no status change. Someone ends up matching blockchain transactions to increment IDs by hand.
What a Magento store needs is a module that behaves like any other payment method in the admin (a configuration group, real invoices, order comments) but settles like crypto: final, in seconds, to a wallet you control.
How to choose a Magento 2 crypto payment plugin: six checks
"Best" depends on what you need, but six questions separate a module you can run in production from one you will regret. Ask them of any vendor, including us:
- Where do the funds settle? In your own wallet, or in a balance the provider holds and pays out later? Only the first leaves nobody able to freeze the money.
- What marks the order paid? It should be a server-to-server webhook whose signature is verified over the raw request bytes, with a replay window, and whose amount and currency are checked against the order. The return URL should never count.
- What happens when the webhook arrives twice? Look for deduplication by event ID and a database lock around the invoice step. Without them, retries become duplicate invoices.
- Does it run in production mode? It should pass
setup:di:compile, use Magento's payment gateway adapter rather than a core override, and state which Magento and PHP versions it supports. - Which coins and networks, and who decides? USDC and USDT on low-fee networks cover most buyers. The accepted list should be enforced on the provider's side, not only in a dropdown in your admin.
- Can you read the code? An open-source module lets your developer check how the webhook is verified and where the money goes before it touches a live order.
Our guide to open-source crypto payment plugins turns checks 2, 3 and 6 into a 15-minute audit you can run on any repository.
How Payzum's Magento 2 module handles a USDC payment
The module is a standard Magento payment method built on the payment gateway adapter. It has one job: turn an order into a Payzum invoice, then let a signed webhook, and nothing else, decide the outcome.
At checkout: a hosted page and the buyer's choice of coin
The buyer picks Payzum (labelled "Crypto / Stablecoins (Payzum)" by default) and clicks Place Order. The module creates the Payzum invoice in the same request that places the order, through an observer on sales_order_place_after. By the time the browser learns the order exists, the invoice exists too. The redirect step only retries if Payzum was unreachable at that moment, and both paths share an idempotency key, so they can't create two invoices.
Payzum receives the order total, the currency, the order number and your callback URLs. No customer personal data leaves your store. The buyer lands on a hosted checkout with a QR code and a deposit address, chooses the coin and network, and pays from any wallet without creating an account.
The module never picks the coin. Your accepted tokens live in the Payzum dashboard under Merchants → Settings → Accepted tokens, enforced server-side. For most stores that means USDC and USDT on fast, low-fee networks: Solana confirms in about 0.4 seconds, Base and Polygon in about two. If you also accept other crypto, optional auto-convert to USDC or USDT is available on most supported networks. The trade-offs between the two stablecoins are in USDT vs USDC for payments.
The checkout renderer is a local Knockout component served from your own static files. It loads no third-party script on the payment page, so under 2.4.7's restrict-mode CSP it needs no whitelist entry, and it adds nothing to your 6.4.3 script inventory. It doesn't make your card methods' PCI scope disappear, but a buyer who pays this way never types a card number into your store.
After payment: the signed IPN is the only source of truth
Payzum calls https://your-store.com/payzum/ipn/index server to server. Before reading a single field, the module verifies an HMAC-SHA-512 signature over the raw request bytes with your webhook secret, compares it in constant time, and rejects replays outside a 10-minute window. A bad signature gets a 401 and the order isn't touched.
Then it locks the order row (SELECT … FOR UPDATE), reloads the order and checks the event ID against the ones it has already applied. On a finished payment it compares the amount and currency paid with the order's grand total. Only if they match does it create a Magento invoice (captured offline, with the Payzum transaction ID) and move the order to Processing. If anything fails mid-way, it rolls back and answers 503 so Payzum retries the delivery. Never a 200 for a payment it hasn't recorded. The engineering behind this pattern is in signed webhooks for crypto payments.
The HTTP client and signature check come from the official payzum/payzum-php SDK. It ships inside the module's vendor/ folder, so an app/code install needs no Composer step.
Where the money goes
Nowhere near Payzum. The buyer's payment goes from their wallet straight to the wallet you set in your dashboard, and the module's code contains no wallet address at all. There is no Payzum balance to withdraw, freeze or wait for. The full model is explained in what a non-custodial crypto payment processor is.
How to set up the Magento 2 crypto payment plugin, step by step
You need Magento Open Source or Adobe Commerce on the 2.4 line and PHP 8.1 or later. Shell access to run bin/magento helps. Most of the time goes into the staging test, which is the step worth doing properly.
- Set up your Payzum merchant account. Sign up at merchant.payzum.com, add the wallet you want to be paid into and choose your accepted tokens, for example USDC on Base, Solana and Polygon, plus USDT. Create an API key (64 hexadecimal characters) and note your webhook (IPN) secret.
- Install the module. Download
payzum-magento2-1.2.0.zipfrom the repository's Releases page and unzip it insideapp/code/. The archive already contains thePayzum/CryptoPayments/folder, so the module lands atapp/code/Payzum/CryptoPayments. Don't use GitHub's green "Download ZIP" button: it unpacks tomagento2-payzum-main/, which Magento won't load. If you manage the store with Composer, runcomposer require payzum/module-crypto-paymentsinstead. - Enable it. Run
bin/magento module:enable Payzum_CryptoPayments, thenbin/magento setup:upgrade,bin/magento setup:di:compileandbin/magento cache:flush. Production mode is fully supported. - Configure it. Open Stores → Configuration → Sales → Payment Methods → Payzum — Crypto & Stablecoins. Set Enabled to Yes, paste the API key and webhook secret, and set Environment to Staging for now. Staging has its own API keys; a production key won't work there.
- Check that the webhook can reach you. There is nothing to paste: the module sends its own IPN URL with every invoice. Just make sure
/payzum/ipn/indexon your store's base URL accepts POST requests from the internet. A staging site behind basic auth or an IP allowlist will never hear back. - Test on staging. Place an order. The order history shows "Payzum invoice created — awaiting payment". Pay it and watch an invoice appear and the order move to Processing. Then underpay one order on purpose and confirm it goes On Hold.
- Go live. Switch Environment to Production, paste your production API key and secret, flush the cache and place one small real order.
The configuration screen at a glance
| Setting | What to enter | Scope |
|---|---|---|
| Enabled | Yes, to show Payzum as a payment method at checkout. | Default, website |
| Title | What buyers see. Default: "Crypto / Stablecoins (Payzum)". Translate it per store view. | Default, website, store view |
| API Key | Your 64-character key from the Payzum dashboard. Stored encrypted. | Default, website |
| Webhook secret | The IPN signing secret that verifies every HMAC-SHA-512 signature. Stored encrypted. | Default, website |
| Environment | Production (merchant.payzum.com) or Staging (staging.payzum.com, separate keys). | Default, website |
| New order status | The status a freshly placed, not-yet-paid order gets. | Default, website |
| Sort order | Where Payzum appears among your payment methods. | Default, website |
There is deliberately no coin picker and no signature-header field. Accepted tokens live in your Payzum dashboard, and the signature header is fixed by the SDK, so nothing on this screen can drift out of sync with your account.
What happens to the Magento order at each step
| What happened | Effect in Magento |
|---|---|
| Order placed | Your configured new-order status, with the comment "Payzum invoice created — awaiting payment (buyer picks the coin)" |
Payment finished, amount and currency match | Invoice created (captured offline), order → Processing, transaction ID in the history |
Payment finished, amount or currency don't match | Not invoiced. Both figures go to the order history and the log, marked "manual review required" |
| Partially paid | Order → On Hold, awaiting the remainder |
| Remainder arrives | Hold released, invoice created, order → Processing |
| Invoice expired, or payment failed | Order cancelled, unless it was already invoiced |
| Still waiting | A status-history comment only |
| Same event delivered again | Ignored: event IDs are deduplicated |
| Grand total of zero (100%-off cart rule) | Order → Processing without a crypto invoice |
Nothing in this table is triggered by the buyer's browser. A closed tab never loses a paid order, and a visit to the success page never marks an unpaid one.
Use cases: Magento stores that take USDC and USDT
The setup is the same for every store. What changes is which part of it pays for itself.
- B2B distributor taking trade orders. An industrial-parts distributor runs its trade catalog on Magento and takes $18,000 orders from buyers in other countries. On a card at Braintree's US rates plus the international surcharge, one order would cost $700.49 in fees. A wire takes days and arrives short of bank charges. Paid in USDT on a low-fee network, the order is invoiced seconds after confirmation. If the buyer's treasury sends it in two transfers, the order waits On Hold until the second one lands.
- Brand with several store views. An apparel brand runs English, Spanish and Portuguese store views and sells into Latin America, where most of its card sales pay both the international and the currency surcharge. It sets one API key at website level and translates the payment-method title per store view ("Paga con USDC o USDT"). The money from every store view lands in the same wallet.
- High-ticket electronics. A store averaging $2,400 per order pays $69.65 in card fees per sale at 2.89% + $0.29. A stolen-card order can come back weeks later as a $15 chargeback plus the lost goods. A USDC payment is final once confirmed, and the amount check means the order is only invoiced when the full $2,400 has arrived.
- A store that has been skimmed before. After a CosmicSting-era cleanup, a merchant wants to give returning buyers a way to pay that involves no card number on the site. Payzum appears as one more method; the payment happens on the hosted page. The card methods stay in PCI scope, but every buyer who switches is one fewer card typed into the checkout.
Payzum for Magento 2 vs a card module, a custodial crypto module and a self-hosted server
Compared on neutral criteria. Card figures are PayPal Braintree's published US pricing, checked on 1 October 2026.
| Criterion | Card module (PayPal Braintree) | Custodial crypto module | Self-hosted crypto server | Payzum for Magento 2 |
|---|---|---|---|---|
| Where the funds settle | With the acquirer, then paid out to your bank | In the gateway's wallet, then withdrawn | In your own wallet | In your own wallet, directly |
| Time until you hold the funds | Days | Depends on the provider's payout schedule | On-chain confirmation | Seconds after on-chain confirmation (Solana ~0.4 s, Base and Polygon ~2 s) |
| Chargebacks | Yes, for months after the sale; $15 each | None on-chain | None on-chain | None: payments are final |
| Cost per order | 2.89% + $0.29, +1% international card, +1% non-USD | Varies by provider | Free software; you pay for hosting and upkeep | Network cost in cents on Base, Polygon or Solana |
| Who can freeze the money | The acquirer | The gateway | No third party | No one at Payzum: there is no Payzum balance |
| Card data on your checkout | Yes: in PCI DSS scope | No | No | No: hosted page, no third-party script |
| What you operate | The module | The module | The server, its updates and its chain connections | The module; Payzum runs the hosted checkout |
| Module source code | Check the vendor | Varies | Usually open source | Public on GitHub, OSL-3.0 |
A self-hosted server is a fair choice if you want no third party at all and have someone to run it. Payzum is for stores that want the same custody without operating payment infrastructure. And nothing stops you from keeping your card module: most stores add Payzum as one more payment method, and Sort order decides where it appears.
Common objections, answered
"My customers don't have crypto."
Most of them don't need to. Payzum is an extra payment method next to your cards, not a replacement. The buyers who choose it are the ones who would otherwise abandon the cart, wire you money days late or trigger your highest card surcharges.
"What about volatility?"
Your prices stay in your store currency: the module sends the order's grand total in the order currency, and the buyer pays the equivalent in the coin they pick. If you accept only USDC and USDT, you receive dollar stablecoins. If you accept other crypto too, optional auto-convert to USDC or USDT is available on most supported networks.
"After CosmicSting, I don't install modules on trust."
Good, and you don't have to. The code is public under OSL-3.0, the same license as Magento Open Source. The webhook handler is Controller/Ipn/Index.php: it skips Magento's form key check only because every request must carry a valid HMAC signature instead. The API key and secret are stored with Magento's encrypted backend model, there is no wallet address in the code, and the only data sent out is the total, currency, order number and callback URLs.
"How do refunds work if payments are final?"
Through Magento's own credit-memo flow. Because the invoice was captured offline, you create an offline credit memo on the order, then send the USDC back from your wallet under the refund policy you publish. You decide when money goes back; a card network doesn't decide for you.
Frequently asked questions
What is the best crypto payment plugin for Magento 2?
The best Magento 2 crypto payment plugin settles to a wallet you control, invoices orders only from a signed server-to-server webhook with the amount checked, handles duplicate webhooks safely, runs in production mode and has code you can audit. Payzum's open-source module (OSL-3.0) meets all of these for Magento 2.4 and Adobe Commerce, with USDC and USDT settled non-custodially and no chargebacks.
How do I accept USDC and USDT payments on Magento 2 or Adobe Commerce?
Install Payzum's module from its release zip into app/code/Payzum/CryptoPayments, or with composer require payzum/module-crypto-payments. Run module:enable, setup:upgrade, setup:di:compile and cache:flush, then paste your API key and webhook secret under Stores → Configuration → Sales → Payment Methods. Choose USDC, USDT and their networks as accepted tokens in your Payzum dashboard.
Which Magento versions does the Payzum module support?
Magento Open Source and Adobe Commerce on the 2.4 line (magento/framework 103.0), with PHP 8.1 or later. It is compatible with setup:di:compile and production mode. It ships a renderer for the standard Luma checkout; Hyvä Checkout and headless front ends are not covered by the module itself.
Which Magento order status is set when a crypto payment arrives?
When a signed webhook reports the payment finished and the amount and currency match, the module creates an invoice and moves the order to Processing. A partial payment puts the order On Hold until the remainder arrives. Expired or failed invoices cancel the order unless it was already invoiced. A mismatched amount is never invoiced and is flagged for manual review.
Is the Payzum module on the Adobe Commerce Marketplace?
No, as of 1 October 2026. The module is public on GitHub at payzum-dev/magento2-payzum under OSL-3.0, with a packaged release zip, and it is published on Packagist as payzum/module-crypto-payments for Composer installs.
What happens if a customer underpays a Magento order in crypto?
The order goes On Hold with a note that a partial payment was received. When the buyer sends the remainder, the finished webhook releases the hold, creates the invoice and moves the order to Processing. Nothing is invoiced until the full amount, in the order's currency, has been paid.
Book 20 minutes and we'll get USDC live on your Magento store
Every Magento store is set up differently: websites and store views, Luma or a custom checkout, ERP sync, B2B accounts, markets. Book 20 minutes with our team and we'll map how you'd accept USDC and USDT in yours: accepted tokens and networks, configuration scopes, how the order states fit your fulfilment, and a staging order before you go live. Non-custodial, to a wallet you control. Running more than one cart? See the WooCommerce setup guide and the drop-in crypto payment plugin overview.
If the calendar does not load, book directly here · [email protected]
This article is general information, not legal, tax, security or financial advice. The module is provided under the OSL-3.0 license in its repository; test it on staging before using it in production. PCI DSS obligations depend on how your store accepts cards, so confirm your scope with your acquirer or a Qualified Security Assessor. Refund rules, accounting treatment and tax obligations for stablecoin payments vary by jurisdiction; confirm them with your own advisers.