Skip to content

Fix: load membership and customer with the correct helpers in PayPal Express IPN#1378

Open
vuckro wants to merge 3 commits into
Ultimate-Multisite:mainfrom
vuckro:fix/paypal-ipn-correct-loaders
Open

Fix: load membership and customer with the correct helpers in PayPal Express IPN#1378
vuckro wants to merge 3 commits into
Ultimate-Multisite:mainfrom
vuckro:fix/paypal-ipn-correct-loaders

Conversation

@vuckro

@vuckro vuckro commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

In PayPal_Gateway::process_webhooks() the IPN custom field is
payment_id|membership_id|customer_id, but all three ids were loaded with
wu_get_payment(). So $membership and $customer were the wrong object type
(or false), leading to wrong-object data handling and a fatal when the later
code calls Membership-only methods (is_active(), renew(), …).

Changes

  • Use wu_get_membership() and wu_get_customer() for the respective ids.
  • Guard the index count so a malformed custom value doesn't raise
    undefined-index warnings.

Affects the legacy PayPal Express (NVP) gateway IPN path only.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed PayPal gateway webhook processing to properly identify and link payments, memberships, and customers from PayPal transaction data.

… Express IPN

In PayPal_Gateway::process_webhooks() the IPN `custom` field is
"payment_id|membership_id|customer_id", but all three ids were loaded with
wu_get_payment(), so $membership and $customer were either the wrong object
type or false — leading to wrong-object data corruption (and a fatal when the
later code calls Membership-only methods like is_active()/renew()). Also guard
the index count so a malformed `custom` value doesn't raise undefined-index
warnings.

Use wu_get_membership() and wu_get_customer() for the respective ids.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PayPal gateway webhook processor now correctly parses the IPN custom field and retrieves the associated payment, membership, and customer entities using the appropriate lookup functions instead of incorrectly using the payment lookup for membership and customer indices.

Changes

PayPal IPN Processing

Layer / File(s) Summary
PayPal webhook custom field parsing
inc/gateways/class-paypal-gateway.php
The process_webhooks() method validates that the custom field split produces at least 3 elements and correctly maps indices to their entity lookups: wu_get_payment() for payment, wu_get_membership() for membership, and wu_get_customer() for customer.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

review-feedback-scanned

Suggested reviewers

  • superdav42

Poem

A PayPal hook came in one day,
With IDs mixed up in a wrong way,
But now they're mapped just right,
Payment, membership, customer—oh what a sight! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the specific bug fix: using correct helper functions for loading membership and customer objects in the PayPal Express IPN webhook processing.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
inc/gateways/class-paypal-gateway.php (2)

957-957: ⚡ Quick win

Correct the method reference in the comment.

The comment references set_express_checkout(), but no such method exists in this file. The custom field is actually built in process_checkout() at line 474.

📝 Proposed fix
-// `custom` is built as "payment_id|membership_id|customer_id" (see set_express_checkout()).
+// `custom` is built as "payment_id|membership_id|customer_id" (see process_checkout() line 474).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@inc/gateways/class-paypal-gateway.php` at line 957, Update the inline comment
that says the `custom` field is built by "set_express_checkout()" to correctly
reference the actual builder function `process_checkout()` where `custom` is
composed ("payment_id|membership_id|customer_id"); locate the comment near the
`custom` usage and replace the incorrect method name with `process_checkout()`
so the comment accurately points to the source of the `custom` value.

1700-1700: 💤 Low value

Unused variable: parsed $custom is never accessed.

The $custom variable is parsed from $body['PAYMENTREQUEST_0_CUSTOM'] but is never used before the method returns $body at line 1702. This appears to be leftover or incomplete code.

♻️ Suggested cleanup

Remove the unused line if it serves no purpose:

-		$custom = explode('|', (string) $body['PAYMENTREQUEST_0_CUSTOM']);
-
 		return $body;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@inc/gateways/class-paypal-gateway.php` at line 1700, Remove the unused
parsing of PAYMENTREQUEST_0_CUSTOM in class-paypal-gateway.php: delete the line
that assigns $custom = explode('|', (string) $body['PAYMENTREQUEST_0_CUSTOM'])
in the method where $body is returned (ensure it is not used elsewhere in that
method), or if the custom value was intended to be used, instead apply the
parsed $custom to the appropriate $body field or downstream logic (locate the
code in the class PayPal gateway method that currently returns $body and either
remove the $custom assignment or integrate $custom into that method's returned
data).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@inc/gateways/class-paypal-gateway.php`:
- Line 957: Update the inline comment that says the `custom` field is built by
"set_express_checkout()" to correctly reference the actual builder function
`process_checkout()` where `custom` is composed
("payment_id|membership_id|customer_id"); locate the comment near the `custom`
usage and replace the incorrect method name with `process_checkout()` so the
comment accurately points to the source of the `custom` value.
- Line 1700: Remove the unused parsing of PAYMENTREQUEST_0_CUSTOM in
class-paypal-gateway.php: delete the line that assigns $custom = explode('|',
(string) $body['PAYMENTREQUEST_0_CUSTOM']) in the method where $body is returned
(ensure it is not used elsewhere in that method), or if the custom value was
intended to be used, instead apply the parsed $custom to the appropriate $body
field or downstream logic (locate the code in the class PayPal gateway method
that currently returns $body and either remove the $custom assignment or
integrate $custom into that method's returned data).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e6dea0d1-f7f3-4199-8b47-2a7ce67da456

📥 Commits

Reviewing files that changed from the base of the PR and between 4c6ceed and d8f569c.

📒 Files selected for processing (1)
  • inc/gateways/class-paypal-gateway.php

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants