{"id":316322,"date":"2026-06-29T14:52:17","date_gmt":"2026-06-29T14:52:17","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/ultrafan\/"},"modified":"2026-07-29T13:09:43","modified_gmt":"2026-07-29T13:09:43","slug":"ultrafan","status":"publish","type":"plugin","link":"https:\/\/mai.wordpress.org\/plugins\/ultrafan\/","author":23499451,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.36.2","stable_tag":"1.36.2","tested":"7.0.2","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"Ultrafan","header_author":"NewPlay Technology (Ultrafan TM)","header_description":"Connects WooCommerce to the Ultrafan affiliate network \u2014 tracks affiliate clicks, fires conversion pixels, settles COD payments, handles refunds\/cancellations, and sends periodic reconciliation reports.","assets_banners_color":"","last_updated":"2026-07-29 13:09:43","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/wordpress.org\/plugins\/ultrafan\/","header_author_uri":"https:\/\/ultrafan.world","rating":0,"author_block_rating":0,"active_installs":0,"downloads":216,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.30.1":{"tag":"1.30.1","author":"ultrafan","date":"2026-06-29 14:51:40"},"1.33.0":{"tag":"1.33.0","author":"ultrafan","date":"2026-07-10 09:49:20"},"1.33.1":{"tag":"1.33.1","author":"ultrafan","date":"2026-07-10 10:33:26"},"1.36.1":{"tag":"1.36.1","author":"ultrafan","date":"2026-07-24 09:41:15"},"1.36.2":{"tag":"1.36.2","author":"ultrafan","date":"2026-07-29 13:09:43"}},"upgrade_notice":{"1.30.0":"<p>Initial release \u2014 not uploaded in WordPress Plugin Directory.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.jpg":{"filename":"icon-128x128.jpg","revision":3590303,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.jpg":{"filename":"icon-256x256.jpg","revision":3590303,"resolution":"256x256","location":"assets","locale":"","width":256,"height":257},"icon.svg":{"filename":"icon.svg","revision":3590303,"resolution":false,"location":"assets","locale":false}},"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.30.1","1.33.0","1.33.1","1.36.1","1.36.2"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"<strong>Settings page<\/strong> \u2014 Configure Merchant ID, API Key, cron schedule, and product-feed options under Ultrafan \u2192 Settings.","2":"<strong>Reconciliation Runs<\/strong> \u2014 History of every reconciliation attempt with status, record count, HTTP response, and date range.","3":"<strong>Order meta<\/strong> \u2014 Affiliate tracking data (transaction ID, network, UTM params, conversion\/settlement status) visible on the WooCommerce order detail page."}},"plugin_section":[],"plugin_tags":[369,984,456,550,286],"plugin_category":[35,36,55],"plugin_contributors":[269477],"plugin_business_model":[],"class_list":["post-316322","plugin","type-plugin","status-publish","hentry","plugin_tags-affiliate","plugin_tags-conversion","plugin_tags-marketing","plugin_tags-tracking","plugin_tags-woocommerce","plugin_category-advertising","plugin_category-analytics","plugin_category-seo-and-marketing","plugin_contributors-ultrafan","plugin_committers-ultrafan"],"banners":[],"icons":{"svg":"https:\/\/ps.w.org\/ultrafan\/assets\/icon.svg?rev=3590303","icon":"https:\/\/ps.w.org\/ultrafan\/assets\/icon.svg?rev=3590303","icon_2x":false,"generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p><strong>Ultrafan<\/strong> is the official WooCommerce integration for the <a href=\"https:\/\/ultrafan.world\">Ultrafan<\/a> affiliate network. It automates the full affiliate lifecycle inside your WooCommerce store without requiring any JavaScript snippets or external tag managers.<\/p>\n\n<h4>Key Features<\/h4>\n\n<ul>\n<li><strong>Click tracking<\/strong> \u2014 Captures <code>transaction_id<\/code>, <code>network_id<\/code>, <code>offer_id<\/code>, and all UTM parameters from affiliate landing URLs. Parameters are stored in first-party cookies so attribution survives the entire checkout journey.<\/li>\n<li><strong>Conversion pixel<\/strong> \u2014 Fires <code>POST \/conversion<\/code> to the Ultrafan server the moment an order is placed, with full order details (amount, currency, items, payment method).<\/li>\n<li><strong>COD settlement<\/strong> \u2014 When a cash-on-delivery order's invoice is marked paid, the plugin fires <code>POST \/conversion\/settle<\/code> automatically.<\/li>\n<li><strong>Refund &amp; cancellation webhooks<\/strong> \u2014 On credit-memo creation or order cancellation the plugin notifies Ultrafan in real time (<code>POST \/conversion\/refund<\/code>).<\/li>\n<li><strong>Periodic reconciliation<\/strong> \u2014 A configurable cron job (default: Monday 02:00) batches paid orders and refunds into a signed <code>POST \/reconcile<\/code> report. A <strong>Run Now<\/strong> button in WP Admin lets you send ad-hoc reports for any date range.<\/li>\n<li><strong>Admin transparency<\/strong> \u2014 A dedicated <strong>Ultrafan \u2192 Reconciliation<\/strong> menu in WP Admin shows every reconciliation run with status, record count, HTTP response, and the exact date range covered.<\/li>\n<li><strong>HPOS compatible<\/strong> \u2014 Fully compatible with WooCommerce High-Performance Order Storage.<\/li>\n<\/ul>\n\n<h4>External Service<\/h4>\n\n<p>This plugin communicates with the <strong>Ultrafan affiliate API<\/strong> operated by NewPlay Technology:<\/p>\n\n<ul>\n<li><strong>Service URL:<\/strong> <code>https:\/\/affiliate.newplay.tech<\/code> (production) \/ <code>https:\/\/test-affiliate.newplay.tech<\/code> (test&amp;development)<\/li>\n<li><strong>Endpoints used:<\/strong> <code>\/conversion<\/code>, <code>\/conversion\/settle<\/code>, <code>\/conversion\/refund<\/code>, <code>\/reconcile<\/code><\/li>\n<li><strong>Data sent:<\/strong> affiliate transaction ID, order ID, order total, currency, payment method (normalised to a short code), base64-encoded item list, delivery cost, subtotal, and discount amount.<\/li>\n<li><strong>Privacy policy:<\/strong> https:\/\/www.ultrafan.world\/privacy-policy<\/li>\n<li><strong>Terms of service:<\/strong> https:\/\/www.ultrafan.world\/terms-conditions<\/li>\n<\/ul>\n\n<p>No personal data (name, email, address) is included in any outbound request. The plugin uses a pre-shared API key (stored in WP options) to authenticate with the server.<\/p>\n\n<h3>Cookies &amp; localStorage<\/h3>\n\n<p>Cookies and localStorage parameters are GDPR compliant, as they do not contain and client data, and they are in favour of the client.\nThe parameters are:\n- transaction_id, user id (utm_conten t), conversion id (utm_term) - ultrafan affiliate parameters\n- utm_source=\"ultrafan\", utm_medium=\"affiliate\", utm_campaign=... (not defined, future use) - the merchant to see, that this purchase is from affiliate\n- network_id = whether it is prod\/stage\/test\/dev<\/p>\n\n<!--section=installation-->\n<p><strong>From the WordPress Plugin Directory (recommended):<\/strong><\/p>\n\n<ol>\n<li>Go to <strong>Plugins \u2192 Add New<\/strong> in your WP Admin.<\/li>\n<li>Search for \"Ultrafan\".<\/li>\n<li>Click <strong>Install Now<\/strong> then <strong>Activate<\/strong>.<\/li>\n<li>Go to <strong>Ultrafan \u2192 Settings<\/strong> to enter your credentials.<\/li>\n<\/ol>\n\n<p><strong>Manual upload:<\/strong><\/p>\n\n<ol>\n<li>Download the plugin zip from the WordPress Plugin Directory.<\/li>\n<li>Go to <strong>Plugins \u2192 Add New \u2192 Upload Plugin<\/strong> and upload the zip.<\/li>\n<li>Activate and configure as above.<\/li>\n<\/ol>\n\n<p><strong>Configuration:<\/strong><\/p>\n\n<p>After activation, navigate to <strong>Ultrafan \u2192 Settings<\/strong>:<\/p>\n\n\n\n\n  Setting\n  Description\n\n\n\n\n  Merchant ID\n  Your <code>shop_id<\/code> from the Ultrafan server. Sent as <code>X-Merchant-ID<\/code> on reconciliation and settlement calls.\n\n\n  Merchant Name\n  Display name included in reconciliation headers.\n\n\n  API Key\n  Per-merchant secret provided by NewPlay Technology. Stored encrypted.\n\n\n  Enable Reconciliation\n  Enables or disables the automatic reconciliation cron job.\n\n\n  Cron Schedule\n  Standard cron expression \u2014 default <code>0 2 * * 1<\/code> (Monday 02:00).\n\n<!--section=faq-->\n<dl>\n<dt id=\"what%20affiliate%20network%20does%20this%20plugin%20support%3F\"><h3>What affiliate network does this plugin support?<\/h3><\/dt>\n<dd><p>This plugin is built exclusively for the <strong>Ultrafan<\/strong> affiliate network operated by NewPlay Technology. It is not a generic affiliate plugin.\nThe support is via email help@ultrafan.world.<\/p><\/dd>\n<dt id=\"what%20data%20is%20sent%20to%20the%20ultrafan%20server%3F\"><h3>What data is sent to the Ultrafan server?<\/h3><\/dt>\n<dd><p>Each conversion call includes: an anonymised affiliate transaction ID, the WooCommerce order ID, grand total, currency, normalised payment method code, base64-encoded item list (SKU, name, price, quantity), delivery cost, subtotal, and discount amount. No customer name, email, or shipping address is ever transmitted.<\/p><\/dd>\n<dt id=\"is%20the%20plugin%20compatible%20with%20woocommerce%20hpos%3F\"><h3>Is the plugin compatible with WooCommerce HPOS?<\/h3><\/dt>\n<dd><p>Yes. The plugin explicitly declares compatibility with WooCommerce High-Performance Order Storage (custom order tables).<\/p><\/dd>\n<dt id=\"can%20i%20trigger%20a%20reconciliation%20report%20manually%3F\"><h3>Can I trigger a reconciliation report manually?<\/h3><\/dt>\n<dd><p>Yes. Go to <strong>WooCommerce \u2192 Ultrafan \u2192 Reconciliation<\/strong>, choose a date range, and click <strong>Run Now<\/strong>.<\/p><\/dd>\n<dt id=\"what%20payment%20method%20codes%20are%20sent%3F\"><h3>What payment method codes are sent?<\/h3><\/dt>\n<dd>\n\n\n  Code\n  Meaning\n\n\n\n\n  <code>COD<\/code>\n  Cash on delivery \/ deferred payment\n\n\n  <code>WAL<\/code>\n  PayPal, Apple Pay, Google Pay, or other digital wallets\n\n\n  <code>CRC<\/code>\n  Credit\/debit card (Stripe, Braintree, Adyen, etc.)\n\n\n  <code>DEF<\/code>\n  Bank transfer\n\n\n  <code>OTR<\/code>\n  Any unrecognised gateway\n\n\n<\/dd>\n<dt id=\"what%20happens%20if%20the%20ultrafan%20server%20is%20unreachable%3F\"><h3>What happens if the Ultrafan server is unreachable?<\/h3><\/dt>\n<dd><p>The plugin retries failed conversion and settlement calls. Reconciliation failures are logged in the <strong>Reconciliation Runs<\/strong> admin screen and will be retried on the next cron run (unreconciled records are never lost).<\/p><\/dd>\n<dt id=\"does%20this%20plugin%20set%20cookies%3F\"><h3>Does this plugin set cookies?<\/h3><\/dt>\n<dd><p>Yes. First-party cookies (<code>ultrafan_transaction_id<\/code>, <code>ultrafan_network_id<\/code>, UTM cookies) are set for 5\u201330 days when a visitor lands via an affiliate link. A long-lived <code>affiliate_ultrafan<\/code> cookie (365 days) is also set for returning-customer attribution. All cookies use <code>SameSite=Lax; Secure<\/code> attributes.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.36.2<\/h4>\n\n<ul>\n<li>Fixed the <strong>Ultrafan \u2192 Orders<\/strong> screen listing every store order instead of only affiliate orders on sites using the legacy WordPress posts order storage. The grid now selects affiliate orders directly from order meta, so it behaves the same whether or not High-Performance Order Storage is enabled.<\/li>\n<li>Fixed the Orders screen pagination rendering a link for every page (hundreds of buttons on large stores); it now shows a compact, windowed pager.<\/li>\n<li>Fixed reconciliation re-sending orders it had already reconciled on sites using the legacy WordPress posts order storage. Already-reconciled orders are now skipped in code, so each paid order is reported to the affiliate server only once regardless of the storage backend.<\/li>\n<li>Reconciliation log entries now report how many candidate orders were eligible versus skipped (non-affiliate or already reconciled), instead of only the raw candidate count \u2014 so a \"found N, sent 0\" run is clear at a glance.<\/li>\n<\/ul>\n\n<h4>1.36.1<\/h4>\n\n<ul>\n<li>Card and other off-site payments now record a conversion reliably. Previously the conversion pixel only fired when the shopper reached the order-received (thank-you) page, so orders paid through gateways that confirm payment by redirect or webhook (for example Stripe) could be missed. Conversion now also fires the moment payment completes.<\/li>\n<li>Conversions are no longer sent twice. A single order fires exactly one conversion across the thank-you and payment-completed triggers, and a conversion the affiliate server declines is no longer retried in a loop. The server's response is now recorded in the logs when a conversion is declined, to make troubleshooting easier.<\/li>\n<li>Settlement is now limited to cash-on-delivery and other offline methods (bank transfer, cheque), matching the Magento module. Card, wallet, and buy-now-pay-later orders \u2014 which are already reported as paid at checkout \u2014 no longer trigger a settlement call.<\/li>\n<\/ul>\n\n<h4>1.36.0<\/h4>\n\n<ul>\n<li>Fixed automatic reconciliation never running: the first scheduled run used an empty time window so no orders were ever picked up. It now looks back over a real window and tracks its own progress cursor, independent of the run history.<\/li>\n<li>Fixed manual \"Run Now\" reconciliation corrupting the automatic schedule \u2014 a manual run over an arbitrary date range no longer drags the nightly job's progress backwards.<\/li>\n<li>Reconciliation now selects orders by last-modified date, so cash-on-delivery and other offline orders that are settled days after checkout are correctly reconciled instead of being missed.<\/li>\n<li>On-hold orders are no longer permanently frozen as unpaid on the affiliate server; their paid state is reported once they reach processing\/completed.<\/li>\n<li>Reconciliation now back-stops refunds whose real-time refund webhook failed to send.<\/li>\n<li>Cancellations issued after a partial refund no longer double-count the already-refunded amount.<\/li>\n<li>The product feed is now written through the WordPress filesystem API.<\/li>\n<li>Plugin reactivation no longer risks clearing saved settings when only the internal version marker is missing.<\/li>\n<\/ul>\n\n<h4>1.35.1<\/h4>\n\n<ul>\n<li>Fixed affiliate orders not appearing in the <strong>Ultrafan \u2192 Orders<\/strong> grid on stores using the block-based Checkout. Affiliate tracking (transaction_id, network_id, UTM params) is now persisted to order meta on both the classic and block\/Store API checkout, so the Orders grid populates and the downstream conversion, settlement, refund, and reconciliation flows have the data they rely on.<\/li>\n<li>Cancellation webhooks now skip foreign (non-Ultrafan) affiliate orders, matching the conversion, settlement, and refund flows and the Magento module's behaviour.<\/li>\n<li>Added missing log entries across the settlement, refund, and cancellation flows (early-exit conditions and a pre-send \"Firing\u2026\" entry) so every webhook attempt is traceable in <strong>Ultrafan \u2192 Settings \u2192 Logs<\/strong>.<\/li>\n<\/ul>\n\n<h4>1.35.0<\/h4>\n\n<ul>\n<li>Refactored the plugin into a namespaced MVC + service-class architecture (Ultrafan\\ namespace, PSR-4 autoloader) with <code>declare(strict_types=1)<\/code> on every file and consistent naming throughout. No change to tracking, conversion, settlement, refund, reconciliation, or feed behaviour, and existing settings\/order data are preserved.<\/li>\n<li>Moved the settings screen out of the WooCommerce Integrations tab into a dedicated <strong>Ultrafan \u2192 Settings<\/strong> page (WordPress Settings API). The same option storage is reused, so existing configuration carries over automatically.<\/li>\n<li>Decoupled logging from WooCommerce's WC_Logger. The plugin now keeps its own log in a dedicated table, viewable under <strong>Ultrafan \u2192 Settings \u2192 Logs<\/strong> (with level filter and a clear action). Every log entry is written locally and, on a best-effort basis, also sent to the affiliate log endpoint.<\/li>\n<li>Fixed an in-request transaction_id hand-off that never took effect due to a mismatched global-variable name.<\/li>\n<\/ul>\n\n<h4>1.33.1<\/h4>\n\n<ul>\n<li>Added missing assets<\/li>\n<\/ul>\n\n<h4>1.33.0<\/h4>\n\n<ul>\n<li>S2S POST tracking: implemented the token-in-path contract. POST \/ultrafan\/tr stores the payload keyed by an opaque token; GET \/ultrafan\/tr\/{TOKEN} resolves it, persists the affiliate cookies\/session, and 302-redirects to the stored target_url. Fixes POST-tracked visitors landing on the shop home instead of the product page.<\/li>\n<li>Merges the product-feed feature with the token-based S2S tracking contract.<\/li>\n<li>Send X-Merchant-ID on every outbound call (conversion, settle, refund) so the affiliate server can enforce the per-merchant API key on \/conversion too. Corrected the API Key setting help text.<\/li>\n<\/ul>\n\n<h4>1.31.3<\/h4>\n\n<ul>\n<li>Ultrafan Orders grid and order meta box now display User ID (utm_content) and Conversion ID (utm_term) with a fallback to WooCommerce Order Attribution meta, so they show even when the Ultrafan copy is empty.<\/li>\n<\/ul>\n\n<h4>1.31.2<\/h4>\n\n<ul>\n<li>Order attribution parity: affiliate orders now populate WooCommerce's native \"Order attribution\" panel server-side, so GET and S2S\/POST tracking show identical attribution (previously POST orders showed \"Direct\").<\/li>\n<\/ul>\n\n<h4>1.31.1<\/h4>\n\n<ul>\n<li>Product Feed screen: added a \"Copy URL\" button next to the latest feed URL (View\/Download).<\/li>\n<\/ul>\n\n<h4>1.31.0<\/h4>\n\n<ul>\n<li>Added Product Feed export: generates a Google Shopping style JSON feed of the WooCommerce catalogue.<\/li>\n<li>New \"Enable Product Feed\" checkbox in the General settings section and a \"Product Feed\" settings section (brand, default Google product category, feed title\/description).<\/li>\n<li>New \"Ultrafan Product Feed\" admin screen (shown only when enabled) with export history, manual \"Generate Feed Now\" button, and view\/download links.<\/li>\n<li>Daily WP-Cron export at 03:00 AM (site timezone) writing to wp-content\/uploads\/ultrafan-feed\/.<\/li>\n<\/ul>\n\n<h4>1.30.1<\/h4>\n\n<ul>\n<li>Added check for network id to avoid invalid captures<\/li>\n<\/ul>\n\n<h4>1.30.0<\/h4>\n\n<ul>\n<li>Initial public release (aligned with other stores).<\/li>\n<li>Click tracking with first-party cookies (<code>transaction_id<\/code>, <code>network_id<\/code>, UTMs).<\/li>\n<li>Conversion webhook: <code>POST \/conversion<\/code> with JSON body and API key authentication.<\/li>\n<li>COD settlement webhook: <code>POST \/conversion\/settle<\/code>.<\/li>\n<li>Refund and cancellation webhooks: <code>POST \/conversion\/refund<\/code>.<\/li>\n<li>Reconciliation cron: <code>POST \/reconcile<\/code> with per-merchant API key, refund records included.<\/li>\n<li>Admin UI: Reconciliation Runs log with Run Now button.<\/li>\n<li>HPOS compatibility declaration.<\/li>\n<li>All cookies use <code>SameSite=Lax; Secure<\/code>.<\/li>\n<\/ul>","raw_excerpt":"Connects WooCommerce to the Ultrafan affiliate network - handles clicks, conversion pixels, COD payments, refunds, and sends reconciliation reports.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mai.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/316322","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mai.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/mai.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/mai.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=316322"}],"author":[{"embeddable":true,"href":"https:\/\/mai.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/ultrafan"}],"wp:attachment":[{"href":"https:\/\/mai.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=316322"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/mai.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=316322"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/mai.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=316322"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/mai.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=316322"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/mai.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=316322"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/mai.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=316322"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}