Skip to content

Releases: dukenukemall/fungies-wp-plugin

v2.4.4 - Customer email prefill fix

Choose a tag to compare

@dukenukemall dukenukemall released this 24 May 12:34

v2.4.4 - Customer email prefill fix on hosted checkout

A small but customer-visible fix: the WooCommerce billing email was passed to the Fungies hosted checkout but silently ignored, so customers always had to retype their email at checkout even though we knew it.

Root cause

Fungies_Checkout_URL_Builder::build() was sending the email as ?fngs-user-email=.... Per the official Fungies docs (billing-data prefill reference), the hosted-checkout prefill parameter is fngs-customer-email.

The two names look almost identical but flow in opposite directions:

Parameter Direction Purpose
fngs-customer-email Inbound (you -> Fungies) Prefill the email field on the Fungies checkout page
fngs-user-email Outbound (Fungies -> you) System param Fungies appends to the post-purchase Instant Redirect URL

The plugin was using the outbound name in the inbound slot. Fungies just ignored it.

The fix

  • Fungies_Checkout_URL_Builder::build() now sends fngs-customer-email for prefill.
  • The return-side handler in Fungies_Checkout::handle_return() still reads fngs-user-email from the redirect URL where Fungies appends it - that side was always correct.
  • Added an inline rationale comment in the URL builder linking to the docs so the next reader doesn't repeat the confusion.
  • Corrected two URL examples in readme.txt and one in the developer guide PDF that had propagated the same mistake.

Customer impact

After upgrading, customers who proceed from WooCommerce to the Fungies hosted checkout will see their email address already filled in. No data migration is required; existing orders are unaffected.

Install / Upgrade

Drop-in replacement for v2.4.3. Download fungies-checkout-2.4.4.zip below and upload via WordPress Admin -> Plugins -> Add New -> Upload Plugin.

v2.4.3 — Plugin Check follow-up

Choose a tag to compare

@dukenukemall dukenukemall released this 18 May 09:52

v2.4.3 — Plugin Check follow-up

Tiny correctness fix on top of v2.4.2.

What

The three phpcs:ignore WordPress.DB.SlowDBQuery.* annotations added in v2.4.2 didn't actually suppress their warnings. Reason: phpcs:ignore applies only to the immediately next line, but the slow-query sniff fires on the 'meta_key' / 'meta_value' / 'meta_query' array-key string tokens which live 2-3 lines inside the wc_get_orders() / get_posts() array literal.

Fix

Switched each of the three sites to range-based phpcs:disable / phpcs:enable pairs that wrap just the offending array literal:

  • Fungies_Order_Sync::find_order_by_meta()
  • Fungies_Return_Resolver::by_meta()
  • Fungies_Product_Sync::push_to_fungies() (the meta_query array)

The rationale comments above each suppression are preserved so reviewers still see why the suppression is justified (low-cardinality indexed Fungies meta keys, single-row lookups).

No runtime changes

This is a lint-only fix. Drop-in replacement for v2.4.2.

v2.4.2 — Plugin Check pass

Choose a tag to compare

@dukenukemall dukenukemall released this 18 May 09:46

v2.4.2 — WordPress.org Plugin Check pass

Resolves every Error and warning flagged by the WP.org Plugin Check tool. No runtime behaviour changes.

Errors fixed

  • WordPress.DB.PreparedSQL.NotPrepared (class-fungies-workspace-meta.php lines 94-95) — Replaced the string-concatenated meta_key clause with a fully prepared statement using $wpdb->prepare() + $wpdb->esc_like(). Removed the now-dead pushed_offer_meta_key_sql_clause helper.
  • WordPress.DB.PreparedSQL.InterpolatedNotPrepared + PluginCheck.Security.DirectDB.UnescapedDBParameter (class-fungies-product-sync.php lines 114, 120) — cleanup_pushed_duplicates() is now a single $wpdb->prepare() call with %s placeholders. The interpolated $pushed_clause string is gone.
  • WordPress.WP.I18n.MissingTranslatorsComment — Added /* translators: ... */ comments above every gettext call with placeholders:
    • class-fungies-admin-settings.php lines 216, 302
    • class-fungies-order-sync.php lines 87, 144, 194
    • class-fungies-product-sync.php line 51
  • WordPress.WP.I18n.UnorderedPlaceholdersText (class-fungies-admin-settings.php line 302) — Reworked 'Connected to %s API! (%s)' into ordered placeholders 'Connected to %1$s API! (%2$s)' so translators can reorder.

Warnings annotated with narrow, justified phpcs:ignore

