Dette er en demoshop til testformål. Ordrer vil ikke blive gennemført. Luk

Videre til indhold
  • Forside
  • Løsninger
    • Hjemmesider
    • Nyhedsbreve
    • Webshop
    • WordPress
  • Webalive plugin
    • WooCommerce produkt sortering
  • kontakt
  • Forside
  • Løsninger
    • Hjemmesider
    • Nyhedsbreve
    • Webshop
    • WordPress
  • Webalive plugin
    • WooCommerce produkt sortering
  • kontakt

© 2019

Webalive plugin

← Tilbage til alle plugins

WebAlive Members Premium

WebAlive Members Premium

Af WebAlive

Version 1.8.101 WP 5.0+ Testet 7.0 PHP 8.0+ Opdateret 2026-06-21

Beskrivelse

WebAlive Members Premium er et omfattende plugin designet til at hjælpe foreninger med at administrere deres medlemmer, begivenheder, betalinger og integration med WordPress-brugere. Nøglefunktioner:
  • Administrér medlemmer med detaljerede profiler
  • Synkronisér wa_members-tabellen med WordPress-brugere
  • Opret, opdatér eller fjern brugere automatisk baseret på medlemshandlinger
  • Importér medlemmer fra CSV eller ekstern MSSQL-database
  • Moderniseret import-workflow med AJAX-feedback
  • Importoversigt med statistik (tilføjede/overspringede/opdaterede/fejl)
  • Valgfri Fortryd Import & Logfremviser for sporbarhed
  • Håndtér begivenheder, aktiviteter og betalingsdata
  • AJAX-drevet adminpanel med Bootstrap UI
  • Responsive modaler til redigér/fjern/genaktivér medlem
  • Valgfri Mailchimp-integration til nyhedsbreve og automation
Ændringslog

1.8.101 (2026-06-21)

  • New: dedicated Roles tab under Settings (Settings -> Roles). Lists every WordPress role currently registered on the site (via wp_roles()->role_names) with two checkbox columns: "Member management" (Members / Categories / Subscriptions / Payments / POA / Orders) and "System settings" (Settings / Mailchimp Audit / WAM-Go Audit / WAM ID Audit). Admin ticks the boxes for whichever roles should have access; on save the corresponding capability is added or removed on each role via add_cap / remove_cap. The Administrator row is read-only with both boxes ticked (admin always has both).
  • New: dedicated capability wamp_manage_settings for the system-settings page group. Replaces the previous hardcoded manage_options check on Settings, Mailchimp Audit, WAM-Go Audit and WAM ID Audit (both menu registration and inline defense-in-depth current_user_can() calls). Administrator is granted the cap automatically via install().
  • Change: WAM_Premium_Roles::install() no longer hardcodes any role slug or display name beyond administrator and wamp_member_admin. The previous one-time grants to content_editor (1.8.99) and "Content Editor" by display name (1.8.100) are removed — those grants are now under the admin's explicit control via the new Roles tab. INSTALL_VERSION bumped from 3 to 4 so existing sites pick up the new admin cap.

1.8.100 (2026-06-21)

  • Fix: in 1.8.99 the install routine looked up the staff role by the hard-coded slug content_editor, which is not the actual slug used on every site. The lookup now iterates wp_roles()->role_names and matches any role whose display name equals "Content Editor" (case-insensitive, with or without space/dash) so the correct role is found regardless of the underlying slug. INSTALL_VERSION bumped from 2 to 3 so existing sites re-run the install routine once on next page load.

1.8.99 (2026-06-21)

  • Fix: WAM_Premium_Roles::install() now also grants wamp_manage_members to the content_editor role (if it exists), in addition to administrator and wamp_member_admin. INSTALL_VERSION bumped from 1 to 2 so existing sites re-run the install routine once on next page load and pick up the new grant. After this update Content Editor staff users can again see Members / Categories / Subscriptions / Payments / POA / Orders. Settings / Mailchimp Audit / WAM-Go Audit / WAM ID Audit remain administrator-only (manage_options).

1.8.98 (2026-06-21)

  • Revert: removed the WAM_Premium_Roles::enforce_caps() self-healing mechanism and its init priority-99 hook that was added in 1.8.97. No additional roles are touched by the plugin; the cap whitelist is back to what it has been since 1.8.52: wamp_manage_members is only granted to administrator and wamp_member_admin via install(), and any other role that needs it (e.g. a custom content_editor staff role) is managed entirely outside the plugin via a role-editor plugin or WP-CLI — the plugin does not add to, remove from, or otherwise modify those roles.

1.8.97 (2026-06-21)

  • Fix (defensive): wamp_manage_members capability is now self-healed on every request via WAM_Premium_Roles::enforce_caps() (hooked on init, priority 99). The method walks a whitelist of roles and re-adds the capability if it is missing. Previously the cap was only granted on plugin activation (via register_activation_hook → install()), so if a third-party role plugin or DB restore stripped the cap from a custom role later, the role lost access to the member-management pages (Members, Categories, Subscriptions, Payments, POA, Orders) until the cap was re-added by hand. Default whitelist: administrator, wamp_member_admin, content_editor. Extend via filter: add_filter( 'wamp_manage_members_roles', fn($roles) => array_merge($roles, ['my_custom_role']) );. Cheap: in-memory has_cap check first, write only when actually missing, guarded by a per-request static flag so it runs at most once per page load.

1.8.96 (2026-06-19)

  • New: member portal #pane-profile now shows an "Add" card for Member 2 when the household membership (MemberStatus = 2 / dual category) only has the primary wam_members record created. Previously the right-hand Member 2 card was hidden entirely until an admin or a checkout flow inserted the secondary row, so members had no self-service way to fill in their partner's name, email and mobile. The Add card collects First name, Last name, Email and Mobile and creates the secondary wam_members row (same MemberNo, inherits Address/Zip/City/Area/MemberStatus/NextPayment from the primary, generates UniqID, fires wam_member_created so the WP user + Mailchimp sync handlers run as for any new member). New endpoints: AJAX action wam_profile_add_secondary and REST route POST wam/v1/profile-add-secondary. The boot payload (wam_portal_boot / wam/v1/portal-boot) now also returns a can_add_secondary boolean so the JS knows whether to render the Add card. Once a secondary exists, the existing Edit card (email + mobile) takes over as before.

1.8.95 (2026-06-19)

  • Fix: clicking "Save" (Gem) in the member edit modal no longer fails silently. The submit handler now shows an error notice when the AJAX request itself fails (network/PHP fatal/nonce expired) or when the server returns success=false (e.g. update rejected, member not found). Previously a non-success response just left the modal open with no indication of what went wrong.

1.8.94 (2026-06-19)

  • Fix: Mailchimp ADDRESS is no longer composed when the WAMP Address (street) column is empty. Previously, members with only Zip (or Zip+City) but no street were sent with addr1="" plus zip/country, which Mailchimp rejected as "Please enter a complete address" (HTTP 400) — that failure aborted the whole upsert for the member. Now the sync skips ADDRESS for those members and successfully syncs the remaining merge fields (FNAME, LNAME, MEMBERNO, ZIP, etc.).
  • Improved: audit "Add" diagnostics and mc_upsert_request skip log now say address requires a non-empty street (WAMP Address column is empty) when that is why ADDRESS was not composed.

1.8.93 (2026-06-19)

  • Improved: address-skip diagnostics (both mc_upsert_request log and audit "Add" response) now quote the actual stored value of the Default country setting (e.g. default country setting = '' vs default country setting = 'DK') instead of just saying "empty". Makes it immediately obvious whether the option was actually saved in the database vs typed but not submitted.

1.8.92 (2026-06-19)

  • New: audit "Add" response now also lists every Mailchimp tag that was NOT sent and the exact reason (e.g. "ADDRESS: no Country in WAMP row and no Default country in Settings -> Mailchimp", "NEXTPAY: paired to NextPayment but the WAMP value is empty", "MSTATUS: paired to MemberStatus but tag does not exist in Mailchimp audience"). Makes the audit page self-diagnosing for every member.

1.8.91 (2026-06-19)

  • Fix: the "Create missing merge tags in Mailchimp" button (Settings -> Mailchimp) again bootstraps the curated WAMP-relevant tag set in the audience (FNAME, LNAME, PHONE, MOBILE, ADDRESS, MEMBERNO, NEXTPAY, MSTATUS, BIRTHDAY, AGE, GENDER, STATUS, EXTID, NOTE1, NOTE2, TITLE, AREA, YEAR) plus any already-paired tags. This is an explicit admin bootstrap action only; runtime sync still ONLY processes tags the admin has paired on the settings page.
  • New: audit "Add" action now returns the exact merge fields actually sent (count + tag list) so admins can see immediately whether real data reached Mailchimp. Message format: "Added to Mailchimp (N merge fields sent: FNAME, LNAME, ...)".

1.8.90 (2026-06-19)

  • Change: address-type Mailchimp merge tags (e.g. ADDRESS) are no longer offered as a WAMP pairing in Settings -> Mailchimp. Mailchimp's address is a composite object (street + city + zip + country) that does not map 1:1 to WAMP's Address column (which is street only).
  • Change: address-type tags are now composed automatically by the sync from WAMP Address (street) + City + Zip + Country (or the Default country admin setting). All other tags still require explicit pairing on the settings page.
  • UI: the WAMP-column dropdown for address-type rows is replaced with an info note explaining the auto-composition.

1.8.89 (2026-06-19)

  • Change: Mailchimp sync now ONLY processes merge tags that the admin has explicitly paired on Settings -> Mailchimp (Merge Field Mapping). All built-in default mappings and same-name fallbacks have been removed. Unpaired tags are never synced.
  • Removed: get_default_merge_mapping() (no longer used; the active mapping is the only source of truth).
  • Removed: "Create missing merge tags" no longer creates tags from a hard-coded fallback list — it only creates the tags currently paired in settings.

1.8.88 (2026-06-19)

  • Fix: ExtID column is now exposed in the Mailchimp Merge Field Mapping UI dropdown and accepted by the save handler. Default mapping references it (EXTID -> ExtID); previously it would have been silently filtered out by the allowed-columns whitelist when admin tried to map it.

1.8.87 (2026-06-19)

  • Fix: default mapping merge tag names now respect Mailchimp's 10-character limit. Previously NEXTPAYMENT (11) and MEMBERSTATUS (12) were either rejected at create or silently truncated, breaking sync. Now using NEXTPAY and MSTATUS.
  • Improved: mc_upsert_request log entries now state the EXACT reason a mapped WAMP column was not sent (e.g. "NEXTPAY: not created in Mailchimp audience" or "ADDRESS: address requires country (WAMP has no Country and default country setting is empty)").

1.8.86 (2026-06-19)

  • New: "Default country (address sync)" setting under Mailchimp options. Holds an ISO-2 country code (e.g. DK) that is used as the country in Mailchimp address payloads when the WAMP Country column is empty (or the column does not exist on this install). This is an explicit admin configuration, not a silent fallback.
  • Result: members with Address/City/Zip but no Country (e.g. Sara: "Øresunds alle 25", 2791 Dragør) now sync to Mailchimp's ADDRESS field when the default country is set.

1.8.85 (2026-06-19)

  • Improved: Mailchimp default merge mapping now also covers BIRTHDAY, AGE, GENDER/MALEFEMALE, NEXTPAYMENT, MEMBERSTATUS, STATUS, EXTID, NOTE1, NOTE2. These are pushed by audit Add / Batch Add / Auto-sync when the corresponding tag exists in the Mailchimp audience.
  • New: WAMP_PAYLOG now records the exact upsert payload sent to Mailchimp from the audit page, including (a) non-empty WAMP columns for the member, (b) the merge_fields actually sent, (c) WAMP columns that have a mapping but did NOT get included (and which MC tag was expected). Use this to diagnose any missing data.

1.8.84 (2026-06-19)

  • Improved: replaced the comma-separated "Delete merge tags" input with a per-row trash icon in the Merge Field Mapping table. Click the icon, confirm, and the merge tag is removed from Mailchimp via AJAX. Reserved tags (EMAIL, UNIQID, GUID) show a lock icon instead.

1.8.83 (2026-06-18)

  • New: "Delete merge tags in Mailchimp" input + button under Settings -> Mailchimp -> Merge Field Mapping. Admin enters comma-separated tag names and confirms; the merge fields are removed from the Mailchimp audience via DELETE /lists/{id}/merge-fields/{merge_id} (irreversible). Requires manage_options + nonce.

1.8.82 (2026-06-18)

  • Fix: skip Mailchimp-reserved merge tag names (UNIQID, EMAIL, GUID) when creating tags via the settings button (Mailchimp returns HTTP 400 "reserved and can't be used"). CS_UNIQID is still used as the WAMP UniqID merge field.
  • Hardened: "Create missing merge tags" no longer aborts the whole batch on a single reserved-name response.

1.8.81 (2026-06-18)

  • Fix: ZIP merge tag is now explicitly created as text in Mailchimp (postnummer / Danish ZIP, preserves leading zeros).
  • New: "Fix merge tag types" button under Settings -> Mailchimp -> Merge Field Mapping. PATCHes existing merge fields in Mailchimp so their type matches WAMP expectations (e.g. ZIP -> text).

