/** * Convert contry string (e.g. United States of America) into 2 or 3 letter (e.g. US or USA) * Or country 2 or 3 letters code to country string in English * Or betweeen country codes: Values for $nbLetters: * 3 : country -> 3 letters * 2 : country -> 2 letters * -2 : 2 letters -> country * -3 : 3 letters -> country * 23 : 2 letters -> 3 letters * 32 : 3 letters -> 2 letters * * @param string $country Full text country name (if $nbLetters = 2 or 3) or country code (if $nbLetters = -2 or -3 or 23 or 32) * @param int $nbLetters Number of letters code (2 or 3 for full name to code and -2 or -3 for code to name) * @return string 2/3/full-letters country name */ protected function countryToLetters($country, $nbLetters) { $countries = new cbpaidCountries(); switch ($nbLetters) { case 3: $ret = $countries->countryToThreeLetters($country); break; case 2: $ret = $countries->countryToTwoLetters($country); break; case -2: $ret = $countries->twoLettersToCountry($country); break; case -3: $ret = $countries->threeLettersToCountry($country); break; case 23: $ret = $countries->twoToThreeLettersCountry($country); break; case 32: $ret = $countries->threeToTwoLettersCountry($country); break; default: trigger_error('Unknown nbLetters in countryToLetters', E_USER_WARNING); $ret = null; break; } if ($ret === null) { $n = $nbLetters < 0 ? 255 : $nbLetters % 10; $ret = substr($country, 0, $n); } return $ret; }
/** * Computes 2-letters country code from the $this->address_country and stores it into $this->address_country_code */ protected function _computeTwoLettersCountryFromCountry( ) { $countries = new cbpaidCountries(); $twoLettersCountry = $countries->countryToTwoLetters( $this->address_country ); if ( $twoLettersCountry ) { $this->address_country_code = $twoLettersCountry; } }
/** * Prepares and signs payflow payment $requestParams * * @param cbpaidPaymentBasket $paymentBasket * @param bool $subscription * @return array $requestParams */ private function _payflowPayment( $paymentBasket, $subscription = false ) { $requestParams = array(); if ( $this->hasPaypalPayflow() ) { $countries = new cbpaidCountries(); if ( $paymentBasket->period3 ) { if ( $paymentBasket->period1 ) { $amount = sprintf( '%.2f', $paymentBasket->mc_amount1 ); } else { $amount = sprintf( '%.2f', $paymentBasket->mc_amount3 ); } } else { $amount = sprintf( '%.2f', $paymentBasket->mc_gross ); } if ( $this->getAccountParam( 'normal_gateway' ) == '0' ) { $requestParams['MODE'] = 'TEST'; } $request = array( 'PARTNER' => 'PayPal', 'VENDOR' => $this->getAccountParam( 'paypal_payflow_vendor' ), 'USER' => $this->getAccountParam( 'paypal_payflow_user' ), 'PWD' => $this->getAccountParam( 'paypal_payflow_password' ), 'TRXTYPE' => 'S', 'AMT' => $amount, 'CREATESECURETOKEN' => 'Y', 'SECURETOKENID' => uniqid(), 'TEMPLATE' => $this->getAccountParam( 'template_layout', 'MINLAYOUT' ), 'ORDERDESC' => $paymentBasket->item_name, 'INVNUM' => $paymentBasket->invoice, 'CURRENCY' => $paymentBasket->mc_currency, 'USER1' => $paymentBasket->id, 'USER2' => $paymentBasket->user_id, 'USER3' => $paymentBasket->item_number, 'USER4' => ( $subscription ? 'R' : 'S' ) ); if ( $subscription ) { $request['RECURRING'] = 'Y'; } if ( $this->getAccountParam( 'givehiddenbillemail' ) && ( strlen( $paymentBasket->payer_email ) <= 127 ) ) { $request['EMAIL'] = $paymentBasket->payer_email; } if ( $this->getAccountParam( 'givehiddenbilladdress' ) ) { cbimport( 'cb.tabs' ); $addressFields = array( 'BILLTOFIRSTNAME' => array( $paymentBasket->first_name, 30 ), 'BILLTOLASTNAME' => array( $paymentBasket->last_name, 30 ), 'BILLTOSTREET' => array( $paymentBasket->address_street, 150 ), 'BILLTOZIP' => array( $paymentBasket->address_zip, 9 ), 'BILLTOCITY' => array( $paymentBasket->address_city, 45 ), 'BILLTOCOUNTRY' => array( $countries->countryToTwoLetters( $paymentBasket->address_country ), 2 ) ); if ( $paymentBasket->address_state != 'other' ) { $addressFields['BILLTOSTATE'] = array( substr( $paymentBasket->address_state, -2 ), 2 ); } foreach ( $addressFields as $k => $valueMaxlength ) { $adrField = cbIsoUtf_substr( $valueMaxlength[0], 0, $valueMaxlength[1] ); if ( $adrField ) { $request[$k] = $adrField; } } } if ( $this->getAccountParam( 'givehiddenbilltelno' ) && ( strlen( $paymentBasket->contact_phone ) <= 50 ) ) { $request['BILLTOPHONENUM'] = $paymentBasket->contact_phone; } if ( $this->getAccountParam( 'givehiddenshipemail' ) && ( strlen( $paymentBasket->payer_email ) <= 127 ) ) { $request['SHIPTOEMAIL'] = $paymentBasket->payer_email; } if ( $this->getAccountParam( 'givehiddenshipaddress' ) ) { cbimport( 'cb.tabs' ); $addressFields = array( 'SHIPTOFIRSTNAME' => array( $paymentBasket->first_name, 30 ), 'SHIPTOLASTNAME' => array( $paymentBasket->last_name, 30 ), 'SHIPTOSTREET' => array( $paymentBasket->address_street, 150 ), 'SHIPTOZIP' => array( $paymentBasket->address_zip, 9 ), 'SHIPTOCITY' => array( $paymentBasket->address_city, 45 ), 'SHIPTOCOUNTRY' => array( $countries->countryToThreeLetters( $paymentBasket->address_country ), 3 ) ); if ( $paymentBasket->address_state != 'other' ) { $addressFields['SHIPTOSTATE'] = array( substr( $paymentBasket->address_state, -2 ), 2 ); } foreach ( $addressFields as $k => $valueMaxlength ) { $adrField = cbIsoUtf_substr( $valueMaxlength[0], 0, $valueMaxlength[1] ); if ( $adrField ) { $request[$k] = $adrField; } } } if ( $this->getAccountParam( 'givehiddenshiptelno' ) && ( strlen( $paymentBasket->contact_phone ) <= 50 ) ) { $request['SHIPTOPHONENUM'] = $paymentBasket->contact_phone; } $formUrl = array(); foreach ( $request as $k => $v ) { $formUrl[$k] = $k . '=' . $v; } $formUrl = implode( '&', $formUrl ); $results = array(); $response = null; $status = null; $error = $this->_httpsRequest( $this->gatewayUrl( 'psp' ), $formUrl, 105, $response, $status, 'post', 'normal' ); if ( $response ) { parse_str( $response, $results ); } if ( $error || ( $status != 200 ) || ( ! $response ) ) { $this->_setLogErrorMSG( 3, null, $this->getPayName() . ' HTTPS POST request to payment gateway server failed.', CBPTXT::T( "Submitted subscription payment didn't return an error but didn't complete." ) . ' ' . CBPTXT::T( 'Please contact site administrator to check error log.' ) ); } else { if ( cbGetParam( $results, 'RESULT' ) == '0' ) { $requestParams['SECURETOKEN'] = cbGetParam( $results, 'SECURETOKEN' ); $requestParams['SECURETOKENID'] = cbGetParam( $results, 'SECURETOKENID' ); } else{ $this->_setLogErrorMSG( 3, null, $this->getPayName() . ' Paypal Payflow error returned. ERROR: ' . cbGetParam( $results, 'RESPMSG' ), CBPTXT::T( 'Please contact site administrator to check error log.' ) ); } } } return $requestParams; }
/** * Attempts to subscribe a credit card for recurring subscription of a payment basket. * * @param array $card contains type, number, firstname, lastname, expmonth, expyear, and optionally: address, zip, country * @param cbpaidPaymentBasket $paymentBasket * @param int $now unix timestamp of now * @param cbpaidsubscriptionsNotification $ipn returns the stored notification * @param int $occurrences returns the number of occurences pay-subscribed firmly * @param int $autorecurring_type returns: 0: not auto-recurring, 1: auto-recurring without payment processor notifications, 2: auto-renewing with processor notifications updating $expiry_date * @param int $autorenew_type returns: 0: not auto-renewing (manual renewals), 1: asked for by user, 2: mandatory by configuration * @return mixed subscriptionId if subscription request succeeded, otherwise ARRAY( 'level' => 'inform', 'spurious' or 'fatal', 'errorText', 'errorCode' => string ) of error to display */ protected function processSubscriptionPayment( $card, $paymentBasket, $now, &$ipn, &$occurrences, &$autorecurring_type, &$autorenew_type ) { $return = false; if ( $this->hasPaypalApi() ) { $countries = new cbpaidCountries(); list( $p3, $t3, $start ) = $this->_paypalPeriodsLimits( explode( ' ', $paymentBasket->period3 ), $now ); if ( $paymentBasket->period1 ) { list( /* $p1 */, /* $t1 */, $start ) = $this->_paypalPeriodsLimits( explode( ' ', $paymentBasket->period1 ), $now ); $initialAmount = $paymentBasket->mc_amount1; } else { $initialAmount = $paymentBasket->mc_amount3; } $requestParams = array( 'METHOD' => 'CreateRecurringPaymentsProfile', 'SUBSCRIBERNAME' => cbIsoUtf_substr( $card['firstname'] . ' ' . $card['lastname'], 0, 32 ), 'PROFILESTARTDATE' => substr( date( 'c', $start ), 0, 19 ), 'PROFILEREFERENCE' => $paymentBasket->invoice, 'DESC' => cbIsoUtf_substr( $paymentBasket->item_name, 0, 127 ), 'BILLINGPERIOD' => $t3, 'BILLINGFREQUENCY' => $p3, 'INITAMT' => sprintf( '%.2f', $initialAmount ), 'AMT' => sprintf( '%.2f', $paymentBasket->mc_amount3 ), 'CURRENCYCODE' => $paymentBasket->mc_currency, 'CREDITCARDTYPE' => cbIsoUtf_substr( $card['type'], 0, 10 ), 'ACCT' => substr( preg_replace ( '/[^0-9]+/', '', strval( $card['number'] ) ), 0, 22 ), 'EXPDATE' => substr( sprintf( '%02d', intval( $card['expmonth'] ) ), 0, 2 ) . substr( strval( intval( $card['expyear'] ) ), 0, 4 ), 'CVV2' => substr( preg_replace ( '/[^0-9]+/', '', strval( $card['cvv'] ) ), 0, 4 ), 'EMAIL' => cbIsoUtf_substr( $paymentBasket->payer_email, 0, 127 ), 'PAYERID' => $paymentBasket->user_id, 'FIRSTNAME' => cbIsoUtf_substr( $card['firstname'], 0, 25 ), 'LASTNAME' => cbIsoUtf_substr( $card['lastname'], 0, 25 ), 'STREET' => cbIsoUtf_substr( $paymentBasket->address_street, 0, 100 ), 'CITY' => cbIsoUtf_substr( $paymentBasket->address_city, 0, 40 ), 'STATE' => cbIsoUtf_substr( substr( $paymentBasket->address_state, -2 ), 0, 2 ), 'COUNTRYCODE' => $countries->countryToTwoLetters( $paymentBasket->address_country ), 'ZIP' => cbIsoUtf_substr( $paymentBasket->address_zip, 0, 20 ) ); if ( $paymentBasket->recur_times ) { $requestParams['TOTALBILLINGCYCLES'] = $paymentBasket->recur_times; } $this->_signRequestParams( $requestParams ); $results = array(); $response = null; $status = null; $error = $this->_httpsRequest( str_replace( 'www', 'api-3t', $this->gatewayUrl( 'psp' ) . '/nvp' ), $requestParams, 105, $response, $status, 'post', 'normal' ); if ( $response ) { parse_str( $response, $results ); } if ( $error || ( $status != 200 ) || ( ! $response ) ) { $this->_setLogErrorMSG( 3, $ipn, $this->getPayName() . ' HTTPS POST request to payment gateway server failed.', CBPTXT::T( "Submitted subscription payment didn't return an error but didn't complete." ) . ' ' . CBPTXT::T( 'Please contact site administrator to check error log.' ) ); $logType = 'C'; } else { if ( cbGetParam( $results, 'ACK' ) == 'Success' ) { $autorecurring_type = 2; $autorenew_type = ( $autorecurring_type ? ( ( $this->getAccountParam( 'enabled', 0 ) == 3 ) && ( $paymentBasket->isAnyAutoRecurring() == 2 ) ? 1 : 2 ) : 0 ); $return = cbGetParam( $results, 'PROFILEID' ); $logType = 'A'; } else { $this->_setLogErrorMSG( 3, $ipn, $this->getPayName() . ' Paypal API error returned. ERROR: ' . cbGetParam( $results, 'L_LONGMESSAGE0' ) . ' CODE: ' . cbGetParam( $results, 'L_ERRORCODE0' ), cbGetParam( $results, 'L_SHORTMESSAGE0' ) . '. ' . CBPTXT::T( 'Please contact site administrator to check error log.' ) ); $logType = 'W'; } } $ipn = $this->_logNotification( $logType, $now, $paymentBasket, $card, $requestParams, $response, $results, $return ); } else { $this->_setLogErrorMSG( 3, $ipn, $this->getPayName() . ' Needed Paypal API username, password and signature not set.', CBPTXT::T( "Submitted subscription payment didn't return an error but didn't complete." ) . ' ' . CBPTXT::T( 'Please contact site administrator to check error log.' ) ); } return $return; }