LayerHopDocsLaunch app (opens in a new tab)

WordPress and WooCommerce

Accept crypto in a WooCommerce store or on any WordPress site with the LayerHop plugin. Customers pay with any token on any chain; orders are marked paid automatically once LayerHop verifies the payment on chain.

The LayerHop plugin adds a "Crypto (any token)" payment method to WooCommerce and a [layerhop_button] shortcode for any WordPress site. Customers pay with any token on any chain they hold; you receive USDC or USDT on the chain you choose, straight to your wallet. Orders are marked paid automatically once LayerHop has verified the payment on chain.

The current version is 1.1.0. The plugin is open source (GPL-2.0-or-later) at github.com/layerhop/layerhop-wordpress, with its changelog.

Install#

  1. Download layerhop.zip from the latest GitHub release (or the mirror at layerhop.com/downloads/layerhop-wordpress.zip). Use the release asset, not GitHub's "Source code" archive: WordPress expects the layerhop folder at the root of the zip.
  2. In WordPress: Plugins → Add New Plugin → Upload Plugin, choose the zip, then Activate.

Or with WP-CLI:

Terminal
wp plugin install https://github.com/layerhop/layerhop-wordpress/releases/latest/download/layerhop.zip --activate

To update, upload the newer zip the same way and confirm Replace current with uploaded. Settings and orders are kept.

Requirements: WordPress 6.2+, PHP 7.4+, and WooCommerce 7.6+ for the payment gateway. Both the classic and the block-based checkout are supported, and the plugin is compatible with HPOS. It is translatable (text domain layerhop, template in languages/layerhop.pot).

Set up the WooCommerce payment method#

  1. In the LayerHop dashboard, create an API key (API keys). Use an lh_test_ key first to try everything without real funds (Test mode).
  2. In WordPress: WooCommerce → Settings → Payments → Crypto (any token) — LayerHop → Manage:
    • paste the API key;
    • choose what you are paid in (for example USDC on Base) and your payout address on that chain;
    • choose the payment display: redirect to the LayerHop payment page, or a popup on your site (embedded checkout).
  3. Copy the webhook URL shown on that page (https://your-site/wp-json/layerhop/v1/webhook). In the LayerHop dashboard, open Webhooks, add an endpoint with that URL (in test mode for a test key), and copy its signing secret (whsec_…) back into the plugin's Webhook signing secret field.
  4. Save, then press Test connection in the Setup status box at the top of the page. It should say Connected with the mode of your key. The payment method appears at checkout.

The setup checklist in that box shows whether the method is enabled, the API key and its mode, the payout address, the webhook secret, the last webhook received, the last rejected webhook (with the reason) and the store currency.

The store currency must be USD (or a custom USDC / USDT currency): the order total is charged as the same amount of USDC or USDT. Other currencies hide the payment method and show an admin notice.

How an order is paid#

  1. The customer picks "Crypto (any token)" at checkout and places the order. The order is Pending payment.
  2. The plugin creates a LayerHop checkout session for the order total (reference = order number) and sends the customer to the payment, or opens it as a popup.
  3. The customer pays with any token on any chain from their own wallet.
  4. LayerHop verifies the delivery to your payout address and sends checkout.session.completed to your site. The plugin checks the signature, fetches the session again with your key to confirm it is paid for the right amount and address, then marks the order paid (Processing, or Completed for virtual products) with a note: who paid, with what and the transaction hash.
  5. If a payment attempt fails or is refunded, the order gets a note and stays pending so the customer can try again; if the session expires unpaid (or you expire it), the order is cancelled.

While the customer waits on the thank-you page, the plugin also asks LayerHop directly every few seconds, so an order is confirmed even if a webhook is delayed or missed. Both paths run the same checks, and an order is only ever marked paid once.

The LayerHop payment box on orders#

Each LayerHop order has a LayerHop payment box in the order sidebar:

  • the checkout session id and its live status, fetched from the LayerHop API with your key;
  • the amount and settlement token, and the hosted payment link while the order is unpaid;
  • what the customer paid with, the payer, and the source and delivery transactions (with explorer links in live mode);
  • the amount refunded, if any;
  • Check payment status now: asks LayerHop for the session and completes the order if it is verifiably paid, with exactly the same checks as the webhook.

Refunds#

LayerHop is non-custodial, so refunds are signed from your own wallet in the dashboard, not sent by the plugin (Refunds). Paid orders have a Refund in LayerHop dashboard link, and the plugin does not offer WooCommerce's Refund via gateway. When a refund completes, LayerHop sends checkout.session.refunded:

  • full refund: an order note with the amount and transaction, a WooCommerce refund is recorded (no restocking) and the order moves to Refunded;
  • partial refund: an order note with the amount refunded so far.

Make sure your webhook endpoint receives checkout.session.refunded (selecting all checkout.session.* events covers it).

Buttons on any WordPress site#

No WooCommerce needed: create a product in the LayerHop dashboard and add the shortcode to any page or post:

Text
[layerhop_button product="prod_…" label="Pay with crypto"]

The button opens the payment in a popup. In the block editor you can also add the LayerHop payment button block instead of typing the shortcode. Payments arrive as webhooks to your LayerHop account like any other checkout.

Test locally#

Your local WordPress cannot receive webhooks from the internet. Forward them with the CLI:

Terminal
LAYERHOP_API_KEY=lh_test_… LAYERHOP_WEBHOOK_SECRET=whsec_… \
  npx @layerhop/cli listen --forward-to http://localhost:8080/wp-json/layerhop/v1/webhook

Use the same whsec_… secret in the plugin settings. Then place a test order and press Simulate test payment on the payment page; the order turns paid about 10 to 20 seconds later.

Troubleshooting#

Start with the setup checklist on the settings page: it shows most problems directly.

Problem Fix
Payment method not shown at checkout The method must be enabled, the store currency USD (or USDC / USDT), and the API key and payout address set.
Test connection says the key was rejected Check the key was copied completely, isn't revoked, and is the kind you meant (test or live).
Orders stay pending after paying Press Check payment status now on the order. Then check that the webhook endpoint exists in the dashboard for the right mode (test or live) and that the signing secret matches. The dashboard's Webhooks page shows each delivery and your site's response.
Last rejected webhook in the checklist, or "Invalid signature" in the log The secret in the plugin doesn't match the endpoint's (test and live endpoints have different secrets), or the server clock is off by more than 5 minutes. If you rotated it, paste the new one; both work during the rotation's grace period.
An order went On hold The session finished but didn't match the order (amount, recipient, token). Read the order note and check your wallet before fulfilling.

Found a bug or want a feature? Open an issue on GitHub. Security issues go to security@layerhop.com, not to a public issue.

Last updated