1.8.80 (2026-06-18)

  • New: explicit "Create missing merge tags in Mailchimp" button under Settings -> Mailchimp -> Merge Field Mapping; calls Mailchimp API directly to create configured/default tags (FNAME, LNAME, PHONE, MOBILE, ADDRESS, CITY, ZIP, COUNTRY, UNIQID, CS_UNIQID, MEMBERNO, ID, etc.) and ADDRESS as native address type.
  • Removed: implicit on-the-fly auto-creation of merge tags during sync (was confusing and ran without admin consent).
  • Removed: country fallback to DK in address sync. Address payload is now built strictly from WAMP Country value (skipped when missing/invalid).

1.8.79 (2026-06-18)

  • Fix: ADDRESS merge tag is now created via Mailchimp API as address type (not plain text), so structured address sync works correctly.
  • Fix: address sync now applies country fallback (DK) when country is empty, preventing address payload from being skipped.

1.8.78 (2026-06-18)

  • Improved: Mailchimp audit/add/sync now ensures configured/default merge tags exist in the audience before building merge payloads.
  • Fix: preserved default merge-tag mappings even when custom mapping is saved, so tags like MOBILE, UNIQID and CS_UNIQID continue to sync as expected.

1.8.77 (2026-06-18)

  • Change: removed Mailchimp URL setting from WAMP Mailchimp options.
  • Change: Mailchimp API base URL is now derived automatically from API key datacenter suffix (for example -us22 -> https://us22.api.mailchimp.com/3.0).
  • Fix: prevents merge-tag fetch HTTP 404 caused by entering admin UI host URLs.

1.8.75 (2026-06-16)

  • New: when an existing member's email is changed (from admin Members module or the front-end portal), the Mailchimp sync handler now automatically reconciles the Mailchimp audience without admin having to run the Mailchimp Audit page. Flow in WAM_Premium_Mailchimp_Sync::sync_member_to_mailchimp() after the wam_member_updated action fires: (1) GET Mailchimp by the new email's subscriber hash — if a contact exists there, the row is upserted normally (PUT with merge fields, same as before). (2) If no contact exists under the new email, the handler queries Mailchimp's /search-members endpoint with the WAMP UniqID and filters the result to a contact whose CS_UNIQID merge field matches exactly; this finds the SAME person under a different (old) email. (3) Dual-membership guard: before touching the old email's Mailchimp contact, the handler checks wam_members for any OTHER active row (DelReason=0, different id) that still owns the old email — if yes (e.g. household with 1 MemberNo and 2 names where the second person just got their own email added), the old contact is left alone and only the new email is upserted on the renamed person. (4) When the old email is exclusively this person's, the handler PATCHes /lists/{list_id}/members/{md5(old_email)} with the new email + full merge fields if the old contact's status is subscribed/unsubscribed/pending; for cleaned/archived/transactional (Mailchimp forbids PATCHing those — typos on cleaned addresses being the user's documented case) the old contact is permanently deleted via /actions/delete-permanent and a fresh contact is created under the new email via PUT. (5) If no UniqID match is found at all, the upsert simply creates a new contact under the new email as before. New helper search_mailchimp_member_by_uniqid() is also reusable from other flows. No call sites need to change — the existing wam_member_updated action payload ([ 'id' => N ]) is enough; the rename detection is fully server-side via the Mailchimp API.

1.8.74 (2026-06-16)

  • New: new online member signups via the front-end / QuickPay flow are now automatically pushed to Mailchimp at the moment the wam_members rows are INSERTed. Previously this was only handled by the Mailchimp Audit page after the fact (admin had to run a manual batch). Implementation: WAM_Premium_Helper::create_members_from_order() now fires the existing wam_member_created action for the freshly-inserted primary row (and the duplicate/co-applicant row when present), passing [ 'id' => N ] to match the payload shape already used by the admin members-AJAX code paths. The existing WAM_Premium_Mailchimp_Sync::sync_member_to_mailchimp() handler picks up the action when Mailchimp sync is enabled (option mailchimp_sync = 1); it reads the row from wam_members, builds merge fields from the configured mapping, and calls upsert_member_row_to_mailchimp() (PUT to /lists/{list_id}/members/{md5(email)}, status = subscribed). The action runs only AFTER successful insert, AFTER the idempotency guard short-circuits, so calling create_members_from_order() multiple times for the same order does not produce repeat Mailchimp upserts. Safe by design: when Mailchimp settings are missing, the option is disabled, the member has no email, or Mailchimp returns an error, the helper does NOT fail the order — the sync result is logged to WAMP_PAYLOG (wam_member_mc_sync_triggered) and the existing Mailchimp Audit page remains as the recovery tool for after-the-fact reconciliation.

1.8.73 (2026-06-16)

  • Fix: WAM ID Audit "Soft-deleted rows pending hard delete" table was confusing because it showed the MemberStatus column (category id, values 1-5) but no explicit DelReason column, so it looked like rows with DelReason != 99 were being offered for hard-delete. The SQL filter is correct (WHERE DelReason = 99), but the UI didn't display it. Now the table includes an explicit DelReason column that should always read 99 for every row in this section, and a runtime guard skips any row whose DelReason somehow isn't 99 (belt-and-braces: never offer hard-delete on a non-soft-deleted row).

1.8.72 (2026-06-16)

  • Improved: WAM ID Audit cleanup is now a two-step flow. Step 1 (duplicate groups, top of the page) keeps the Soft-delete button on unreferenced rows — it sets DelReason = 99 (reversible, row stays in the database). Step 2 is a new section below labeled "Soft-deleted rows pending hard delete" that lists every wam_members row with DelReason = 99 and is NOT referenced by any shop_order. Each such row gets a Hard-delete button which performs DELETE FROM wam_members WHERE id = X after a JS confirm and a safety re-check on the server (refuses if any order has appeared that references the row). This separates the destructive step from the discovery step: admin first soft-deletes a row, verifies nothing else breaks (welcome emails, portal logins, payment receipts), and only then hard-deletes from the second section. Both buttons go through POST with nonce + manage_options check; hard-delete additionally re-verifies the row's DelReason is still 99 before issuing the DELETE.

1.8.71 (2026-06-16)

  • Improved: WAM ID Audit page redesigned to focus on actual duplicate cleanup. Instead of listing every order with its sibling rows, the page now queries wam_members directly and shows ONLY groups where 2 or more rows share the same MemberNo AND the same normalized name (Fname + Lname, case/whitespace insensitive) — i.e. the actual triple-INSERT bug duplicates. Each group lists its rows in id order with: row id, name, email, MemberStatus, DelReason, and a "Referenced by" column showing every shop_order that points to this row via _wam_member_primary_id or _wam_member_second_id. Rows that are NOT referenced by any order (the bug-leftover duplicates) get a Soft-delete button that sets DelReason = 99 (POST + nonce + manage_options capability check), removing the row from active lookups without losing data. Order-based filters (filter by order id, only-issues checkbox) are removed since the page is now member-centric; the MemberNo filter is kept for spot-checks. Page remains read-only by default — only the explicit per-row Soft-delete button writes (one row at a time).

1.8.70 (2026-06-16)

  • Improved: WAM ID Audit page now also surfaces sibling member rows for each order's MemberNo. For every order the page already showed _wam_member_primary_id and _wam_member_second_id; it now adds a "Sibling rows for MemberNo X" sub-row that lists every wam_members row sharing the same MemberNo and tags each one as PRIMARY (referenced as _wam_member_primary_id on this order), SECOND (referenced as _wam_member_second_id on this order), OTHER ORDER #N (referenced by a different shop_order via either primary or second meta), or UNREFERENCED (no shop_order references it). UNREFERENCED rows that match the primary row's name+email are the prime suspects for triple-INSERT bug duplicates and are highlighted in red. The issue-flag now also triggers when sibling rows look like bug duplicates (extra UNREFERENCED rows with identical name+email as the primary), making the "Only show issues" filter directly useful as a cleanup work list. Read-only — still no writes.

1.8.69 (2026-06-16)

  • New: admin-only audit tool under WebaLive Members Premium → "WAM ID Audit" (page=wam-premium-wam-id-audit). Read-only diagnostic view that lists every WooCommerce shop_order which carries _wam_member_primary_id post meta together with the related _wam_member_second_id, _wam_memberid, _wam_memberno, _wam_is_new_member, _wam_category_id and _wam_order_sku values. The page resolves each id back to its wam_members row (Fname/Lname/Email/MemberStatus/DelReason) so an administrator can quickly confirm which row is the canonical "valid" member for an order. Used as the inventory step for cleaning up triple-INSERT bug duplicates: it makes the order ↔ member id linkage visible without touching any data. Page requires manage_options and is hidden from non-admins. Filters: by MemberNo, by order id, and a checkbox to only show orders where the resolved primary or secondary id is missing/soft-deleted (delreason != 0 or row gone). No data is written; no AJAX actions; nothing scheduled.

1.8.68 (2026-06-16)

  • Fix: the membership-payments table inside the member detail modal (admin Members page) was empty for newly signed-up members — their first kontingent/subscription payment did not appear even though the row existed in wam_payment with the correct memberno. Root cause: the SQL filter in fetch_member_detail_callback() only matched rows where reference LIKE 'Kontingent %' OR orderno LIKE 'BS%', which fits portal-renewal orders (whose _wam_order_title is set to "Kontingent ÅÅÅÅ") and BS-import rows, but NOT brand-new signups. New-member rows are written by WAM_Premium_Helper::upsert_payment_from_quickpay(), which derives reference from the order's _wam_order_title (typically the product/category name like "Nyt medlemskab") and uses the WC order id as orderno (no BS prefix), so they never matched the filter. Fix: extend the filter so the modal also picks up rows where category is WAMP_PAY_CATEGORY_NEW (1) or WAMP_PAY_CATEGORY_RENEW (2), keeping the existing legacy reference/orderno matches as a fallback for older data and BS imports. The category column is set consistently by get_order_category_info() and is the same field that already drives the renewal-receipt email gate, so this aligns the UI with the rest of the membership-payment logic.

1.8.67 (2026-06-11)

  • Fix: new online member signups via WooCommerce + QuickPay created the member 3 times in wa_members instead of once. Root cause: WAM_Premium_Helper::create_members_from_order() is invoked from three independent code paths for the same WooCommerce order — WAM_Premium_Gateway::process_payment() (gateway.php:136, runs at checkout submit), the Woo payments finalizer (woo-payments.php:232, runs in the WC order completion chain), and the QuickPay server callback receiver (wam-premium-callback.php:641, runs when QP POSTs the capture callback). Each path was protected by the existing _wam_is_new_member='1' gate (added earlier to stop portal-kontingent orders from inserting), but there was no idempotency check on the function itself, so all three calls executed $wpdb->insert(WAMP_MEMBER, ...) — and if a co-applicant (_wam_duplicate_member) was present, the result was 6 rows. Fix is a single idempotency guard placed at the top of create_members_from_order(), right after the new-member gate: if _wam_member_primary_id is already set on the order (>0), the function logs member_create_skipped_duplicate and returns the existing primary/duplicate IDs without inserting. This makes the function safe to call any number of times for the same order from any hook, without changing the public contract (callers still get a success/primary_id/duplicate_id result). No call sites were removed — keeping all three paths means a member is still created reliably even if one hook fails to fire (e.g. QuickPay callback delayed, or order completion hook suppressed by another plugin).

1.8.66 (2026-06-11)

  • Fix: latent namespace-resolution fatals in three namespaced AJAX classes (class-wam-premium-kontingent-ajax.php, class-wam-premium-payments-ajax.php, class-wam-premium-members-ajax.php). Same root cause as 1.8.62/1.8.65: each file begins with namespace WAM_Premium\Admin;, but the capability check used WAM_Premium_Roles::can_manage() and one helper call used WAM_Premium_Helper::waet_enqueue_by_uuid() without a leading backslash. PHP resolves unqualified class names into the current namespace (no fallback to global for classes), so these calls would have fataled the moment any of these AJAX endpoints were hit (bulk_charge, send_request, delete_member, pdf_nocontact, search_member, create_payment, move_payment_member, mark_paid, queue_payment_request_email). Fixed 10 references in total (6 in kontingent-ajax, 3 in payments-ajax, 1 in members-ajax) by switching to the fully qualified \WAM_Premium_Roles::can_manage() / \WAM_Premium_Helper::... form and using class_exists('\\WAM_Premium_Roles') so the existence check also targets the global namespace. The class-wam-premium-poa.php file uses the same pattern but is in the global namespace and was unaffected; left untouched.
  • Audit: scanned all 17 namespaced WAMP admin classes plus the front include files for the same defect. No other instances found. WC function calls (wc_get_order, get_woocommerce_currency_symbol, etc.) in the rest of the plugin are either already guarded with function_exists() or live inside code paths that only run when WooCommerce is active (gateway, finalizer, autocharge, renewals, callback, woo-payments, quickpay-metabox).

1.8.65 (2026-06-11)

  • Fix: fatal "Call to undefined function get_woocommerce_currency_symbol()" when opening the Payments / Kontingent page on sites where WooCommerce is not active. The call in Kontingent_Page::render() (class-wam-premium-kontingent-page.php:151) was unguarded; all other WC calls in the codebase already use function_exists(). Now uses the same guard with a DKK fallback. (Error was reported as WAM_Premium\Admin\get_woocommerce_currency_symbol because the file is namespaced and PHP shows the FQ name in not-found errors.)

1.8.64 (2026-06-10)

  • New: "Side panel flyout breakpoint" setting under Settings → General (members_options tab). Lets the site admin choose at which viewport width (px) the right info panel collapses into the flyout introduced in 1.8.63. Default 1280, allowed 600–2400, 0 = always show as flyout, -1 = never use flyout (panel stays inline at all viewports). Stored in option wam_premium_side_flyout_breakpoint.
  • Refactor: the flyout @media block was moved out of the static wam-premium.css and is now emitted dynamically from wam-premium-right-column.php using the saved breakpoint. The CSS file only keeps the base hidden state for the toggle/close/backdrop elements.

1.8.63 (2026-06-10)

  • Improved: on narrow viewports (≤ 1280px) the right-hand WAMP info panel (#wam-premium-admin-side) is no longer just hidden — it now slides in from the right edge as a flyout. A small toggle button is fixed to the right margin (chevron icon) so the user can pull it in on demand. Close via the X inside the panel, the backdrop, or the Esc key. Wide screens are unchanged. Implementation is plain CSS + a few lines of vanilla JS, no jQuery dependency.

1.8.62 (2026-06-08)

  • Fix: fatal "Class WAM_Premium\Admin\WA_Members_Admin_Helper not found" thrown from the members-list AJAX handler (get_columns() in class-wam-premium-members-list.php), which made the list render empty rows on every site. The helper class lives in the GLOBAL namespace, but the list-table file is namespaced as WAM_Premium\Admin, so the unprefixed reference resolved into the wrong namespace at call time. The string-based class_exists('WA_Members_Admin_Helper') check did NOT catch it because that form already looks in the global namespace. Fixed by using the fully qualified \WA_Members_Admin_Helper reference (plus matching class_exists('\\WA_Members_Admin_Helper')).

1.8.61 (2026-06-08)

  • Fix: Settings → Table options now correctly saves per-column Label and Max width values. Previously the Removed Member List table rendered the same name="wam_premium_list_column_labels[KEY]" and name="wam_premium_list_column_widths[KEY]" inputs as the Active table; PHP keeps the LAST value for duplicate keys in $_POST, so the empty input from the Removed table silently overwrote whatever the user typed in the Active table, and the save handler then skipped the empty value entirely. The Removed list now shows Label and Max width as read-only and points the user to edit them in the Active list above. Both lists keep their own independent Show-checkboxes and column order.

1.8.60 (2026-06-08)

  • Improved: members-list column picker (Settings → Table options) now introspects the actual wa_members table via SHOW COLUMNS and only offers UI keys that are backed by an existing DB column. Keys mapping to virtual/composite columns (Name requires Fname+Lname, Street requires Address) are handled in the mapping. Result is cached per-request.
  • Hardened: the WP_List_Table now also filters the rendered column headers against the existing DB columns, so old saved selections for fields that have since been removed from the schema silently drop out instead of producing empty columns.

1.8.59 (2026-06-08)

  • Fix: Members list (page=wam-premium) showed an empty table on sites whose wa_members table does not contain every optional column added in 1.8.57 (Title, MaleFemale, Country, ExtID). On those sites the explicit SELECT failed (Unknown column) and the whole result set came back empty. The query now selects * so missing optional columns no longer abort the query; the row mapping already uses ?? '' fallbacks for the optional fields, so cells stay empty when the underlying column is absent.

1.8.58 (2026-06-07)

  • New: per-column "Max width (chars)" setting under Settings → Table options for both Active and Removed member lists. When set (> 0) the cell is clipped with an ellipsis at that character width, so wide tables fit in narrow viewports without breaking text into multiple lines. Empty value = no limit (default WP behavior).
  • Improved: responsive layout for the members list (page=wam-premium). On viewports below 1280px the right sidebar ("other plugins" / promo) is hidden and the table wrapper allows horizontal scroll instead of squeezing text. Below 960px the list-table font size is reduced (13px) and below 782px further reduced (12px) with tighter cell padding, so content stays readable on laptops and tablets without browser zoom.

1.8.57 (2026-06-07)

  • Fix: Members list (page=wam-premium) now actually shows data for the optional columns Title, Country, Gender (MaleFemale) and ExtID when they are enabled under Settings → Table options. The underlying query and row mapping were missing these database fields, so the column header appeared but the cells were always empty even though phpMyAdmin showed valid data.

1.8.56 (2026-06-01)

  • Fix: Admin-bar "Members Premium" entry is now visible to the Member Administrator role (not only administrators). Registration was moved out of the admin-only class so the entry appears in all contexts (front-end and back-end) for any user with the WAMP management capability.
  • New: Plugin icon shown next to the "Members Premium" label in the admin bar.

1.8.55 (2026-06-01)

  • New: WAMP entry added to the WordPress admin bar (top black bar). Visible to administrators and to the Member Administrator role. Provides quick links to Members, Categories, Payments, Subscriptions, POA (when enabled) and Orders (when WooCommerce is active). Settings link is shown to administrators only.

1.8.54 (2026-06-01)

  • Change: POA feature now defaults to disabled (wam_premium_poa_active = no) on sites that have never set the option. Existing sites where the option has been explicitly saved (yes or no) are unaffected. To enable POA, tick the checkbox under Settings → POA options.

1.8.53 (2026-06-01)

  • UI: "POA Entries" submenu is now only registered when POA is enabled in Settings (wam_premium_poa_active = yes). When POA is disabled, the menu item is hidden.
  • UI: "Orders" submenu under Members Premium is now only registered when WooCommerce is active. On sites without Woo, the item is hidden.

1.8.52 (2026-06-01)

  • New: dedicated "Member Administrator" role + custom capability wamp_manage_members so non-admin staff can manage the member registry without being granted full WordPress administrator rights. Administrators automatically receive the capability (auto-installed on plugin update via WAM_Premium_Roles::install(), idempotent). The new role grants only basic read + wamp_manage_members — nothing else.
  • Access: the following pages and AJAX actions are now gated by the new capability (Administrator + Member Administrator can use them): Members, Categories, Subscriptions, Payments, Import Payments, Import Members, POA Entries, Orders, plus the kontingent AJAX (bulk_charge, send_request, delete_member, pdf_nocontact, search_member, create_payment), refresh_member_next_payment, move_payment_member, queue_payment_request_email, and POA add/delete AJAX endpoints.
  • Access: the following remain administrator-only (manage_options): Settings, Mailchimp Audit, WAM-Go Audit, and the WAM-Go column in the members list. These are system-configuration / debug tools.
  • Frontend: the existing member-only-page bypass (wam_premium_mep_member_only_bypass) now also bypasses for users with the new capability, so Member Administrators can view member-only content while supporting users.
  • Helper: WAM_Premium_Roles::can_manage() is the single source of truth for runtime checks; admins always pass via fallback to manage_options so the gates remain robust even mid-upgrade.

1.8.51 (2026-05-30)

  • Fix: Mage event orders that pay through the WAM gateway and create a subscription in the same flow as the first charge (typical case: member who has previously paid kontingent via bank and now buys an event ticket) sometimes ended up with WWEF attendee posts but no Mage attendee posts (mep_events_attendees), leaving the ticket PDF without QR code or ticket number. Order #17449 is a representative example. The QuickPay callback now calls WAM_Premium_Payment_Finalizer::ensure_event_data($order_id) immediately after the existing finalize sequence; this re-fires woocommerce_order_status_{current} and _changed so Mage's and WWEF's own attendee-creation hooks get a second chance. Idempotent (gated by _wamp_event_data_bound order-meta), no-op for non-event orders, no-op when Mage attendees already exist. Member-create, kontingent emails, and all other WAMP business logic are untouched.

1.8.50 (2026-05-30)

  • Internal (additive only, no behavior change): introduce skeleton classes WAM_Premium_Payment_Finalizer and WAM_Premium_Post_Payment in lib/classes/. These define the contract for a future unified payment finalizer and the named action hooks for post-payment side-effects (member created/renewed, email dispatched, promotion applied, finalized). No existing payment path calls into them yet — they are loaded but inert. This is the structural foundation for migrating the 6 divergent payment paths (callback subscription, callback direct, autocharge, vipps, vipps renewal, admin/portal/bridge) onto a single code path in subsequent releases.

1.8.49 (2026-05-22)

  • Compatibility: Tested with WordPress 7.0 and WooCommerce 10.7.

1.8.48

  • Fix: Edit and Delete buttons in member details card modal now work correctly — they close the details modal and open the appropriate edit/delete modal with proper AJAX loading.
  • Fix: Modal transitions properly chain via fadeOut callback instead of triggering unhandled events.

1.8.47

  • Admin POA: "Send POA Reminders Now" now reports honestly. Previously the UI always said "sent" even when the reminder option was off, no verify page was configured, no candidate POAs existed, members had no email on file, or wp_mail() returned false / fired wp_mail_failed. The AJAX response now includes a stats object (reminder_enabled, verify_page, candidates, attempted, sent, skipped_no_email, mail_errors) and a human-readable reason when nothing is sent.

1.8.46

  • Admin POA PDF: Added section name (Confirmed in green / Unconfirmed in orange) at the bottom-center of every page so pages from the two sections can no longer be mixed up. Implemented via a pre-render of the Confirmed section to count its pages, then DomPDF's page_script() callback stamps the correct label on each page of the final PDF.

1.8.45

  • Admin POA PDF: Fixed unwanted page break right after the section subheader and content overflowing past the page bottom. Removed the outer table-wrapper that was used to repeat the colored banner — DomPDF could not break cleanly inside that giant cell. The Confirmed (green) / Unconfirmed (orange) banner is now a simple block at the top of each section.
  • Admin POA PDF: Footer now shows just Page X (the / Y total page count was never resolved by DomPDF inside a fixed-positioned footer and rendered as / 0). Also widened the bottom page margin so the footer no longer collides with the last data row.

1.8.44

  • Admin POA PDF: Reverted to a reliable fixed <footer> (site name, generation date, Page X / Y). The previous @page named-page margin boxes were unreliable in DomPDF and made the footer disappear entirely. The Confirmed (green) / Unconfirmed (orange) section indicator is now rendered as a repeating colored band at the top of every page within each section (via repeating table head), which is far more robust.

1.8.43

  • Admin POA PDF: Footer now shows the current section name (Confirmed in green, Unconfirmed in orange) on the right, instead of total page count. Implemented via DomPDF named pages and @page margin boxes.

1.8.42

  • Admin POA: All POA-related UI labels in the admin dashboard, the POA list page and the POA PDF export now use English source strings wrapped in __() / esc_html__() so they are properly i18n-ready (Danish translations belong in .po/.mo).
  • Admin POA: JS dashboard pill labels (Board, Members, Yes, No, Unlimited) are now passed in via wam_premium_poa.i18n instead of being hardcoded.

1.8.41

  • Admin POA: Reworked the bulk-action Export PDF from page=wam-premium-poa (Apply on the bulk dropdown). The PDF now uses the event/begivenhed as title and a footer with site name, generation date/time and page number.
  • Admin POA: PDF is split into two sections with a page break — first Bekræftede, then Ubekræftede. Each section shows a subheader with the total count for the section.
  • Admin POA: Rows are sorted by Fuldmagt til and then by first/last name. When Fuldmagt til changes, a small group block is rendered with a per-recipient mini dashboard (Antal, Ja, Nej, Ubegrænset).
  • Admin POA: List columns are now Medlem (navn + medlemsnummer i parentes), Fuldmagt til, Instruktion and Oprettet (dato).

1.8.40

  • Admin POA dashboard: Consolidated Bekræftet (confirmed count) into the Antal card, now showing format "Total (Confirmed)" for compact display.
  • Admin POA dashboard: Removed the separate Bekræftet card; one less visual element to reduce clutter.
  • Admin POA dashboard: Added distinct background colors to each dashboard card for better visual hierarchy and semantic clarity.

1.8.39

  • Admin POA dashboard: Refined visual styling for better readability with clearer, card-level breakdown layout for Fuldmagt til and Instruction.
  • Admin POA dashboard: Breakdown metrics are now shown as compact styled items (still including confirmed counts in parentheses).

1.8.38

  • Admin POA dashboard: Improved summary details with clearer breakdowns:
  • Fuldmagt til now shows board vs member counts and confirmed counts in parentheses.
  • Instruction now shows Ja/Nej/Ubegrænset counts with confirmed counts in parentheses.

1.8.37

  • Admin POA: Added a dashboard at the top of the page=wam-premium-poa screen in the same card style as page=wam-premium, showing totals for Antal, Fuldmagt til, Instruction, and Bekræftet.
  • Admin POA: Dashboard counters now update live when using search/event filters and after deleting entries.

1.8.36

  • Portal Profile: Member 2 (partner) card now has its own independent Edit / Save button, so the primary member card and the partner card can be edited and saved separately without affecting each other. Saving Member 2 only writes the partner's email/mobile and never touches the primary member row. New AJAX/REST endpoint wam_profile_save_secondary (wam/v1/profile-save-secondary).

1.8.35

  • Fix: Fatal Cannot declare class ComposerAutoloaderInit… when generating POA PDF (and other dompdf paths). The plugin shipped two identical dompdf installations (lib/dompdf/ and dompdf/dompdf/); both autoloaders could be required in the same request, so the same composer init class was declared twice. All dompdf require sites now go through lib/dompdf/autoload.inc.php and are guarded by class_exists('\Dompdf\Dompdf') to defend against other plugins that ship dompdf as well.
  • WAM-Go: Added a third, ultra-permissive rewrite (/wam-go/.+?/<post_id>/) and a template_redirect 404 safety net that catches any /wam-go/…/<numeric post_id>/ URL the rewrite rules missed (e.g. literal << Test MemberNo >> segments containing characters the web server normalizes/strips). The visitor is redirected to the trailing post permalink without any login attempt.
  • Portal POA tab: Added an intro panel at the top of the tab with a Create power of attorney button that links to the configured POA shortcode page (Settings → POA page). Shown both when the member has no documents yet and above the existing list.
  • Portal UI: Reduced tab padding and font size and forced nowrap so the now seven possible tabs (Profile, Cards, Subscription, Payments, Orders, POA, Settings) try to stay on a single line on desktop. On narrow screens they wrap normally with even tighter spacing.
  • i18n: New keys poa_create_intro, poa_create_btn.

1.8.34

  • WAM-Go: More aggressive detection of unresolved newsletter merge tags / preview placeholders. Links containing <<…>>, *|…|*, or text like Test MemberNo/Test UniqueId (sent by Mailchimp test campaigns) now skip the login attempt and redirect straight to the target post (e.g. /wam-go/<< Test MemberNo >>/<< Test UniqueId >>/9115/ lands on post 9115 without login).
  • WAM-Go: When an actual login attempt fails (invalid token, unknown member), the visitor is now redirected to the requested post permalink instead of the site home page, so the intended content is still shown.
  • POA shortcode: When the visitor is already logged in (e.g. arrived via /wam-go/), the [wam_poa] shortcode now auto-detects their member number from their account and goes straight to the candidate view, hiding the "Enter Your Member ID" search field.

1.8.33

  • i18n: Added missing PHP-localized strings payment ("Payment") and phone ("Phone") used as labels in the portal MobilePay subscription card. Previously fell back to the lowercase i18n key (so the labels rendered as untranslated "PAYMENT"/"PHONE" via CSS uppercase, with no way to translate them).
  • UX: Portal MobilePay subscription card — payer phone is now displayed formatted (+45 21 41 12 66 instead of 4521411266). Falls back to the raw value if the format cannot be detected.

1.8.32

  • Fix: WAMP WAET bootstrap now ensures WAET template/variable tables exist before creating templates, and only treats a template as created if it can be read back afterwards. This fixes cases where no WAMP WAET templates appeared even after deleting them and reloading.

1.8.31

  • Improve: Added a standard organization footer to WAMP WAET startup templates: © {{org_name}} • {{org_addr}} • {{org_zip}} {{org_city}} • {{org_email}}.

1.8.30

  • Fix: WAMP WAET bootstrap now retries automatically when the expected WAMP-owned templates are still missing, instead of treating the version flag alone as success. This prevents a "no templates created" state from getting stuck.

1.8.29

  • Fix: WAMP WAET startup templates now ship their header title contrast through template CSS (WAET-native) instead of relying on inline heading color, and existing WAMP-owned WAET templates get that CSS rule added on bootstrap.

1.8.28

  • Fix: WAET startup template headers now force white heading text in the header block so {{subject}} always keeps contrast against the header background across themes.

1.8.27

  • Improve: Updated WAET startup table markup so table cells wrap content in <div> inside <td> for better WAET editor compatibility when editing templates later.

1.8.26

  • Improve: WAMP WAET startup templates are now theme-aware and built with WAET theme classes (container, header, content, footer, button/btn) so they respect selected WAET theme settings (light/blue/red).

1.8.25

  • Improve: Added a dedicated WAMP startup-template folder for WAET (templates/waet-startup/) with maintainable template files and manifest.
  • Improve: WAET bootstrap now loads startup templates from files, making it easier to refine and ship polished default templates.

1.8.24

  • New: WAMP now auto-creates ready-to-use WAET templates for all Email settings cards (standard member message, payment request, membership receipt, new member receipt, one-time code, subscription receipt) and auto-assigns them in WAMP settings when missing.
  • New: WAMP now auto-registers required WAET merge tags used by these templates, so templates remain editable and fully functional after customization.

1.8.23

  • Fix: Portal MobilePay subscribe — payment row reference is now always Kontingent YY (e.g. Kontingent 26) instead of {Cat_name} YY. This makes the row appear in the Kontingent overview list (which filters on reference LIKE 'Kontingent %' OR orderno LIKE 'BS%') — previously the latest MobilePay payment was missing from the list.
  • i18n: Replaced Danish source strings with English (Danish moves to .po/.mo translations as it should). All visible English fallback strings in the front portal now use proper English: "Skift betalingsmetode" → "Change payment method", "Start fast betaling med MobilePay" → "Start MobilePay subscription", "Current kontingent" → "Current membership fee", "Kontingent payment completed." → "Membership fee payment completed.", "No kontingent payments found." → "No membership fee payments found." etc. Added missing PHP-localized strings for previously JS-only fallbacks (okMobilePay, okExplainedMp, retry_card, actions, active, total, view, no_orders, signing_in, enter_code, member_number, link_account, email_diff, no_access, yes_verify, no_member_found, kontingent_paid_*).
  • Note: i18n keys themselves still use the kontingent_* / noKontingent identifiers (they are not user-visible). The DB field WAMP_PAYMENT.reference = 'Kontingent YY' is also unchanged because it is referenced by the SQL filter reference LIKE 'Kontingent %' used to build the membership fee overview — changing the reference would orphan all existing payment rows.

1.8.22

  • Fix: Portal "Fast betaling" tab — Tilføj betalingskort (QuickPay card setup) is now hidden on sites where Vipps/MobilePay is the configured payment method. Previously the QuickPay button could appear when no MobilePay agreement existed yet, even on Vipps-only sites.
  • Fix: After a successful MobilePay portal subscription the user landed on a blank ?tab=payment page (the legacy payments tab does not exist in the new layout). The Vipps return URL now sends the member to ?tab=kontingent so the Kontingent tab is focused.
  • Fix: Portal MobilePay subscribe (existing member) now mirrors the new-member flow end-to-end: an initial_charge_amount equal to the kontingent is sent to Vipps, and on return a WAMP_PAYMENT row (status=processed, type=MobilePay, acquirer=vipps, RENEW category, orderno=MB{yy}{memberno}, reference={cat_name} {yy}, transid=chargeId) is inserted plus WAMP_MEMBER.NextPayment is updated. The Kontingent tab now correctly shows "Kontingent betalt" instead of "Ikke betalt" after subscribing.

1.8.21

  • Change: Vipps productName now contains only the category/type name (e.g. Husstandsmedlem) — the site-name prefix (Nordstrandforeningen - ) has been dropped. Affects both the new-member signup flow and the portal Start fast betaling/Skift betalingsmetode flow.

1.8.20

  • (placeholder)

1.8.19

  • Fix: Portal "Kontingent" tab — the Start fast betaling med MobilePay button is now only shown when the member actually needs to pay (canPay or isOverdue). Members whose kontingent is already paid ("Kontingent betalt") no longer see the button.
  • Fix: "Sæt din adgangskode" (welcome-flow direct password set) returned Ugyldig handling. The REST endpoint wam/v1/password-change only handled send/verify steps; the set_direct step now works there too (parity with the AJAX handler).
  • Fix: Portal "Kontingent" tab — when Vipps/MobilePay is enabled, the Betal nu (QuickPay one-shot card) button is hidden so members only see the MobilePay flow. When Vipps is disabled, only the Betal nu card flow is shown.

1.8.18

  • Fix: payer_phone on MobilePay subscription rows is now reliably populated. Vipps Recurring v3 GET /agreements typically does not echo back phoneNumber (it sits behind userinfoUrl which requires extra OAuth scope), so we now (1) persist the row immediately on agreement creation with status='pending' and the phone we just sent to Vipps — capturing the number "while we still have it", before the customer ever changes MobilePay number; (2) on return, fall back through: agreement response → transient → WAMP_MEMBER.Mobile (E.164-normalized); and (3) self-heal existing MobilePay rows with empty payer_phone on the next portal load via a one-shot UPDATE from WAMP_MEMBER.Mobile.

1.8.17

  • New: Portal "Fixed Payment" tab — for active MobilePay agreements a Skift betalingsmetode button now lets the member stop the current Vipps agreement and start a new one (e.g. when their MobilePay number changes). Implemented via new AJAX action wam_vipps_portal_subscribe.
  • New: Portal "Kontingent" tab — members without an active recurring agreement now see a Start fast betaling med MobilePay button that initiates a new Vipps agreement (no initial charge; first real charge happens at next renewal). Reuses the same AJAX action.
  • New: WAM_Premium_Vipps_Redirect handles a mode='portal_subscribe' transient — on ACTIVE status the subscription row is upserted (without creating a new member / WP user) and the user is sent back to the portal payment tab.
  • Fix: A logout_redirect filter (priority 99) now honors ?redirect_to= from the logout URL when the host matches home_url(), overriding third-party plugins/themes that force a home redirect on logout.
  • New: i18n strings change_payment_method, confirm_change_payment_method, start_mobilepay_subscription, payment_setup_redirect_mp.

1.8.16

  • Fix: A wam_subscriptions row is now ensured for every order that carries a _wam_qp_subscription_id when WAM_Premium_Helper::maybe_mark_order_completed_after_capture() runs. Closes the gap where a QuickPay callback that fires late, in non-success state, or not at all (admin completion / async finalization) left no Fixed Payment row even though the order was marked paid.
  • Fix: Portal "Fixed Payment" tab now self-heals: when no active wam_subscriptions row exists for the member, the lookup falls back to wam_payment for a captured row carrying a subscription_id and rebuilds the subscription row. For Vipps/MobilePay agreements the live agreement is fetched (get_agreement) so status, payer phone, amount, currency and interval reflect the real state.
  • Schema: wam_payment.transid widened from INT to VARCHAR(64) via dbDelta on activator run. Vipps chargeId (e.g. chr_xxxxxxxx) was being silently cast to 0 on insert, so legacy rows show no transid; new inserts will now persist the real id. (Existing zero-valued rows are not backfilled.)

1.8.15

  • New: After a brand-new member is created from a frontend payment (_wam_is_new_member order), the QuickPay continue page now redirects to /wam-go/<memberno>/<uniqid>/<portal_page_id>/?wam-welcome=<memberno>&tab=settings. The member lands already-logged-in on the configured portal page (wam_premium_portal_page_id) with the Settings tab open. Idempotent via _wam_welcome_redirected order meta.
  • New: Portal Settings tab now shows a direct “Set your password” form (no email verification code) for users who have never set a password — e.g. just-created members arriving via the welcome wam-go redirect. Eligibility is server-gated by user_meta _wam_password_set. After the first set, subsequent password changes use the existing OTP flow.
  • New: i18n strings set_password, set_password_help.

1.8.14

  • Fix: WAM_Premium_User_Sync now hydrates the member payload from the database when only an id is supplied to the wam_member_created action. Previously the handler returned early because the action payload contained no email, leaving any pre-existing WP user with a stale _wam_memberid after a member row was hard-deleted and re-created with a new auto-increment id. With hydration the existing WP user's _wam_memberid (and _wam_memberno) is now updated to the new row id at create time — preventing the same root cause that 1.8.13 only patched at portal-boot time.

1.8.13

  • Fix: current_memberid() now also re-links _wam_memberid when the stored meta value points to a non-existent or deleted member row (stale meta). Previously only missing meta triggered the auto-link. Fixes “No profile data” for users whose WAMP row was recreated/renumbered after the initial link.

1.8.12

  • Fix: current_memberid() auto-links _wam_memberid for logged-in users with missing meta, using the existing link_memberid_by_email_fname() helper. This makes the portal-boot path consistent with the OTP-verify, MEP-event-redirect, and member-link form paths that already auto-link. Fixes portal “ukendt medlem” after successful OTP login when meta was not set during verify.

1.8.11

  • Fix: portal Cards pane no longer crashes with ReferenceError: wam_premium_front is not defined — window. prefix added on wam_premium_front.portal.payment_tab lookup, matching the safe pattern used elsewhere in the script. This restores portal rendering for logged-in members on sites where the global was not yet bound at render time (regression vs. 1.8.7).
  • Fix: removed defensive SHOW COLUMNS … LIKE 'payer_phone' fallback in get_subscription_state_by_memberid(). The column is created/upgraded by dbDelta() via the activator on plugin version bump, so the runtime check is unnecessary noise.

1.8.10

  • Fix: version bump for migration retest; schema update is triggered on plugin version change.
  • Fix: subscription table create SQL keeps dbDelta-safe CREATE TABLE " . $table . " ( style.

1.8.9

  • Fix: table migration flow is now kept strictly version-driven; WAM_Premium_Activator::create_all_tables() runs on plugin version bump.
  • Fix: migration bootstrap now calls init_tables() in instance context.
  • Fix: settings warning removed by defining Free From Month saved value before first use.

1.8.8

  • Fix: portal subscription lookup now tolerates missing payer_phone column on older sites and returns null instead of breaking REST JSON.
  • Fix: schema upgrade version check aligned with current plugin version so create_all_tables() runs on version bump.
  • Fix: subscription table SQL declaration corrected for upgrade runs.

1.8.7

  • Fix: next_payment date calculation — free_from_month no longer double-skips year.
  • Fix: Free From Month setting now has "Not used" option (value 0) to disable the feature.
  • New: Payer phone number (E.164) stored from Vipps agreement in subscription record.
  • New: Portal Cards pane shows MobilePay icon, payer phone, and hides expiry/change-card button for MobilePay subscriptions.
  • New: Portal subscription data returns actual provider from DB instead of hardcoded 'quickpay'.
  • New: Member Portal settings tab in admin — toggle individual portal tabs active/inactive.
  • Fix: Member edit form double-member toggle — #memberstatus now has data-duplicate attribute and duplicate-fields HTML.
  • Fix: Admin JS change handler listens on both #CategorySelect and #memberstatus for duplicate toggle.
  • Fix: update_member_detail_callback now creates secondary member when switching to a duplicate category.

1.8.6

  • Fix: next_payment date calculation — free_from_month no longer double-skips year.
  • Fix: Free From Month setting now has "Not used" option (value 0) to disable the feature.
  • New: Payer phone number (E.164) stored from Vipps agreement in subscription record.
  • New: Portal Cards pane shows MobilePay icon, payer phone, and hides expiry/change-card button for MobilePay subscriptions.
  • New: Portal subscription data returns actual provider from DB instead of hardcoded 'quickpay'.
  • New: Member Portal settings tab in admin — toggle individual portal tabs active/inactive.
  • Fix: Member edit form double-member toggle — #memberstatus now has data-duplicate attribute and duplicate-fields HTML.
  • Fix: Admin JS change handler listens on both #CategorySelect and #memberstatus for duplicate toggle.
  • Fix: update_member_detail_callback now creates secondary member when switching to a duplicate category.

1.8.5

  • Fix: Membership rules modal rewritten with custom CSS/JS — no Bootstrap dependency.
  • Fix: Modal opens via jQuery click handler; closes on X, button, overlay click, or Escape key.
  • Enhancement: MobilePay payments now use order format MBYYNNNN (year + member number).
  • Enhancement: Payment status set to 'processed' instead of 'captured' for MobilePay.
  • Enhancement: Payment type set to 'MobilePay', reference to 'Kontingent YY'.
  • Enhancement: subscription_id and transid stored in payment records for Vipps tracking.
  • Enhancement: Renewal payments now include member name and email.
  • New: Refund button for MobilePay payments in admin Betalingsoversigt (calls Vipps Recurring API).
  • Enhancement: Subscriber overview shows Provider column and 'MobilePay' instead of card details.
  • Enhancement: Payment table shows Type and Reference columns.

1.8.4

  • Fix: Membership rules modal moved back inside form; uses native Bootstrap data-bs-toggle with href anchor.
  • Fix: HTML attributes kept out of translated strings to prevent translation cache conflicts.

1.8.3

  • Fix: Membership rules modal now opens via JS click handler instead of inline attributes, avoiding translation cache conflicts.

1.8.2

  • Fix: Membership rules link now opens in a Bootstrap modal instead of a new tab.
  • Fix: Modal placed outside form element to prevent form submission conflicts.

1.8.1

  • Feature: Vipps Order Prefix setting to prevent order ID collisions across sites sharing the same MSN.
  • Admin: New Member Payment Gateway selector (QuickPay / Vipps MobilePay / WooCommerce) controls form payment flow.

1.8.0

  • Feature: Vipps MobilePay Recurring integration for new member sign-up (Faste betalinger).
  • New API client class for Vipps Recurring API v3 (agreements + charges).
  • New AJAX handler for [wam_new_member_form] → Vipps MobilePay flow.
  • New redirect handler that polls agreement status and creates member on approval.
  • New cron handler for automatic renewals via Vipps charge API.
  • WAMP_SUBSCRIPTION schema: added provider, amount, interval_count, interval_unit, cat_id columns.
  • Updated upsert_subscription() to support new columns.
  • Admin settings: Vipps MobilePay configuration section (MSN, client_id, client_secret, subscription key, test mode, continue page).
  • Admin settings: New Member Payment Gateway selector (QuickPay / Vipps MobilePay / WooCommerce) controls which flow the form uses.

1.7.90

  • Feature: [wam_new_member_form] now uses standard WooCommerce checkout instead of order-pay page.
  • Auto-creates a virtual WC product per WAM category (matched by SKU, syncs name/price/image on change).
  • Adds product to cart and redirects to /kasse with full billing fields, gateway selection, and no "guest" message.
  • WAM meta is stamped on the order via woocommerce_checkout_order_created hook.
  • Billing fields are pre-filled from the membership form data.
  • handle_payment_complete still triggers member creation via map_order_lines (product has _wam_cat_id meta).

1.7.89

  • Feature: reCAPTCHA v3 spam protection on new member forms (both QuickPay and WooCommerce flows). Uses existing site/secret keys from plugin settings. Skips gracefully when keys are not configured.

1.7.88

  • Fix: New member orders now set billing_country to DK — missing country caused WooCommerce payment gateways to be unavailable on the order-pay page.

1.7.88

  • Fix: Edit and Delete buttons in member details card now work correctly — they close the details modal and open the appropriate edit/delete modal.
  • Fix: Modal transitions properly chain via fadeOut callback instead of triggering unhandled events.

1.7.87

  • Fix: WooCommerce new member form ([wam_new_member_form]) now has a working JS submit handler — previously only the QuickPay form was bound.
  • Fix: JS form handler reads AJAX action from data-wam-action attribute, supporting both QP and WC flows.
  • Fix: Handles both redirect and redirect_url response keys for WC checkout redirect.

1.7.86

  • Fix: New member form — added missing i18n keys for validation messages (emailRequired, firstNameRequired, etc.), which caused silent JS failure on submit.
  • Fix: New member form — accept_rules checkbox validation now correctly stops form submission with early return.

1.7.85

  • Fix: New member form — secondary name/email fields now visible on page load when a duplicate member type is pre-selected.

1.7.84

  • Improve: FIK import — per-row checkbox to include/exclude individual payments before import, with check-all toggle.
  • Improve: FIK import — validates FIK strings against configured prefix, skipping foreign FIK (e.g. BS indbetalingskort).
  • Fix: FIK import — date parsing now handles dd.mm.yyyy format (bank CSV standard).

1.7.83

  • New: FIK import tab on Payments Import page — parses FIK +71 payment strings from CSV (Dato, FIK-streng, Beløb), extracts member number, and imports payments with status "Betalt via FIK" / type "FIK-betaling".
  • Dedup: FIK import checks transid (digit string) + date + type to prevent duplicate imports.

1.7.82

  • Fix: Portal cards tab — QP payment link opens in popup window instead of full redirect, keeping portal page alive so MitID app-switch can return to the QP window.

1.7.81

  • Fix: Portal cards tab — QuickPay subscription now created via REST API (POST /subscriptions + PUT /link) instead of Payment Window form POST, solving mobile MitID redirect failures where subscriptions were never created.

1.7.80

  • New: FIK +71 payment string support — settings for prefix and account under Payments, new {{FIK-streng}} template variable for payment request, receipt, and test emails.
  • New: Payment date field and "Advance NextPayment" checkbox in Create Payment modal.

1.7.79

  • New: "Create payment" button on Kontingent tab — manual payment registration via modal with member search.

1.7.78

  • Fix: Removed non-existent sku and product_id columns from WAMP_PAYMENT inserts — resolves "Unknown column" DB errors.
  • Fix: Payment inserts now write category and reference (e.g. "Kontingent 2026") via get_order_category_info().
  • Fix: WC email suppression filters corrected to accept 3 parameters (matches WooCommerce hook signature).
  • Fix: Kontingent callback email dedup now checks _wam_kontingent_receipt_sent_at guard.

1.7.77

  • i18n: All PHP and JS source strings converted to English — Danish translations via .po/.mo files.
  • New: Member export (PDF/Excel) now uses the columns configured in Settings for the current view (active/removed).
  • New: PDF export auto-switches to landscape orientation when more than 7 columns are active.
  • New: Custom column labels from Settings are used as export headers.

1.7.76

  • Fix: Ad-hoc intro tekst bruger nu inline i stedet for

    — undgår ugyldig nesting i WAET skabelonens eksisterende

    -wrapper.

1.7.75

  • New: Dobbeltmedlemmer med forskellig email vises nu som separate valgbare rækker pÃ¥ kontingent email-siden.
  • Fix: Dedup i send_request ændret fra MemberNo til id, sÃ¥ begge emails modtager betalingsanmodningen.

1.7.74

  • Fix: Bootstrap/Popper JS no longer loaded globally on all admin pages — fixes WooCommerce order save redirect.
  • New: Ad-hoc intro text field on kontingent email group page — bold text prepended to payment request emails.

1.7.73

  • New: "Ingen email" checkbox on member edit form — clears email address for members without active email.
  • Fix: Member search now finds multi-word queries like "flemming aunel" by matching each word against full name.
  • Fix: Search input is trimmed so leading/trailing spaces no longer cause "Ingen emner fundet".

1.7.72

  • Fix: Removed 60-minute dedup guard on payment request emails — emails now send every time.
  • New: {{amount}} placeholder — formatted kontingent amount from category (e.g. 200,00 kr).

1.7.71

  • New: {{member_type}} placeholder in payment request emails — resolves to wam_cat_name via MemberStatus.
  • New: {{active_url}} placeholder — wam-go auto-login link to member portal kontingent tab.
  • New: {{amount}} placeholder — formatted kontingent amount from category (e.g. 200,00 kr).
  • Fix: Order-pay retry on failed/pending orders now works. Stale QuickPay meta cleared before retrying.
  • Fix: Bridge maybe_done() now checks order.is_paid() before skipping charge.
  • Fix: Duplicate WAMP_PAYMENT rows no longer created on order-pay retries.

1.7.69

  • Fix: Kontingent amounts now count double-member categories (dobbelt medlemmer) as 1 restance per MemberNo instead of 2. Summary cards, member list, bulk charge, and send-request all deduplicate by MemberNo. Double-member names shown joined with "&" in table.

1.7.68

  • Feature: Subject field added to all 6 WAET email template cards in settings (Standard member message, Payment request, and One-time code were missing it).
  • Feature: Test emails and production sends now use the configured subject with {{placeholder}} resolution.
  • Fix: Intro text newlines now render as line breaks in emails — WAET Renderer applies nl2br for _text variables.

1.7.67

  • Feature: Recover Payment button in QuickPay metabox when no transaction is linked to an order. Searches QuickPay by the stored recurring order_id, syncs all payment data (card, status, transaction id) back to WAMP_PAYMENT and order meta, and completes the order if already captured.

1.7.66

  • Fix: Fatal error on WooCommerce thank-you page — woocommerce_valid_order_statuses_for_order_again filter closure now accepts optional $order parameter since WC calls it with only 1 argument from woocommerce_order_again_button().

1.7.65

  • Fix: Active and removed member lists now use separate column settings. Active list uses wam_premium_list_columns, removed list uses wam_premium_list_notactive_columns with own sortable configuration in Settings.

1.7.64

  • Improvement: Subscription delete button now has two-step flow — active subscriptions get cancelled in QuickPay first, already cancelled subscriptions get permanently deleted from the database. Different icons and confirm messages for each action.

1.7.63

  • Fix: Refresh NextPayment prompt was skipped when member had non-kontingent payments — now checks only kontingent payments (reference LIKE 'Kontingent %' OR orderno LIKE 'BS%') matching the member overlay display.

1.7.62

  • Fix: Refresh NextPayment now also prompts for year when member has zero payments in WAMP_PAYMENT, even if WC order meta exists.

1.7.61

  • Fix: Fatal error in payment edit form — number_format_i18n() now casts amount to float before formatting.
  • New: Reference field added to payment edit form — admin can edit payment reference, with change logging.
  • Improvement: Refresh NextPayment now prompts admin for year when no orders found, instead of silent error. Uses renewal month from settings to set forfaldsdato.

1.7.60

  • New: Date (created_at) field added to payment edit form — admin can now correct the payment date.
  • New: Refresh NextPayment button now sets forfaldsdato when member has no payments — uses renewal month from settings to calculate overdue date.

1.7.59

  • New: "Betalingsoversigt" tab replaces old "Members Payment Status" — shows two separate tables for kontingent payments and other payments, with search across memberno/name/address.
  • New: Edit, delete, and move payments between members via modal dialogs. Move feature lets admin reassign a payment from one member to another.
  • New: All payment edits, deletes, and moves are logged to WAMP_PAYLOG with admin username and change details.
  • Improvement: Kontingent tab "Medlemsnr." column width set to 100px for compact layout.
  • Improvement: Kontingent tab card column now shows card brand icons (SVG) matching the subscriptions page style.

1.7.58

  • Fix: Undefined variable $subject_label in payment/subscription acknowledge emails — replaced with $vars['subject'] which holds the resolved subject line.
  • Fix: dompdf fatal error "Cannot declare class ComposerAutoloaderInit..." when another plugin already loaded dompdf — added class_exists guard before requiring autoloader.

1.7.57

  • Improvement: Kontingent "Har email" group now shows separate rows for dual members (dobbeltmedlemmer) — each member with their own email gets their own row, increasing contact reach. Summary counts also reflect individual members.
  • New: PDF download button on "Ingen kontakt" tab — exports member list with medlemsnr, navn, adresse, postnr, by, telefon, mobil, kategori and forfaldsdato for follow-up.

1.7.56

  • CRITICAL Fix: Progress bar notice still appeared on page load because WordPress core common.js relocates ALL .notice elements out of their container to the top of the page, bypassing display:none on the parent. Replaced .notice with custom .wam-progress-notice class that WP does not touch.

1.7.55

  • CRITICAL Fix: Kontingent progress bar ("Behandler...") was visible on page load with active spinner. Root cause: WordPress core common.js auto-initializes .notice.is-dismissible elements and overrides display:none. Removed is-dismissible class; dismiss button kept with manual handler. Spinner no longer starts with is-active in HTML — only activated by JS when bulk action runs.

1.7.54

  • Fix: Event orders now use autocapture=true in QuickPay recurring charge — prevents capture failures caused by timing issues when the manual capture call runs before QP has fully authorized. Membership orders keep existing autocapture=false + manual capture flow.
  • Fix: Event orders now correctly set payment category to WAMP_PAY_CATEGORY_EVENT (4) instead of WAMP_PAY_CATEGORY_NEW (0).

1.7.53

  • Fix: Progress bar spinner now stops reliably — moved cleanup from complete to success/error callbacks, spinner hidden via CSS visibility, finishProgress() function prevents any code-path from leaving it active.
  • Fix: NextPayment now uses the pre-calculated _wam_next_payment date from order meta instead of re-computing +1 year from DB (which caused double-advance to 2028 instead of 2027).
  • Fix: Amount in WAET payment acknowledge email now formatted with 2 decimals (e.g. "200,00" instead of "200").
  • Fix: WooCommerce customer_completed_order email now fully suppressed for kontingent orders — added to the kontingent suppression list alongside the other WC email types.

1.7.52

  • Fix: Kontingent orders now use the payment acknowledge email template instead of the subscription acknowledge template — kontingent charges go through QuickPay subscription but should use the payment template for correct email content.
  • Fix: Kontingent progress bar ("Behandler...") is now dismissible (X button) and auto-fades after bulk action completes. Notice style changes to success on completion.

1.7.51

  • CRITICAL Fix: Kontingent bulk charge always reported failure ("0 OK, 1 fejl") because charge_subscription() checked for a non-existent 'success' key in the QuickPay response array — now correctly checks HTTP status from raw.status.
  • CRITICAL Fix: WooCommerce "failed order" email (customer_failed_order, failed_order) was NOT suppressed for kontingent orders, causing customers to receive "payment failed" messages even though the charge was captured successfully. Both email types are now suppressed.

1.7.50

  • Fix: Kontingent progress bar ("Behandler...") now auto-hides after 6 seconds when bulk action completes.

1.7.49

  • Fix: Member detail modal could not be closed (X / click outside) on Kontingent tab — close handler was inside paymentList.init() which is skipped when payment table is absent.
  • Fix: Clicking outside modal content (backdrop) now closes the modal.
  • Add: "Luk" (Close) button added to member detail card alongside Edit/Delete.
  • Fix: Undefined variables ($brand, $bin, $last4, $exp_month, $exp_year) in quickpay_payment_by_subscription — card metadata now initialised from QuickPay response with fallback to WAMP_SUBSCRIPTION.

1.7.48

  • Fix: Payment acknowledgment email now fills all template placeholders — card_brand, card_no, card_issued_to fall back to WAMP_SUBSCRIPTION data when QuickPay metadata is empty.
  • Fix: card_issued_to defaults to member name when not provided by QuickPay.
  • Fix: Kontingent orders now set _wam_order_title and _wam_next_payment so member_year is correctly resolved in email templates.
  • Fix: All WooCommerce transactional emails (new order, processing, on-hold, invoice, cancelled) are suppressed for kontingent orders — receipts are handled exclusively by WAET.

1.7.47

  • Fix: Kontingent bulk action spinner now stops after completion.
  • Fix: paymentList AJAX no longer fires on kontingent tab (avoids unnecessary request).
  • Fix: NextPayment refresh removes member row from kontingent table when updated (member is no longer overdue).

1.7.46

  • Fix: NextPayment refresh button now works on Kontingent tab (handler was only bound on Members page).
  • Fix: Removed MemberID/memberid column guessing — all member lookups now use the correct id column (fetch_member_row_by_id, member_row_identity_where, maybe_mark_order_completed_after_capture).
  • Fix: Payments list number_format error on PHP 8.x when amount is a string.

1.7.45

  • Fix: Safety-net hook (priority 99) on order completion ensures NextPayment is synced even when the primary handler misses it.
  • Add: Manual NextPayment refresh button (dashicons-update) in member detail modal — fetches latest _wam_next_payment from completed orders.

1.7.44

  • Fix: Kontingent view-member modal now reuses the full member detail card from the members page (fetch_member_detail) instead of a custom simplified view.

1.7.43

  • Add: New Kontingent tab replaces Payments List — dashboard summary cards + 3-group member table (has card / has email / no contact).
  • Add: Bulk charge for members with active subscription card — creates WC order + QuickPay recurring charge + advances NextPayment.
  • Add: Bulk send payment request email for members without card but with email (via WAET, with 60-min dedup).
  • Add: Member info modal + soft-delete option for members with no card and no email.

1.7.42

  • Fix: Payments dashboard now groups by the type column directly (Betalingsservice, MobilePay, Payment) instead of deriving channel from multiple columns.
  • Fix: Dashboard summary totals and pie chart are no longer limited by a date cutoff — all completed payments are counted.
  • Add: Per-channel summary cards (BS, MobilePay, Payment) with payment count and member count in the dashboard header.
  • Fix: Double members (sharing MemberNo) now count as two persons in all dashboard member counts.
  • Fix: Order payment processing — all code paths now route through the central maybe_mark_order_completed_after_capture() function.

1.7.41

  • Add: MC audit — "Forgotten" (GDPR permanently deleted) emails are now cached server-side and filtered out of the "Missing in Mailchimp" ADD list into a separate read-only section.
  • Add: MC audit — "Batch Add All" button tries to subscribe all missing members at once; forgotten emails are automatically detected and cached for future audit runs.
  • Add: Single ADD errors for forgotten emails are now also cached, so they disappear from the ADD list on the next audit run.

1.7.40

  • Fix: MC audit email-change detection now matches by UniqID (or ID+name fallback) instead of MemberNo — prevents false "Update email" for household members (husband/wife sharing MemberNo but with different UniqID).

1.7.39

  • Fix: MC merge fields — universal rule: empty WAMP values are now always omitted from the API payload (prevents Invalid Resource errors for all field types).
  • Fix: MC merge field code de-duplicated — explicit mapping and same-name fallback merged into a single clean code path.
  • Add: MC audit now detects email changes — members whose email was changed in WAMP are shown in a separate "Email changed" section instead of "Missing in MC".
  • Add: MC audit email-change action respects MC contact status: subscribed/unsubscribed/pending → PATCH email; cleaned/archived → permanent delete + re-create.

1.7.38

  • Add: QuickPay Branding ID setting — optional branding_id is now sent with all Payment Window requests when configured.

1.7.37

  • Fix: Event order reorder bypass — added woocommerce_valid_order_statuses_for_order_again filter so WC never processes event order-again requests.
  • Fix: Moved URL blocker from template_redirect (too late) to wp_loaded priority 10 (before WC_Form_Handler at priority 20).
  • Fix: Expanded event order detection to also check event_id, _wwef_attendees, _wwef_ticket_label, _wwep_event_id, and mep_events post type.

1.7.36

  • Fix: Audit ADDRESS comparison now skips sub-keys where WAMP value is empty (e.g. country) to avoid false pending results.

1.7.35

  • Add: Missing DB columns now available in Table Options (Title, Gender, Country, UniqID, ExtID, UUID, Status, SMS Valid, Group SMS, DelReason, Created, Updated).
  • Fix: Mailchimp audit comparison normalises ADDRESS sub-keys and trims whitespace to eliminate false "pending" results.
  • Fix: Audit diff message now shows exactly which merge tags differ instead of generic text.

1.7.34

  • Add: Immediate Mailchimp sync on every member create, update, or removal (admin and frontend).
  • Fix: Rewritten MC sync/remove callbacks to always fetch full member row from DB by ID — fixes broken hooks that only passed partial data.
  • Add: Double-membership awareness on removal — if one half is removed, MC is re-synced from the remaining active member instead of archiving.
  • Add: Frontend profile save, email update, and admin new-member creation now fire MC sync hooks.

1.7.33

  • Fix: Reduced batch auto-sync page size from 200 to 25 to prevent 504 gateway timeouts on shared hosting.

1.7.32

  • Add: Configurable match method for Mailchimp auto-sync (ID+EMAIL, UniqID+EMAIL, EMAIL+FNAME+LNAME) via dropdown on Audit page.
  • Add: Batch auto-sync AJAX now uses the selected match method.
  • Fix: Audit status table only shows members pending sync (hides 100% matched rows).
  • Fix: WAET sendqueue table existence check prevents DB error when WAET not installed.

1.7.31

  • Add: Mailchimp merge field mapping UI in Settings > Mailchimp — map MC tags to WAMP columns via dropdowns, fetched live from MC API.
  • Add: Merge field overview table on Mailchimp Audit page with mapping status and link to edit.
  • Add: CS_UNIQID and SPONSOR merge tag mappings (UniqID, meta2).
  • Add: Dashboard hides missing-payment box when count is 0.
  • Fix: PHP 8.4 deprecation — fgetcsv escape parameter in area CSV import.
  • Improve: Sync engine reads mapping from saved settings instead of hardcoded array.

1.7.30

  • Add: Configurable member list columns — select which columns to display via Settings > General.
  • Add: Custom column labels — rename any column (e.g. meta3 → Title) in settings.
  • Add: Default sort order setting — choose which column and direction the member list sorts by on load.
  • Add: All visible columns are now sortable (clickable headers).
  • Add: Optional member number assignment checkbox on CSV and MSSQL import.
  • Improve: SQL query now fetches all available fields (Birthday, Age, Area, meta1-4, YEAR, Phone, Note1).

1.7.29

  • Update: DomPDF library updated from 3.1.0 to 3.1.5 (bugfixes and security patches).
  • Update: FPDI library updated from 2.6.3 to 2.6.6 (security fix).
  • Fix: PHP 8.4 deprecation — added explicit $escape parameter to fputcsv() calls in paylog CSV export.
  • Fix: PHP 8.4 deprecation — added explicit $escape parameter to fgetcsv() call in CSV import helper.

1.7.28

  • Fix: MSSQL import now uses safe property reader — missing columns return defaults instead of PHP warnings, and DateTime objects are auto-converted to strings.
  • Fix: SQL injection in MSSQL import replaced with $wpdb->prepare().
  • Fix: MSSQL import tries both cs_medlemmer and cs_members table names.
  • Fix: Title from MSSQL mapped to meta3, Profession to meta4.
  • Add: meta4 field support in WP user sync (_wam_meta4 user meta) and Mailchimp sync (META4 merge field).

1.7.27

  • Fix: MSSQL database import AJAX handler no longer crashes on connection failure — sqlsrv_errors() array is now properly formatted as a readable string instead of causing a PHP 8 TypeError.
  • Fix: Failed MSSQL connections now return early with wp_send_json_error() instead of attempting SQL queries on a dead connection.
  • Fix: Added function_exists('sqlsrv_connect') guard in the AJAX handler to prevent fatal errors when the extension is missing.

1.7.26

  • Fix: Guard sqlsrv_connect() call with function_exists() check to prevent fatal error on servers without the PHP sqlsrv extension.
  • Improve: MSSQL connection failure now displays detailed error info (SQLSTATE, message, code) for easier debugging.

1.7.25

  • Feature: WooCommerce is now optional. The plugin activates and runs without WooCommerce, providing member management, categories, import/export, email templates, and native subscriptions. Payment-related features (gateway, QuickPay, checkout, order processing) are conditionally loaded only when WooCommerce is active.
  • Add: New wam_has_woocommerce() helper function for consistent WC availability checks throughout the plugin.
  • UI: Portal hides Cards, Payments, Kontingent, and Orders tabs when WooCommerce is not installed.
  • UI: Admin Settings hides Payments tab when WooCommerce is not installed.

1.7.24

  • Fix: 3DS enforcement now includes all valid QuickPay card types: creditcard → 3d-creditcard, visa-electron → 3d-visa-electron, and mastercard-debet → 3d-mastercard-debet. This resolves "The card type used is not supported" errors when users select debit card variants in payment settings.
  • Add: Admin QuickPay Card Types multiselect now includes Visa Electron (Debit) and Mastercard Debit options alongside existing credit card types.

1.7.23

  • Fix: Restored missing helper method WAM_Premium_Helper::get_order_category_code() used by order summary rendering. This removes the fatal error in member portal flows that trigger order summary/category mapping.

1.7.22

  • Improve: [wam_portal_tab_note] can now be used without parameters and resolves context/tab dynamically from active login/portal shortcode rendering.
  • Add: [wam_member_login] and [wam_member_portal] now support action/tab attributes to select initial tab and matching tab-note context.
  • Improve: Portal frontend now respects shortcode-selected initial tab via data-initial-tab before fallback URL/payment flow logic.

1.7.21

  • Fix: QuickPay order metabox manual capture now re-checks payment state via API on capture errors and treats already-captured payments as success, synchronizing order/payment status instead of showing a false failure.
  • Fix: QuickPay order metabox now shows detailed AJAX error text when manual capture fails, so admin sees the real cause.

1.7.20

  • Fix: Accepted kontingent/direct-payment callbacks no longer force orders to wc-failed when capture is not immediately confirmed. These now move to pending/on-hold with automatic QuickPay finalization scheduling.
  • Fix: Renewal cron flow now treats in-flight/pending QuickPay states as on-hold + finalization instead of failed.

1.7.19

  • Fix: Kontingent/renewal receipt sending is now enforced across all completion paths. When capture completes (portal immediate, async cron finalization, or Woo payment completion), the plugin now triggers renewal receipt delivery with WAET payment acknowledgment template priority and deduplicates with a per-order sent flag.

1.7.18

  • Feature: Added a dedicated Settings -> Tab texts tab with rich text editors for per-tab portal/login notes.
  • Feature: Added shortcode [wam_portal_tab_note context="portal|login" tab="..."] for explicit placement of tab notes.
  • UI: Notes are now rendered in both [wam_member_login] and [wam_member_portal] tab content using Gutenberg-compatible rendering (do_blocks + shortcode handling).

1.7.17

  • Fix: While a kontingent renewal capture is pending finalization, portal summary now suppresses overdue/due + Pay now actions to prevent duplicate charge attempts and misleading “not paid/due” messaging.

1.7.16

  • Fix: Portal kontingent capture now prioritizes immediate completion by charging with QuickPay autocapture enabled and extending synchronous capture confirmation before falling back to pending finalization.

1.7.15

  • Fix: Kontingent callback no longer reclassifies renewal orders as new-member orders. WAET routing now stays on payment acknowledgment templates for renewals, and kontingent year (member_year / description) is derived from _wam_order_title when it contains a year.

1.7.14

  • Fix: WooCommerce default "customer completed order" email is now disabled for kontingent/renewal orders, so members do not receive the generic completed-order wording. Renewal communication continues through the WAM payment email flow.

1.7.13

  • Fix: Portal kontingent payment no longer creates a new blank member row. create_members_from_order() now detects non-new-member orders (no _wam_is_new_member flag) and returns the existing member's DB id instead of INSERT-ing a new row. handle_payment_complete() has an additional guard to skip member creation entirely for renewal/kontingent orders.

1.7.12

  • Changes in the admin payment handling.

1.7.11

  • Refactor: Payments dashboard tab moved out of the view and into a dedicated admin class to match the shared /views loader structure.

1.7.10

1.7.9

  • Maintenance: Minor charges.

1.7.8

  • Fix: When a double membership shows Member 2 in the portal, Member 2 email and mobile can now be edited and saved from the same profile edit flow without email verification.

1.7.6

  • Fix: Portal profile address editing now resolves and saves Area through the same DAWA-based area lookup used in admin, using a hidden area field and persisting WAMP_MEMBER.Area when present.

1.7.5

  • Fix: Portal member-row selection no longer assumes a MemberID column when disambiguating or logging matched WAMP_MEMBER rows, so default installs using id stay deterministic.

1.7.4

  • Fix: Portal profile saves now resolve the real WAMP_MEMBER column names from the live table schema before updating, so default installs write Zip instead of the non-existent PostalCode column and only touch optional columns when they actually exist.

1.7.3

  • Fix: Portal profile updates now persist to the canonical memberid row in WAMP_MEMBER, avoiding writes through shared household identifiers.
  • Fix: New kontingent-order and post-capture member updates now prefer memberid over MemberNo when syncing WAMP_MEMBER data.

1.7.2

  • Fix: Portal kontingent QuickPay bridge now returns through the same post-capture completion path as the direct portal charge flow, including consistent paid/pending portal redirects and NextPayment sync.
  • Fix: Profile address save now strips any trailing DAWA postcode/city text from the address line before persisting, while keeping postcode and city in their own fields.
  • Fix: When changing profile email, the portal now shows the full new email in the verification message and auto-saves as soon as the verification code reaches its full length.

1.7.1

  • Add: Member portal profile card now supports inline editing for email, mobile, and address with an Edit/Save toggle in the top-right corner.
  • Add: Profile address editing now uses DAWA autocomplete in the portal edit flow.
  • Add: Changing profile email now sends a verification code to the new email address and only saves the profile after the code is verified.

1.7.00

  • Fix: Legacy Woo order QuickPay transaction meta is now healed from WAMP_PAYMENT.transid when old data mistakenly stored subscription_id in transaction-id fields. This repair now runs through the shared helper/meta sync path used by admin order views and payment resolution.

1.6.99

  • Fix: QuickPay refresh/admin sync now prioritizes refunded and cancelled states correctly, so refunded QP payments no longer fall back to processed in WAMP_PAYMENT or order meta.
  • UI: The WAM-Go column on the Members admin page now copies the generated link to the clipboard and shows copied status instead of opening a new tab.

1.6.98

  • Fix: When a cancelled order has no real QuickPay transaction, stale QP order meta is now cleared instead of lingering in admin. WAMP_PAYMENT still syncs to cancelled/refunded based on the actual payment row.

1.6.97

  • Fix: Completed-order admin save and bulk-complete now run the same QuickPay process as cancelled orders: fetch QP state, attempt capture when authorized/waiting, and update WAMP_PAYMENT to the actual QP result.

1.6.96

  • Fix: Added direct handling of WooCommerce bulk cancel actions from the admin orders list (handle_bulk_actions-edit-shop_order and HPOS equivalent), so bulk-cancelled orders now run the QuickPay refund/cancel logic and sync WAMP_PAYMENT per order.

1.6.95

  • Fix: WAM_Premium_Woo_Payments hooks are now initialized from plugin bootstrap for both admin and frontend. Previous admin order updates/cancellations had no effect because the payment hooks were only being registered from the frontend class.

1.6.94

  • Fix: Cancelled Woo orders now also auto-cancel non-captured QuickPay payments via the payment cancel endpoint; if the remote payment is already cancelled/refunded, WAMP_PAYMENT is synced to that state on admin update.

1.6.93

  • Fix: save_post_shop_order now also runs the cancelled-order QuickPay/WAMP_PAYMENT sync, so clicking "Update" on a cancelled Woo order triggers the refund/sync path even if Woo status hooks do not fire on that save.

1.6.92

  • Fix: When a Woo order is set to cancelled, the plugin now checks the QuickPay payment state first, auto-refunds captured payments, and syncs the real result to WAMP_PAYMENT.

1.6.91

  • Fix: Added save_post_shop_order hook — when admin clicks "Update" on a completed order, QP status is verified and WAMP_PAYMENT synced. Covers the case where woocommerce_order_status_completed does NOT fire because status didn’t change.

1.6.90

  • Debug: Full logging in sync_wamp_payment_status_via_qp() — logs every decision point (hook fired, no row, API call, result, rows_affected).
  • Debug: Bootstrap hook logs whether WAM_Premium_Helper is loaded when woocommerce_order_status_completed fires.

1.6.89

  • Refactor: New central helpers in WAM_Premium_Helper — qp_fetch_payment(), qp_resolve_payment_id_from_order(), sync_wamp_payment_status_via_qp().
  • Fix: woocommerce_order_status_completed hook now calls QuickPay API to verify actual payment status before syncing WAMP_PAYMENT.

1.6.88

  • Fix: Direct top-level hook on woocommerce_order_status_completed now unconditionally syncs WAMP_PAYMENT.status to 'processed' — no class chain, no init() dependency.

1.6.87

  • Fix: Portal kontingent CSS selectors corrected from #pane-kontingent to #pane-subscription so styles actually apply.
  • UI: "Overdue" label right-aligned above the "Pay now" button in kontingent summary.

1.6.86

  • Fix: Portal "Betal nu" kontingent payment now uses maybe_mark_order_completed_after_capture() — orders no longer stuck on "pending" or "processing".
  • Fix: QuickPay bridge (checkout return flow) now uses maybe_mark_order_completed_after_capture() instead of bare payment_complete() — same issue.

1.6.85

  • Fix: Manual WooCommerce order completion now bumps WAMP_MEMBER.NextPayment forward — the missing update_member_next_payment() method has been implemented.
  • UI: Portal kontingent "Overdue" label now bolder (700) and "Pay now" button spans full width instead of right-aligned.

1.6.84

  • Fix: Refund and cancellation now sync WAMP_PAYMENT.status to 'refunded'/'cancelled', so the member portal shows the correct status in both Kontingent and Betalinger.

1.6.73

  • Fix: WAMP_PAYMENT upsert now deduplicates by Woo order context (_wam_payment_id/orderno) in addition to transid, preventing duplicate rows for the same order.
  • Fix: Missing payer identity in WAMP_PAYMENT is now backfilled from Woo order billing meta and callback fields when member row data is not yet available.
  • Fix: Async finalize path now backfills and links missing WAMP_PAYMENT rows to the Woo order via _wam_payment_id.

1.6.72

  • Change: Members Dashboard redesigned with large KPI total card and per-category cards showing count, label, and category image/icon.
  • Fix: Category image (wam_cat_image_id) now loaded from WAMP_CATEGORY and displayed in dashboard cards.
  • i18n: All Danish source strings in __(), esc_html_e(), and esc_attr_e() wrappers converted to English across callbacks, shortcodes, import views, and admin classes.

1.6.83

  • Fix: When a WooCommerce order is manually set to "completed" (e.g. via Edit Order → Update), WAMP_PAYMENT.status is now always synced to "processed" immediately. Previously only worked for orders without product-line mapping.

1.6.82

  • Fix: WAMP_PAYMENT.status now synced to "processed" in maybe_mark_order_completed_after_capture() so all capture paths (callback, portal, renewals, finalization) update the payments table — not just the callback.

1.6.81

  • Fix: All 4 capture paths now respect the wam_premium_payment_quickpay_captured_completed setting.
  • Fix: Subscription callback, direct payment callback, portal charge, and renewal cron all use maybe_mark_order_completed_after_capture() instead of bare payment_complete() or hardcoded status.

1.6.80

  • Feature: Email subject lines for Membership receipt, Subscription receipt and New member receipt are now configurable in settings.
  • Feature: Subject settings support {{key}} placeholders (same variables available in WAET templates).
  • Fix: Payment acknowledgment emails now load intro_text from settings instead of sending empty.
  • Fix: Kontingent payment receipt no longer uses wrong subject ("Card linked" instead of "Renewal").

1.6.79

  • Feature: Added subject setting for Membership receipt and Subscription receipt email types.
  • Fix: intro_text loaded from settings in both payment acknowledgment methods.

1.6.78

  • Fix: Missing order meta writes — _wam_qp_transaction and _transaction_id now written in subscription payment callback.
  • Fix: Added _wam_qp_id and _wam_qp_transaction to portal kontingent capture and callback subscription capture paths.

1.6.77

  • Fix: WAM-Go now handles Mailchimp emails with unresolved merge tags (<<MemberNo>>/<<UniqueId>>) gracefully — redirects to post without login attempt.

1.6.76

  • Fix: WAMP_MEMBER.NextPayment now synced after cron renewal payments.
  • Fix: WAMP_PAYMENT.status synced to "captured" after successful capture in 4 locations.
  • Fix: Metabox refund button now visible for payments with status "processed".

1.6.75

  • Fix: Renewals cron broken reference to helper method.

1.6.74

  • Fix: QuickPay callback no longer confuses transid with subscription_id — 4 locations corrected.
  • Fix: orderno now uses wc_order_id instead of internal payment id.

1.6.71

  • Fix: QuickPay method details are now resolved from WAMP_SUBSCRIPTION when recurring charge payload lacks card metadata, even if memberno already exists.
  • Fix: Recurring payment flow now persists resolved card metadata to order meta (_wam_qp_brand, _wam_qp_last4, etc.) so shop_order list shows actual method instead of generic fallback.
  • Fix: Orders list rendering now backfills and saves missing card method details to both order meta and WAMP_PAYMENT from subscription data when available.

1.6.70

  • Fix: In post_type=shop_order QuickPay payment column, Method is now always shown with robust fallback (card brand from payment meta/order meta, otherwise gateway title/QuickPay Payment).
  • Fix: Added fallback for missing card brand/last4 from order meta (_wam_qp_brand, _wam_qp_last4) so partially populated orders still show method details.

1.6.69

  • Fix: WAMP_PAYMENT upsert no longer requires memberid for new-member recurring payments; payment rows are now created using reserved memberno when memberid is not available yet.
  • Fix: Prevented early validation failure in QuickPay payment upsert that previously skipped creating payment records for new members.

1.6.68

  • Change: Version bump for release packaging alignment.

1.6.67

  • Fix: New-member QuickPay callback no longer creates a duplicate copied Woo order.
  • Fix: Added callback finalization idempotency guard to skip duplicate callback finalization on the same order.

1.6.66

  • Fix: Removed final-order copy flow; setup order is now promoted directly to member_order to avoid duplicate paid orders.

1.6.61

  • Fix: Customer portal password-login errors no longer show WordPress username-oriented wording. Messages are now email/code based only.
  • Change: Replaced fallback raw WP_Error login output with user-friendly portal messages that do not refer to username login.

1.6.60

  • Fix: Password login in customer portal now resolves WP users by Gmail-equivalent email (dot-insensitive for gmail/googlemail), preventing false "unknown email" failures when users enter dotted/undotted variants.
  • Fix: Post-login member sync now prefers canonical member email from WAMP_MEMBER when Gmail aliases are used.

1.6.59

  • Fix: Customer portal member lookup now treats gmail.com/googlemail.com addresses as dot-insensitive in local part (e.g. flemmingaunel@gmail.com = flemming.aunel@gmail.com).
  • Fix: Token login fallback now accepts Gmail-equivalent member email and continues with canonical database email.
  • Fix: User creation/linking in portal now prefers canonical member email from WAMP_MEMBER to avoid mismatches/duplicates when user enters Gmail alias variants.

1.6.58

  • Fix: Resolved QuickPay error No available payment-method for transaction caused by array-valued cardtypelock being cast to string (Array) in payment window builders.
  • Fix: qp_enforce_3ds_payment_methods() now accepts both array and comma-separated string input and normalizes safely.
  • Fix: 3DS enforcement now only outputs valid/known card method tokens (dankort, 3d-visa, 3d-mastercard, 3d-maestro) and ignores unknown values instead of generating invalid 3d-* methods.

1.6.57

  • Fix: Enforced QuickPay payment_methods on all WAMP payment window builders (new-member setup, portal subscription setup, gateway subscription setup, and shortcode payment flow), so 3DS locking is always sent.
  • Fix: payment_methods now always passes through WAM_Premium_Helper::qp_enforce_3ds_payment_methods() (also when cardtypelock is empty), preventing non-3DS fallbacks.
  • Add: New generic filter wam_qp_payment_methods_default for overriding default enforced methods (dankort,3d-visa,3d-mastercard,3d-maestro), while keeping backward compatibility with wam_qp_subscription_payment_methods_default.

1.6.56

  • Fix: WAMP cron now also drains WAET's own sendqueue for WAMP-owned templates (payment request, payment ack, etc.) as a belt-and-suspenders fallback when WAET's waet_process_queue cron is delayed or not running.
  • Fix: "Send Payment Request" button was disabling the wrong element (ID mismatch), allowing multiple simultaneous batch submissions and duplicate email queuing for the same members.
  • Fix: Batch payment-request AJAX calls are now serialized (one at a time) instead of being fired in parallel, preventing server overload and database conflicts on large member selections.
  • Fix: Added server-side deduplication guard: if a payment request email was already queued for a member within the last 60 minutes, the request is skipped silently instead of inserting a duplicate queue entry.

1.6.55

  • Fix: Subscription payment windows now always use 3DS-enforced payment methods (PSD2 FraudFilter status 30100). Converts plain card type names (visa, mastercard) to their 3D counterparts (3d-visa, 3d-mastercard); leaves dankort as-is (inherently 3DS in DK). Default if no cardtypelock is set: dankort,3d-visa,3d-mastercard,3d-maestro.
  • Add: New helper WAM_Premium_Helper::qp_enforce_3ds_payment_methods() with filter wam_qp_subscription_payment_methods_default for overriding the default set.

1.6.54

  • Add: WAM-GO login handler now supports optional target query parameter for redirect override after successful member login.
  • Security: target is validated as same-site URL/path only; invalid targets automatically fall back to existing post_id permalink behavior.
  • Add: New helper wam_premium_build_wam_go_url() to build backward-compatible WAM-GO URLs with optional safe target override.

1.6.53

  • Fix: Disabled WooCommerce "order again" for MEP event orders (including direct ?order_again= links) to prevent incorrect 0,01 product base price reuse on reorders.

1.6.52

  • Fix: Corrected WAMP_PAYMENT inserts to use created_at (schema-aligned) in checkout, Woo payment sync, and renewal flows, preventing SQL fatals and missing payment rows.

1.6.51

  • Fix: QuickPay capture flow now resolves recurring payment stage from both state and last successful operation, improving reliability for approved/authorized transitions.
  • Fix: Async capture finalization now retries capture when recurring payment is approved/authorized and keeps retrying transient waiting states safely.
  • Add: QuickPay metabox now shows Capture button for all non-final states when a payment id exists, so manual capture is always available when auto-capture/finalization has not completed.
  • Change: Manual capture, refresh-confirmed capture, and async capture-finalization now use the existing setting wam_premium_payment_quickpay_captured_completed to set order status to completed (or processing when disabled).

1.6.50

  • Fix: QuickPay order metabox now backfills missing QuickPay meta from existing order meta and local payment rows before showing that no QuickPay payment was found.
  • Fix: Woo payment completion now restores missing QuickPay transaction/order metadata and computes missing NextPayment values for recurring membership orders.
  • Fix: New-member Woo orders now store NextPayment, title, SKU, and pay-category metadata at creation time.
  • Fix: Portal kontingent Woo order items now use the membership category image so thumbnails render correctly in Woo order views.

1.6.49

  • Fix: Subscription callback no longer forces orders to failed on transient QuickPay race/idempotency errors; moves to on-hold/pending finalization instead.
  • Fix: Added asynchronous finalization persistence so local order/payment metadata keeps QuickPay Transaction ID in sync when resolved later.
  • Add: Extended wam_payment_log schema with ordreid + index for reliable order-level tracing.
  • Add: Centralized payment logging helper used across callback/finalization/recovery flows with backward compatibility for older table schema.
  • Add: Admin recovery AJAX endpoint to bulk move failed subscription orders to on-hold and schedule automatic QuickPay finalization retries.
  • Change: Customer-facing payment messages are now softer during async capture/finalization to reduce uncertainty when payment is still being verified.

1.6.48

  • Maintenance release: internal prep for upcoming QuickPay callback/finalization hardening.

1.6.47

  • Maintenance release: plugin packaging consistency update.

1.6.10

  • Add: Manual member assignment in MobilePay import preview — allows overriding auto-matched members when MobilePay includes middle names or other variations
  • Add: Member picker input in import preview table for each payment row; updates staging table before merge
  • Add: AJAX handler wam_premium_update_manual_memberno to persist user selections from preview UI

1.6.9

  • Fix: QuickPay enabled setting can now be reliably toggled on/off in Payments settings.
  • Change: Normalize legacy QuickPay toggle values for backward compatibility.

1.6.8

  • Add: MobilePay CSV import — two-step flow on the Import Payments page (MobilePay tab)
  • Add: Automatic member matching via email (from message field), mobile last-4-digits, or full name
  • Add: Preview table shows matched/unmatched rows before committing; deduplicated by transaction ID

1.6.7

  • Fix: Load shared front assets on pages using [wam_new_member_form] so form styling and behavior match [quickpay_new_member_form]
  • Change: Apply DAWA address autocomplete container markup consistently to both new-member shortcodes
  • Fix: Import admin and AJAX class parsing/structure corrections for stable deployment

1.6.6

  • Add: CSV import supports format selection (new English-column format and legacy standard format)
  • Add: Missing MemberNo in import now uses standard automatic member-number allocation
  • Fix: Members import admin page conditional rendering to prevent PHP parse errors in deployment

1.6.5

  • Add: New shortcode [wam_new_member_form] — generic WooCommerce payment variant of [quickpay_new_member_form]; creates a pending WooCommerce order and redirects the user to the active payment gateway
  • Add: CSV member import now supports fallback member-number assignment when MemberNo is missing (uses standard auto-allocation setup)

1.6.4

  • Change: Maintenance release

1.6.3

  • Fix: Load WordPress media library correctly on Categories admin page so category images can be selected
  • Change: Hide category selection in quickpay_new_member_form when only one selectable membership category exists

1.6.2

  • Change: Declare WooCommerce feature compatibility explicitly (HPOS compatible, Cart/Checkout Blocks not supported)

1.6.1

  • Fix: Deployment packaging correction to include missing runtime class files (including WAM Go helper) in released builds

1.6.0

  • Change: WordPress login links now route members to the configured medlemsportal URL while preserving admin authentication flows
  • Change: Direct requests to wp-login.php now redirect guests to medlemsportal with redirect target preserved where relevant
  • Change: One-time login code expiry is now centralized and configurable in seconds via plugin settings/filter

1.5.3

  • Change: Always resolve {{org_email}} {{org_name}} • {{org_street}} • {{org_postal_code}} • {{org_city}} placeholders from settings when sending WAET emails

1.4.25

  • Fix: WAET email template settings — intro text uses rich text editor consistently
  • Fix: WAET template test-send works across templates (member no + email)
  • Change: Create/update WAET sendqueue table only via version bump table update

1.4.24

  • Fix: Self-healing BOM cleanup — scans all plugin PHP files on first load after update and strips UTF-8 BOMs at source
  • Fix: Eliminates BOM contamination permanently even when server-side files contain BOMs introduced during build/sync

1.4.23

  • Fix: ob_start callback now strips UTF-8 BOMs from output instead of just buffering them
  • Fix: Prevents BOM contamination of WordPress update and AJAX responses

1.4.22

  • Fix: Remove UTF-8 BOM contamination that corrupted AJAX/update JSON responses
  • Fix: Remove PHP close tags (?>) from class and include files (WordPress coding standard)
  • Fix: Add early AJAX output buffer in main plugin file to catch stray output from require_once
  • Fix: All AJAX handlers now flush ALL output buffer levels before sending JSON

1.4.21

  • Security: Rewrite Members_List_Table::get_table_data() with $wpdb->prepare() — removes esc_sql() and direct variable interpolation
  • Fix: CRITICAL bug in helpers.php update_max_ordernumber_from_input() — $wpdb->get_var() was misused as prepare(), %s never substituted
  • Fix: Replace die(json_encode()) with wp_send_json() in wa_members_ajax_response()
  • Fix: Guard $wpdb->prepare() with empty params in export_members and export_member_addresses
  • Fix: Remove trailing PHP close tag from Members_List_Table

1.4.20

  • Fix: Remove undefined $value reference in Members_List_Table constructor (PHP 8 warning)
  • Fix: Skip $wpdb->prepare() when no placeholders in Category and Payments get_total_count() (WP 6.2+ compat)
  • Fix: Add output buffer safety to all AJAX handlers to prevent stray PHP output corrupting JSON
  • Fix: Add error callback to members AJAX display for debugging
  • Fix: Category search/status event binding now reads from DOM instead of passing jQuery Event

1.4.19

  • Fix: Use dedicated AJAX action for WAET test emails to avoid handler collisions
  • Change: Align WAET queue table schema with production structure

1.4.18

  • Change: Simplify WAET template settings into accordion list
  • Change: Accordion closes other templates when opened
  • Fix: Test email buttons now target the correct template fields
  • Change: Use internal sequential order id for 0 DKK subscription setup and Woo order number for paid charge

1.4.17

  • Fix: New member flow creates order line item and keeps WAMP_PAYMENT linked to Woo order

1.4.16

  • Fix: Nonce handling returns user-friendly error instead of 403

1.4.15

  • Change: Standardize recurring charges on quickpay_payment_by_subscription

1.4.14

  • Change: Woo gateway redirects to QuickPay Payment Window if subscription is missing

1.4.13

  • Fix: Remove members area table fallback and fail fast when bootstrap/table is missing

1.4.12

  • Build: Version bump

1.4.11

  • Fix: Remove dbDelta inline comments in members area table

1.4.10

  • Build: Update available for injection validation

1.4.9

1.4.8

  • Fix: Member token login - create user if not exists
  • Fix: Database schema version now matches plugin version (WAMP_VERSION)
  • Fix: SQL syntax error in wam_members_area table creation (removed invalid comment)

1.4.7

  • Fix: Member token login undefined variable error in portal AJAX

1.4.6

  • Remove bundled update checker (WAUM handles updates)
  • Cards terminology and i18n keys for portal
  • Update POT template

1.4.5

  • Update language files

1.4.4

  • Change Subscription to Card

1.4.3

  • Build: Ensure PluginInstaller loader is packaged correctly from shared source

1.4.2

  • Update Checker: Make class generic and pass slug/server from bootstrap

1.4.1

  • Update Checker: Use dynamic slug via WAMP_SLUG

1.4.0

  • WebAlive Tab: Load shared installer loader in plugin bootstrap

1.3.9

  • Use new tab=webalive

1.3.8

  • Changed handling of wp login and members

1.3.7

  • JS updated for better apple handling

1.3.6

  • Debug: Added error logging for plugin-info.php failures to diagnose "Plugin not found" issues

1.3.5

  • WebAlive Tab: Ultra-minimal remote loader implementation (~50 lines inline)
  • WebAlive Tab: Shows all available WebAlive plugins (sales channel)
  • Architecture: All logic loaded from update server - no class files needed
  • Optimization: Reduced from 172 lines to 50 lines of integration code

1.3.4

  • Architecture: Removed PluginInstallerRemote - WebAlive tab now only in WAUM
  • Optimization: Reduced plugin size by removing duplicate installer code
  • Update: Relies on WAUM for plugin installation interface

1.3.2

  • Added WebAlive plugin installer tab integration
  • Users can now browse and install all WebAlive plugins from WordPress admin

1.3.1

  • Skiftet titel til WebAlive Members Premium
  • Plugin now checks for updates automatically via custom update server
  • Improved plugin update workflow and notifications

1.3.0

  • Added automatic update checker integration with updates.webalive.dk
  • Plugin now checks for updates automatically via custom update server
  • Improved plugin update workflow and notifications

1.2.0

  • Previous stable release with all membership management features

0.9.0

  • Added WP User sync logic with wa_members table
  • AJAX-powered modals for member actions (edit, remove, unremove)
  • Enhanced UI with Bootstrap styles
  • Optimized database queries and pagination
  • Added Mailchimp tab and API configuration
  • Modernized import workflow (CSV & MSSQL) with AJAX feedback and summary cards

0.8.0

  • Initial public release
© 2026 Webalive - live website