$email, 'name' => $txt['who_member'], 'id' => 0, ); // We need to see whether we can find the correct payment gateway, we'll going to go through all our gateway scripts and find out if they are happy with what we have. $txnType = ''; $gatewayHandles = loadPaymentGateways(); foreach ($gatewayHandles as $gateway) { $gatewayClass = new $gateway['payment_class'](); if ($gatewayClass->isValid()) { $txnType = $gateway['code']; break; } } if (empty($txnType)) generateSubscriptionError($txt['paid_unknown_transaction_type']); // Get the subscription and member ID amoungst others... @list ($subscription_id, $member_id) = $gatewayClass->precheck(); // Integer these just in case. $subscription_id = (int) $subscription_id; $member_id = (int) $member_id; // This would be bad... if (empty($member_id)) generateSubscriptionError($txt['paid_empty_member']); // Verify the member. $request = $smcFunc['db_query']('', ' SELECT id_member, member_name, real_name, email_address FROM {db_prefix}members WHERE id_member = {int:current_member}', array( 'current_member' => $member_id, ) ); // Didn't find them? if ($smcFunc['db_num_rows']($request) == 0) generateSubscriptionError(sprintf($txt['paid_could_not_find_member'], $member_id)); $member_info = $smcFunc['db_fetch_assoc']($request); $smcFunc['db_free_result']($request); // Get the subscription details. $request = $smcFunc['db_query']('', ' SELECT cost, length, name FROM {db_prefix}subscriptions WHERE id_subscribe = {int:current_subscription}', array( 'current_subscription' => $subscription_id, ) ); // Didn't find it? if ($smcFunc['db_num_rows']($request) == 0) generateSubscriptionError(sprintf($txt['paid_count_not_find_subscription'], $member_id, $subscription_id)); $subscription_info = $smcFunc['db_fetch_assoc']($request); $smcFunc['db_free_result']($request); // We wish to check the pending payments to make sure we are expecting this. $request = $smcFunc['db_query']('', ' SELECT id_sublog, payments_pending, pending_details FROM {db_prefix}log_subscribed WHERE id_subscribe = {int:current_subscription} AND id_member = {int:current_member} LIMIT 1', array( 'current_subscription' => $subscription_id, 'current_member' => $member_id, ) ); if ($smcFunc['db_num_rows']($request) == 0) generateSubscriptionError(sprintf($txt['paid_count_not_find_subscription_log'], $member_id, $subscription_id)); $subscription_info += $smcFunc['db_fetch_assoc']($request); $smcFunc['db_free_result']($request); // Is this a refund etc? if ($gatewayClass->isRefund()) { // Delete user subscription. removeSubscription($subscription_id, $member_id); // Mark it as complete so we have a record. $smcFunc['db_query']('', ' UPDATE {db_prefix}log_subscribed SET end_time = {int:current_time} WHERE id_subscribe = {int:current_subscription} AND id_member = {int:current_member} AND status = {int:not_active}', array( 'current_time' => time(), 'current_subscription' => $subscription_id, 'current_member' => $member_id, 'not_active' => 0, ) ); // Receipt? if (!empty($modSettings['paid_email']) && $modSettings['paid_email'] == 2) { $replacements = array( 'NAME' => $subscription_info['name'], 'REFUNDNAME' => $member_info['member_name'], 'REFUNDUSER' => $member_info['real_name'], 'PROFILELINK' => $scripturl . '?action=profile;u=' . $member_id, 'DATE' => timeformat(time(), false), ); emailAdmins('paid_subscription_refund', $replacements, $notify_users); } } // Otherwise is it what we want, a purchase? elseif ($gatewayClass->isPayment() || $gatewayClass->isSubscription()) { $cost = unserialize($subscription_info['cost']); $total_cost = $gatewayClass->getCost(); $notify = false; // For one off's we want to only capture them once! if (!$gatewayClass->isSubscription()) { $real_details = @unserialize($subscription_info['pending_details']); if (empty($real_details)) generateSubscriptionError(sprintf($txt['paid_count_not_find_outstanding_payment'], $member_id, $subscription_id)); // Now we just try to find anything pending. We don't really care which it is as security happens later. foreach ($real_details as $id => $detail) { unset($real_details[$id]); if ($detail[3] == 'payback' && $subscription_info['payments_pending']) $subscription_info['payments_pending']--; break; } $subscription_info['pending_details'] = empty($real_details) ? '' : serialize($real_details); $smcFunc['db_query']('', ' UPDATE {db_prefix}log_subscribed SET payments_pending = {int:payments_pending}, pending_details = {string:pending_details} WHERE id_sublog = {int:current_subscription_item}', array( 'payments_pending' => $subscription_info['payments_pending'], 'current_subscription_item' => $subscription_info['id_sublog'], 'pending_details' => $subscription_info['pending_details'], ) ); } // Is this flexible? if ($subscription_info['length'] == 'F') { $found_duration = 0; // This is a little harder, can we find the right duration? foreach ($cost as $duration => $value) { if ($duration == 'fixed') continue; elseif ((float) $value == (float) $total_cost) $found_duration = strtoupper(substr($duration, 0, 1)); } // If we have the duration then we're done. if ($found_duration!== 0) { $notify = true; addSubscription($subscription_id, $member_id, $found_duration); } } else { $actual_cost = $cost['fixed']; // It must be at least the right amount. if ($total_cost != 0 && $total_cost >= $actual_cost) { // Add the subscription. $notify = true; addSubscription($subscription_id, $member_id); } } // Send a receipt? if (!empty($modSettings['paid_email']) && $modSettings['paid_email'] == 2 && $notify) { $replacements = array( 'NAME' => $subscription_info['name'], 'SUBNAME' => $member_info['member_name'], 'SUBUSER' => $member_info['real_name'], 'SUBEMAIL' => $member_info['email_address'], 'PRICE' => sprintf($modSettings['paid_currency_symbol'], $total_cost), 'PROFILELINK' => $scripturl . '?action=profile;u=' . $member_id, 'DATE' => timeformat(time(), false), ); emailAdmins('paid_subscription_new', $replacements, $notify_users); } } // In case we have anything specific to do. $gatewayClass->close(); // Log an error then die. function generateSubscriptionError($text) { global $modSettings, $notify_users; // Send an email? if (!empty($modSettings['paid_email'])) { $replacements = array( 'ERROR' => $text, ); emailAdmins('paid_subscription_error', $replacements, $notify_users); } // Then just log and die. log_error($text); exit; } ?>