Why WooCommerce Doesn't Natively Accept Cryptocurrency and How to Fix It
In the WooCommerce core, there are no handlers for blockchain transactions, so accepting crypto requires integration. Two paths: a ready-made plugin from a processor (CoinGate, NOWPayments, Coinbase Commerce) or a custom WooCommerce payment gateway with your own wallet. The difference is in custody, fees, and control level. We use both approaches, and below we break down when each is more profitable.
Common Problems When Integrating Crypto Payments into WooCommerce and How We Solve Them
Exchange Rate Volatility and Amount Fixation
Between order creation and payment, 10–20 minutes pass—the rate can change by 2–5%. If you don't fix the crypto amount, the store risks receiving less money. Our solution: at checkout, we fetch the rate via Chainlink Oracle (or exchange API) and store the equivalent in satoshi/wei. We set an order lifetime of 15–20 minutes; after expiry, the user moves to a new one with the current rate. This reduces slippage risk to 0.1%.
Underpayment and Overpayment
Due to user errors or network delays, part of the funds may not arrive. Our handling:
| Status | Action |
|---|---|
| paid | Full amount—order completes |
| underpaid | Status on-hold, email to manager |
| overpaid | Accept all, excess as bonus or refund |
| expired | Order cancelled, funds not accepted |
We also check a unique _crypto_payment_id to avoid duplicate webhook processing. Duplicate calls don't change order status if already completed. Log via WC_Logger.
How to Choose Between a Ready-Made Plugin and a Custom Gateway
Ready-made plugins (CoinGate, NOWPayments) are good for a quick start: setup takes 1–2 hours, processor fee 1–3%. However, you lose control over funds and can't change processing logic. A custom gateway gives full control: you manage the wallet, fees are only network gas ($0.01–$0.50 per transaction). With volumes over 500 orders per month, a custom solution pays off in 3–4 months and saves up to 40% on fees—2-3 times more profitable compared to ready-made plugins.
How We Do It: A Custom Gateway Case on Polygon
A client once wanted to accept USDT on Polygon with minimal fees. Ready-made plugins didn't fit—they needed their own node and custom refund logic. We developed a WooCommerce Payment Gateway that:
- Uses
ethers.jsto sign transactions on the server (Node.js microservice); - Fixes the rate via Chainlink USDT/USD feed;
- Generates a unique deposit address for each order;
- Processes webhook from the node with signature verification (EIP-712).
Below is the structure of the WC_Crypto_Gateway class. Setup took 5 days; the client got 0% fees (only gas ~$0.01 per transfer) and full control.
class WC_Crypto_Gateway extends WC_Payment_Gateway {
public function __construct() {
$this->id = 'crypto_gateway';
$this->method_title = 'Crypto Payment';
$this->method_description = 'Accept cryptocurrency payments';
$this->has_fields = false;
$this->supports = ['products'];
$this->init_form_fields();
$this->init_settings();
$this->title = $this->get_option('title');
$this->description = $this->get_option('description');
$this->api_key = $this->get_option('api_key');
add_action('woocommerce_update_options_payment_gateways_' . $this->id,
[$this, 'process_admin_options']
);
add_action('woocommerce_api_' . $this->id, [$this, 'handle_webhook']);
}
public function process_payment($order_id) {
$order = wc_get_order($order_id);
// Create payment request via our API
$payment = $this->create_crypto_payment([
'amount' => $order->get_total(),
'currency' => get_woocommerce_currency(),
'order_id' => $order_id,
'callback_url' => WC()->api_request_url($this->id),
'success_url' => $this->get_return_url($order),
]);
if (is_wp_error($payment)) {
wc_add_notice('Payment error: ' . $payment->get_error_message(), 'error');
return ['result' => 'fail'];
}
// Save external ID for reconciliation
$order->update_meta_data('_crypto_payment_id', $payment['id']);
$order->update_status('pending', 'Awaiting crypto payment');
$order->save();
return [
'result' => 'success',
'redirect' => $payment['payment_url'],
];
}
public function handle_webhook() {
$payload = file_get_contents('php://input');
$data = json_decode($payload, true);
if (!$this->verify_webhook_signature($payload, $_SERVER['HTTP_X_SIGNATURE'] ?? '')) {
status_header(400);
exit('Invalid signature');
}
$order = wc_get_order($data['order_id']);
if (!$order) {
status_header(404);
exit('Order not found');
}
switch ($data['status']) {
case 'paid':
$order->payment_complete($data['payment_id']);
$order->add_order_note(sprintf(
'Crypto payment confirmed. Received %s %s',
$data['amount_received'],
$data['currency']
));
break;
case 'expired':
$order->update_status('cancelled', 'Crypto payment expired');
break;
case 'underpaid':
$order->update_status('on-hold', sprintf(
'Underpayment: expected %s, received %s',
$data['amount_expected'],
$data['amount_received']
));
break;
}
status_header(200);
exit('OK');
}
}
Plugin Registration
// crypto-payment-gateway.php (in wp-content/plugins/)
/**
* Plugin Name: Crypto Payment Gateway
* Description: Custom cryptocurrency payment gateway
* Version: 1.0.0
* Requires Plugins: woocommerce
*/
if (!defined('ABSPATH')) exit;
add_action('plugins_loaded', function() {
if (!class_exists('WC_Payment_Gateway')) return;
require_once plugin_dir_path(__FILE__) . 'includes/class-wc-crypto-gateway.php';
});
How to Set Up Crypto Payments on WooCommerce
- Choose integration method—ready-made plugin or custom gateway. If you need non-custodial acceptance without intermediaries, go custom.
- Install and activate the plugin (if ready-made) or deploy your own microservice for signing transactions.
- Configure gateway parameters—wallet address, limits, order lifetime (we recommend 15–20 minutes).
- Add webhook URL in provider settings or your node. URL format:
https://example.com/wc-api/crypto_gateway. - Test in sandbox—pay a test order, check underpayment, expiry, duplicate webhooks.
- Go live—after successful testing, enable active mode. Monitor via
WC_Logger.
How We Test and Guarantee Reliability
We always go through scenarios in sandbox: successful payment, expiry, underpayment, duplicate webhook, rate reset. We use WC_Logger for all events.
| Stage | What We Do | Duration |
|---|---|---|
| Analysis | Gather requirements, choose provider or write spec for custom | 1–2 days |
| Implementation | Code gateway, webhook, handlers | 3–7 days |
| Testing | Cover all cases in sandbox | 1–2 days |
| Deployment | Deploy to production, set up monitoring | 1 day |
What's Included
- Selection and setup of payment provider (CoinGate, BTCPay Server, own node) or custom gateway development from scratch.
- Full WooCommerce Payment Gateway class with all status support.
- Webhook handler with HMAC verification.
- Edge case handling: rate difference, underpayment, expiry, duplicates.
- Gas optimization for smart contracts (using
uncheckedblocks,Packedstructs)—cost reduction by 15–20%. - Integration with
WC_Loggerfor debugging. - Installation and operation documentation.
Our team has 6+ years of blockchain development experience and over 40 successful payment system integrations in WooCommerce. Have a difficult case? Get a consultation—we'll find the optimal solution for your budget and timeline. Contact us for a cost estimate. Order crypto payment integration for WooCommerce, and we'll configure everything for your business.







