Official Documentation

CoverMyOrder

Customer opt-in shipping protection for WooCommerce. Collect a small fee at checkout, run an automated claims pipeline, resolve by refund or reship, and keep 100% of the premium — no SaaS round-trip, no per-claim fees, no data leaving your database.

v1.8.0 WordPress 6.3+ PHP 7.4+ WooCommerce 8.0+ HPOS-compatible

Perfect for

  • High-value orders
  • International shipping
  • Fragile & breakable goods
  • Dropshipping & print-on-demand
  • Subscription boxes
  • Multi-carrier WooCommerce stores

Overview

3 min

Two independent plugins that install and activate side by side, matching the pattern of a WooCommerce extension and its add-on: the free plugin never requires Pro, and Pro never replaces or modifies the free plugin's files.

Protection

The row created at checkout when a customer opts in — the premium paid, the coverage cap, and the plan snapshot at that moment.

Claim

A customer's request against one protected order — one click, no manual amount entry, routed to auto-decision or the operator queue.

Plan

The pricing and coverage rules a protection is quoted from — one flat-fee plan on free, unlimited priced plans on Pro.

Reserve

The running ledger of premium collected vs. claims paid out — your loss ratio at a glance.

What happens on a protected order

  1. Customer opts in at checkout

    A cart/checkout toggle (classic and Blocks-aware) lets the customer add protection before paying. The premium is added as a fee line on the order, so it flows through your existing tax and payment configuration unchanged.

  2. A Protection record is created

    At payment time, the plugin captures the premium, the coverage cap, a snapshot of the plan they picked, and the coverage window. The snapshot matters: editing a plan later never retroactively changes what an already-protected order was sold.

  3. Confirmation is surfaced

    A branded card appears on the thank-you page and in the order email so the customer knows the order is covered, with a link into the claim portal.

  4. The customer files a claim if something goes wrong

    Through a self-serve portal — one click per protected order, no manual amount entry. Photos, video and PDFs attach as evidence.

  5. The claim is decided

    On Pro, simple claims can auto-decide through a visual rule engine. Everything else — and everything on free — routes to the operator queue for manual review.

  6. Approved claims resolve

    Either as a native WooCommerce refund, or — on Pro — as a reship: a duplicate $0 order in processing status that the merchant fulfils again.

Throughout, the reserve ledger tracks every unit of currency collected and paid out, so the loss ratio is always one glance away.

What CoverMyOrder is not

It is not an insurance policy, and it does not underwrite anything. The plugin is the software that lets you operate a shipping protection programme: you collect the premium, you hold the reserve, you decide the claims, and you carry the risk. Whether you are permitted to sell such a product, and under what terms, depends on the law where you trade — that question is outside the plugin's scope and is worth putting to a professional before launch.

No SaaS round-trip. Protections, claims, evidence and ledger rows all live in your own database. Nothing about a claim leaves your server unless you configure an outbound webhook yourself.

Requirements

1 min

Minimum supported versions. Anything older is untested rather than actively blocked, but is not supported.

ComponentMinimumNotes
WordPress6.3+Uses the Blocks integration API for the Cart/Checkout Block toggle.
PHP7.4+Typed properties and arrow functions are used throughout the domain layer.
WooCommerce8.0+Required for the Cart and Checkout Blocks integration surface.
HPOSCompatibleAll order reads and writes go through the WooCommerce CRUD layer, so High Performance Order Storage is supported rather than merely tolerated.
MySQL / MariaDBInnoDBThe plugin creates its own indexed tables; the storage engine must support foreign-key-shaped access patterns and transactions.
Action SchedulerBundled with WooUsed as the background queue for deferred work.
A payment gateway that supports refunds via the API is required if you want to resolve claims as refunds without leaving wp-admin. Gateways without refund support will still let you approve a claim, but you will have to issue the money back manually and mark it resolved.

Installation

3 min

Free first, then Pro. Installing Pro never touches the free plugin's files or database rows.

Free plugin

  1. Plugins → Add New

    Search “CoverMyOrder”, click Install, then Activate. Or upload covermyorder-1.8.0.zip directly.

  2. Run the setup wizard

    Appears automatically on first activation — pick a plan, enable the badge, configure tracking.

