XF 2.2 vBulletin 4 to XenForo recurring PayPal subscriptions

Charlie G

Member
Following on from this thread from 3 years ago.

Has anyone resolved the issue with recurring subscription via Paypal?

Given that the PayPal communication will fail to connect to the old vB connector PHP script due to it no longer being there, what will the result be?
  • Will the subscriber get charged another renewal by Paypal regardless of failed PHP communication. If this occurs then I guess the member will need to have their subscription manually added to their XF account.
  • Or, will PayPal fail to process the subscription completely because of the failed comms between itself and the none existent vBulletin connector?
 
In the end, I wrote dummy PHP endpoint to continue to respond to PayPal. It accepts the IPN call by PayPal so they don't fail, and then logs all the actions to a couple of text files on my end (ipnfails.txt and ipnhits.txt).

The above serves two purposes, (a) the IPN calls never fail because I'm still responding to PayPal, (b) I can see which users of my forum are still under the old vBulleting PayPal IPN system should I wish to follow up with them.

I created the above system over 3 years ago and just checked my ipnhits.txt files and there's still recurring transactions coming through them all these years later... so I'm glad I took the time to do it otherwise I would have likely lost out on a lot of this revenue.
 
One more thing. I'm glad I took the time to do this so that I could stop worrying about the existing PayPal subscriptions and I could then go ahead and move away from vBulletin to Xenforo.

Xenforo is far and away better than vBulletin. Life is much easier now I've made the move.

My biggest hang-up was these recurring profiles from vBulletin. Once I was able to assure myself they would continue to "poll back" to PayPal indefinitely I was able to go ahead with the migration to Xenforo. So glad I did!
 
Thanks Wutime, I really appreciate your reply.

Am I right in thinking the dummy PHP endpoint you wrote keeps PayPal happy and you then have to manually extend the date(s) to the subscription/member upgrade for the user account on your XenForo?

I wouldn't have a clue how to write the PHP endpoint so any help with that would be gratefully appreciated 🙏

Xenforo is far and away better than vBulletin. Life is much easier now I've made the move.
I'm looking forward to making the move once I am sure I have the subscriptions sorted.
 
Last edited:
A custom add-on is required to maintain the subscriptions with certainty, PM sent.
i would be interested in this custom add-on as we are moving from IPS4.7 to Xenforo 2.2 if it will work for that as well. please DM me with any info. we are willing to compensate for it as well since i can not seem to find one on the site in resources.
 
Literally the only thing holding me back from migrating from IPS4 has been recurring payments. I'm not far of the point of biting the bullet and writing a very clear guide for folk how to setup new, then a db update to extend renewals by a few months for each.
 
In the end, I wrote dummy PHP endpoint to continue to respond to PayPal. It accepts the IPN call by PayPal so they don't fail, and then logs all the actions to a couple of text files on my end (ipnfails.txt and ipnhits.txt).

The above serves two purposes, (a) the IPN calls never fail because I'm still responding to PayPal, (b) I can see which users of my forum are still under the old vBulleting PayPal IPN system should I wish to follow up with them.

I created the above system over 3 years ago and just checked my ipnhits.txt files and there's still recurring transactions coming through them all these years later... so I'm glad I took the time to do it otherwise I would have likely lost out on a lot of this revenue.
May you share the script?
 
In the end, I wrote dummy PHP endpoint to continue to respond to PayPal. It accepts the IPN call by PayPal so they don't fail, and then logs all the actions to a couple of text files on my end (ipnfails.txt and ipnhits.txt).

The above serves two purposes, (a) the IPN calls never fail because I'm still responding to PayPal, (b) I can see which users of my forum are still under the old vBulleting PayPal IPN system should I wish to follow up with them.

I created the above system over 3 years ago and just checked my ipnhits.txt files and there's still recurring transactions coming through them all these years later... so I'm glad I took the time to do it otherwise I would have likely lost out on a lot of this revenue.
Would you be willing to share this dummy script?
 
Oh sorry, I should have shared this years ago but I had notifications turned off until about a year ago. Apologies.

This PHP script acts as a dummy endpoint for legacy PayPal IPNs from old vBulletin subscriptions. It validates incoming IPNs, prevents failures to keep recurring payments active, and logs verified transactions (with details) to ipnhits.txt and invalid ones (with timestamps) to ipnfails.txt. No database updates or processing occurs—it's purely for monitoring and preservation during migrations (e.g., to Xenforo). The PHP is for PHP (7+).

PHP:
<?php