Each suppression has an inline rationale comment immediately above it, so reviewers can see why the warning is being silenced:

  • WordPress.Security.NonceVerification.Recommended — Two read-only branches: the wc-api=fungies_return redirect handler (class-fungies-checkout.php) and the admin-settings tab discrimination (class-fungies-admin-settings.php). Neither mutates state; payment state lives in the parallel HMAC-SHA256-verified webhook.
  • WordPress.DB.DirectDatabaseQuery.DirectQuery + NoCaching — Three single-row prepared lookups against indexed meta_key / meta_value pairs (one each in workspace-meta, product-sync, order-sync). Running them through WP_Query adds overhead with no caching benefit since they fire once per webhook line item / sync pass.
  • WordPress.DB.SlowDBQuery.* — Same indexed lookups + the single meta_query NOT EXISTS on _fungies_offer_id used by the push pass. Low-cardinality keys set only on synced products.

Upgrade

Drop-in replacement for v2.4.1. No data migrations, no config changes required.

v2.4.1 — WP.org compliance

Choose a tag to compare

@dukenukemall dukenukemall released this 18 May 09:29

v2.4.1 — WP.org compliance pass

Two small but mandatory fixes flagged by the WordPress.org plugin reviewer. No runtime behaviour changes.

Fixed

  • Requires Plugins header — Added Requires Plugins: woocommerce to the main plugin header (introduced in WordPress 6.5). WordPress now refuses to activate Fungies for WooCommerce unless WooCommerce itself is installed and active, and the WooCommerce dependency is now displayed in the Plugins screen.
  • Text domain matches slug — Renamed the gettext text domain from fungies-wp to fungies-for-woocommerce across all 97 gettext calls and the plugin header. This is required for the WordPress.org translation platform (translate.wordpress.org) to pick up our strings for community translation.

Upgrade notes

  • Any external .po / .mo files keyed off the old fungies-wp domain must be re-generated against the new fungies-for-woocommerce domain.
  • No code changes are required on your store — the upgrade is fully backwards-compatible for end users.

Install / Upgrade

Download fungies-checkout-2.4.1.zip below and upload it via WordPress Admin → Plugins → Add New → Upload Plugin, or activate Auto-Update once we publish to wordpress.org.

v2.4.0 — WP.org compliance pass: URL/SSRF hardening + opt-in debug logging

Choose a tag to compare

@dukenukemall dukenukemall released this 15 May 11:58

Fungies for WooCommerce 2.4.0

WP.org compliance pass — security hardening, opt-in debug logging, i18n cleanup, and readme polish ahead of submission.

Install

Download fungies-checkout-2.4.0.zip below and upload via WordPress Admin → Plugins → Add New → Upload Plugin. WordPress will detect the existing 2.3.x install and prompt to replace it.


🔒 Security

  • Fungies Store URL field is now an HTML5 url-typed input that saves through WC's esc_url_raw sanitizer. The runtime read site additionally re-validates with esc_url_raw + wp_http_validate_url and rejects any scheme other than http/https before building a customer redirect — closing a potential javascript:/file:// redirect-injection vector.
  • HTTPS host allowlist (fungies.io, fungies.net) now gates media_sideload_image calls before fetching product images, mitigating SSRF risk from third-party image URLs. Extensible via the new fungies_image_host_allowlist filter; uses a dot-boundary suffix check so evilfungies.io cannot impersonate fungies.io.
  • Webhook REST route carries an inline rationale documenting the HMAC-SHA256 signature verification, timing-safe hash_equals comparison, missing-secret rejection, and idempotency-key replay protection that act as the real auth gate. No behaviour change — guards future "tighten security" refactors that would break the integration.

🔕 Privacy

  • New "Debug Logging" admin toggle at WooCommerce → Settings → Fungies gates verbose API request/response dumps in the wc-logs fungies source. Errors and warnings still log unconditionally so genuine failures remain diagnosable; verbose dumps are off by default.
  • The previous always-on "Detailed Logging" feature description in readme.txt is replaced with an opt-in worded description that signals deliberate behaviour to WP.org reviewers.

🌐 i18n

  • Wrapped two previously-untranslated admin AJAX error strings in __() with translator comments and numbered placeholders (%1$s / %2$s) per WP coding standards.

🧹 Cleanup

  • Removed console.log / console.error calls from front-end Blocks checkout JS so the customer's browser console stays clean.
  • Removed obsolete Donate link: https://fungies.io from readme (homepage donate links trigger spam suspicion in WP.org review).
  • Removed == Screenshots == section from readme (no screenshot assets are shipped — referencing nonexistent screenshots would render broken image tiles on the WP.org plugin page).

📦 Docs / packaging

  • Older changelog entries (2.1.x, 2.0.x, 1.x) moved to a new changelog.txt per the WP.org FAQ guidance to keep readme.txt trimmed to the current major plus one back.
  • .gitattributes now export-ignores README.md, build.ps1, and fungies-*.zip so the shipped plugin zip contains only runtime files.