Premium add-on Pro

  1. Free plugin must already be active

    Pro checks for it on load and shows an admin notice with a link to install or activate it if it's missing. Pro will not boot without it.

  2. Upload covermyorder-pro-1.8.0.zip

    Plugins → Add New → Upload Plugin, or drop the unzipped folder into wp-content/plugins/covermyorder-pro/.

  3. Activate and enter your licence key

    Every Pro gate flips on immediately once a licence is active — there is no separate configuration step and nothing to migrate.

Updating

Update the free plugin first, then Pro. The two are versioned together and a Pro release always targets the free release of the same version number. Running Pro 1.8.0 against free 1.7.x is unsupported: Pro hooks extension points that may not exist in the older core, and will surface an admin notice rather than fail silently.

Uninstalling

A Keep data on uninstall toggle in Settings → Data & privacy controls whether protections, claims, and ledger history survive plugin removal. It defaults to preserve, so accidental deactivation never silently deletes claims history.

Deactivating is always safe. Deactivation never deletes a row. Only uninstalling with the preserve toggle switched off will drop the custom tables — and that is a deliberate two-step action.

Getting started

3 min

The setup wizard runs once, automatically, right after activation. Three questions, then a test order to prove the loop works end to end.

The wizard

  1. Pick a plan

    Name it, set the flat fee, set the coverage cap. This becomes your one free-tier plan (see Plans & pricing).

  2. Enable the badge

    The “Protected by CoverMyOrder” trust badge, shown on cart, checkout and thank-you.

  3. Configure tracking

    Optional. Connect an AfterShip webhook for automatic carrier tracking-event ingestion.

Prove the loop works

Before you announce anything to customers, run one order all the way through. It takes about five minutes and it is the only way to know your gateway, your emails and your refund path all behave.

  1. Place a test order with protection opted in

    Use a real gateway in test mode rather than Cash on Delivery — you want to exercise the refund path, and COD cannot refund.

  2. Confirm the thank-you card and the order email

    Both should show the order is covered. If the email does not, the usual cause is a caching or transactional-email plugin intercepting the WooCommerce mailer.

  3. Check the order in wp-admin

    The premium should appear as a fee line on the order, and a Protection row should exist under CoverMyOrder → Claims → the order.

  4. File a test claim

    Through [covermyorder_portal] or My Account → Protection. Attach a photo so you exercise the evidence upload path too.

  5. Approve and resolve it

    Resolve as a refund and confirm the money actually leaves the gateway. Then check the Reserve ledger: you should see the premium in, and the payout out, with a running balance.

Do not skip the refund step. A claims programme that can take money but cannot give it back is worse than no programme at all. Confirm the refund lands before you go live.

Plans & pricing

4 min

A plan is the pricing and coverage rule a protection is quoted from. Free ships exactly one; Pro turns the screen into a card list of up to twelve.

Free: one plan

A single form with three fields: a name, a flat fee, and a fixed coverage cap. That is the complete free-tier surface. There is no coverage-model choice, because coverage is always a fixed cap — there is nothing to choose between. There is no percentage-pricing option either.

Pro: up to twelve plans Pro

Pro replaces the single form entirely with a card-per-plan list. Each card is a self-contained mini-editor. Once Pro's card list is active, the old single-plan form hides itself — the card list is the only Plans UI you will see.

  • A drag handle plus up/down buttons to reorder — the order here is the order customers see at checkout.
  • A segmented control for price: flat fee, or percentage of the order.
  • A segmented control for coverage: fixed amount, 100% of order, or multiplier.
  • A native colour swatch setting that plan's accent, used on its card, its checkout chip, and the customer-facing badge.
  • An Active toggle — switching a plan off dims its card and swaps its checkout preview for a “won't appear at checkout” note, without deleting it.
  • A star to mark the default plan, pre-selected for customers.
  • A live checkout preview chip, tinted with the plan's own colour, showing exactly what customers will see as you edit.

Pricing models

ModelTierBehaviour
Flat feeFreeThe same premium on every order, regardless of cart value.
Percentage of orderProThe premium scales with the order subtotal. Supplied by a PercentageStrategy that Pro registers through covermyorder/pricing/strategy_for_model.

Coverage models

ModelTierPayout ceiling for a claim
Fixed amountFreeA flat cap, the same on every order. The only model available in free.
100% of orderProThe order total itself becomes the ceiling.
MultiplierProThe ceiling is a multiple of the premium paid.

Category price overrides Pro

Charge more or less when a cart contains particular product categories — higher for fragile glassware, lower for a category that never goes missing. The pricing engine that applies overrides ships in the free plugin; what Pro adds is the only UI that writes the option.

