<?php
/*
  $Id: paypal.php,v 1.4 2004/11/22 08:53:25 shidairiki Exp $
  modified by gregbaboolal@yahoo.com 2003/12/31

  osCommerce, Open Source E-Commerce Solutions
  http://www.oscommerce.com

  Copyright (c) 2003 osCommerce

  Released under the GNU General Public License
*/

  class paypal {
    var $code, $title, $description, $enabled;

// class constructor
    function paypal() {
      global $order;

      $this->code = 'paypal';
      $this->title = MODULE_PAYMENT_PAYPAL_TEXT_TITLE;
      $this->description = MODULE_PAYMENT_PAYPAL_TEXT_DESCRIPTION;
      $this->sort_order = MODULE_PAYMENT_PAYPAL_SORT_ORDER;
      $this->enabled = ((MODULE_PAYMENT_PAYPAL_STATUS == 'True') ? true : false);

      if ((int)MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID > 0) {
        $this->order_status = MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID;
      }

      if (is_object($order)) $this->update_status();

      $this->form_action_url = 'https://www.paypal.com/cgi-bin/webscr';
    }

// class methods
    function update_status() {
      global $order, $db;

      if ( ($this->enabled == true) && ((int)MODULE_PAYMENT_PAYPAL_ZONE > 0) ) {
        $check_flag = false;
        $check_query = $db->Execute("select zone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . MODULE_PAYMENT_PAYPAL_ZONE . "' and zone_country_id = '" . $order->billing['country']['id'] . "' order by zone_id");
        while (!$check_query->EOF) {
          if ($check_query->fields['zone_id'] < 1) {
            $check_flag = true;
            break;
          } elseif ($check_query->fields['zone_id'] == $order->billing['zone_id']) {
            $check_flag = true;
            break;
          }
		  $check_query->MoveNext();
        }

        if ($check_flag == false) {
          $this->enabled = false;
        }
      }
    }

    function javascript_validation() {
      return false;
    }

    function selection() {
      return array('id' => $this->code,
                   'module' => $this->title);
    }

    function pre_confirmation_check() {
      return false;
    }

    function confirmation() {
      return false;
    }

    function process_button() {
      global $order, $currencies, $currency;

      if (MODULE_PAYMENT_PAYPAL_CURRENCY == 'Selected Currency') {
        $my_currency = $_SESSION['currency'];
      } else {
        $my_currency = substr(MODULE_PAYMENT_PAYPAL_CURRENCY, 5);
      }
      if (!in_array($my_currency, array('CAD', 'EUR', 'GBP', 'JPY', 'USD'))) {
        $my_currency = 'USD';
      }
      return $this->_getPayPalFields($order, $currencies,$my_currency);
    }

    function before_process() {
      global $order, $ipn;
      include_once(DIR_WS_CLASSES.'paypal/ipn.class.php');

      if( !MODULE_PAYMENT_PAYPAL_IPN_AUTO_RETURN ) {
        $ipn = new paypal_ipn(MODULE_PAYMENT_PAYPAL_IPN_DEBUG_EMAIL,$_POST,zen_session_name(),MODULE_PAYMENT_PAYPAL_IPN_DEBUG);
      }

      //post back to PayPal to validate
      if( !MODULE_PAYMENT_PAYPAL_IPN_AUTO_RETURN && $ipn->authenticate('www.paypal.com') ) {
        //check to see whether the txn_id already exists
        if(!$ipn->unique_txn_id()) {
          //txn_id has already been stored, so reset shopping cart session
          $_SESSION['cart']->reset(true);
          if (is_object($GLOBALS['cart'])) $GLOBALS['cart']->reset(true);
          // unregister session variables used during checkout
          unset($_SESSION['sendto']);
          unset($_SESSION['billto']);
          unset($_SESSION['shipping']);
          unset($_SESSION['payment']);
          unset($_SESSION['comments']);
          zen_redirect(zen_href_link(FILENAME_CHECKOUT_SUCCESS, 'paypal=authorized', 'SSL'));
        } else {
          //PayPal hasn't notified us yet but the customer is here, so continue the transaction.
          //Really we could do further checks like checking for
          //a valid payment i.e. $ipn_cart->valid_payment($ipn,$cart,$currency)
          $ipn->insert_ipn_txn();
          $order->paypal_ipn_id = $ipn->get_paypal_ipn_id();
          return false;
        }

      } elseif (isset($_GET['referer']) && $_GET['referer'] == 'paypal' && MODULE_PAYMENT_PAYPAL_IPN_AUTO_RETURN) {
          //Assume the IPN has been processed already,
          //which because PayPal gives no guarantee the following is 'currently'
          //not the ideal thing to be doing.
          $_SESSION['cart']->reset(true);
          if (is_object($GLOBALS['cart'])) $GLOBALS['cart']->reset(true);
          // unregister session variables used during checkout
          unset($_SESSION['sendto']);
          unset($_SESSION['billto']);
          unset($_SESSION['shipping']);
          unset($_SESSION['payment']);
          unset($_SESSION['comments']);
          zen_redirect(zen_href_link(FILENAME_CHECKOUT_SUCCESS, 'paypal=redirect', 'SSL'));
      } else {
        zen_redirect(zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL'));
        //return false;
      }
    }

    function after_process() {
     global $insert_id, $order, $db;
     $db->Execute("update " . TABLE_ORDERS . " set paypal_ipn_id = '" . (int)$order->paypal_ipn_id . "' where orders_id = '" . (int)$insert_id . "'");
     return false;
    }

    function output_error() {
      return false;
    }

    function check() {
	  global $db;
      if (!isset($this->_check)) {
        $check_query = $db->Execute("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_PAYMENT_PAYPAL_STATUS'");
        $this->_check = $check_query->RecordCount();
      }
      return $this->_check;
    }

    function install() {
      global $db;
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('PayPal 支払いを有効にする', 'MODULE_PAYMENT_PAYPAL_STATUS', 'True', 'PayPal での支払いを受け付けますか?', '6', '0', 'zen_cfg_select_option(array(\'True\', \'False\'), ', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('E-Mailアドレス', 'MODULE_PAYMENT_PAYPAL_ID','".STORE_OWNER_EMAIL_ADDRESS."', 'PayPal サービスに使用するE-Mailアドレスを設定して下さい。', '6', '2', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Business ID', 'MODULE_PAYMENT_PAYPAL_BUSINESS_ID','".STORE_OWNER_EMAIL_ADDRESS."', 'Email address or account ID of the payment recipient', '6', '3', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('処理通貨設定', 'MODULE_PAYMENT_PAYPAL_CURRENCY', 'Selected Currency', 'クレジットカード処理に使用する通貨を設定して下さい。', '6', '4', 'zen_cfg_select_option(array(\'Selected Currency\',\'Only USD\',\'Only CAD\',\'Only EUR\',\'Only GBP\',\'Only JPY\'), ', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('表示の整列順', 'MODULE_PAYMENT_PAYPAL_SORT_ORDER', '0', '表示の整列順を設定できます。数字が小さいほど上位に表示されます', '6', '5', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, set_function, date_added) values ('適用地域', 'MODULE_PAYMENT_PAYPAL_ZONE', '0', '適用地域を選択すると、選択した地域のみで利用可能となります。', '6', '6', 'zen_get_zone_class_title', 'zen_cfg_pull_down_zone_classes(', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('初期注文ステータス', 'MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID', '0', '設定したステータスが受注時に適用されます。', '6', '7', 'zen_cfg_pull_down_order_statuses(', 'zen_get_order_status_name', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Background Color', 'MODULE_PAYMENT_PAYPAL_CS', '0', 'Select the background color of PayPal\'s payment pages.<br />0=White, 1=Black', '6', '8', 'zen_cfg_select_option(array(\'0\',\'1\'), ', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Store Logo', 'MODULE_PAYMENT_PAYPAL_STORE_LOGO_ENABLED', '1', 'If you do not have SSL then set to 0.<br />0 = No, 1 = Yes', '6', '9', 'zen_cfg_select_option(array(\'0\',\'1\'), ', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Store logo', 'MODULE_PAYMENT_PAYPAL_STORE_LOGO_IMAGE_NAME', 'logo.gif', 'The image file name for PayPal to display', '6', '10', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('PayPal Page Style Name', 'MODULE_PAYMENT_PAYPAL_PAGE_STYLE', '', 'The name of the page style you have configured in your PayPal Account', '6', '11', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Include a note with payment', 'MODULE_PAYMENT_PAYPAL_NO_NOTE', '0', 'Choose whether your customer should be prompted to include a note or not?<br />0=Yes, 1=No', '6', '12', 'zen_cfg_select_option(array(\'0\',\'1\'), ', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Return URL behavior', 'MODULE_PAYMENT_PAYPAL_RM', '2', 'How should the customer be sent back from PayPal to the specified URL?<br />0=No IPN, 1=GET, 2=POST', '6', '13', 'zen_cfg_select_option(array(\'0\',\'1\',\'2\'), ', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Shopping Cart Method', 'MODULE_PAYMENT_PAYPAL_METHOD', '1', 'What type of shopping cart do you want to use?<br />1=Aggregate, 2=Itemized', '6', '14', 'zen_cfg_select_option(array(\'1\',\'2\'), ', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable PayPal Shipping Address', 'MODULE_PAYMENT_PAYPAL_SHIPPING_ALLOWED', '0', 'Allow the customer to choose their own PayPal shipping address?<br />0=No, 1=Yes', '6', '15', 'zen_cfg_select_option(array(\'0\',\'1\'), ', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Using PayPal Auto-Return', 'MODULE_PAYMENT_PAYPAL_IPN_AUTO_RETURN', '1', 'Are you using the PayPal Auto-Return Feature?<br />The customer\'s order is generated by the IPN not when they return to the site<br />0=No, 1=Yes (Recommended)', '6', '16', 'zen_cfg_select_option(array(\'0\',\'1\'), ', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Email Notifications', 'MODULE_PAYMENT_PAYPAL_IPN_DEBUG', '2', 'The email notification level<br />(1 is recommended)', '6', '17', 'zen_cfg_select_option(array(\'0\',\'1\',\'2\'), ', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Test Mode', 'MODULE_PAYMENT_PAYPAL_IPN_DEBUG_TEST', '0', '0 = Off, 1 = On', '6', '18', 'zen_cfg_select_option(array(\'0\',\'1\'), ', now())");
      $db->Execute("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Notification Address', 'MODULE_PAYMENT_PAYPAL_IPN_DEBUG_EMAIL','".STORE_OWNER_EMAIL_ADDRESS."', 'The e-mail address to send (level 1) notifications to', '6', '19', now())");
    }

    function remove() {
	  global $db;
      $db->Execute("delete from " . TABLE_CONFIGURATION . " where configuration_key in ('" . implode("', '", $this->keys()) . "')");
    }

    function keys() {
      return array('MODULE_PAYMENT_PAYPAL_STATUS', 'MODULE_PAYMENT_PAYPAL_ID', 'MODULE_PAYMENT_PAYPAL_BUSINESS_ID', 'MODULE_PAYMENT_PAYPAL_CURRENCY', 'MODULE_PAYMENT_PAYPAL_ZONE', 'MODULE_PAYMENT_PAYPAL_ORDER_STATUS_ID', 'MODULE_PAYMENT_PAYPAL_SORT_ORDER','MODULE_PAYMENT_PAYPAL_CS', 'MODULE_PAYMENT_PAYPAL_STORE_LOGO_ENABLED', 'MODULE_PAYMENT_PAYPAL_STORE_LOGO_IMAGE_NAME', 'MODULE_PAYMENT_PAYPAL_PAGE_STYLE', 'MODULE_PAYMENT_PAYPAL_NO_NOTE', 'MODULE_PAYMENT_PAYPAL_METHOD', 'MODULE_PAYMENT_PAYPAL_SHIPPING_ALLOWED', 'MODULE_PAYMENT_PAYPAL_IPN_AUTO_RETURN', 'MODULE_PAYMENT_PAYPAL_IPN_DEBUG','MODULE_PAYMENT_PAYPAL_IPN_DEBUG_TEST','MODULE_PAYMENT_PAYPAL_IPN_DEBUG_EMAIL','MODULE_PAYMENT_PAYPAL_RM');
    }

    function _getPayPalFields(&$order, &$currencies, $my_currency) {

      $paypal_fields = zen_draw_hidden_field('cmd', '_ext-enter') . //allows the customer addr details to be passed
      zen_draw_hidden_field('business', MODULE_PAYMENT_PAYPAL_BUSINESS_ID) ;
      if(MODULE_PAYMENT_PAYPAL_STORE_LOGO_ENABLED) $paypal_fields .= zen_draw_hidden_field('image_url', zen_href_link(DIR_WS_IMAGES.MODULE_PAYMENT_PAYPAL_STORE_LOGO_IMAGE_NAME, '', 'SSL')) ;
      if(MODULE_PAYMENT_PAYPAL_IPN_AUTO_RETURN) $paypal_return = 'referer=paypal';
        else $paypal_return = '';
      $paypal_fields .= zen_draw_hidden_field('return', zen_href_link(FILENAME_CHECKOUT_PROCESS, $paypal_return, 'SSL'));
      $paypal_fields .= zen_draw_hidden_field('cancel_return', zen_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL')) .
      zen_draw_hidden_field('notify_url', zen_href_link('ipn.php', '', 'SSL',false,false,true));
      $paypal_fields .= zen_draw_hidden_field('bn', 'osc-ipn-v1');
      if(!MODULE_PAYMENT_PAYPAL_SHIPPING_ALLOWED) $paypal_fields .= zen_draw_hidden_field('no_shipping', '1' );

      if(MODULE_PAYMENT_PAYPAL_METHOD == 2) {

        $paypal_fields .= zen_draw_hidden_field('upload', sizeof($order->products) ) .
        zen_draw_hidden_field('redirect_cmd', '_cart') .
        zen_draw_hidden_field('handling_cart', number_format($order->info['shipping_cost'] * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency)));
        //Let PayPal Calculate the amount since we're essentiall uploading a shopping cart
        //zen_draw_hidden_field('amount', number_format(($order->info['total'] - $order->info['shipping_cost']) * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency)));

      } else {

        $paypal_fields .= zen_draw_hidden_field('item_name', STORE_NAME) .
        zen_draw_hidden_field('redirect_cmd', '_xclick') .
        zen_draw_hidden_field('amount', number_format(($order->info['total'] - $order->info['shipping_cost']) * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency))) .
        zen_draw_hidden_field('shipping', number_format($order->info['shipping_cost'] * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency)));

      }

      //See Manual: 0= No IPN, 1 = GET, 2 = POST
      $paypal_fields .= zen_draw_hidden_field('rm', MODULE_PAYMENT_PAYPAL_RM) .
      zen_draw_hidden_field( 'custom', zen_session_id() ) .

      zen_draw_hidden_field('currency_code', $my_currency) .

      $this->_drawCustomerDetails($order) .

      //Customer comment field - defualt 'yes'
      $this->_drawNoteOption(MODULE_PAYMENT_PAYPAL_NO_NOTE , MODULE_PAYMENT_PAYPAL_CUSTOMER_COMMENTS) .

      //PayPal Background Color
      zen_draw_hidden_field('cs',MODULE_PAYMENT_PAYPAL_CS) .
      zen_draw_hidden_field('page_style',MODULE_PAYMENT_PAYPAL_PAGE_STYLE);

      if(MODULE_PAYMENT_PAYPAL_METHOD == 2) {
        //Customer Order Details
        for ($i=0; $i<sizeof($order->products); $i++) {
          $index = $i+1;
          $paypal_fields .= zen_draw_hidden_field('item_name_'.$index, $order->products[$i]['name']).
          zen_draw_hidden_field('item_number_'.$index, $order->products[$i]['model']).
          zen_draw_hidden_field('quantity_'.$index, $order->products[$i]['qty']).
          zen_draw_hidden_field('amount_'.$index, number_format($order->products[$i]['final_price']* $currencies->get_value($my_currency),2));

          //$paypal_fields .= zen_draw_hidden_field('tax_'.$index, number_format($order->info['tax'] * $currencies->get_value($my_currency),2));
          $taxValue = ($order->products[$i]['final_price'] * ($order->products[$i]['tax'] / 100)) * $currencies->get_value($my_currency);
          $paypal_fields .= zen_draw_hidden_field('tax_'.$index, number_format($taxValue, 2));


          //Customer Specified Product Options: PayPal Max = 2
          if ($order->products[$i]['attributes']) {
            for ($j=0, $n=sizeof($order->products[$i]['attributes']); $j<2; $j++) {
              if($order->products[$i]['attributes'][$j]['option']){
                $paypal_fields .= $this->_drawPayPalOptionSet($j,$index,$order->products[$i]['attributes'][$j]['option'],$order->products[$i]['attributes'][$j]['value']);
              } else {
                $paypal_fields .= $this->_drawPayPalOptionSet($j,$index,' ',' ');
              }
            }
          } else {
            for ($j=0; $j<2; $j++) {
              $paypal_fields .= $this->_drawPayPalOptionSet($j,$index,' ',' ');
            }
          }
        }
      } else { //method 1
        $item_number;
        for ($i=0; $i<sizeof($order->products); $i++) {
          $item_number .= ' '.$order->products[$i]['name'].' ,';
        }
        $item_number = substr_replace($item_number,'',-1);
        $paypal_fields .= zen_draw_hidden_field('item_number', $item_number);
      }
      return $paypal_fields;
    }

    function _drawCustomerDetails(&$order) {
      //Customer Details - for those who haven't signed up to PayPal
      $paypal_fields = zen_draw_hidden_field('email', $order->customer['email_address']) .
      zen_draw_hidden_field('first_name', $order->customer['firstname']) .
      zen_draw_hidden_field('last_name', $order->customer['lastname']) .
      zen_draw_hidden_field('address1', $order->customer['street_address']) .
      zen_draw_hidden_field('address2', '') .
      zen_draw_hidden_field('city', $order->customer['city']) .
      zen_draw_hidden_field('state', zen_get_zone_code($order->customer['country']['id'],$order->customer['zone_id'],$order->customer['zone_id'])) .
      zen_draw_hidden_field('zip', $order->customer['postcode']);
      //User Country Preference
      //Note: Anguilla[AI], Dominican Republic[DO], The Netherlands[NL] have different codes to the iso codes in the osC db
      $paypal_fields .= zen_draw_hidden_field('lc', $order->customer['country']['iso_code_2']);
      //Telephone is problematic.
      $telephone = preg_replace('/\D/', '', $order->customer['telephone']);
      $paypal_fields .= zen_draw_hidden_field('night_phone_a',substr($telephone,0,3));
      $paypal_fields .= zen_draw_hidden_field('night_phone_b',substr($telephone,3,3));
      $paypal_fields .= zen_draw_hidden_field('night_phone_c',substr($telephone,6,4));
      $paypal_fields .= zen_draw_hidden_field('day_phone_a',substr($telephone,0,3));
      $paypal_fields .= zen_draw_hidden_field('day_phone_b',substr($telephone,3,3));
      $paypal_fields .= zen_draw_hidden_field('day_phone_c',substr($telephone,6,4));
      return $paypal_fields;
    }

    function _drawPayPalOptionSet($sub_index,$index,$option=' ',$value=' ') {
        return zen_draw_hidden_field('on'.$sub_index.'_'.$index,$option).
          zen_draw_hidden_field('os'.$sub_index.'_'.$index,$value);
    }

    function _drawNoteOption($option='1',$msg='Add Comments About Your Order') {
      $no_note = zen_draw_hidden_field('no_note',$option);
      if (!$option) return $no_note .= zen_draw_hidden_field('cn',$msg);
      else return $no_note;;
    }

  }
?>