Mercurial > hg > vamp-website
comparison forum/Sources/Subscriptions-PayPal.php @ 76:e3e11437ecea website
Add forum code
author | Chris Cannam |
---|---|
date | Sun, 07 Jul 2013 11:25:48 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
75:72f59aa7e503 | 76:e3e11437ecea |
---|---|
1 <?php | |
2 | |
3 /** | |
4 * Simple Machines Forum (SMF) | |
5 * | |
6 * @package SMF | |
7 * @author Simple Machines http://www.simplemachines.org | |
8 * @copyright 2011 Simple Machines | |
9 * @license http://www.simplemachines.org/about/smf/license.php BSD | |
10 * | |
11 * @version 2.0.3 | |
12 */ | |
13 | |
14 // This won't be dedicated without this - this must exist in each gateway! | |
15 // SMF Payment Gateway: paypal | |
16 | |
17 if (!defined('SMF')) | |
18 die('Hacking attempt...'); | |
19 | |
20 class paypal_display | |
21 { | |
22 public $title = 'PayPal'; | |
23 | |
24 public function getGatewaySettings() | |
25 { | |
26 global $txt; | |
27 | |
28 $setting_data = array( | |
29 array('text', 'paypal_email', 'subtext' => $txt['paypal_email_desc']), | |
30 ); | |
31 | |
32 return $setting_data; | |
33 } | |
34 | |
35 // Is this enabled for new payments? | |
36 public function gatewayEnabled() | |
37 { | |
38 global $modSettings; | |
39 | |
40 return !empty($modSettings['paypal_email']); | |
41 } | |
42 | |
43 // What do we want? | |
44 public function fetchGatewayFields($unique_id, $sub_data, $value, $period, $return_url) | |
45 { | |
46 global $modSettings, $txt, $boardurl; | |
47 | |
48 $return_data = array( | |
49 'form' => 'https://www.' . (!empty($modSettings['paidsubs_test']) ? 'sandbox.' : '') . 'paypal.com/cgi-bin/webscr', | |
50 'id' => 'paypal', | |
51 'hidden' => array(), | |
52 'title' => $txt['paypal'], | |
53 'desc' => $txt['paid_confirm_paypal'], | |
54 'submit' => $txt['paid_paypal_order'], | |
55 'javascript' => '', | |
56 ); | |
57 | |
58 // All the standard bits. | |
59 $return_data['hidden']['business'] = $modSettings['paypal_email']; | |
60 $return_data['hidden']['item_name'] = $sub_data['name'] . ' ' . $txt['subscription']; | |
61 $return_data['hidden']['item_number'] = $unique_id; | |
62 $return_data['hidden']['currency_code'] = strtoupper($modSettings['paid_currency_code']); | |
63 $return_data['hidden']['no_shipping'] = 1; | |
64 $return_data['hidden']['no_note'] = 1; | |
65 $return_data['hidden']['amount'] = $value; | |
66 $return_data['hidden']['cmd'] = !$sub_data['repeatable'] ? '_xclick' : '_xclick-subscriptions'; | |
67 $return_data['hidden']['return'] = $return_url; | |
68 $return_data['hidden']['a3'] = $value; | |
69 $return_data['hidden']['src'] = 1; | |
70 $return_data['hidden']['notify_url'] = $boardurl . '/subscriptions.php'; | |
71 | |
72 // Now stuff dependant on what we're doing. | |
73 if ($sub_data['flexible']) | |
74 { | |
75 $return_data['hidden']['p3'] = 1; | |
76 $return_data['hidden']['t3'] = strtoupper(substr($period, 0, 1)); | |
77 } | |
78 else | |
79 { | |
80 preg_match('~(\d*)(\w)~', $sub_data['real_length'], $match); | |
81 $unit = $match[1]; | |
82 $period = $match[2]; | |
83 | |
84 $return_data['hidden']['p3'] = $unit; | |
85 $return_data['hidden']['t3'] = $period; | |
86 } | |
87 | |
88 // If it's repeatable do soem javascript to respect this idea. | |
89 if (!empty($sub_data['repeatable'])) | |
90 $return_data['javascript'] = ' | |
91 document.write(\'<label for="do_paypal_recur"><input type="checkbox" name="do_paypal_recur" id="do_paypal_recur" checked="checked" onclick="switchPaypalRecur();" class="input_check" />' . $txt['paid_make_recurring'] . '</label><br />\'); | |
92 | |
93 function switchPaypalRecur() | |
94 { | |
95 document.getElementById("paypal_cmd").value = document.getElementById("do_paypal_recur").checked ? "_xclick-subscriptions" : "_xclick"; | |
96 }'; | |
97 | |
98 return $return_data; | |
99 } | |
100 } | |
101 | |
102 class paypal_payment | |
103 { | |
104 private $return_data; | |
105 | |
106 // This function returns true/false for whether this gateway thinks the data is intended for it. | |
107 public function isValid() | |
108 { | |
109 global $modSettings; | |
110 | |
111 // Has the user set up an email address? | |
112 if (empty($modSettings['paypal_email'])) | |
113 return false; | |
114 // Check the correct transaction types are even here. | |
115 if ((!isset($_POST['txn_type']) && !isset($_POST['payment_status'])) || (!isset($_POST['business']) && !isset($_POST['receiver_email']))) | |
116 return false; | |
117 // Correct email address? | |
118 if (!isset($_POST['business'])) | |
119 $_POST['business'] = $_POST['receiver_email']; | |
120 if ($modSettings['paypal_email'] != $_POST['business'] && (empty($modSettings['paypal_additional_emails']) || !in_array($_POST['business'], explode(',', $modSettings['paypal_additional_emails'])))) | |
121 return false; | |
122 return true; | |
123 } | |
124 | |
125 // Validate all the data was valid. | |
126 public function precheck() | |
127 { | |
128 global $modSettings, $txt; | |
129 | |
130 // Put this to some default value. | |
131 if (!isset($_POST['txn_type'])) | |
132 $_POST['txn_type'] = ''; | |
133 | |
134 // Build the request string - starting with the minimum requirement. | |
135 $requestString = 'cmd=_notify-validate'; | |
136 | |
137 // Now my dear, add all the posted bits. | |
138 foreach ($_POST as $k => $v) | |
139 $requestString .= '&' . $k . '=' . urlencode($v); | |
140 | |
141 // Can we use curl? | |
142 if (function_exists('curl_init') && $curl = curl_init((!empty($modSettings['paidsubs_test']) ? 'https://www.sandbox.' : 'http://www.') . 'paypal.com/cgi-bin/webscr')) | |
143 { | |
144 // Set the post data. | |
145 curl_setopt($curl, CURLOPT_POST, true); | |
146 curl_setopt($curl, CURLOPT_POSTFIELDSIZE, 0); | |
147 curl_setopt($curl, CURLOPT_POSTFIELDS, $requestString); | |
148 | |
149 curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); | |
150 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1); | |
151 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); | |
152 curl_setopt($curl, CURLOPT_FORBID_REUSE, 1); | |
153 curl_setopt($curl, CURLOPT_HTTPHEADER, array( | |
154 'Host: www.' . (!empty($modSettings['paidsubs_test']) ? 'sandbox.' : '') . 'paypal.com', | |
155 'Connection: close' | |
156 )); | |
157 | |
158 // Fetch the data returned as a string. | |
159 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); | |
160 | |
161 // Fetch the data. | |
162 $this->return_data = curl_exec($curl); | |
163 | |
164 // Close the session. | |
165 curl_close($curl); | |
166 } | |
167 // Otherwise good old HTTP. | |
168 else | |
169 { | |
170 // Setup the headers. | |
171 $header = 'POST /cgi-bin/webscr HTTP/1.1' . "\r\n"; | |
172 $header .= 'Content-Type: application/x-www-form-urlencoded' . "\r\n"; | |
173 $header .= 'Host: www.' . (!empty($modSettings['paidsubs_test']) ? 'sandbox.' : '') . 'paypal.com' . "\r\n"; | |
174 $header .= 'Content-Length: ' . strlen ($requestString) . "\r\n"; | |
175 $header .= 'Connection: close' . "\r\n\r\n"; | |
176 | |
177 // Open the connection. | |
178 if (!empty($modSettings['paidsubs_test'])) | |
179 $fp = fsockopen('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30); | |
180 else | |
181 $fp = fsockopen('www.paypal.com', 80, $errno, $errstr, 30); | |
182 | |
183 // Did it work? | |
184 if (!$fp) | |
185 generateSubscriptionError($txt['paypal_could_not_connect']); | |
186 | |
187 // Put the data to the port. | |
188 fputs($fp, $header . $requestString); | |
189 | |
190 // Get the data back... | |
191 while (!feof($fp)) | |
192 { | |
193 $this->return_data = fgets($fp, 1024); | |
194 if (strcmp(trim($this->return_data), 'VERIFIED') == 0) | |
195 break; | |
196 } | |
197 | |
198 // Clean up. | |
199 fclose($fp); | |
200 } | |
201 | |
202 // If this isn't verified then give up... | |
203 // !! This contained a comment "send an email", but we don't appear to send any? | |
204 if (strcmp(trim($this->return_data), 'VERIFIED') != 0) | |
205 exit; | |
206 | |
207 // Check that this is intended for us. | |
208 if ($modSettings['paypal_email'] != $_POST['business'] && (empty($modSettings['paypal_additional_emails']) || !in_array($_POST['business'], explode(',', $modSettings['paypal_additional_emails'])))) | |
209 exit; | |
210 | |
211 // Is this a subscription - and if so it's it a secondary payment that we need to process? | |
212 if ($this->isSubscription() && (empty($_POST['item_number']) || strpos($_POST['item_number'], '+') === false)) | |
213 // Calculate the subscription it relates to! | |
214 $this->_findSubscription(); | |
215 | |
216 // Verify the currency! | |
217 if (strtolower($_POST['mc_currency']) != $modSettings['paid_currency_code']) | |
218 exit; | |
219 | |
220 // Can't exist if it doesn't contain anything. | |
221 if (empty($_POST['item_number'])) | |
222 exit; | |
223 | |
224 // Return the id_sub and id_member | |
225 return explode('+', $_POST['item_number']); | |
226 } | |
227 | |
228 // Is this a refund? | |
229 public function isRefund() | |
230 { | |
231 if ($_POST['payment_status'] == 'Refunded' || $_POST['payment_status'] == 'Reversed' || $_POST['txn_type'] == 'Refunded' || ($_POST['txn_type'] == 'reversal' && $_POST['payment_status'] == 'Completed')) | |
232 return true; | |
233 else | |
234 return false; | |
235 } | |
236 | |
237 // Is this a subscription? | |
238 public function isSubscription() | |
239 { | |
240 if (substr($_POST['txn_type'], 0, 14) == 'subscr_payment' && $_POST['payment_status'] == 'Completed') | |
241 return true; | |
242 else | |
243 return false; | |
244 } | |
245 | |
246 // Is this a normal payment? | |
247 public function isPayment() | |
248 { | |
249 if ($_POST['payment_status'] == 'Completed' && $_POST['txn_type'] == 'web_accept') | |
250 return true; | |
251 else | |
252 return false; | |
253 } | |
254 | |
255 // How much was paid? | |
256 public function getCost() | |
257 { | |
258 return (isset($_POST['tax']) ? $_POST['tax'] : 0) + $_POST['mc_gross']; | |
259 } | |
260 | |
261 // exit. | |
262 public function close() | |
263 { | |
264 global $smcFunc, $subscription_id; | |
265 | |
266 // If it's a subscription record the reference. | |
267 if ($_POST['txn_type'] == 'subscr_payment' && !empty($_POST['subscr_id'])) | |
268 { | |
269 $_POST['subscr_id'] = $_POST['subscr_id']; | |
270 $smcFunc['db_query']('', ' | |
271 UPDATE {db_prefix}log_subscribed | |
272 SET vendor_ref = {string:vendor_ref} | |
273 WHERE id_sublog = {int:current_subscription}', | |
274 array( | |
275 'current_subscription' => $subscription_id, | |
276 'vendor_ref' => $_POST['subscr_id'], | |
277 ) | |
278 ); | |
279 } | |
280 | |
281 exit(); | |
282 } | |
283 | |
284 // A private function to find out the subscription details. | |
285 private function _findSubscription() | |
286 { | |
287 global $smcFunc; | |
288 | |
289 // Assume we have this? | |
290 if (empty($_POST['subscr_id'])) | |
291 return false; | |
292 | |
293 // Do we have this in the database? | |
294 $request = $smcFunc['db_query']('', ' | |
295 SELECT id_member, id_subscribe | |
296 FROM {db_prefix}log_subscribed | |
297 WHERE vendor_ref = {string:vendor_ref} | |
298 LIMIT 1', | |
299 array( | |
300 'vendor_ref' => $_POST['subscr_id'], | |
301 ) | |
302 ); | |
303 // No joy? | |
304 if ($smcFunc['db_num_rows']($request) == 0) | |
305 { | |
306 // Can we identify them by email? | |
307 if (!empty($_POST['payer_email'])) | |
308 { | |
309 $smcFunc['db_free_result']($request); | |
310 $request = $smcFunc['db_query']('', ' | |
311 SELECT ls.id_member, ls.id_subscribe | |
312 FROM {db_prefix}log_subscribed AS ls | |
313 INNER JOIN {db_prefix}members AS mem ON (mem.id_member = ls.id_member) | |
314 WHERE mem.email_address = {string:payer_email} | |
315 LIMIT 1', | |
316 array( | |
317 'payer_email' => $_POST['payer_email'], | |
318 ) | |
319 ); | |
320 if ($smcFunc['db_num_rows']($request) == 0) | |
321 return false; | |
322 } | |
323 else | |
324 return false; | |
325 } | |
326 list ($member_id, $subscription_id) = $smcFunc['db_fetch_row']($request); | |
327 $_POST['item_number'] = $member_id . '+' . $subscription_id; | |
328 $smcFunc['db_free_result']($request); | |
329 } | |
330 } | |
331 | |
332 ?> |