This lives on the Settings page, not the Plans page. It is the single most commonly missed screen in the plugin. If you are hunting for per-category pricing under Plans, you will not find it.

Global coverage cap Pro

One store-wide payout ceiling that applies underneath every plan's own cap. If a plan would pay out £500 but the global cap is £300, the claim pays £300. It exists so a mispriced plan cannot bankrupt the reserve.

Fallback plans

If a checkout requests a plan id that no longer resolves — deleted, deactivated, or a stale page cache — the pricing layer asks covermyorder/pricing/fallback_plan_id for a substitute rather than failing the checkout. Deactivating a plan mid-session is therefore safe: in-flight carts fall back instead of erroring.

Editing a plan never rewrites history. The plan is snapshotted onto the Protection at checkout. Raising a coverage cap tomorrow does not raise the cap on an order sold today, and lowering a premium does not entitle anyone to a partial refund of what they already paid.

Admin guide

5 min

wp-admin → CoverMyOrder. Screens marked Pro only appear once the add-on is active and licensed.

Dashboard

KPIs (fees collected, active claims, reserve balance, loss ratio), sparkline charts, and a traffic-light health indicator. A matching “CoverMyOrder — At a Glance” widget is added to the default wp-admin home screen, so the numbers are visible without navigating anywhere.

Claims

A native WP_List_Table queue with status filters and an overdue-SLA column. Claim detail shows the evidence gallery, a customer risk profile sidebar, the carrier tracking timeline, and approve / deny / resolve actions with a full activity log.

Pro adds bulk queue actions, a reship resolution option alongside refund, a richer risk profile (lifetime order history), and auto-claim creation straight from a carrier webhook.

Plans

Covered in full under Plans & pricing. In short: one form in free, a twelve-card list in Pro.

Rules Pro

A visual rule builder with composable conditions and auto-approve / auto-deny actions, so simple claims never wait on an operator. Anything a rule does not match falls through to the manual queue — rules narrow the queue, they do not replace it.

Branding

Free: two colour presets (Indigo, Trust Green) and editable cart-toggle copy — title, description, opt-in and opt-out labels, thank-you text — with a live badge preview. The trust badge itself is mandatory-on in free, with a hardcoded title and description.

Pro adds five more presets plus a custom hex picker, a custom badge logo, per-surface placement control (or hiding the badge entirely), and agency white-labelling: a custom name in the admin menu, the email footers, and the customer portal.

Reserve

A paginated ledger of every premium collected and every claim paid out, with a running balance — the same number the Dashboard's loss-ratio KPI is built from. See Reserve & ledger.

Settings

Free ships three cards:

CardWhat it controls
Coverage policyPricing strategy and its parameters.
Tracking webhookThe inbound AfterShip secret used to authenticate carrier tracking events.
Data & privacyThe preserve-on-uninstall toggle.

Pro injects two more sections onto this same page: per-category pricing overrides and the global coverage cap. Both are described under Plans & pricing.

Webhooks Pro

Outbound, HMAC-signed claim-event delivery to Slack, Zapier, or any custom URL. See Webhooks for the payload and signature details.

Claims workflow

4 min

From the customer clicking “file a claim” to the money leaving your account — and the audit trail that records it.

The lifecycle

  • Submitted

    The customer files from the portal — one click, evidence attached, no manual amount entry.

  • Auto-decided Pro

    The rule engine gets first refusal. A matching rule auto-approves or auto-denies without an operator ever seeing the claim.

  • Under review

    Everything a rule did not match — and everything on free — lands in the operator queue with an overdue-SLA column.

  • Approved or denied

    The decision, with a reason, written to the claim activity log.

  • Resolved

    The money actually moves, or the replacement actually ships. Approval and resolution are separate actions with separate log entries.

A claim submitted through the portal lands as submitted. On Pro, the rule engine gets first refusal: if a rule matches, the claim is auto-approved or auto-denied without an operator ever seeing it. Everything else — and everything on free — moves to under review in the operator queue.

An approved claim is not finished. It still has to be resolved: the money has to actually move, or the replacement has to actually ship. That distinction is why approval and resolution are separate actions with separate log entries.

Evidence

Photos, videos and PDFs attach to a claim as evidence. The default limit is 10 files at 10 MB each — the same in free and Pro. There is no built-in Pro override, but both limits are filterable:

