Skip to content
LITE
Integrations

Integrations

6 min readUpdated August 2026Applies to: Lite & Pro

Nine platforms are integrated: WooCommerce, Easy Digital Downloads, SureCart, MemberPress, Paid Memberships Pro, LifterLMS, LearnDash, GiveWP, and four form plugins. Every one of them implements the same shape — “is my platform even active?” and “register my hooks” — and every one creates and reverses referrals through the same internal class, ReferralCreator. That is where self-referral blocking and one-referral-per-order idempotency live, so they apply identically across all nine, not as nine separate implementations that happen to agree with each other.

They switch themselves on#

Each integration checks whether its platform is active and registers nothing if it is not, so an unused integration costs nothing — no hooks, no queries, no settings screen for a plugin you do not run. WooCommerce checks for the WooCommerce class or the woocommerce_loaded action having already fired. The others check their own platform’s equivalent signal. A site running WooCommerce and GiveWP side by side gets exactly those two integrations registered; the other seven never touch a hook.

How a referral actually gets credited#

Whichever platform triggers it, the path is the same: the integration’s hook fires, it hands ReferralCreator the order (affiliate reference, amount, coupon codes, customer ID), and ReferralCreator does the same three checks every time before anything is written — the affiliate exists and is active, self-referral is blocked unless squad_affiliate_allow_own_referrals says otherwise (default false), and exists_for_order() refuses a second referral for an order that already has one. Only after those pass does it resolve a rate, run the fail-open risk scorer, and write the row. None of the nine integrations duplicate that logic themselves — they cannot, because it lives in one place they all call into.

WooCommerce#

The WooCommerce integration is HPOS-aware — it declares compatibility with WooCommerce’s high-performance order storage and reads orders through wc_get_order(), so it works whichever orders table your store is actually configured to use. It creates a referral when an order reaches completed or processing (filterable via squad_affiliate_wc_trigger_statuses, if your store’s flow reaches “paid” differently), and reverses it when the order is refunded or cancelled.

A refund or cancellation rejects the referral outright. There is no partial-refund math anywhere in the code — a referral that is still pending or unpaid when the order is refunded or cancelled is rejected in full, not adjusted proportionally to the refunded amount. A coupon can also carry an “Affiliate ID” field in the coupon editor, so a code maps straight to an affiliate without a link or a cookie ever being involved — see Coupon-code attribution.

Easy Digital Downloads#

Creates a referral on edd_complete_purchase; reverses it only when the payment status changes to refunded or revoked — an on-hold or failed payment doesn’t touch a referral that was never created in the first place. Discount codes are read from the payment’s own user_info meta, the same place EDD itself stores them, so no separate mapping step is needed for EDD’s native discounts to be visible to the coupon-attribution lookup.

SureCart#

API-backed rather than post-backed: it listens for surecart/checkout_confirmed to create a referral and surecart/purchase_revoked to reverse one. Amounts arrive in minor units (cents) and are converted to major units unless the currency is zero-decimal. SureCart has no coupon-to-affiliate attribution — tracking here is cookie-based only, so a store running SureCart without also running referral links has no second attribution path for a customer who typed a code without clicking through.

MemberPress#

A single status hook, mepr-txn-status-complete, covers both a member’s first payment and every renewal after it, so recurring commission follows a subscription without any separate renewal logic having to exist. mepr-txn-status-refunded reverses it. There is no separate “is this a renewal” branch to configure — the hook simply fires again each billing cycle, and each firing is its own order with its own referral.

Creates on pmpro_after_checkout; reverses on pmpro_updated_order, but only when the order’s new status is refunded or cancelled — an order moving to any other status leaves an existing referral alone. A membership level change that isn’t a refund or cancellation does not touch a referral already recorded for the original checkout.

LifterLMS#

Creates on lifterlms_order_status_completed; reverses on a _refunded or _cancelled status. LifterLMS itself has no tax or shipping components, so there’s nothing to strip out of the commissionable amount here that WooCommerce or EDD would otherwise need to account for through the squad_affiliate_exclude_shipping_tax setting — the order total is the whole basis.

LearnDash#

One hook, learndash_transaction_created — and that’s the whole integration. There is no refund or reversal hook for LearnDash-native transactions, so a refunded LearnDash purchase does not automatically unwind its referral the way the other eight platforms do. The integration does stand down deliberately in one case: if the transaction carries WooCommerce or EDD order-id meta (LearnDash sold through one of those checkouts), it does nothing, so the sale is not credited twice by two integrations firing on the same purchase.

GiveWP#

A single hook, give_update_payment_status, handles both directions: publish or complete creates a referral, refunded, failed, abandoned or revoked reverses one. No tax or shipping components here either. Recurring donations can pay recurring commission, and a zero commission rate is a legitimate choice if you only want the attribution report without paying out on it — donation programmes sometimes track a partner’s reach without paying them per gift.

Forms#

Four form plugins are detected by name, not generically: Contact Form 7 (wpcf7_mail_sent), Gravity Forms (gform_after_submission), WPForms (wpforms_process_complete) and Fluent Forms (fluentform/submission_inserted). All four hook at priority 20, so the form plugin finishes its own processing first — a form that mails a notification or writes an entry does that before this plugin ever looks at the submission. Contact Form 7 submissions have no entry ID, so there is no dedup key for them by design — a resubmitted CF7 form is treated as a new lead, not a duplicate to be caught, because CF7 itself gives nothing to catch it with.

Nothing on the list?#

POST /squad-affiliate/v1/referrals lets an admin record a referral manually for a checkout none of the nine cover — see REST API, abilities and MCP for what that endpoint does and doesn’t guard against, since it isn’t wired to the same self-referral and one-per-order checks the platform integrations get through ReferralCreator. If you’re building against a checkout that has no integration here, that endpoint — or a custom call into ReferralCreator itself, if you’re comfortable writing a small integration of your own — is the way in.