/**	
 * Starts transaction process for specified transaction
 * 
 * @param int $localTranID				- starting transaction database ID
 * @param bool $recurring				- indicates whether transaction recurring or not
 * @param int $recurringDays			- if $recurring true, then this value specifies
 * 										  subscription days
 * 
 * @return bool 						- true if start is successful, false otherwise
 * 
 * 
 */
function moduleStartTransaction($localTranID, $recurring = false, $recurringDays = 0)
{
    global $providerConf;
    global $checkoutURL;
    global $memberID;
    // defined in checkout.inc.php
    global $cryptKey;
    global $currency_code;
    global $prof;
    global $date_format;
    // validate arguments
    $localTranID = (int) $localTranID;
    $recurringDays = (int) $recurringDays;
    $tranRes = db_res("SELECT DATE_FORMAT(`Date`,  '{$date_format}' ) AS 'Date', `Amount`, `Currency`, `Status`, `Data`, `Description` FROM `Transactions`\r\n\t\t\t\t\t\t\tWHERE `ID` = {$localTranID}\r\n\t\t\t\t\t\t\tAND `Status` = 'pending'\r\n\t\t\t\t\t\t\tAND `IDProvider` = {$providerConf['ID']}");
    if (!$tranRes || mysql_num_rows($tranRes) == 0) {
        return false;
    }
    $tranArr = mysql_fetch_assoc($tranRes);
    $tranData = transStringToData($tranArr['Data']);
    $actionURL = 'https://www.2checkout.com/2co/buyer/purchase';
    $formData = array();
    // account ID
    $formData['sid'] = $providerConf['Param_sid'];
    // transaction common data
    $formData['cart_order_id'] = $localTranID;
    $formData['total'] = sprintf("%.2f", (double) $tranArr['Amount']);
    $formData['tran_description'] = $tranArr['Description'];
    $formData['pay_method'] = $providerConf['Param_pay_method'];
    $formData['fixed'] = 'Y';
    // return and redirect
    $returnURL = returnURLByAction($tranData['action'], $tranData['data']);
    $formData['return_url'] = $returnURL;
    // test mode
    if ($providerConf['Mode'] != 'live') {
        $formData['demo'] = 'Y';
    }
    Redirect($actionURL, $formData, 'post', $providerConf['Caption']);
    exit;
}
/**
 * start checkout process
 */
function StartCheckout(&$errorMessage)
{
    global $dir;
    global $memberID;
    // defined in checkout.inc.php
    global $collectDataArr;
    global $enable_recurring;
    global $en_credits;
    global $credit2money;
    // these globals for module require call
    global $site;
    global $providerConf;
    global $checkoutFilename;
    global $checkoutURL;
    global $debugFilename;
    // if buy for credits
    if ($_REQUEST['use_credits'] == 'on' && $en_credits) {
        $amount = sprintf('%.2f', (double) $collectDataArr['amount']);
        $creditsAmount = sprintf("%.2f", (double) ($collectDataArr['amount'] * $credit2money));
        $creditBalance = getProfileCredits($memberID);
        $result = 0;
        if ($collectDataArr['checkout_action'] == 'credits') {
            $errorMessage = 'Credits couldn\'t be bought by credits';
            return false;
        }
        if ($creditBalance < $creditsAmount) {
            $result = 1000;
        } else {
            $purchaseRes = performPurchase($memberID, $collectDataArr['checkout_action'], $collectDataArr['data'], $amount, $result);
            if ($purchaseRes) {
                decProfileCredits($memberID, $creditsAmount);
                $result = 1;
            } else {
                $result = -1;
            }
        }
        $returnURL = returnURLByAction($collectDataArr['checkout_action'], $collectDataArr['data']);
        processValidationResult($result, $errorMessage, 0, $returnURL);
    } else {
        $providerID = (int) $_REQUEST['prov_id'];
        $providerRes = db_res("SELECT `Name`, `CheckoutFilename` FROM `PaymentProviders` WHERE `ID` = {$providerID} AND `Active`");
        if (!$providerRes || mysql_num_rows($providerRes) == 0) {
            $errorMessage = 'Wrong payment provider specified';
            return false;
        }
        $providerArr = mysql_fetch_assoc($providerRes);
        if (strlen(trim($providerArr['CheckoutFilename']))) {
            $checkoutFilename = $providerArr['CheckoutFilename'];
        } else {
            $checkoutFilename = $dir['checkout'] . $providerArr['Name'] . '.php';
        }
        if (!file_exists($checkoutFilename)) {
            $errorMessage = 'Checkout file not found';
            return false;
        }
        require_once $checkoutFilename;
        $validateRes = moduleValidateConfiguration($errorMessage);
        if (!$validateRes) {
            return false;
        }
        $localTranID = initiateTransaction($collectDataArr, $memberID, $providerID);
        if ($localTranID === false) {
            $errorMessage = 'Transaction initiating error';
            return false;
        }
        $subscriptionalPayment = $enable_recurring && $collectDataArr['allow_subscribe'] == 'on' && $_REQUEST['prov_recurring'] == 'on';
        if ($subscriptionalPayment) {
            $subsRes = initiateSubscription($localTranID, $collectDataArr['subscribe_days']);
            if (!$subsRes) {
                $errorMessage = 'Subscription initiating error';
                return false;
            }
        }
        $startRes = moduleStartTransaction($localTranID, $subscriptionalPayment, $collectDataArr['subscribe_days']);
        if (!$startRes) {
            $errorMessage = 'Transaction starting error';
            return false;
        }
    }
    return true;
}
/**
 * Performs appropriate action for payment result
 *
 * If database transaction ID specified and it is possible to determine return URL
 * then it posts result to return page. Otherwise it just shows error message.
 *
 * @param int $result					- payment result
 * 		-1 - fraud attempt
 * 		 0 - transaction declined or not completed
 * 		 1 - transaction successful
 * 		 2 - internal error
 * @param string $errorMessage			- error message which was
 * @param int $localTranID				- transaction ID
 *
 *
 */