add_filter( 'covermyorder/evidence/max_files_per_claim', fn() => 20 );
add_filter( 'covermyorder/evidence/max_bytes_per_file', fn() => 25 * MB_IN_BYTES );

Resolution paths

PathTierWhat happens
RefundFreeA native WooCommerce refund against the original order, through your gateway. The amount is capped by the coverage model on the protection and, if set, by the global coverage cap.
ReshipProA duplicate order is created at $0 in processing status, which you fulfil again exactly like any other order. The original order is left untouched.

Risk and fraud signals

The claim detail screen carries a customer risk profile sidebar. Free shows a basic profile; Pro extends it with lifetime order history, and the rule engine can act on those signals directly — auto-denying, or simply flagging for a human.

Every state change is logged. Approvals, denials, resolutions, rule decisions and operator notes all append to the claim activity log. Nothing about a claim is silently mutable, which is what makes the reserve ledger defensible after the fact.

Carrier tracking

With an AfterShip webhook configured, carrier tracking events are ingested automatically and shown as a timeline on the claim. On Pro, a tracking event that indicates a lost or damaged shipment can create the claim itself, with no customer action at all.

Reserve & ledger

3 min

The reserve is the number that tells you whether the programme is working. Everything else on the dashboard is decoration by comparison.

What the ledger records

Two kinds of row, in one append-only table, with a running balance:

Row typeCreated whenEffect on balance
Premium collectedA protected order is paid for.Increases
Claim paid outAn approved claim is resolved.Decreases

Nothing is aggregated away and nothing is edited in place. Every entry ties back to a WooCommerce order, which is what lets you hand the ledger to an accountant and have the numbers survive the conversation.

Loss ratio

The single KPI worth watching: total paid out, divided by total collected. Below 1.0 the programme is profitable; above 1.0 it is subsidising your shipping losses out of margin. The Dashboard shows it as a traffic light so you notice the direction of travel before the balance does.

The reserve is an accounting record, not a bank account. The plugin does not ring-fence money or move it anywhere. Premiums land in your normal gateway payouts along with everything else. The ledger tells you how much of that money is notionally spoken for — it is on you to not spend it.

CSV export Pro

Claims, protections, and the full reserve ledger export to CSV for reconciliation against your books.

Customer portal

3 min

Everything a customer sees, from checkout through filing a claim.

Cart & checkout badge

The opt-in toggle and trust badge render on both classic checkout and Cart/Checkout Blocks.

Thank-you card

Confirms coverage right after purchase, with a link into the claim portal.

My Account → Protection

A native WooCommerce endpoint listing every protected order.

[covermyorder_portal]

A standalone shortcode and block version of the same portal, cookie-identified — no password required.

Claim status emails

Branded HTML emails for every stage: submitted, approved, denied, resolved.

Evidence uploads

Photos, videos and PDFs attach to a claim as evidence.

Guest claims

The shortcode portal is cookie-identified, so a customer who checked out as a guest can still file and track a claim without creating an account. This matters more than it sounds: requiring a password at the moment someone is already annoyed that their parcel is missing is how you turn a claim into a chargeback.

Overriding the customer-facing views

Every template a customer sees can be overridden from your theme. See Templates.

Free vs Pro

3 min

The complete capability split, kept in sync with what the code actually gates — not what a feature list might imply.

CapabilityFreePro
Plans1, flat fee, fixed coverage capUp to 12, flat or percentage pricing, fixed / 100%-of-order / multiplier coverage, per-plan accent colour, drag-to-reorder
Category price overridesEngine ships in core; no UI to configure itAdds the Settings-page UI that writes the option
Global coverage capOne store-wide payout ceiling under every plan's own cap
RulesManual review onlyVisual rule builder, auto-approve / auto-deny
Branding2 presets, badge mandatory-on, hardcoded title/description+5 presets, custom hex, custom logo, placement control, badge can be hidden, agency white-label
ClaimsBulk & single actions, risk profile+ Reship resolution, richer risk profile, auto-claim from carrier webhook
AnalyticsStandard dashboard, top SKUs with claims+ Carrier-level loss ratio & payout analytics
Evidence per claim10 files @ 10 MB (filterable)Same defaults today
REST APIRead-only+ Write access via API tokens
IntegrationsOutbound webhooks, CSV export, SMS via Twilio, multi-store management

How the gating actually works

