HELP! Paypal not working in 2.3

HELP! Paypal not working in 2.3

by Alan Kmiecik -
Number of replies: 4

I've spent about 80 hours trying to get this working (i.e. have read pretty much every forum entry related to the topic)

I setup a fresh Moodle 2.3.1 site. Enabled Paypal, created course, set entrolment.  Created user and went to enrol.

Added IPN to Paypal, ensured UTF-8 was set.

Modified config.php to use sandbox (i.e. added 

$CFG->usepaypalsandbox = 'www.sandbox.paypal.com';)

Done everthing I can think of that needs to be done but still gettting

"Thank you for your payment! Unfortunately your payment has not yet been fully processed,"

Average of ratings: -
In reply to Alan Kmiecik

Re: HELP! Paypal not working in 2.3

by Alan Kmiecik -

So here is what I have setup...

Moodle Setup

Paypal setup

Site Administration -Plugins - Enrolments - Paypal

 

(That would be the email of the sandbox business account)

 

 

Course Administration - Users - Enrolment Methods - Paypal

Moodle config.php has line $CFG->usepaypalsandbox = 'www.sandbox.paypal.com';

 

My Account - Profile - My Settings - Instant Payment Notification

 

 

Note: Moodle config.php has line $CFG->wwwroot   = 'http://www.aquinascollegecatechetics.org/testsite';

 

 

My Account - Profile - My Settings - Language Encoding - More Options

 

 

 

 

 

enrol.html

 

<div align="center">

 

<p><?php print_string("paymentrequired") ?></p>

<p><b><?php echo $instancename; ?></b></p>

<p><b><?php echo get_string("cost").": {$instance->currency} {$cost}"; ?></b></p>

<p><img alt="<?php print_string('paypalaccepted', 'enrol_paypal') ?>" src="https://www.paypal.com/en_US/i/logo/PayPal_mark_60x38.gif" /></p>

<p><?php print_string("paymentinstant") ?></p>

<?php

    $paypalurl = empty($CFG->usepaypalsandbox) ? 'https://www.paypal.com/cgi-bin/webscr' : 'https://www.sandbox.paypal.com/cgi-bin/webscr';

?>

<form action="<?php echo $paypalurl ?>" method="post">

 

<input type="hidden" name="cmd" value="_xclick" />

<input type="hidden" name="charset" value="utf-8" />

<input type="hidden" name="business" value="<?php p($this->get_config('paypalbusiness'))?>" />

<input type="hidden" name="item_name" value="<?php p($coursefullname) ?>" />

<input type="hidden" name="item_number" value="<?php p($courseshortname) ?>" />

<input type="hidden" name="quantity" value="1" />

<input type="hidden" name="on0" value="<?php print_string("user") ?>" />

<input type="hidden" name="os0" value="<?php p($userfullname) ?>" />

<input type="hidden" name="custom" value="<?php echo "{$USER->id}-{$course->id}-{$instance->id}" ?>" />

 

<input type="hidden" name="currency_code" value="<?php p($instance->currency) ?>" />

<input type="hidden" name="amount" value="<?php p($cost) ?>" />

 

<input type="hidden" name="for_auction" value="false" />

<input type="hidden" name="no_note" value="1" />

<input type="hidden" name="no_shipping" value="1" />

<input type="hidden" name="notify_url" value="<?php echo "$CFG->wwwroot/enrol/paypal/ipn.php"?>" />

<input type="hidden" name="return" value="<?php echo "$CFG->wwwroot/enrol/paypal/return.php?id=$course->id" ?>" />

<input type="hidden" name="cancel_return" value="<?php echo $CFG->wwwroot ?>" />

<input type="hidden" name="rm" value="2" />

<input type="hidden" name="cbt" value="<?php print_string("continuetocourse") ?>" />

 

<input type="hidden" name="first_name" value="<?php p($userfirstname) ?>" />

<input type="hidden" name="last_name" value="<?php p($userlastname) ?>" />

<input type="hidden" name="address" value="<?php p($useraddress) ?>" />

<input type="hidden" name="city" value="<?php p($usercity) ?>" />

<input type="hidden" name="email" value="<?php p($USER->email) ?>" />

<input type="hidden" name="country" value="<?php p($USER->country) ?>" />

 

<input type="submit" value="<?php print_string("sendpaymentbutton", "enrol_paypal") ?>" />

 

</form>

 

</div>

 

 ipn.php

 

<?php

// This file is part of Moodle - http://moodle.org/

//

// Moodle is free software: you can redistribute it and/or modify

