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