- How to best prepare for and deal with this scenario in practice?
- How does s2Member's logic handle this case? (Some experimental results below)
Scenario: User creates a PayPal subscription for Level 1 access, which works just fine. Somehow, the user becomes confused and thinks they must sign up again. Even though my site's logic is supposed to keep them away from the subscription button, they manage to sign up with another subscription (there are a few ways this could happen). Now they have 2 active subscriptions.
Here's what I've found from Sandbox testing: Upon initial subscription, s2Member receives an IPN and assigns subscr_id (say, I-ABCDE) to user's account and sets them at Level 1, as expected. Upon future redundant subscription (which PayPal is happy to take), s2Member receives an IPN identifying the customer by the original subscr_id (I-ABCDE), but including a new subscr_id (say, I-VWXYZ). s2Member's log (see below) shows that it updates payment times for the associated member. In the WordPress User panel I see that s2Member has replaced the user's subscr_id with the new one (I-VWXYZ).
- What is the result of 'Updated Payment Times'?
- What will happen when recurring payments are made on each of these subscriptions?
Second IPN (redundant subscription) from s2member-logs/paypal-ipn.log:
- Code: Select all
'option_name1' => 'Referencing Customer ID',
'option_selection1' => 'I-ABCDE',
...
'subscr_id' => 'I-VWXYZ',
...
's2member_log' =>
array (
0 => 'IPN received on: Sun Jul 3, 2011 4:16:31 pm UTC',
1 => 's2Member POST vars verified through a POST back to PayPal®.',
2 => 's2Member originating domain ( _SERVER[HTTP_HOST] ) validated.',
3 => 's2Member txn_type identified as subscr_payment|recurring_payment.',
4 => 'Sleeping for 5 seconds. Waiting for a possible subscr_signup|subscr_modify|recurring_payment_profile_created.',
5 => 'Awake. It\'s Sun Jul 3, 2011 4:16:36 pm UTC. s2Member txn_type identified as subscr_payment|recurring_payment.',
6 => 'Updated Payment Times for this Member.',
),
Cancellation testing: The customer decides to cancel the second subscription. The IPN cancel signal includes the Customer ID as the original subscr_id (not the WordPress user ID). s2Member sorts this out and sets the user's EOT. This is not entirely correct, because there is still another active subscription.
- What will happen when the other subscription makes a payment? Will the subscription be reinstated? Will the EOT be extended?
- Code: Select all
'subscr_id' => 'I-VWXYZ',
'option_name1' => 'Referencing Customer ID',
'option_selection1' => 'I-ABCDE',
's2member_log' =>
array (
0 => 'IPN received on: Sun Jul 3, 2011 4:47:46 pm UTC',
1 => 's2Member POST vars verified through a POST back to PayPal®.',
2 => 's2Member originating domain ( _SERVER[HTTP_HOST] ) validated.',
3 => 's2Member txn_type identified as subscr_cancel|recurring_payment_profile_cancel.',
4 => 'Auto-EOT Time for this account: Tue Jul 5, 2011 4:16 pm UTC',
),
The customer decides to cancel the original subscription, as well. PayPal sends an IPN referencing the subscr_id of the original subscription (I-ABCDE). This time, the Customer ID = WordPress User ID (instead of a subscr_id). Unfortunately, s2Member cannot find a user with said Customer ID and given subscr_id, so the action fails.
- Code: Select all
'subscr_id' => 'I-ABCDE',
'option_name1' => 'Referencing Customer ID',
'option_selection1' => '5',
's2member_log' =>
array (
0 => 'IPN received on: Sun Jul 3, 2011 4:49:01 pm UTC',
1 => 's2Member POST vars verified through a POST back to PayPal®.',
2 => 's2Member originating domain ( _SERVER[HTTP_HOST] ) validated.',
3 => 's2Member txn_type identified as subscr_cancel|recurring_payment_profile_cancel.',
4 => 'Unable to handle Cancellation. Could not get the existing User ID from the DB.',
),
In the end, the user is degraded (to Level 0) after the EOT. However, there are many ways in which this would cause a lot of customer support overhead. Any advice is appreciated.
Request: One thing I'd like to request is an activity page within s2Member that digests and interprets these log events for me, and puts flags on unexpected/failure cases. I'd never have any clue what was going on behind the scenes in a live situation, without wading through reams of logs.