Guides → Setup

WooCommerce

WooCommerce setup

Install the Open Border payment gateway on WooCommerce, configure it, take a sandbox card payment through both Blocks and classic checkout, and switch to live.

Written against
Public beta plugin 0.2.0 · Blocks and classic checkout
Who owns what
WooCommerce owns carts, orders, stock, and customer emails. Open Border owns payment and tax state.

Step 1

Before you start

Check your store against the tested matrix. CI exercises every one of these stacks against posts-authoritative, HPOS-only, and HPOS-with-sync order storage, so all three storage modes are supported.

Tested matrix
PurposePHPWordPressWooCommerceOrder storage
Recommended8.37.0.110.9.4HPOS authoritative
Current PHP edge8.57.0.110.9.4HPOS authoritative
Previous release8.36.9.410.8.1Posts or HPOS, with sync tested
  • An Open Border merchant account whose KYB review has been approved.
  • A store currency of USD, GBP, EUR, CAD, or AUD. The charge currency selects the Open Border legal entity that acquires the payment; the shipping destination independently drives duty and tax.
  • WooCommerce price precision set to two decimal places. Any other precision is rejected before payment.
  • The classic product editor enabled. The gateway fails closed while WooCommerce’s beta block product editor is on, because that editor does not expose the HS-code fields the gateway needs.
  • An Open Border HS code on every product and variation you sell.
  • HTTPS on the storefront. Both live and sandbox checkout fail closed without it.
  • WP-Cron running. Hourly reconciliation is what repairs a delayed or dead-lettered payment callback.

Step 2

Get your test keys

  1. 1 Open the Open Border dashboard in test mode Sign in and switch the dashboard to the sandbox rail.
  2. 2 Copy the secret key It starts with sk_test_. It stays on the WooCommerce server. Never place it in browser code, a theme file, source control, a log, or a screenshot.
  3. 3 Leave the webhook secret for later The whsec_ signing secret is issued once, when you create the webhook endpoint. Do that after the plugin is installed, so you can copy the exact callback URL the plugin displays rather than typing one.

Step 3

Install

Verify the release checksum before you install. An archive whose checksum does not match its published .sha256 must not be installed.

Verify the release ZIP
sha256sum -c openborder-payments-0.2.0.zip.sha256
  1. 1 Upload the plugin Go to Plugins → Add New → Upload Plugin, upload openborder-payments-0.2.0.zip, and activate it. Once the WordPress.org listing is live, install and update from the plugin directory instead.
  2. 2 Open the gateway settings Go to WooCommerce → Settings → Payments → Open Border.
  3. 3 Leave the gateway disabled for now Configure it fully first. Enabling it before the callback and HS codes are ready means a shopper can reach a checkout that will reject their cart.

Step 4

Configure

Gateway settings
FieldWhat it doesSet it to
Enable / Disable Offers Open Border as a payment method at checkout. Off until a sandbox checkout has succeeded end to end.
Title and description What the shopper sees as the payment method name and blurb. Whatever suits your storefront.
Sandbox mode Selects the rail. Sandbox and live requests are each pinned to their official Open Border API origin. Enabled for evaluation. The origin is not merchant-configurable, so a misconfiguration cannot send live traffic somewhere unexpected.
Secret key Authenticates every server-side Open Border call on the selected rail. A sandbox sk_test_OB_… key while testing, and a separate live key later. Never a production key in a demo store.
Webhook secret Verifies the signature on each inbound callback for the selected rail. The whsec_ value from the matching rail’s endpoint. Configure the live callback separately — rails, keys, endpoints, and stored attempts never cross.
Tax policy Either create and require an Open Border tax quote from the exact order lines, HS codes, shipping, destination, currency, and customer email — or require zero WooCommerce tax and duty and send no quote at all. The quote policy in almost every case; its total must equal the already-persisted WooCommerce total. The zero-tax policy rejects any order carrying WooCommerce item or shipping tax.
Debug logging Opt-in diagnostics through WC_Logger, carrying only order and attempt identifiers, the rail, the projected status, and stable safe error codes. On while you are integrating. It never records keys, tokens, client secrets, customer data, or raw provider responses.

Then set the classifications. In the classic product editor, add an Open Border HS code to every product or variation under its shipping and inventory fields. For a variation, set the code on the variation itself; the parent product’s code is only a fallback. The plugin snapshots the classification onto the order line before payment, so a later catalogue edit cannot change what was charged.

Step 5

Connect webhooks

In the Open Border dashboard, create a webhook endpoint for the exact sandbox callback URL the plugin displays in its settings, then subscribe it to all seven payment and refund events. Subscribing to only some of them leaves specific outcomes unreconciled.

  • payment_intent.created
  • payment_intent.succeeded
  • payment_intent.captured
  • payment_intent.canceled
  • payment_intent.failed
  • refund.succeeded
  • refund.failed

Copy the one-time whsec_ value into the sandbox webhook-secret field, and configure the live callback as a separate endpoint with its own secret later.

  • Callbacks are verified over the exact raw body with HMAC-SHA256, a five-minute timestamp window, a constant-time comparison, rail matching, and a globally unique delivery ID. A proxy that rewrites the body or drops a header makes every delivery fail.
  • The server clock must be synchronised, or the timestamp window will reject valid deliveries.
  • A callback is only a prompt. The plugin reads authoritative payment status from Open Border before applying a forward-only transition, so a duplicate or out-of-order delivery is safe.
  • Hourly WP-Cron reconciliation repairs a delayed or dead-lettered callback. If WP-Cron does not run, payments can sit pending with no repair path.

Step 6

Run a test payment

Enable the gateway with sandbox mode on and run these on the storefront. Do the whole set on both checkout surfaces: Blocks is the default for new WooCommerce installs, classic is still common on upgraded stores, and they are separate code paths sharing one payment service.

  1. 1 Successful payment on Blocks checkout Add a product carrying an HS code and check out with card 4242 4242 4242 4242, any future expiry, any CVC. The order calls payment_complete() exactly once; WooCommerce then owns stock, the paid email, and the processing-versus-completed choice.
  2. 2 Successful payment on classic checkout Switch the store to classic checkout and repeat. Both surfaces call the same payment service, but the browser tokenisation differs, so verify each.
  3. 3 Authentication challenge Use card 4000 0027 6000 3184. The order stays pending while a browser-only page replays the same idempotent request to fetch a client secret, completes the challenge, and reconciles. Abandon the challenge instead and a later checkout should supersede the stale attempt without a second charge.
  4. 4 Decline and retry Use card 4000 0000 0000 0002. The unpaid order is marked failed and a deliberate retry with a new card is permitted, receiving a fresh attempt number and idempotency key.
  5. 5 Guest and signed-in checkout Run at least one payment each way. They use the same service, but confirm your store’s account settings do not interfere.
  6. 6 Duplicate callback Send a test event from the dashboard, then replay the same delivery. Both should answer success, and the second must not reprocess.
  7. 7 Check the logs are clean Confirm no sk_, whsec_, authorization or signature header, payment token, client secret, customer email or address, or raw provider response appears anywhere in the WooCommerce log.
What each Open Border status does to a WooCommerce order
Open Border statusWooCommerce projection
requires_actionThe order stays pending while the shopper completes authentication, then reconciles.
succeeded / capturedCalls payment_complete() exactly once. WooCommerce owns stock, the paid email, and the final status.
failedMarks an unpaid order failed and permits a deliberate new-token attempt.
canceledMarks an unpaid order cancelled.
authorizedPuts the order on hold for manual review, because this beta requires automatic capture and exposes no capture or cancel control.
unknown outcomeKeeps the attempt single-flight, blocks a new token, and retries status and replay through reconciliation.

Step 7

Go live

  1. 1 Issue live credentials Get an sk_live_ secret key from the dashboard in live mode, and create a separate live webhook endpoint with its own whsec_ secret subscribed to the same seven events.
  2. 2 Turn sandbox mode off API origins are not merchant-configurable, so the live origin is pinned. Stored test-rail attempts stay stamped to the test rail.
  3. 3 Confirm HTTPS and WP-Cron Live checkout fails closed without HTTPS, and reconciliation cannot repair a delayed callback without WP-Cron.
  4. 4 Confirm HS codes across the real catalogue Check the products you actually sell, including every variation, not just the one you tested with.
  5. 5 Publish your privacy disclosures Enabling the gateway sends the order reference, customer email and name, billing and shipping addresses, line descriptions with SKU and HS-code snapshots, shipping, currency, and amounts to Open Border, and card and device data directly to the payment processor. Disclose both processors in your own privacy notice.
  6. 6 Take one small real payment Confirm the order, the paid email, stock handling, and callback delivery all behave as in sandbox before opening the gateway to shoppers.
  7. 7 Enable the gateway on live Watch the first live orders reconcile before advertising the payment method.

Step 8

Troubleshooting

Symptoms and what to check
SymptomWhat to check
The gateway is absent from checkoutPHP 8.3+, WordPress 6.9+, WooCommerce 10.8+, the classic product editor enabled, a supported currency, two-decimal prices, and API and webhook credentials matching the selected mode.
“Enter valid card details”The processor’s browser script is being blocked by a content-security policy or an ad blocker. Also re-enter the card after any currency or mode change.
Missing HS codeSet the code on the variation first, falling back to its parent product, then create a fresh order. An existing order keeps the snapshot it was built with.
Tax quote mismatch or expiredDo not change the address, coupons, shipping, lines, or classifications after an attempt has been allocated. Return to checkout for a new attempt.
The payment stays pendingConfirm WP-Cron runs, the rail-specific callback URL is publicly reachable over HTTPS, its secret is current, and all seven events are subscribed. Run the scheduled hook manually if you need to.
The provider outcome is unknownDo not retry with a new card or key. Preserve the order and let replay and status reconciliation resolve it. Escalate with the order and attempt number only.
Invalid signature or stale callbackVerify the exact mode-specific whsec_ value, that your proxies preserve raw request bodies and all three Open Border headers, and that server time is synchronised.

Step 9

Upgrade and remove

To upgrade: back up the WordPress database, then install a newer checksum-verified ZIP through the normal WordPress upgrade flow. Activation is idempotent and upgrades only the plugin’s own tables. Do not roll back across a documented schema boundary unless the target release says it supports that.

Deactivating stops the reconciliation schedule but preserves settings, attempts, delivery deduplication, and order audit metadata — so deactivate only once every unresolved payment has reached a terminal state.

Uninstalling removes the API and webhook settings including secrets, the scheduled tasks, and every unresolved request body that contains a payment token or customer data. It deliberately keeps the installation ID, scrubbed attempt history, delivery history, and WooCommerce order metadata, so non-sensitive payment and duplicate-delivery evidence stays auditable.