comparison forum/subscriptions.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.2
12 */
13
14 /*
15 This file is the file which all subscription gateways should call
16 when a payment has been received - it sorts out the user status.
17
18 void generateSubscriptionError()
19 // log the error for posterity
20 */
21
22 // Start things rolling by getting SMF alive...
23 $ssi_guest_access = true;
24 if (!file_exists(dirname(__FILE__) . '/SSI.php'))
25 die('Cannot find SSI.php');
26
27 require_once(dirname(__FILE__) . '/SSI.php');
28 require_once($sourcedir . '/ManagePaid.php');
29
30 // For any admin emailing.
31 require_once($sourcedir . '/Subs-Admin.php');
32
33 loadLanguage('ManagePaid');
34
35 // If there's literally nothing coming in, let's take flight!
36 if (empty($_POST))
37 die($txt['paid_no_data']);
38
39 // I assume we're even active?
40 if (empty($modSettings['paid_enabled']))
41 exit;
42
43 // If we have some custom people who find out about problems load them here.
44 $notify_users = array();
45 if (!empty($modSettings['paid_email_to']))
46 foreach (explode(',', $modSettings['paid_email_to']) as $email)
47 $notify_users[] = array(
48 'email' => $email,
49 'name' => $txt['who_member'],
50 'id' => 0,
51 );
52
53 // We need to see whether we can find the correct payment gateway,
54 // we'll going to go through all our gateway scripts and find out
55 // if they are happy with what we have.
56 $txnType = '';
57 $gatewayHandles = loadPaymentGateways();
58 foreach ($gatewayHandles as $gateway)
59 {
60 $gatewayClass = new $gateway['payment_class']();
61 if ($gatewayClass->isValid())
62 {
63 $txnType = $gateway['code'];
64 break;
65 }
66 }
67
68 if (empty($txnType))
69 generateSubscriptionError($txt['paid_unknown_transaction_type']);
70
71 // Get the subscription and member ID amoungst others...
72 @list ($subscription_id, $member_id) = $gatewayClass->precheck();
73
74 // Integer these just in case.
75 $subscription_id = (int) $subscription_id;
76 $member_id = (int) $member_id;
77
78 // This would be bad...
79 if (empty($member_id))
80 generateSubscriptionError($txt['paid_empty_member']);
81
82 // Verify the member.
83 $request = $smcFunc['db_query']('', '
84 SELECT id_member, member_name, real_name, email_address
85 FROM {db_prefix}members
86 WHERE id_member = {int:current_member}',
87 array(
88 'current_member' => $member_id,
89 )
90 );
91 // Didn't find them?
92 if ($smcFunc['db_num_rows']($request) == 0)
93 generateSubscriptionError(sprintf($txt['paid_could_not_find_member'], $member_id));
94 $member_info = $smcFunc['db_fetch_assoc']($request);
95 $smcFunc['db_free_result']($request);
96
97 // Get the subscription details.
98 $request = $smcFunc['db_query']('', '
99 SELECT cost, length, name
100 FROM {db_prefix}subscriptions
101 WHERE id_subscribe = {int:current_subscription}',
102 array(
103 'current_subscription' => $subscription_id,
104 )
105 );
106
107 // Didn't find it?
108 if ($smcFunc['db_num_rows']($request) == 0)
109 generateSubscriptionError(sprintf($txt['paid_count_not_find_subscription'], $member_id, $subscription_id));
110
111 $subscription_info = $smcFunc['db_fetch_assoc']($request);
112 $smcFunc['db_free_result']($request);
113
114 // We wish to check the pending payments to make sure we are expecting this.
115 $request = $smcFunc['db_query']('', '
116 SELECT id_sublog, payments_pending, pending_details, end_time
117 FROM {db_prefix}log_subscribed
118 WHERE id_subscribe = {int:current_subscription}
119 AND id_member = {int:current_member}
120 LIMIT 1',
121 array(
122 'current_subscription' => $subscription_id,
123 'current_member' => $member_id,
124 )
125 );
126 if ($smcFunc['db_num_rows']($request) == 0)
127 generateSubscriptionError(sprintf($txt['paid_count_not_find_subscription_log'], $member_id, $subscription_id));
128 $subscription_info += $smcFunc['db_fetch_assoc']($request);
129 $smcFunc['db_free_result']($request);
130
131 // Is this a refund etc?
132 if ($gatewayClass->isRefund())
133 {
134 // If the end time subtracted by current time, is not greater
135 // than the duration (ie length of subscription), then we close it.
136 if ($subscription_info['end_time'] - time() < $subscription_info['length'])
137 {
138 // Delete user subscription.
139 removeSubscription($subscription_id, $member_id);
140 $subscription_act = time();
141 $status = 0;
142 }
143 else
144 {
145 loadSubscriptions();
146 $subscription_act = $subscription_info['end_time'] - $context['subscriptions'][$subscription_id]['num_length'];
147 $status = 1;
148 }
149
150 // Mark it as complete so we have a record.
151 $smcFunc['db_query']('', '
152 UPDATE {db_prefix}log_subscribed
153 SET end_time = {int:current_time}
154 WHERE id_subscribe = {int:current_subscription}
155 AND id_member = {int:current_member}
156 AND status = {int:status}',
157 array(
158 'current_time' => $subscription_act,
159 'current_subscription' => $subscription_id,
160 'current_member' => $member_id,
161 'status' => $status,
162 )
163 );
164
165 // Receipt?
166 if (!empty($modSettings['paid_email']) && $modSettings['paid_email'] == 2)
167 {
168 $replacements = array(
169 'NAME' => $subscription_info['name'],
170 'REFUNDNAME' => $member_info['member_name'],
171 'REFUNDUSER' => $member_info['real_name'],
172 'PROFILELINK' => $scripturl . '?action=profile;u=' . $member_id,
173 'DATE' => timeformat(time(), false),
174 );
175
176 emailAdmins('paid_subscription_refund', $replacements, $notify_users);
177 }
178
179 }
180 // Otherwise is it what we want, a purchase?
181 elseif ($gatewayClass->isPayment() || $gatewayClass->isSubscription())
182 {
183 $cost = unserialize($subscription_info['cost']);
184 $total_cost = $gatewayClass->getCost();
185 $notify = false;
186
187 // For one off's we want to only capture them once!
188 if (!$gatewayClass->isSubscription())
189 {
190 $real_details = @unserialize($subscription_info['pending_details']);
191 if (empty($real_details))
192 generateSubscriptionError(sprintf($txt['paid_count_not_find_outstanding_payment'], $member_id, $subscription_id));
193 // Now we just try to find anything pending.
194 // We don't really care which it is as security happens later.
195 foreach ($real_details as $id => $detail)
196 {
197 unset($real_details[$id]);
198 if ($detail[3] == 'payback' && $subscription_info['payments_pending'])
199 $subscription_info['payments_pending']--;
200 break;
201 }
202 $subscription_info['pending_details'] = empty($real_details) ? '' : serialize($real_details);
203
204 $smcFunc['db_query']('', '
205 UPDATE {db_prefix}log_subscribed
206 SET payments_pending = {int:payments_pending}, pending_details = {string:pending_details}
207 WHERE id_sublog = {int:current_subscription_item}',
208 array(
209 'payments_pending' => $subscription_info['payments_pending'],
210 'current_subscription_item' => $subscription_info['id_sublog'],
211 'pending_details' => $subscription_info['pending_details'],
212 )
213 );
214 }
215
216 // Is this flexible?
217 if ($subscription_info['length'] == 'F')
218 {
219 $found_duration = 0;
220 // This is a little harder, can we find the right duration?
221 foreach ($cost as $duration => $value)
222 {
223 if ($duration == 'fixed')
224 continue;
225 elseif ((float) $value == (float) $total_cost)
226 $found_duration = strtoupper(substr($duration, 0, 1));
227 }
228
229 // If we have the duration then we're done.
230 if ($found_duration!== 0)
231 {
232 $notify = true;
233 addSubscription($subscription_id, $member_id, $found_duration);
234 }
235 }
236 else
237 {
238 $actual_cost = $cost['fixed'];
239 // It must be at least the right amount.
240 if ($total_cost != 0 && $total_cost >= $actual_cost)
241 {
242 // Add the subscription.
243 $notify = true;
244 addSubscription($subscription_id, $member_id);
245 }
246 }
247
248 // Send a receipt?
249 if (!empty($modSettings['paid_email']) && $modSettings['paid_email'] == 2 && $notify)
250 {
251 $replacements = array(
252 'NAME' => $subscription_info['name'],
253 'SUBNAME' => $member_info['member_name'],
254 'SUBUSER' => $member_info['real_name'],
255 'SUBEMAIL' => $member_info['email_address'],
256 'PRICE' => sprintf($modSettings['paid_currency_symbol'], $total_cost),
257 'PROFILELINK' => $scripturl . '?action=profile;u=' . $member_id,
258 'DATE' => timeformat(time(), false),
259 );
260
261 emailAdmins('paid_subscription_new', $replacements, $notify_users);
262 }
263 }
264
265 // In case we have anything specific to do.
266 $gatewayClass->close();
267
268 // Log an error then die.
269 function generateSubscriptionError($text)
270 {
271 global $modSettings, $notify_users, $smcFunc;
272
273 // Send an email?
274 if (!empty($modSettings['paid_email']))
275 {
276 $replacements = array(
277 'ERROR' => $text,
278 );
279
280 emailAdmins('paid_subscription_error', $replacements, $notify_users);
281 }
282
283 // Maybe we can try to give them the post data?
284 if (!empty($_POST))
285 foreach ($_POST as $key => $val)
286 $text .= '<br />' . $smcFunc['htmlspecialchars']($key) . ': ' . $smcFunc['htmlspecialchars']($val);
287
288 // Then just log and die.
289 log_error($text);
290
291 exit;
292 }
293
294 ?>