function processValidationResult($result, $errorMessage, $localTranID = 0, $returnURL = '')
{
    global $site;
    // arguments validation
    $result = (int) $result;
    $localTranID = (int) $localTranID;
    $formData = array('result' => $result);
    if ($localTranID) {
        $tranRes = db_res("SELECT `Data` FROM `Transactions`\r\n\t\t\t\t\t\t\t\tWHERE `ID` = {$localTranID}");
        if ($tranRes && mysql_num_rows($tranRes) > 0) {
            $tranArr = mysql_fetch_assoc($tranRes);
            $tranData = transStringToData($tranArr['Data']);
            $returnURL = returnURLByAction($tranData['action'], $tranData['data']);
        }
    }
    switch ($result) {
        case -1:
            reportFraudAttempt($errorMessage);
            if (strlen($returnURL)) {
                Redirect($returnURL, $formData, 'post');
            } else {
                PrintErrorPage(_t('_RESULT-1'));
            }
            break;
        case 0:
            if (strlen($returnURL)) {
                Redirect($returnURL, $formData, 'post');
            } else {
                PrintErrorPage(_t('_RESULT0'));
            }
            break;
        case 1:
            if (strlen($returnURL)) {
                Redirect($returnURL, $formData, 'post');
            } else {
                Redirect($site['url'] . 'member.php', $formData, 'post');
            }
            break;
        case 2:
            PrintErrorPage('Internal error occured: ' . $errorMessage);
            break;
        case 1000:
            if (strlen($returnURL)) {
                Redirect($returnURL, $formData, 'post');
            } else {
                PrintErrorPage(_t('_RESULT1000'));
            }
            break;
    }
}
/**	
 * Starts transaction process for specified transaction
 * 
 * @param int $localTranID				- starting transaction database ID
 * @param bool $recurring				- indicates whether transaction recurring or not
 * @param int $recurringDays			- if $recurring true, then this value specifies
 * 										  subscription days
 * 
 * @return bool 						- true if start is successful, false otherwise
 * 
 * 
 */
function moduleStartTransaction($localTranID, $recurring = false, $recurringDays = 0)
{
    global $providerConf;
    global $checkoutURL;
    global $memberID;
    // defined in checkout.inc.php
    global $cryptKey;
    global $currency_code;
    global $enable_recurring;
    global $date_format;
    // validate arguments
    $localTranID = (int) $localTranID;
    $recurringDays = (int) $recurringDays;
    $tranRes = db_res("SELECT DATE_FORMAT(`Date`,  '{$date_format}' ) AS 'Date', `Amount`, `Currency`, `Status`, `Data`, `Description` FROM `Transactions`\r\n\t\t\t\t\t\t\tWHERE `ID` = {$localTranID}\r\n\t\t\t\t\t\t\tAND `Status` = 'pending'\r\n\t\t\t\t\t\t\tAND `IDProvider` = {$providerConf['ID']}");
    if (!$tranRes || mysql_num_rows($tranRes) == 0) {
        return false;
    }
    $tranArr = mysql_fetch_assoc($tranRes);
    $tranData = transStringToData($tranArr['Data']);
    if ($providerConf['Mode'] != 'live') {
        $actionURL = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
    } else {
        $actionURL = 'https://www.paypal.com/cgi-bin/webscr';
    }
    $formData = array();
    // command and recurring parameters
    if ($recurring) {
        $formData['cmd'] = '_xclick-subscriptions';
        $formData['a3'] = sprintf("%.2f", (double) $tranArr['Amount']);
        $formData['p3'] = $recurringDays;
        $formData['t3'] = 'D';
        $formData['src'] = '1';
        // repeat billings unles member cancels subscription
        $formData['sra'] = '1';
        // reattempt on failure
    } else {
        $formData['cmd'] = '_xclick';
        $formData['amount'] = sprintf("%.2f", (double) $tranArr['Amount']);
    }
    // business (merchant ID)
    if ($providerConf['Mode'] != 'live') {
        $formData['business'] = $providerConf['Param_test_business'];
    } else {
        $formData['business'] = $providerConf['Param_business'];
    }
    // transaction common data
    $formData['item_name'] = $tranArr['Description'];
    $formData['item_number'] = $localTranID;
    $formData['currency_code'] = $currency_code;
    $formData['no_note'] = $providerConf['Param_no_note'] ? '1' : '0';
    $formData['no_shipping'] = '1';
    $formData['custom'] = md5($tranArr['Date'] . $tranArr['Data'] . $cryptKey);
    // return and redirect
    switch ($providerConf['Param_process_type']) {
        case 'Direct':
            $formData['return'] = $checkoutURL;
            $formData['rm'] = '2';
            break;
        case 'IPN':
            $returnURL = returnURLByAction($tranData['action'], $tranData['data']);
            $formData['return'] = $returnURL;
            $formData['notify_url'] = $checkoutURL;
            $formData['rm'] = '1';
            break;
        case 'PDT':
            $formData['return'] = $checkoutURL;
            $formData['rm'] = '2';
            break;
    }
    Redirect($actionURL, $formData, 'post', $providerConf['Caption']);
    exit;
}