Upgrade notes

  • After updating, verify the new "Debug Logging" checkbox is off if you weren't already inspecting wc-logs.
  • If you serve product images from a custom domain (not *.fungies.io or *.fungies.net), add it to the allowlist:
add_filter( 'fungies_image_host_allowlist', function ( $hosts ) {
    $hosts[] = 'cdn.your-domain.com';
    return $hosts;
} );
  • If your existing Fungies Store URL value is malformed (no scheme, etc.), the plugin will now refuse to redirect and log a warning. Fix the URL in WooCommerce → Settings → Fungies.

Diff summary

10 files changed, 284 insertions(+), 147 deletions(-).

Full Changelog: v2.3.1...v2.4.0

v2.3.1 — Instant coupon push on save

Choose a tag to compare

@dukenukemall dukenukemall released this 09 May 08:15

v2.3.1 — Instant coupon push on save

New

  • Coupons sync to Fungies the moment you save them in WooCommerce, mirroring how products already behaved. Adding the save_post_shop_coupon hook means there is no longer any "stale window" where a customer could apply a coupon at checkout that has not yet propagated to Fungies.
    • Same code path as Sync Now (uses local _fungies_pushed_discount_id__<workspace-hash> post meta first, falls back to remote lookup by discountCode).
    • Debounced via a 5-second transient lock per coupon to absorb double-saves from the WC admin.
    • Skips autosaves and revisions silently.
    • Logs every push to the WooCommerce → Status → Logs (fungies-*.log) source.
  • Deleting a coupon clears the workspace-scoped Fungies ID meta. Re-creating a coupon with the same code creates a fresh Fungies discount instead of trying to update a deleted one.

Pairs with v2.3.0

  • v2.3.0 forwards the applied coupon code to the Fungies hosted checkout.
  • v2.3.1 guarantees the Fungies side already knows about it by the time the customer reaches checkout.

Upgrade notes

  • No DB migrations.
  • The hourly fungies_product_sync_cron and the manual "Sync Now" button still exist as safety nets and now mostly result in 0 created, 0 updated for coupons since the instant push keeps things in sync.
  • If the Fungies API is unreachable during a coupon save, the save still succeeds in WooCommerce; the next Sync Now or cron run will catch up.

v2.3.0 — Forward WC coupon codes to Fungies checkout

Choose a tag to compare

@dukenukemall dukenukemall released this 09 May 08:13

v2.3.0 — Forward WC coupon codes to Fungies checkout

New

  • When a customer applies a coupon at the WooCommerce checkout (e.g. percent10), the redirect URL to the Fungies hosted checkout now includes &fngs-discount-code=<code>. Fungies auto-applies the matching discount on its side, so the post-discount total stays consistent across both checkouts.
  • Requires the coupon to have been synced to Fungies via WooCommerce → Settings → Fungies → Sync Now (or the hourly cron). The plugin forwards the coupon code as-is; Fungies looks it up by discountCode.
  • Multiple coupons: the first applied coupon is forwarded (Fungies hosted checkout supports a single discount code).

Pairs with v2.2.x coupon sync

  • v2.2.0 introduced WC → Fungies coupon sync. v2.3.0 closes the loop on the customer-facing side: discounts now propagate to the Fungies checkout total automatically.

Upgrade notes

  • No DB migrations, no permission changes.
  • Backwards-compatible with single-product redirect URLs and multi-line-item Checkout Element URLs.
  • If the customer applies a coupon code that has not been synced to Fungies, the URL still includes the parameter; Fungies will simply ignore an unknown code and the customer will see the un-discounted Fungies total. Run Sync Now first.

v2.2.3 — Sync WooCommerce coupons to Fungies

Choose a tag to compare

@dukenukemall dukenukemall released this 09 May 08:09

v2.2.3 — Sync WooCommerce coupons to Fungies

New feature

  • WooCommerce coupons are now synced to Fungies on every "Sync Now" (and on the existing hourly cron). Each WC coupon (percent, fixed_cart, fixed_product) is mirrored as a Fungies discount with the same code, amount, amount type, expiration date, and usage limit. The Sync panel in WooCommerce → Settings → Fungies now shows a third row, "Coupons → Fungies", with created / updated / error counts.
  • Mapping is workspace-scoped (sandbox vs production) via _fungies_pushed_discount_id__<workspace-hash> post meta on each shop_coupon, so toggling Sandbox Mode does not orphan the link.
  • Idempotent: re-running Sync skips coupons that already match remote state.