// it under the terms of the GNU General Public License as published by

// the Free Software Foundation, either version 3 of the License, or

// (at your option) any later version.

//

// Moodle is distributed in the hope that it will be useful,

// but WITHOUT ANY WARRANTY; without even the implied warranty of

// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

// GNU General Public License for more details.

//

// You should have received a copy of the GNU General Public License

// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

 

/**

 * Listens for Instant Payment Notification from PayPal

 *

 * This script waits for Payment notification from PayPal,

 * then double checks that data by sending it back to PayPal.

 * If PayPal verifies this then it sets up the enrolment for that

 * user.

 *

 * @package    enrol

 * @subpackage paypal

 * @copyright 2010 Eugene Venter

 * @author     Eugene Venter - based on code by others

 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later

 */

 

 

require("../../config.php");

require_once("lib.php");

require_once($CFG->libdir.'/eventslib.php');

require_once($CFG->libdir.'/enrollib.php');

 

 

/// Keep out casual intruders

if (empty($_POST) or !empty($_GET)) {

    print_error("Sorry, you can not use the script that way.");

}

 

/// Read all the data from PayPal and get it ready for later;

/// we expect only valid UTF-8 encoding, it is the responsibility

/// of user to set it up properly in PayPal business account,

/// it is documented in docs wiki.

 

$req = 'cmd=_notify-validate';

 

$data = new stdClass();

 

foreach ($_POST as $key => $value) {

    $req .= "&$key=".urlencode($value);

    $data->$key = $value;

}

 

$custom = explode('-', $data->custom);

$data->userid           = (int)$custom[0];

$data->courseid         = (int)$custom[1];

$data->instanceid       = (int)$custom[2];

$data->payment_gross    = $data->mc_gross;

$data->payment_currency = $data->mc_currency;

$data->timeupdated      = time();

 

 

/// get the user and course records

 

if (! $user = $DB->get_record("user", array("id"=>$data->userid))) {

    message_paypal_error_to_admin("Not a valid user id", $data);

    die;

}

 

if (! $course = $DB->get_record("course", array("id"=>$data->courseid))) {

    message_paypal_error_to_admin("Not a valid course id", $data);

    die;

}

 

if (! $context = get_context_instance(CONTEXT_COURSE, $course->id)) {

    message_paypal_error_to_admin("Not a valid context id", $data);

    die;

}

 

if (! $plugin_instance = $DB->get_record("enrol", array("id"=>$data->instanceid, "status"=>0))) {

    message_paypal_error_to_admin("Not a valid instance id", $data);

    die;

}

 

$plugin = enrol_get_plugin('paypal');

 

/// Open a connection back to PayPal to validate the data

$header = '';

$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";

$header .= "Content-Type: application/x-www-form-urlencoded\r\n";

$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";

$paypaladdr = empty($CFG->usepaypalsandbox) ? 'www.paypal.com' : 'www.sandbox.paypal.com';

$fp = fsockopen ($paypaladdr, 80, $errno, $errstr, 30);

 

if (!$fp) {  /// Could not open a socket to PayPal - FAIL

    echo "<p>Error: could not access paypal.com</p>";

    message_paypal_error_to_admin("Could not access paypal.com to verify payment", $data);

    die;

}

 

/// Connection is OK, so now we post the data to validate it

 

fputs ($fp, $header.$req);

 

/// Now read the response and check if everything is OK.

 

