RBC-SOP-05 Addendum A — Upgrade Batch Lessons
Version 1.0 | September 2026 | Restricted: Committee & Admin only
This addendum records what the September 2026 upgrade batch revealed. It does not replace SOP 05 — read it alongside. Where the two disagree, this addendum takes precedence, because SOP 05 was written before these cases were encountered.
Seven member records were worked in this batch: one full restoration from the legacy members database, two clean upgrades, one repair of a half-finished upgrade, and three corrections of role-only changes made outside the SOP.
Batch covered
| Member | Subscription | Case type |
|---|---|---|
| Paul Wilson | #2003633 | Full restore from legacy DB, then upgrade |
| Greg Fill | #2001469 | Upgrade — two separate user accounts |
| Chris Smeed | #2003492 | Clean upgrade — Member since reset |
| Damien Clark | #2001195 | Repair of half-finished upgrade |
| Rodney Winkleman | #2003543 | Role-only change corrected |
| Jonathan Bohan | #2001523 | Role-only change corrected |
| Adrian Watson (member) | #2001510 | Role-only change corrected |
1. Confirm it is really one account before you start
SOP 05 assumes a member is one WordPress user. That assumption failed on the first dual-membership case.
Greg Fill exists as two entirely separate user accounts:
| Field | Account 1 | Account 2 |
|---|---|---|
| Username | gregfill |
greg.fill |
gregfill@live.fr |
grefill@live.fr |
|
| Tier | Mid-Week → Ordinary | Social |
| Subscription | #2001469 | #49677 |
The two email addresses differ by a single letter. Before starting any upgrade, search Users by surname and confirm which account you are working on by email address, not by display name.
⚠ If the two memberships genuinely are on one account, the upgrade is more dangerous, not less. Snippet 28 uses set_role(), which wipes all other roles. Activating an Ordinary membership on an account that also holds social_member will silently remove the Social role. Re-add it manually and verify afterwards.
2. Set the line item price directly — never record a part-payment as a refund
Where a member paid an amount other than the full product price (pro-rata, joining fee, or a negotiated figure), set the line item price to the amount actually received.
On Paul Wilson’s April order the product was added at the full $305.25 and an $80.75 refund was applied to bring the net to $224.50. That produced three problems:
- The club’s books now show a payment and a refund that never happened, and the order sits permanently in the Refunded bucket.
- GST was recorded as $27.75 on $277.50 — the GST on the product, not on the money received.
- WooCommerce sent the member a “Refunded order” email for a refund they never got.
A completed order that has been refunded is also no longer editable, so the mistake cannot be corrected in place. Get the price right the first time.
3. Emails now send — there is no “Do Not Send” safety net
WP Mail SMTP is no longer installed on the live site. The staging-era procedure of ticking “Do Not Send” before admin work no longer exists. Every order you create emails the member immediately.
| Action | Emails sent to member |
|---|---|
| Create order, set to Completed | New order · Completed order |
| Apply a refund | Refunded order |
Paul Wilson received five emails in one afternoon, including order confirmations dated April arriving in September and a refund notification for a refund that never occurred.
Before an upgrade session, decide one of:
- Accept the emails and tell the member beforehand what they will see; or
- Temporarily disable New order and Completed order in WooCommerce → Settings → Emails, do the work, and switch them back on immediately afterwards.
If you choose option 2, add the re-enabling step to your session notes. Leaving those emails off affects every member, not just the one you are working on.
4. Name the fee line and set the payment method field
Two small omissions in this batch that both cost visibility later.
Name the fee
The upgrade-difference order for Paul Wilson rendered as “$0.00 fee” because the fee name was never entered. Since $101.75 is also the annual Retired membership fee, an unlabelled $101.75 order is precisely the ambiguity SOP 05 warns about.
After Add item(s) → Add fee, click Edit on the fee line and type the name — Mid-Week to Ordinary upgrade difference — before saving.
Set the payment method properly
Set the Payment method field to Direct bank transfer, not merely a private note saying so. Bank-transfer reporting and the Payment Reconciliation SOP filter on the payment method field. Two orders in this batch carry only “Paid on [date]” with no gateway, and are invisible to those reports.
5. Repairing a half-finished upgrade
SOP 05 warning 3 predicted this case. It occurred, and this is how to identify and repair it.
How to spot it
- The Items column on the Subscriptions list reads “2 items” instead of naming a single product.
- On the subscription, Items Subtotal disagrees with Order Total.
- The Ordinary line often has no GST at all.
Damien Clark’s subscription #2001195 read:
| Line | Price | Total | GST |
|---|---|---|---|
| Mid-Week Membership | $277.50 | $277.50 | $27.75 |
| Ordinary Membership | $370.00 | $370.00 | none |
| Items Subtotal | $647.50 | ||
| Order Total | $305.25 | ||
The member was still being billed the Mid-Week rate.
Repair procedure
- Delete the Mid-Week line item only. Keep the existing Ordinary line — do not add a second.
- Set GST $37.00 on the Ordinary line. Price and Total should already read $370.00.
- Click Recalculate.
- Confirm Items Subtotal $370.00 · GST $37.00 · Order Total $407.00. If the subtotal still reads $647.50, the Mid-Week line is still present.
- Continue from SOP 05 Stage 3 as normal.
⚠ Check the order notes before assuming who did it. The note on #2001195 attributes the change to “Adrian Watson” — a display name shared by three accounts on this site. Do not infer the author from the display name alone.
6. Member since resets silently — verify it twice
On Chris Smeed’s upgrade the new Ordinary record was created with Member since 04/09/2026, the upgrade date, instead of 17/08/2026, his original join date. Nothing warned, and the error is only visible by comparing the new record against the cancelled one.
This field feeds the tenure calculation behind Retired eligibility. Setting it to the upgrade date resets the member’s clock.
Verify it at two points:
- Immediately after saving the new Ordinary membership record.
- Again after linking the subscription — linking can cause Memberships to recalculate the term.
Read the original date off the Mid-Week record before you cancel it, and write it down.
7. Always link the new membership to the subscription
WooCommerce Memberships only auto-manages memberships it created from a purchase. A manually created record that is not linked to a subscription will not follow that subscription’s renewals — the payment activates the subscription while the membership record sits untouched, requiring manual attention every year.
This is the same defect behind the outstanding 467-record membership-to-subscription backfill. Every unlinked record created from here on adds to it.
In Billing Details on the membership record, confirm a Subscription number and a Next Bill On date are both shown. If they are absent, the link was not made.
Consequence of linking: the membership will follow the subscription’s status. If that subscription is ever cancelled or expires, the membership cancels too. That is the intended behaviour — and it is why the subscription must never be cancelled during an upgrade.
8. Role-only changes create silent mismatches
Three members in this batch had been moved to Ordinary by changing the WordPress role only. Their membership records and subscriptions were left on Mid-Week.
Nothing on the site flags this. The member appears correct on the Users list, holds Ordinary access, and would have been invoiced $305.25 instead of $407.00 at the next renewal — a shortfall of $101.75 each.
Never change a member’s tier by editing the role. The role is an output of the membership record, set automatically by Snippet 28. Editing it directly desynchronises the three layers and leaves no trace.
How to scan for existing mismatches
- WooCommerce → Subscriptions, filter Products = Mid-Week Membership. Note every member listed.
- Users → All Users, click the Mid-Week Member role filter. Note every member listed.
- Anyone appearing in list 1 but not list 2 is a mismatch. Check their actual role and membership record.
9. Verification — the three-way reconciliation
After any batch, these three numbers must agree. If they do not, something is half-done.
| Layer | Where to read it |
|---|---|
| Role holders | Users → All Users → Mid-Week Member filter |
| Active subscriptions | Subscriptions → filter Products = Mid-Week Membership (exclude cancelled) |
| Active membership records | Memberships → Members → plan Mid-Week Member (#53833), status Active |
At the close of this batch all three read 9. Run the same check against Ordinary after any large batch.
Per-member verification — every upgraded member should show:
- Subscription Active, one line item, $407.00/year
- Next payment 1 July — if not, record it for the cycle-realignment batch, do not silently correct it
- Membership Ordinary Member (#53834), Active, correct Member since, subscription linked
- Old Mid-Week record Cancelled, not deleted
- Role reads Ordinary Member with no stale Mid-Week role
Note: Snippet 28’s set_role() also removes the customer role during the upgrade. This is expected and appears harmless, but it is why upgraded members read “Ordinary Member” alone while long-standing members read “Ordinary Member, Customer”.
10. Confusable identifiers
Pairs encountered in this batch that differ by one character, or share a name. Copy and paste; never type from memory.
| Pair | Risk |
|---|---|
gregfill@live.fr / grefill@live.fr |
Two different accounts for the same person — one letter apart |
#53834 (Ordinary plan) / #53843 (Ordinary product) |
Digit transposition of each other |
#53834 (Ordinary plan) / #53835 (Retired plan) |
One digit apart |
Three accounts display as “Adrian Watson”: ADRIAN1171 (Pixelkraft), adrianwatson (member), WebAdmin (administrator) |
Order notes and activity logs cannot distinguish them |
| GARY BOHAN (Retired) / JONATHAN BOHAN (Ordinary) | Same surname, different tiers |
krysclark@gmail.com (Krystine Clark) / krysclark@outlook.com (Peter Clark) |
Same local part, different people |
| $101.75 upgrade difference / $101.75 Retired annual fee | Identical amounts, different meanings |
Additions to the SOP 05 checklist
| Stage | Check | ✓ |
|---|---|---|
| Before starting | Confirmed which user account by email address, not display name | |
| Decided on email handling — warn the member, or temporarily disable order emails | ||
| Payment order | Line item priced at the amount actually received — no refund used | |
| Fee line named, not left as “$0.00 fee” | ||
| Payment method field set to Direct bank transfer, not only a note | ||
| Subscription | If “2 items”: Mid-Week line deleted, GST set on the surviving Ordinary line | |
| Items Subtotal $370.00 and Order Total $407.00 agree after Recalculate | ||
| Membership | Original Member since written down before the Mid-Week record was cancelled | |
| Member since re-verified after linking the subscription | ||
| Billing Details shows a Subscription number and Next Bill On date | ||
| Batch close | Three-way reconciliation run — roles, subscriptions and membership records agree |
Still open
- Cycle-realignment batch — members whose next payment is not 1 July. Damien Clark (#2001195, 22/07/2027) was added during this batch and deliberately left uncorrected.
- Membership-to-subscription backfill — approximately 467 records still unlinked.
- Mail visibility — no send logging or delivery-failure reporting since WP Mail SMTP was removed. Reinstating it would restore the “Do Not Send” safety this addendum works around.
- Ordinary membership cap — the cap is 400. Check available vacancies before committing to a large batch of upgrades.
Addendum A to RBC-SOP-05-Mid-Week-to-Ordinary v1.0. Prepared by Pixelkraft, September 2026.