Compatibility / robustness fixes shipped together

  • Use the WooCommerce coupon's actual date_created Unix timestamp for validFrom (the Fungies API accepts but mishandles 0 on non-UTC servers).
  • Omit purchaseLimit from the create payload when no usage limit is set (Fungies create schema does not accept null).
  • Inject id into the body of PATCH /v0/discounts/{id}/update — the Fungies update validator requires it in the body, not just the URL path.
  • Tolerate transient GET /v0/discounts/list 500s by falling back to a row-by-row walk and primarily relying on local post-meta mapping to decide between create vs. update.
  • Self-heal stale mappings: if an update_discount call returns not found (the Fungies row was archived/deleted manually), the plugin clears the local mapping and creates a fresh row on next sync.
  • Fix coupon diff for fixed-amount discounts: Fungies stores fixed amounts in currency minor units (e.g. 1 USD → "100"). The plugin now normalizes via wc_get_price_decimals() before comparing, and converts validUntil from milliseconds to seconds. No more spurious "updated" reports on every sync.

Upgrade notes

  • No DB migrations. New post meta is created on demand per coupon.
  • No new permissions or capabilities.
  • No changes to product sync, checkout flow, webhook handler, or order sync.

v2.1.11 — Fix post-checkout redirect race on production

Choose a tag to compare

@dukenukemall dukenukemall released this 29 Apr 11:47

v2.1.11 — Fix post-checkout redirect race on production

What was broken

Customers returning from the Fungies hosted checkout on production were being bounced back to the WooCommerce checkout/cart page instead of the order-received ("thank you") page. Staging worked correctly.

Root cause

A timing race between the Fungies payment_success webhook and the customer's browser redirect.

  • The old return handler in Fungies_Checkout::handle_return resolved the WC order via either:
    1. _fungies_order_id post meta (which is only set by the webhook), or
    2. A wc_get_orders query restricted to status: pending.
  • On production the webhook fires fast enough that by the time the user's browser lands on ?wc-api=fungies_return, the order has already moved from pendingprocessing. The pending-only fallback then misses, the meta lookup races the webhook commit, and the handler falls through to wp_safe_redirect( wc_get_checkout_url() ).
  • On staging the webhook is slower, so the order is still pending when the user returns, and the old fallback happens to work — masking the bug.

Fix

Introduced Fungies_Return_Resolver with three layered recovery strategies, deterministic to flaky:

  1. WC sessionFungies_Return_Resolver::remember( $order_id ) is called from Fungies_Payment_Gateway::process_payment right before redirecting to Fungies. On return we recover the order id from WC()->session regardless of webhook state. This is the primary path and works in ~100 % of normal flows.
  2. Broadened email fallback — now accepts pending, on-hold, processing, and completed instead of pending only.
  3. Brief poll (~3 s total, 6 × 500 ms) for the meta or a matching order, in case the webhook is landing right at that moment.

_fungies_order_id post meta is now also linked at return time using the fngs-order-id URL param, so any subsequent webhook call matches the existing order via meta and never creates a duplicate orphan order.

What's still in here from earlier

  • v2.1.10 — build.ps1 build script that enforces forward-slash zip packaging.
  • v2.1.9 / v2.1.8 — workspace-scoped _fungies_pushed_* post meta keyed by a hash of the active Fungies secret key, so toggling Sandbox Mode (production ↔ staging) no longer creates duplicates.

Install

Download fungies-checkout-2.1.11.zip and upload via Plugins → Add New → Upload Plugin in WordPress.

v2.1.10 — Locked-in zip packaging via build.ps1

Choose a tag to compare

@dukenukemall dukenukemall released this 29 Apr 11:33

v2.1.10 — Lock in correct zip packaging

Same runtime code as v2.1.9. This release adds a small build script (build.ps1) and uses it to produce the artifact, so we can never regress to the v2.1.8 broken-zip bug again.

What's new

  • build.ps1 — wraps git archive --format=zip to produce fungies-checkout-<version>.zip.
    • Verifies plugin header Version, the FUNGIES_WP_VERSION constant, and readme.txt Stable tag are all in sync.
    • Inspects every zip entry and refuses to ship if any path contains a backslash.
    • This is the only supported way to build the plugin zip from now on. Never use PowerShell Compress-Archive — it writes Windows-style backslash separators that break WordPress on Linux hosts (the v2.1.8 regression).

What's still in here from v2.1.9 / v2.1.8

  • Workspace-scoped _fungies_pushed_* post meta keyed by a hash of the active Fungies secret key, so toggling Sandbox Mode (production ↔ staging) no longer creates duplicates in the destination workspace.
  • Silent migration of legacy unscoped meta to the active workspace on the next successful push.

Install

Download fungies-checkout-2.1.10.zip and upload via Plugins → Add New → Upload Plugin in WordPress.