while (!feof($fp)) {

    $result = fgets($fp, 1024);

    if (strcmp($result, "VERIFIED") == 0) {          // VALID PAYMENT!

 

 

        // check the payment_status and payment_reason

 

        // If status is not completed or pending then unenrol the student if already enrolled

        // and notify admin

 

        if ($data->payment_status != "Completed" and $data->payment_status != "Pending") {

            $plugin->unenrol_user($plugin_instance, $data->userid);

            message_paypal_error_to_admin("Status not completed or pending. User unenrolled from course", $data);

            die;

        }

 

        // If currency is incorrectly set then someone maybe trying to cheat the system

 

        if ($data->mc_currency != $plugin_instance->currency) {

            message_paypal_error_to_admin("Currency does not match course settings, received: ".$data->mc_currency, $data);

            die;

        }

 

        // If status is pending and reason is other than echeck then we are on hold until further notice

        // Email user to let them know. Email admin.

 

        if ($data->payment_status == "Pending" and $data->pending_reason != "echeck") {

            $eventdata = new stdClass();

            $eventdata->modulename        = 'moodle';

            $eventdata->component         = 'enrol_paypal';

            $eventdata->name              = 'paypal_enrolment';

            $eventdata->userfrom          = get_admin();

            $eventdata->userto            = $user;

            $eventdata->subject           = "Moodle: PayPal payment";

            $eventdata->fullmessage       = "Your PayPal payment is pending.";

            $eventdata->fullmessageformat = FORMAT_PLAIN;

            $eventdata->fullmessagehtml   = '';

            $eventdata->smallmessage      = '';

            message_send($eventdata);

 

            message_paypal_error_to_admin("Payment pending", $data);

            die;

        }

 

        // If our status is not completed or not pending on an echeck clearance then ignore and die

        // This check is redundant at present but may be useful if paypal extend the return codes in the future

 

        if (! ( $data->payment_status == "Completed" or

               ($data->payment_status == "Pending" and $data->pending_reason == "echeck") ) ) {

            die;

        }

 

        // At this point we only proceed with a status of completed or pending with a reason of echeck

 

 

 

        if ($existing = $DB->get_record("enrol_paypal", array("txn_id"=>$data->txn_id))) {   // Make sure this transaction doesn't exist already

            message_paypal_error_to_admin("Transaction $data->txn_id is being repeated!", $data);

            die;

 

        }

 

        if ($data->business != $plugin->get_config('paypalbusiness')) {   // Check that the email is the one we want it to be

            message_paypal_error_to_admin("Business email is {$data->business} (not ".

                    $plugin->get_config('paypalbusiness').")", $data);

            die;

 

        }

 

        if (!$user = $DB->get_record('user', array('id'=>$data->userid))) {   // Check that user exists

            message_paypal_error_to_admin("User $data->userid doesn't exist", $data);

            die;

        }

 

        if (!$course = $DB->get_record('course', array('id'=>$data->courseid))) { // Check that course exists

            message_paypal_error_to_admin("Course $data->courseid doesn't exist", $data);;

            die;

        }

 

        $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);

 

        // Check that amount paid is the correct amount

        if ( (float) $plugin_instance->cost <= 0 ) {

            $cost = (float) $plugin->get_config('cost');

        } else {

            $cost = (float) $plugin_instance->cost;

        }

 

        if ($data->payment_gross < $cost) {

            $cost = format_float($cost, 2);

            message_paypal_error_to_admin("Amount paid is not enough ($data->payment_gross < $cost))", $data);

            die;

 

        }

 

        // ALL CLEAR !

 

        $DB->insert_record("enrol_paypal", $data);

 

        if ($plugin_instance->enrolperiod) {

            $timestart = time();

            $timeend   = $timestart + $plugin_instance->enrolperiod;

        } else {

            $timestart = 0;

            $timeend   = 0;

        }

 

        // Enrol user

        $plugin->enrol_user($plugin_instance, $user->id, $plugin_instance->roleid, $timestart, $timeend);

 

        // Pass $view=true to filter hidden caps if the user cannot see them

        if ($users = get_users_by_capability($context, 'moodle/course:update', 'u.*', 'u.id ASC',

                                             '', '', '', '', false, true)) {

            $users = sort_by_roleassignment_authority($users, $context);

            $teacher = array_shift($users);

        } else {

            $teacher = false;

        }

 

        $mailstudents = $plugin->get_config('mailstudents');

        $mailteachers = $plugin->get_config('mailteachers');

        $mailadmins   = $plugin->get_config('mailadmins');

        $shortname = format_string($course->shortname, true, array('context' => $context));

 

 

        if (!empty($mailstudents)) {

            $a->coursename = format_string($course->fullname, true, array('context' => $coursecontext));

            $a->profileurl = "$CFG->wwwroot/user/view.php?id=$user->id";

 

            $eventdata = new stdClass();

            $eventdata->modulename        = 'moodle';

            $eventdata->component         = 'enrol_paypal';

            $eventdata->name              = 'paypal_enrolment';

            $eventdata->userfrom          = $teacher;

            $eventdata->userto            = $user;

            $eventdata->subject           = get_string("enrolmentnew", 'enrol', $shortname);

            $eventdata->fullmessage       = get_string('welcometocoursetext', '', $a);

            $eventdata->fullmessageformat = FORMAT_PLAIN;

            $eventdata->fullmessagehtml   = '';

            $eventdata->smallmessage      = '';

            message_send($eventdata);

 

        }

 

        if (!empty($mailteachers)) {

            $a->course = format_string($course->fullname, true, array('context' => $coursecontext));

            $a->user = fullname($user);

 

            $eventdata = new stdClass();

            $eventdata->modulename        = 'moodle';

            $eventdata->component         = 'enrol_paypal';

            $eventdata->name              = 'paypal_enrolment';

            $eventdata->userfrom          = $user;

            $eventdata->userto            = $teacher;

            $eventdata->subject           = get_string("enrolmentnew", 'enrol', $shortname);

            $eventdata->fullmessage       = get_string('enrolmentnewuser', 'enrol', $a);

            $eventdata->fullmessageformat = FORMAT_PLAIN;

            $eventdata->fullmessagehtml   = '';

            $eventdata->smallmessage      = '';

            message_send($eventdata);

        }

 

        if (!empty($mailadmins)) {

            $a->course = format_string($course->fullname, true, array('context' => $coursecontext));

            $a->user = fullname($user);

            $admins = get_admins();

            foreach ($admins as $admin) {

                $eventdata = new stdClass();

                $eventdata->modulename        = 'moodle';

                $eventdata->component         = 'enrol_paypal';

                $eventdata->name              = 'paypal_enrolment';

                $eventdata->userfrom          = $user;

                $eventdata->userto            = $admin;

                $eventdata->subject           = get_string("enrolmentnew", 'enrol', $shortname);

                $eventdata->fullmessage       = get_string('enrolmentnewuser', 'enrol', $a);

                $eventdata->fullmessageformat = FORMAT_PLAIN;

                $eventdata->fullmessagehtml   = '';

                $eventdata->smallmessage      = '';

                message_send($eventdata);

            }

        }

 

    } else if (strcmp ($result, "INVALID") == 0) { // ERROR

        $DB->insert_record("enrol_paypal", $data, false);

        message_paypal_error_to_admin("Received an invalid payment notification!! (Fake payment?)", $data);

    }

}

 

