<?php

  /**
   * Paypal common class
   * 
   * @package angie.framework.payments
   * @subpackage models
   *
   */
  class PaypalGateway extends PaymentGateway {
    
    const PAYPAL_DIRECT_PAYMENT_METHOD = 'DoDirectPayment';
    const PAYPAL_SET_EXPRESS_CHECKOUT_METHOD = 'SetExpressCheckout';
    const PAYPAL_GET_EXPRESS_CHECKOUT_METHOD = 'GetExpressCheckoutDetails';
    const PAYPAL_DO_EXPRESS_CHECKOUT_METHOD = 'DoExpressCheckoutPayment';
    
    const ENDPOINT_URL = "https://api-3t.paypal.com/nvp";
    const TEST_URL = "https://api-3t.sandbox.paypal.com/nvp";
    const TEST_REDIRECT_URL = "https://www.sandbox.paypal.com/webscr&cmd=_express-checkout";
    const REDIRECT_URL = "https://www.paypal.com/webscr&cmd=_express-checkout";
    const API_VERSION = "51.0";
    
   /**
     * Accepted CC type
     * 
     * @var array
     */
    var $cc_types = array(
      array('name' => 'Visa', 'value' =>'Visa', 'attr' => array('selected' => 'selected')),
      array('name' => 'MasterCard', 'value' =>'MasterCard'),
//      array('name' => 'Discover', 'value' =>'Discover'),
//      array('name' => 'Amex', 'value' =>'Amex'),
    );
    
    /**
     * Accepted currencies
     * 
     * @var array
     */
    var $supported_currencies = array(
      'USD',
      'EUR',
      'AUD',
      'CAD',
      'JPY',
      'GBP',
    );
    
    /**
     * Accepted countries
     * 
     * @var array
     */
    var $countries = array(
      array('name' => 'AFGHANISTAN', 'value' => 'AF'),
      array('name' => 'LAND ISLANDS', 'value' => 'AX'),
      array('name' => 'ALBANIA', 'value' => 'AL'),
      array('name' => 'ALGERIA', 'value' => 'DZ'),
      array('name' => 'AMERICAN SAMOA', 'value' => 'AS'),
      array('name' => 'ANDORRA', 'value' => 'AD'),
      array('name' => 'ANGOLA', 'value' => 'AO'),
      array('name' => 'ANGUILLA', 'value' => 'AI'),
      array('name' => 'ANTARCTICA', 'value' => 'AQ'),
      array('name' => 'ANTIGUA AND BARBUDA', 'value' => 'AG'),
      array('name' => 'ARGENTINA', 'value' => 'AR'),
      array('name' => 'ARMENIA', 'value' => 'AM'),
      array('name' => 'ARUBA', 'value' => 'AW'),
      array('name' => 'AUSTRALIA', 'value' => 'AU'),
      array('name' => 'AUSTRIA', 'value' => 'AT'),
      array('name' => 'AZERBAIJAN', 'value' => 'AZ'),
      array('name' => 'BAHAMAS', 'value' => 'BS'),
      array('name' => 'BAHRAIN', 'value' => 'BH'),
      array('name' => 'BANGLADESH', 'value' => 'BD'),
      array('name' => 'BARBADOS', 'value' => 'BB'),
      array('name' => 'BELARUS', 'value' => 'BY'),
      array('name' => 'BELGIUM', 'value' => 'BE'),
      array('name' => 'BELIZE', 'value' => 'BZ'),
      array('name' => 'BENIN', 'value' => 'BJ'),
      array('name' => 'BERMUDA', 'value' => 'BM'),
      array('name' => 'BHUTAN', 'value' => 'BT'),
      array('name' => 'BOLIVIA', 'value' => 'BO'),
      array('name' => 'BOSNIA AND HERZEGOVINA', 'value' => 'BA'),
      array('name' => 'BOTSWANA', 'value' => 'BW'),
      array('name' => 'BOUVET ISLAND', 'value' => 'BV'),
      array('name' => 'BRAZIL', 'value' => 'BR'),
      array('name' => 'BRITISH INDIAN OCEAN TERRITORY', 'value' => 'IO'),
      array('name' => 'BRUNEI DARUSSALAM', 'value' => 'BN'),
      array('name' => 'BULGARIA', 'value' => 'BG'),
      array('name' => 'BURKINA FASO', 'value' => 'BF'),
      array('name' => 'BURUNDI', 'value' => 'BI'),
      array('name' => 'CAMBODIA', 'value' => 'KH'),
      array('name' => 'CAMEROON', 'value' => 'CM'),
      array('name' => 'CANADA', 'value' => 'CA'),
      array('name' => 'CAPE VERDE', 'value' => 'CV'),
      array('name' => 'CAYMAN ISLANDS', 'value' => 'KY'),
      array('name' => 'CENTRAL AFRICAN REPUBLIC', 'value' => 'CF'),
      array('name' => 'CHAD', 'value' => 'TD'),
      array('name' => 'CHILE', 'value' => 'CL'),
      array('name' => 'CHINA', 'value' => 'CN'),
      array('name' => 'CHRISTMAS ISLAND', 'value' => 'CX'),
      array('name' => 'COCOS (KEELING) ISLANDS', 'value' => 'CC'),
      array('name' => 'COLOMBIA', 'value' => 'CO'),
      array('name' => 'COMOROS', 'value' => 'KM'),
      array('name' => 'CONGO', 'value' => 'CG'),
      array('name' => 'CONGO, THE DEMOCRATIC REPUBLIC OF', 'value' => 'CD'),
      array('name' => 'COOK ISLANDS', 'value' => 'CK'),
      array('name' => 'COSTA RICA', 'value' => 'CR'),
      array('name' => 'COTE D\'IVOIRE', 'value' => 'CI'),
      array('name' => 'CROATIA', 'value' => 'HR'),
      array('name' => 'CUBA', 'value' => 'CU'),
      array('name' => 'CYPRUS', 'value' => 'CY'),
      array('name' => 'CZECH REPUBLIC', 'value' => 'CZ'),
      array('name' => 'DENMARK', 'value' => 'DK'),
      array('name' => 'DJIBOUTI', 'value' => 'DJ'),
      array('name' => 'DOMINICA', 'value' => 'DM'),
      array('name' => 'DOMINICAN REPUBLIC', 'value' => 'DO'),
      array('name' => 'ECUADOR', 'value' => 'EC'),
      array('name' => 'EGYPT', 'value' => 'EG'),
      array('name' => 'EL SALVADOR', 'value' => 'SV'),
      array('name' => 'EQUATORIAL GUINEA', 'value' => 'GQ'),
      array('name' => 'ERITREA', 'value' => 'ER'),
      array('name' => 'ESTONIA', 'value' => 'EE'),
      array('name' => 'ETHIOPIA', 'value' => 'ET'),
      array('name' => 'FALKLAND ISLANDS (MALVINAS)', 'value' => 'FK'),
      array('name' => 'FAROE ISLANDS', 'value' => 'FO'),
      array('name' => 'FIJI', 'value' => 'FJ'),
      array('name' => 'FINLAND', 'value' => 'FI'),
      array('name' => 'FRANCE', 'value' => 'FR'),
      array('name' => 'FRENCH GUIANA', 'value' => 'GF'),
      array('name' => 'FRENCH POLYNESIA', 'value' => 'PF'),
      array('name' => 'FRENCH SOUTHERN TERRITORIES', 'value' => 'TF'),
      array('name' => 'GABON', 'value' => 'GA'),
      array('name' => 'GAMBIA', 'value' => 'GM'),
      array('name' => 'GEORGIA', 'value' => 'GE'),
      array('name' => 'GERMANY', 'value' => 'DE'),
      array('name' => 'GHANA', 'value' => 'GH'),
      array('name' => 'GIBRALTAR', 'value' => 'GI'),
      array('name' => 'GREECE', 'value' => 'GR'),
      array('name' => 'GREENLAND', 'value' => 'GL'),
      array('name' => 'GRENADA', 'value' => 'GD'),
      array('name' => 'GUADELOUPE', 'value' => 'GP'),
      array('name' => 'GUAM', 'value' => 'GU'),
      array('name' => 'GUATEMALA', 'value' => 'GT'),
      array('name' => 'GUERNSEY', 'value' => 'GG'),
      array('name' => 'GUINEA', 'value' => 'GN'),
      array('name' => 'GUINEA-BISSAU', 'value' => 'GW'),
      array('name' => 'GUYANA', 'value' => 'GY'),
      array('name' => 'HAITI', 'value' => 'HT'),
      array('name' => 'HEARD ISLAND AND MCDONALD ISLANDS', 'value' => 'HM'),
      array('name' => 'HOLY SEE (VATICAN CITY STATE)', 'value' => 'VA'),
      array('name' => 'HONDURAS', 'value' => 'HN'),
      array('name' => 'HONG KONG', 'value' => 'HK'),
      array('name' => 'HUNGARY', 'value' => 'HU'),
      array('name' => 'ICELAND', 'value' => 'IS'),
      array('name' => 'INDIA', 'value' => 'IN'),
      array('name' => 'INDONESIA', 'value' => 'ID'),
      array('name' => 'IRAN, ISLAMIC REPUBLIC OF', 'value' => 'IR'),
      array('name' => 'IRAQ', 'value' => 'IQ'),
      array('name' => 'IRELAND', 'value' => 'IE'),
      array('name' => 'ISLE OF MAN', 'value' => 'IM'),
      array('name' => 'ISRAEL', 'value' => 'IL'),
      array('name' => 'ITALY', 'value' => 'IT'),
      array('name' => 'JAMAICA', 'value' => 'JM'),
      array('name' => 'JAPAN', 'value' => 'JP'),
      array('name' => 'JERSEY', 'value' => 'JE'),
      array('name' => 'JORDAN', 'value' => 'JO'),
      array('name' => 'KAZAKHSTAN', 'value' => 'KZ'),
      array('name' => 'KENYA', 'value' => 'KE'),
      array('name' => 'KIRIBATI', 'value' => 'KI'),
      array('name' => 'KOREA, DEMOCRATIC PEOPLE\'S REPUBLIC OF', 'value' => 'KP'),
      array('name' => 'KOREA, REPUBLIC OF', 'value' => 'KR'),
      array('name' => 'KUWAIT', 'value' => 'KW'),
      array('name' => 'KYRGYZSTAN', 'value' => 'KG'),
      array('name' => 'LAO PEOPLE\'S DEMOCRATIC REPUBLIC', 'value' => 'LA'),
      array('name' => 'LATVIA', 'value' => 'LV'),
      array('name' => 'LEBANON', 'value' => 'LB'),
      array('name' => 'LESOTHO', 'value' => 'LS'),
      array('name' => 'LIBYAN ARAB JAMAHIRIYA', 'value' => 'LY'),
      array('name' => 'LIECHTENSTEIN', 'value' => 'LI'),
      array('name' => 'LITHUANIA', 'value' => 'LT'),
      array('name' => 'LUXEMBOURG', 'value' => 'LU'),
      array('name' => 'MACAO', 'value' => 'MO'),
      array('name' => 'MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF', 'value' => 'MK'),
      array('name' => 'MADAGASCAR', 'value' => 'MG'),
      array('name' => 'MALAWI', 'value' => 'MW'),
      array('name' => 'MALAYSIA', 'value' => 'MY'),
      array('name' => 'MALDIVES', 'value' => 'MV'),
      array('name' => 'MALI', 'value' => 'ML'),
      array('name' => 'MALTA', 'value' => 'MT'),
      array('name' => 'MARSHALL ISLANDS', 'value' => 'MH'),
      array('name' => 'MARTINIQUE', 'value' => 'MQ'),
      array('name' => 'MAURITANIA', 'value' => 'MR'),
      array('name' => 'MAURITIUS', 'value' => 'MU'),
      array('name' => 'MAYOTTE', 'value' => 'YT'),
      array('name' => 'MEXICO', 'value' => 'MX'),
      array('name' => 'MICRONESIA, FEDERATED STATES OF', 'value' => 'FM'),
      array('name' => 'MOLDOVA, REPUBLIC OF', 'value' => 'MD'),
      array('name' => 'MONACO', 'value' => 'MC'),
      array('name' => 'MONGOLIA', 'value' => 'MN'),
      array('name' => 'MONTSERRAT', 'value' => 'MS'),
      array('name' => 'MOROCCO', 'value' => 'MA'),
      array('name' => 'MOZAMBIQUE', 'value' => 'MZ'),
      array('name' => 'MYANMAR', 'value' => 'MM'),
      array('name' => 'NAMIBIA', 'value' => 'NA'),
      array('name' => 'NAURU', 'value' => 'NR'),
      array('name' => 'NEPAL', 'value' => 'NP'),
      array('name' => 'NETHERLANDS', 'value' => 'NL'),
      array('name' => 'NETHERLANDS ANTILLES', 'value' => 'AN'),
      array('name' => 'NEW CALEDONIA', 'value' => 'NC'),
      array('name' => 'NEW ZEALAND', 'value' => 'NZ'),
      array('name' => 'NICARAGUA', 'value' => 'NI'),
      array('name' => 'NIGER', 'value' => 'NE'),
      array('name' => 'NIGERIA', 'value' => 'NG'),
      array('name' => 'NIUE', 'value' => 'NU'),
      array('name' => 'NORFOLK ISLAND', 'value' => 'NF'),
      array('name' => 'NORTHERN MARIANA ISLANDS', 'value' => 'MP'),
      array('name' => 'NORWAY', 'value' => 'NO'),
      array('name' => 'OMAN', 'value' => 'OM'),
      array('name' => 'PAKISTAN', 'value' => 'PK'),
      array('name' => 'PALAU', 'value' => 'PW'),
      array('name' => 'PALESTINIAN TERRITORY, OCCUPIED', 'value' => 'PS'),
      array('name' => 'PANAMA', 'value' => 'PA'),
      array('name' => 'PAPUA NEW GUINEA', 'value' => 'PG'),
      array('name' => 'PARAGUAY', 'value' => 'PY'),
      array('name' => 'PERU', 'value' => 'PE'),
      array('name' => 'PHILIPPINES', 'value' => 'PH'),
      array('name' => 'PITCAIRN', 'value' => 'PN'),
      array('name' => 'POLAND', 'value' => 'PL'),
      array('name' => 'PORTUGAL', 'value' => 'PT'),
      array('name' => 'PUERTO RICO', 'value' => 'PR'),
      array('name' => 'QATAR', 'value' => 'QA'),
      array('name' => 'REUNION', 'value' => 'RE'),
      array('name' => 'ROMANIA', 'value' => 'RO'),
      array('name' => 'RUSSIAN FEDERATION', 'value' => 'RU'),
      array('name' => 'RWANDA', 'value' => 'RW'),
      array('name' => 'SAINT HELENA', 'value' => 'SH'),
      array('name' => 'SAINT KITTS AND NEVIS', 'value' => 'KN'),
      array('name' => 'SAINT LUCIA', 'value' => 'LC'),
      array('name' => 'SAINT PIERRE AND MIQUELON', 'value' => 'PM'),
      array('name' => 'SAINT VINCENT AND THE GRENADINES', 'value' => 'VC'),
      array('name' => 'SAMOA', 'value' => 'WS'),
      array('name' => 'SAN MARINO', 'value' => 'SM'),
      array('name' => 'SAO TOME AND PRINCIPE', 'value' => 'ST'),
      array('name' => 'SAUDI ARABIA', 'value' => 'SA'),
      array('name' => 'SENEGAL', 'value' => 'SN'),
      array('name' => 'SERBIA AND MONTENEGRO', 'value' => 'CS'),
      array('name' => 'SEYCHELLES', 'value' => 'SC'),
      array('name' => 'SIERRA LEONE', 'value' => 'SL'),
      array('name' => 'SINGAPORE', 'value' => 'SG'),
      array('name' => 'SLOVAKIA', 'value' => 'SK'),
      array('name' => 'SLOVENIA', 'value' => 'SI'),
      array('name' => 'SOLOMON ISLANDS', 'value' => 'SB'),
      array('name' => 'SOMALIA', 'value' => 'SO'),
      array('name' => 'SOUTH AFRICA', 'value' => 'ZA'),
      array('name' => 'SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS', 'value' => 'GS'),
      array('name' => 'SPAIN', 'value' => 'ES'),
      array('name' => 'SRI LANKA', 'value' => 'LK'),
      array('name' => 'SUDAN', 'value' => 'SD'),
      array('name' => 'SURINAME', 'value' => 'SR'),
      array('name' => 'SVALBARD AND JAN MAYEN', 'value' => 'SJ'),
      array('name' => 'SWAZILAND', 'value' => 'SZ'),
      array('name' => 'SWEDEN', 'value' => 'SE'),
      array('name' => 'SWITZERLAND', 'value' => 'CH'),
      array('name' => 'SYRIAN ARAB REPUBLIC', 'value' => 'SY'),
      array('name' => 'TAIWAN, PROVINCE OF CHINA', 'value' => 'TW'),
      array('name' => 'TAJIKISTAN', 'value' => 'TJ'),
      array('name' => 'TANZANIA, UNITED REPUBLIC OF', 'value' => 'TZ'),
      array('name' => 'THAILAND', 'value' => 'TH'),
      array('name' => 'TIMOR-LESTE', 'value' => 'TL'),
      array('name' => 'TOGO', 'value' => 'TG'),
      array('name' => 'TOKELAU', 'value' => 'TK'),
      array('name' => 'TONGA', 'value' => 'TO'),
      array('name' => 'TRINIDAD AND TOBAGO', 'value' => 'TT'),
      array('name' => 'TUNISIA', 'value' => 'TN'),
      array('name' => 'TURKEY', 'value' => 'TR'),
      array('name' => 'TURKMENISTAN', 'value' => 'TM'),
      array('name' => 'TURKS AND CAICOS ISLANDS', 'value' => 'TC'),
      array('name' => 'TUVALU', 'value' => 'TV'),
      array('name' => 'UGANDA', 'value' => 'TM'),
      array('name' => 'UKRAINE', 'value' => 'UA'),
      array('name' => 'UNITED ARAB EMIRATES', 'value' => 'AE'),
      array('name' => 'UNITED KINGDOM', 'value' => 'GB'),
      array('name' => 'UNITED STATES', 'value' => 'US'),
      array('name' => 'UNITED STATES MINOR OUTLYING ISLANDS', 'value' => 'UM'),
      array('name' => 'URUGUAY', 'value' => 'UY'),
      array('name' => 'UZBEKISTAN', 'value' => 'UZ'),
      array('name' => 'VANUATU', 'value' => 'VU'),
      array('name' => 'VENEZUELA', 'value' => 'VE'),
      array('name' => 'VIETNAM', 'value' => 'VN'),
      array('name' => 'VIRGIN ISLANDS, BRITISH', 'value' => 'VG'),
      array('name' => 'VIRGIN ISLANDS, U.S.', 'value' => 'VI'),
      array('name' => 'WALLIS AND FUTUNA', 'value' => 'WF'),
      array('name' => 'WESTERN SAHARA', 'value' => 'EH'),
      array('name' => 'YEMEN', 'value' => 'YE'),
      array('name' => 'ZAMBIA', 'value' => 'ZM'),
      array('name' => 'ZIMBABWE', 'value' => 'ZW'), 
      
    );
  
    /**
       * Send HTTP POST Request
       *
       * @param	string	The API method name
       * @param	string	The POST Message fields in &name=value pair format
       * @return	array	Parsed HTTP Response body
       */
      function callService($method_name, $nvp_str) {
      	  
      	// Set up your API credentials, PayPal end point, and API version.
      	$api_username = urlencode($this->getApiUsername());
      	$api_password = urlencode($this->getApiPassword());
      	$api_signature = urlencode($this->getApiSignature());
      	if($this->getGoLive() == 1) {
      	  $api_endpoint = PaypalGateway::ENDPOINT_URL;
      	} else {
      	  $api_endpoint = PaypalGateway::TEST_URL;
      	} //if
      	$version = urlencode(PaypalGateway::API_VERSION);
      
      	// Set the curl parameters.
      	$ch = curl_init();
      	curl_setopt($ch, CURLOPT_URL, $api_endpoint);
      	curl_setopt($ch, CURLOPT_VERBOSE, 1);
      
      	// Turn off the server and peer verification (TrustManager Concept).
      	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
      	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
      
      	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      	curl_setopt($ch, CURLOPT_POST, 1);
      
      	// Set the API operation, version, and API signature in the request.
      	$nvpreq = "METHOD=$method_name&VERSION=$version&PWD=$api_password&USER=$api_username&SIGNATURE=$api_signature$nvp_str";
        
      	// Set the request as a POST FIELD for curl.
      	curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
      
      	// Get response from the server.
      	$http_response = curl_exec($ch);
        if(!$http_response) {
      		throw new InvalidParamError("$method_name failed: ".curl_error($ch).'('.curl_errno($ch).')');
      	} //if
      
      	// Extract the response details.
      	$http_response_ar = explode("&", $http_response);
        
      	$http_parsed_response_ar = array();
      	foreach ($http_response_ar as $i => $value) {
      		$tmp_ar = explode("=", $value);
      		if(sizeof($tmp_ar) > 1) {
      			$http_parsed_response_ar[$tmp_ar[0]] = urldecode($tmp_ar[1]);
      		} //if
      	} //if
        if((0 == sizeof($http_parsed_response_ar)) || !array_key_exists('ACK', $http_parsed_response_ar)) {
      		exit("Invalid HTTP Response for POST request($nvpreq) to $api_endpoint.");
      	} //if
      
      	return $http_parsed_response_ar;
      } //makePayPalPayment
    
    
    
    } //PaypalPayment