WooCommerce
Take crypto, Cash App and card payments in a WooCommerce shop. Setup takes about ten minutes; signed events keep your orders up to date.
Download velpay-for-woocommerce.zip (version 1.0.0). Needs WordPress 6.3 or later, WooCommerce 8.0 or later and PHP 8.0 or later. Works with both the block and the classic checkout, and with High-Performance Order Storage.
1. Install the plugin
- In WordPress, open Plugins → Add New → Upload Plugin, pick
velpay-for-woocommerce.zip, then install and activate it. - Go to WooCommerce → Settings → Payments → VelPay. Anything still missing is listed at the top of that page.
2. Add your test key
- In the VelPay dashboard, open Developers → API keys and copy the test secret key (
vp_sk_test_…). Running several shops on one account? Use a key limited to this shop's store. - Paste it into Test secret key and keep Mode on Test.
3. Connect payment events
- Under Payment events, the settings page shows your event URL, for example
https://your-shop.example/wp-json/velpay/v2/events. - In the VelPay dashboard, in test mode, open Developers → Webhooks and add that URL.
- Copy the public key from the same dashboard page into Signing public key and save.
Each event's Ed25519 signature is checked with sodium_crypto_sign_verify_detached, and events more than five minutes old are refused. Until the public key is saved, an order is only confirmed when the customer comes back to your thank-you page.
4. Try a test order
- Tick Show VelPay at checkout, then buy something in your shop and choose VelPay.
- On the VelPay checkout, pick a method and click Simulate payment.
- The WooCommerce order moves to Processing (Completed for virtual, downloadable products), with a note naming the VelPay order.
5. Switch to live
- When your VelPay account is approved for live payments, paste the live secret key into Live secret key.
- Add the same event URL in live mode under Developers → Webhooks; test and live endpoints are kept apart.
- Set Mode to Live and place one small real order.
Settings
| Setting | What it does |
|---|---|
| Name at checkout, Text under the name | How the method appears in your list of payment methods. |
| Mode | Test or live: picks the key, and events from the other mode are ignored. |
| Test secret key, Live secret key | Refused on save unless they start with vp_sk_test_ or vp_sk_live_. |
| Signing public key | The base64 key from Developers → Webhooks. |
| Offer only | Limit checkout to some of crypto, Cash App and card. Leave empty for every method on your account. |
| Time to pay | Minutes the customer has to pay, 15 to 1440 (60 by default). Set WooCommerce's Hold stock at least as long, or WooCommerce may cancel orders that are still being paid. |
| Logging | Writes API calls and events to WooCommerce → Status → Logs under source velpay. Errors are logged either way. |
How orders move
At checkout the plugin creates a VelPay order for the total in minor units, with your order number as reference, the customer's billing email, name and country, return URLs to your shop, and the WooCommerce order id in metadata. Requests carry an Idempotency-Key, so a double click can't create two VelPay orders, and a customer who comes back to pay again gets the same open VelPay order.
| VelPay event | WooCommerce order |
|---|---|
order.paid | Payment complete: Processing or Completed. On hold instead when the VelPay order was for less than the order total. |
order.processing | A note that the payment was seen and is confirming. |
order.underpaid | On hold, with a note saying what arrived. |
order.expired | Failed, so the customer can pay again from their account. |
order.voided | Cancelled. |
refund.created, refund.failed | A note. |
refund.sent | A note with the transaction hash, and Refunded once the whole amount has gone back. |
Each event is applied once; the plugin remembers recent event ids on the order. A crypto payment that lands after expiry still completes the order. If the customer reaches the thank-you page before the event, the plugin asks the VelPay API once. The redirect on its own never marks an order paid.
Refund from the VelPay dashboard or API, not from the WooCommerce order screen: refunds go out to a wallet address the customer gives you. The crypto, Cash App and card guides explain how each method refunds.
Pay button shortcode
For a single payment without a cart, add this to any page or post:
[velpay_button amount="19.99" currency="usd" description="Workshop ticket" label="Buy a ticket"]| Attribute | Notes |
|---|---|
amount | Required, in normal units: 19.99, not 1999. |
currency | usd unless set. |
description | Shown to the payer. |
label | Button text, "Pay now" unless set. |
reference | Start of the order reference; every click adds its own suffix. |
methods | For example crypto,card. |
Buttons use the keys from the gateway settings. Their fields are signed so visitors can't change the amount, and one visitor can start 10 payments per 10 minutes. After paying, the payer returns to the same page and sees a thank-you line. Button payments don't create a WooCommerce order; to act on them, hook velpay_event:
add_action('velpay_event', function (array $event): void {
$order = $event['data']['object'];
if ($event['type'] === 'order.paid' && ($order['metadata']['source'] ?? '') === 'wordpress_button') {
// e.g. email a download link to $order['payer']['email']
}
});For developers
velpay_order_body(filter): the body sent toPOST /api/v1/ordersfor a WooCommerce order, for example to limit methods or preset a coin.velpay_button_order_body(filter): the same for pay buttons.velpay_event(action): every verified event, before the plugin acts on it.- Order meta:
_velpay_order_id(the current VelPay order),_velpay_attempt,_velpay_livemode,_velpay_events.
// functions.php of your theme, or a small site plugin:
add_filter('velpay_order_body', function (array $body, WC_Order $order): array {
$body['methods'] = ['crypto'];
$body['crypto'] = ['network' => 'tron', 'asset' => 'USDT'];
return $body;
}, 10, 2);Several shops can share one VelPay account: each order records the shop's address in metadata.woo_site, and a shop ignores events for orders that aren't its own.
Troubleshooting
- VelPay is missing at checkout: there's no secret key for the selected mode, or VelPay doesn't price in your store currency. The settings page says which.
- Paid orders stay on Pending payment: open the delivery log under Developers → Webhooks.
401means the public key in WordPress doesn't match or the server clock is more than five minutes off. A403or an HTML page usually means a security plugin, firewall or maintenance mode is blocking/wp-json/; allow POST requests to/wp-json/velpay/v2/events. - "The payment couldn't be started": the order note and the log (WooCommerce → Status → Logs, source
velpay) show VelPay's error and itsrequest_id. See errors. - "This payment method isn't available for this order total": the total is outside the limits of every method you offer, for example a 2 USD order with only card allowed.
Removing the plugin
Deactivating keeps everything. Deleting the plugin removes its settings and short-lived data; order notes and _velpay_* order meta stay with your order history. Afterwards, delete the event URL in the VelPay dashboard.