There is no central “capabilities registry.” Free simply never implements the Pro behaviour, and covermyorder/license/is_pro plus a small set of action and filter hooks (covermyorder/plans/allow_multi, covermyorder/admin/settings/advanced_sections, and similar) let Pro extend or fully replace a screen when it is active. See License gating for the mechanism.

FAQ & troubleshooting

4 min

The questions that actually get asked, and the failures that actually happen.

Do I need both plugins, or does Pro replace the free one?

Both. Pro is an add-on, not a replacement — it requires the free plugin to be installed and active, and never modifies the free plugin's files.

What happens to my claims history if I deactivate or uninstall?

Deactivating never deletes anything. Uninstalling only deletes data if “Keep data on uninstall” in Settings → Data & privacy is turned off — and it defaults to preserve.

Can free stores offer more than one protection plan?

No. Free enforces exactly one plan: name, flat fee, fixed coverage cap. Multiple plans, percentage pricing, and coverage multipliers are Pro-only, via the card-based Plans screen.

Why don't I see a coverage-model choice on the free Plans screen?

Coverage is always a fixed cap in free — there is no dropdown because there is nothing to choose between. “100% of order” and “Multiplier” coverage only appear once Pro is active.

Where did the per-category pricing override screen go?

It lives on the Settings page, added by Pro — not on the Plans page. This is the single most commonly missed screen in the plugin.

What's the actual evidence upload limit?

10 files per claim, 10 MB each, by default — the same for free and Pro. Both numbers are filterable (covermyorder/evidence/max_files_per_claim, covermyorder/evidence/max_bytes_per_file).

My outbound webhook signature verification fails — which header is it?

X-CoverMyOrder-Signature (HMAC), alongside X-CoverMyOrder-Event and a User-Agent of CoverMyOrder-Pro/{version}. See Webhooks for the full payload shape. The most common cause of a failed check is verifying against a parsed body rather than the raw request body.

The protection toggle does not appear at checkout.

Three usual causes, in order of likelihood: the plan is switched off (Active toggle on its card); a page or fragment cache is serving a stale cart; or a checkout-customiser plugin is stripping the fee line. Test with caching disabled before anything else.

A claim was approved but no money moved.

Approval and resolution are separate steps. An approved claim still has to be resolved as a refund or a reship. If you resolved it as a refund and nothing left the gateway, the gateway does not support API refunds — issue the refund manually and mark the claim resolved.

Can I run this on a multisite network?

Each site keeps its own tables, plans and ledger. Multi-store management — managing claims across connected stores from one dashboard — is a Pro feature.

Architecture

4 min

A layered architecture, PSR-11 container, autowired, with a two-phase register()boot() provider lifecycle. Each layer only calls downward.

PresentationAdmin UI · Customer portal · Cart/Checkout Blocks · REST
ApplicationControllers · REST endpoints · Hooks · CLI
DomainClaim · Protection · Policy · Money — pure PHP, no WordPress calls
ServicesPricing · Rules · Resolution · Tracking · Evidence
InfrastructureRepositories · Queue (Action Scheduler) · HTTP · Cache · Log
PersistenceCustom InnoDB tables · WooCommerce HPOS · Options · Meta

Why the domain layer has no WordPress in it

Claim, Protection, Policy and Money are plain PHP objects. They do not call get_option(), they do not touch $wpdb, and they do not know WordPress exists. Everything that needs the outside world goes through a repository or a service. The practical payoff is that pricing and coverage logic is unit-testable without booting WordPress at all — which is the only reason the money maths can be trusted.

Provider lifecycle

Service providers run in two phases. register() binds things into the container and must not assume anything else exists yet. boot() runs once everything is registered, and is where hooks are added. Pro registers its own providers inside covermyorder/pro/boot, which fires only after the free plugin has confirmed an active licence.

Data model

3 min

Ten indexed custom InnoDB tables, plus WooCommerce order storage. Not wp_postmeta.

TableHolds
ProtectionsOne row per protected order: the premium, the coverage cap, the plan snapshot, and the coverage window.
ClaimsOne row per claim, against exactly one protection.
Claim eventsThe activity log — every state change, decision and operator note, append-only.
EvidenceUploaded photos, videos and PDFs, linked to a claim.
Tracking eventsCarrier tracking events ingested from the inbound webhook.
Reserve ledgerEvery premium collected and every claim paid out, with a running balance.
RulesThe auto-decision rules built in the visual rule builder. Pro
Fraud signalsThe signals the risk profile and rule engine read from.
Audit logAdministrative actions, separate from the per-claim activity log.
API tokensBearer tokens for REST write access, SHA-256 hashed at rest. Pro

