improved documentation for wiki types
[moodle.git] / enrol / paypal / ipn.php
CommitLineData
04f47a89 1<?php // $Id$
2
3/**
4* Listens for Instant Payment Notification from Paypal
5*
6* This script waits for Payment notification from Paypal,
7* then double checks that data by sending it back to Paypal.
8* If Paypal verifies this then it sets up the enrolment for that
9*
10* Set the $user->timeaccess course array
11*
12* @param user referenced object, must contain $user->id already set
13*/
14
15
3d970777 16 require("../../config.php");
17 require("enrol.php");
18
04f47a89 19/// Keep out casual intruders
3d970777 20 if (empty($_POST) or !empty($_GET)) {
04f47a89 21 error("Sorry, you can not use the script that way.");
22 }
23
24/// Read all the data from Paypal and get it ready for later
25
26 $req = 'cmd=_notify-validate';
27
28 foreach ($_POST as $key => $value) {
29 $value = urlencode(stripslashes($value));
30 $req .= "&$key=$value";
3d970777 31 $data->$key = urldecode($value);
04f47a89 32 }
33
3d970777 34 $custom = explode('-', $data->custom);
35 $data->userid = $custom[0];
36 $data->courseid = $custom[1];
04f47a89 37 $data->payment_amount = $data->mc_gross;
38 $data->payment_currency = $data->mc_currency;
39
40
597342b0 41/// get the user and course records
42
43 if (! $user = get_record("user", "id", $data->userid) ) {
44 email_paypal_error_to_admin("Not a valid user id", $data);
45 die;
46 }
47
48 if (! $course = get_record("course", "id", $data->courseid) ) {
49 email_paypal_error_to_admin("Not a valid course id", $data);
50 die;
51 }
52
53
04f47a89 54/// Open a connection back to PayPal to validate the data
55
56 $header = '';
57 $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
58 $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
59 $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
60 $fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
61
62 if (!$fp) { /// Could not open a socket to Paypal - FAIL
63 echo "<p>Error: could not access paypal.com</p>";
64 email_paypal_error_to_admin("Could not access paypal.com to verify payment", $data);
65 die;
66 }
67
68/// Connection is OK, so now we post the data to validate it
69
70 fputs ($fp, $header.$req);
71
72/// Now read the response and check if everything is OK.
73
74 while (!feof($fp)) {
75 $result = fgets($fp, 1024);
76 if (strcmp($result, "VERIFIED") == 0) { // VALID PAYMENT!
77
04f47a89 78
597342b0 79 // check the payment_status and payment_reason
80
81 // If status is not completed or pending then unenrol the student if already enrolled
82 // and notify admin
83
84 if ($data->payment_status != "Completed" and $data->payment_status != "Pending") {
85 unenrol_student($data->userid, $data->courseid);
86 email_paypal_error_to_admin("Status not completed or pending. User unenrolled from course", $data);
04f47a89 87 die;
88 }
89
597342b0 90 // If status is pending and reason is other than echeck then we are on hold until further notice
91 // Email user to let them know. Email admin.
92
93 if ($data->payment_status == "Pending" and $data->pending_reason != "echeck") {
94 email_to_user($user, getadmin(), "Moodle: Paypal payment", "Your Paypal payment is pending.");
95 email_paypal_error_to_admin("Payment pending", $data);
96 die;
97 }
98
99 // If our status is not completed or not pending on an echeck clearance then ignore and die
100 // This check is redundant at present but may be useful if paypal extend the return codes in the future
101
102 if (! ( $data->payment_status == "Completed" or
103 ($data->payment_status == "Pending" and $data->pending_reason == "echeck") ) ) {
104 die;
105 }
106
107 // At this point we only proceed with a status of completed or pending with a reason of echeck
108
109
110
04f47a89 111 if ($existing = get_record("enrol_paypal", "txn_id", $data->txn_id)) { // Make sure this transaction doesn't exist already
3d970777 112 email_paypal_error_to_admin("Transaction $data->txn_id is being repeated!", $data);
113 die;
04f47a89 114
115 }
116
3d970777 117 if ($data->business != $CFG->enrol_paypalbusiness) { // Check that the email is the one we want it to be
118 email_paypal_error_to_admin("Business email is $data->business (not $CFG->enrol_paypalbusiness)", $data);
119 die;
04f47a89 120
121 }
122
123 if (!$user = get_record('user', 'id', $data->userid)) { // Check that user exists
124 email_paypal_error_to_admin("User $data->userid doesn't exist", $data);
3d970777 125 die;
04f47a89 126 }
127
631cba64 128 if (!$course = get_record('course', 'id', $data->courseid)) { // Check that course exists
3d970777 129 email_paypal_error_to_admin("Course $data->courseid doesn't exist", $data);;
130 die;
04f47a89 131 }
132
3d970777 133 // Check that amount paid is the correct amount
134 if ( (float) $course->cost < 0 ) {
135 $cost = (float) $CFG->enrol_cost;
136 } else {
137 $cost = (float) $course->cost;
138 }
139 $cost = format_float($cost, 2);
140
141 if ($data->payment_gross < $cost) {
142 email_paypal_error_to_admin("Amount paid is not enough ($data->payment_gross < $cost))", $data);
143 die;
04f47a89 144
145 }
146
147 // ALL CLEAR !
148
149 if (!insert_record("enrol_paypal", $data)) { // Insert a transaction record
150 email_paypal_error_to_admin("Error while trying to insert valid transaction", $data);
151 }
152
153 if (!enrol_student($user->id, $course->id)) { // Enrol the student
154 email_paypal_error_to_admin("Error while trying to enrol ".fullname($user)." in '$course->fullname'", $data);
3d970777 155 die;
04f47a89 156 } else {
70beecd4 157 $teacher = get_teacher($course->id);
158
159 if (!empty($CFG->enrol_paypalmailstudents)) {
160 $a->coursename = "$course->fullname";
631cba64 161 $a->profileurl = "$CFG->wwwroot/user/view.php?id=$user->id";
597342b0 162 email_to_user($user, $teacher, get_string("enrolmentnew", '', $course->shortname), get_string('welcometocoursetext', '', $a));
70beecd4 163 }
164
165 if (!empty($CFG->enrol_paypalmailteachers)) {
597342b0 166 email_to_user($teacher, $user, get_string("enrolmentnew", '', $course->shortname), "I have enrolled in your class via Paypal");
04f47a89 167 }
168 }
169
170
171 } else if (strcmp ($result, "INVALID") == 0) { // ERROR
172 insert_record("enrol_paypal", $data);
173 email_paypal_error_to_admin("Received an invalid payment notification!! (Fake payment?)", $data);
174 }
175 }
176
177 fclose($fp);
178 exit;
179
180
181
182/// FUNCTIONS //////////////////////////////////////////////////////////////////
183
184
185function email_paypal_error_to_admin($subject, $data) {
186 $admin = get_admin();
187 $site = get_admin();
188
189 $message = "$site->fullname: Transaction failed.\n\n$subject\n\n";
190
191 foreach ($data as $key => $value) {
192 $message .= "$key => $value\n";
193 }
194
195 email_to_user($admin, $admin, "PAYPAL ERROR: ".$subject, $message);
196
197}
198
199?>