fclose($fp);

exit;

 

 

//--- HELPER FUNCTIONS --------------------------------------------------------------------------------------

 

 

function message_paypal_error_to_admin($subject, $data) {

    echo $subject;

    $admin = get_admin();

    $site = get_site();

 

    $message = "$site->fullname:  Transaction failed.\n\n$subject\n\n";

 

    foreach ($data as $key => $value) {

        $message .= "$key => $value\n";

    }

 

    $eventdata = new stdClass();

    $eventdata->modulename        = 'moodle';

    $eventdata->component         = 'enrol_paypal';

    $eventdata->name              = 'paypal_enrolment';

    $eventdata->userfrom          = $admin;

    $eventdata->userto            = $admin;

    $eventdata->subject           = "PAYPAL ERROR: ".$subject;

    $eventdata->fullmessage       = $message;

    $eventdata->fullmessageformat = FORMAT_PLAIN;

    $eventdata->fullmessagehtml   = '';

    $eventdata->smallmessage      = '';

    message_send($eventdata);

}

 

 

In reply to Alan Kmiecik

Re: HELP! Paypal not working in 2.3

by Alan Kmiecik -
  1. Changed enrol.html:

From:
<?php
$paypalurl = empty($CFG->usepaypalsandbox) ? 'https://www.paypal.com/cgi-bin/webscr' : 'https://www.sandbox.paypal.com/cgi-bin/webscr';
?>

To:
<?php
$paypalurl = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
?>

(did not work)

  1. Changed email of test student to match sandbox personal account

(did not work)

  1. Put in name for test paypal account to match name of student

(did not work)

  1. Replaced ipn.php with ipn-fixed.php from http://tracker.moodle.org/browse/MDL-30647

(did not work)

  1. Applied code change from this bug fix

(did not work)

In reply to Alan Kmiecik

Re: HELP! Paypal not working in 2.3

by Alan Kmiecik -

Sep 12th, 2012 = Gave up on Paypal in Moodle 2.3, simply does not work.  Went back to 2.2.  Also, instructions for Paypal in Moodle Docs is inaccurate.  They are good if you are going to tie the Paypal account to the Moodle instance and sell nothing else.

If you already have a Paypal account, and is has IPN enabled, all you need to do is enable Paypal in Moodle via Plugins - Enrolment - Manage Plugins (or something like that).  Once the eye is open, hit the settings and add the email address for the Paypal account.

In reply to Alan Kmiecik

Re: HELP! Paypal not working in 2.3

by David Lohmeyer -

Alan,

I had problems testing Paypal in 2.3 too.  The problem I was getting was due to my site being local/inaccessible from PayPal.  Once I visited and used my Moodle install on an actual live web address the enrollment went through.