Why custom tables and not post meta

Claims and ledger rows are relational, high-cardinality, and queried by status, date range and order — exactly the access pattern wp_postmeta is worst at. Storing them as meta would mean a self-join per filter and an unindexed scan on every dashboard load.

The full rationale is written up as an architecture decision record in the repository: docs/adr/0001-custom-tables-vs-postmeta.md.

Orders themselves are never written to directly. All order reads and writes go through the WooCommerce CRUD layer, which is what makes HPOS compatibility real rather than nominal.

Hooks reference

5 min

The filters and actions most relevant to extending or auditing the plugin. Not exhaustive of every internal hook, but it covers every hook that gates free/Pro behaviour, and every hook a merchant developer is likely to reach for.

Licensing & Pro boot

HookTypeFires
covermyorder/license/is_profilterAnywhere Pro status is checked. Pro's add-on hooks this at priority 1000 to report its own licence state.
covermyorder/pro/bootactionOnce, after the free plugin confirms a Pro licence is active — Pro registers all of its own service providers here.

Plans & pricing

HookTypeFires
covermyorder/plans/allow_multifilter, default falseThe free/Pro gate for the whole Plans screen. Pro flips it to true, which both unlocks multi-plan saving and tells the free single-plan form to hide itself.
covermyorder/plans/catalogfilterAugments the hydrated plan list at read time.
covermyorder/plans/changedactionAfter plans are saved — useful for cache invalidation.
covermyorder/admin/plans/list_viewactionAbove the Plans form. Pro renders its entire card list here.
covermyorder/pricing/strategy_for_modelfilterResolves which pricing strategy calculates a plan's premium. Pro hooks this to supply percentage pricing — needed for correct checkout pricing on any percentage plan, however it was created.
covermyorder/pricing/fallback_plan_idfilterResolves a fallback plan when a checkout requests a plan id that no longer exists (deleted, deactivated, or a stale cache).

Branding

HookTypeFires
covermyorder/branding/textfilterOverrides cart-toggle and thank-you strings at read time.
covermyorder/branding/presetsfilterInjects additional colour presets — Pro adds 5 here.
covermyorder/branding/badge_enabledfilter, default trueReturning false hides the badge — free hardcodes this to always-on.
covermyorder/branding/placementsfilterBadge position per surface — Pro exposes the picker.
covermyorder/admin/branding/afteractionEnd of the Branding settings screen — Pro injects custom hex, logo and placement controls here.

Settings & evidence

HookTypeFires
covermyorder/admin/settings/advanced_sectionsactionEnd of the Settings screen — Pro's category-override and global-cap sections render here.
covermyorder/admin/settings/save_payloadfilterThe settings payload just before it is saved — lets Pro persist its own fields on the same submit.
covermyorder/evidence/max_files_per_claimfilter, default 10Maximum evidence files per claim.
covermyorder/evidence/max_bytes_per_filefilter, default 10 MBMaximum size per evidence file.

Worked example: a custom pricing strategy

Every pricing model resolves through one filter, so adding your own is a matter of returning a different strategy object for your own model key.

add_filter(
    'covermyorder/pricing/strategy_for_model',
    function ( $strategy, string $model ) {
        if ( 'weight_banded' !== $model ) {
            return $strategy; // not ours — leave it alone
        }
        return new My_Weight_Banded_Strategy();
    },
    10,
    2
);
Always return the incoming value untouched when a filter is not about you. Every hook above is shared. A filter that unconditionally returns its own answer will break percentage pricing, Pro branding, or both.

REST API

4 min

Namespace covermyorder/v1. Read endpoints are available on free; write endpoints require a Pro API token.

GET /wp-json/covermyorder/v1/health

{ "status": "ok", "version": "1.8.0" }

Authentication

ModeUsed byNotes
Cookie + nonceThe admin UI, in a browser contextStandard WordPress REST authentication.
Bearer token ProExternal integrationsSHA-256 hashed at rest. Shown once at creation and never again.
HMAC signatureIncoming webhooksFive-minute replay window. Used by the inbound tracking endpoint.

Endpoints

EndpointAccess
GET /covermyorder/v1/plansFree · public
POST /covermyorder/v1/plans/quoteFree · public
GET /covermyorder/v1/protectionsFree · read
GET /covermyorder/v1/claimsFree · read
POST /covermyorder/v1/claimsPro · write (API token)
POST /covermyorder/v1/trackingHMAC (webhook ingest)

Conventions

  • Rate limiting. Every response carries X-RateLimit-* headers.
  • Errors. RFC 7807 Problem Details, not a bare WordPress error blob.
  • Idempotency. POST, PUT and PATCH honour an Idempotency-Key header with a 24-hour response cache — a retried request returns the original response instead of creating a second claim.
Send an Idempotency-Key on every write. Network retries are not hypothetical, and a duplicate claim on a protected order is a duplicate payout.

Webhooks Pro

4 min

Outbound claim-event delivery to Slack, Zapier, or any custom URL, HMAC-signed.

POST https://your-endpoint.example.com/hook
User-Agent: CoverMyOrder-Pro/1.8.0
X-CoverMyOrder-Event: claim.approved
X-CoverMyOrder-Signature: sha256=<hmac hex digest>
Content-Type: application/json

{
  "event": "claim.approved",
  "claim_id": 4821,
  "order_id": 10932,
  "resolved_amount_cents": 4599
}

Verifying the signature

Compute an HMAC-SHA256 of the raw request body against your configured webhook secret, and compare it to X-CoverMyOrder-Signature with a constant-time comparison.

$signature = $_SERVER['HTTP_X_COVERMYORDER_SIGNATURE'] ?? '';
$expected  = 'sha256=' . hash_hmac( 'sha256', $raw_body, $secret );

if ( ! hash_equals( $expected, $signature ) ) {
    http_response_code( 401 );
    exit;
}
Use the raw body, not a parsed one. If your framework has already decoded the JSON and re-encoded it, the bytes will differ and the signature will never match. This is the cause of almost every “signature verification fails” report.

Delivery

Deliveries are queued through Action Scheduler rather than sent inline, so a slow or unreachable endpoint never blocks an operator approving a claim in wp-admin. Respond 2xx quickly and do your own work asynchronously — a webhook receiver that takes ten seconds to reply is a webhook receiver that will be treated as failed.

Templates

2 min

Every customer-facing view can be overridden from your active theme, WooCommerce-style.

Overridable templates

yourtheme/covermyorder/badge.php
yourtheme/covermyorder/thankyou.php
yourtheme/covermyorder/portal/authenticate.php
yourtheme/covermyorder/portal/dashboard.php
yourtheme/covermyorder/portal/claim-form.php
yourtheme/covermyorder/emails/claim-submitted.php
yourtheme/covermyorder/emails/claim-approved.php

How to override one

  1. Copy the file out of the plugin

    From the plugin's own views/ or themes/default/covermyorder/ folder.

  2. Paste it into your theme at the same relative path

    Under a covermyorder/ directory in your active theme — ideally a child theme.

  3. Edit freely

    Plugin updates never touch files inside your theme.

An override is a fork. The upside is that updates cannot overwrite it; the downside is that updates cannot fix it either. If a later release changes the variables passed into a template, your copy will keep rendering the old ones. Re-check your overrides after a major version bump.

License gating

2 min

There is no capabilities registry, and no per-feature gate methods to call. The mechanism is simpler than that.

src/Licensing/LicenseGate.php exposes exactly two methods: isPro() and upgradeUrl(). It is used only by the Upgrade tab, to hide itself once Premium is installed. The free plugin does not gate anything internally with it.

Instead: free simply never implements the Pro behaviour. The single-plan form only ever writes a flat fee and a fixed cap because that is all its own code does — not because something is checking a permission and blocking a wider write. Pro then extends or fully replaces a screen through ordinary action and filter hooks, registered when its own licence check (covermyorder/license/is_pro) passes:

  • covermyorder/plans/allow_multi flips from false to true, and the free single-plan form checks this same filter to decide whether to hide itself.
  • covermyorder/admin/settings/advanced_sections and covermyorder/admin/branding/after are plain extension points free always fires — empty and inert unless Pro is there to hook them.
  • covermyorder/pricing/strategy_for_model lets Pro supply a PercentageStrategy so a percentage-priced plan calculates correctly at checkout, regardless of which screen created it.
Auditing what is free vs. Pro? Do not look for a gate check to grep for. Look at which class registers the hook, and whether that class only loads inside covermyorder/pro/boot.