// STEP 1: Read raw POST data to avoid serialization issues
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$myPost = [];
foreach ($raw_post_array as $keyval) {
    $keyval = explode('=', $keyval);
    if (count($keyval) === 2) {
        $myPost[$keyval[0]] = urldecode($keyval[1]);
    }
}

// Prepare the request by adding 'cmd' and encoding values
$req = 'cmd=_notify-validate';
foreach ($myPost as $key => $value) {
    $value = urlencode($value);
    $req .= "&$key=$value";
}

// STEP 2: Post IPN data back to PayPal for validation
// Use the live URL by default; uncomment sandbox for testing
$ch = curl_init('https://ipnpb.paypal.com/cgi-bin/webscr');
// $ch = curl_init('https://ipnpb.sandbox.paypal.com/cgi-bin/webscr');

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Connection: Close']);

// If your environment lacks root CA certificates (e.g., WAMP), download 'cacert.pem' from
// https://curl.se/docs/caextract.html and uncomment the line below, adjusting the path.
// curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . '/cacert.pem');

$res = curl_exec($ch);
if ($res === false) {
    // Optional: Log curl error if needed, but avoid terminating
    // error_log("Curl error: " . curl_error($ch));
    curl_close($ch);
    exit;
}
curl_close($ch);

// STEP 3: Inspect IPN validation result and log accordingly
if (strcmp($res, "VERIFIED") === 0) {
    // Extract relevant POST variables (assuming they exist; no additional validation as per original)
    $first_name = $_POST['first_name'] ?? '';
    $last_name = $_POST['last_name'] ?? '';
    $item_number = $_POST['item_number'] ?? '';
    $payment_date = $_POST['payment_date'] ?? '';
    $payer_status = $_POST['payer_status'] ?? '';
    $payment_status = $_POST['payment_status'] ?? '';
    $mc_fee = $_POST['mc_fee'] ?? '';
    $payment_amount = $_POST['mc_gross'] ?? '';
    $payment_currency = $_POST['mc_currency'] ?? '';
    $txn_type = $_POST['txn_type'] ?? '';
    $txn_id = $_POST['txn_id'] ?? '';
    $receiver_email = $_POST['receiver_email'] ?? '';
    $payer_email = $_POST['payer_email'] ?? '';

    // Log to ipnhits.txt in CSV format
    $content = implode(',', [
        $first_name,
        $last_name,
        $item_number,
        $payment_date,
        $payer_status,
        $payment_status,
        $mc_fee,
        $payment_amount,
        $payment_currency,
        $txn_type,
        $txn_id,
        $receiver_email,
        $payer_email
    ]) . "\n";

    $this_directory = __DIR__;
    $fp = fopen($this_directory . '/ipnhits.txt', 'a');
    if ($fp) {
        fwrite($fp, $content);
        fclose($fp);
    }
    // Note: In production, handle file write failures gracefully (e.g., error_log)

} elseif (strcmp($res, "INVALID") === 0) {
    // Log timestamp to ipnfails.txt for investigation
    $content = date("Y-m-d H:i:s") . "\n";

    $this_directory = __DIR__;
    $fp = fopen($this_directory . '/ipnfails.txt', 'a');
    if ($fp) {
        fwrite($fp, $content);
        fclose($fp);
    }
    // Note: In production, handle file write failures gracefully (e.g., error_log)
}

Key Notes:
  • For PayPal classic IPNs only. Run on secure server (HTTPS). PHP 7+ with cURL required.
  • No impact on new forum; preserves old subscriptions.
Steps:
  1. Location: Place in old vBulletin folder (e.g., /forum/payment_gateway.php). Keep path as configured in PayPal.
  2. Create Script: Save the code above as payment_gateway.php.
  3. SSL Certs (If Needed): For missing CA certs (e.g., WAMP), download cacert.pem from https://curl.se/docs/caextract.html, place in folder, uncomment relevant line.
  4. Log Files & Permissions: Create ipnhits.txt and ipnfails.txt in same folder. Set write perms (e.g., chmod 644/666 on Linux; modify for web user on Windows).
  5. Test: Use PayPal IPN Simulator (developer tools) with your URL. Check logs post-simulation.
  6. Logs: ipnhits.txt = CSV details (name, date, amount, etc.); ipnfails.txt = timestamps. Analyze in spreadsheet.
  7. Customizations (Optional): Add DB inserts, email alerts, or extra validations in "VERIFIED" block. Handle write failures with error_log(). Monitor file sizes.
 
Back
Top Bottom