예제 #1
0
 /**
  * Register delivery method with main shop module.
  */
 protected function registerDeliveryMethod()
 {
     if (class_exists('shop')) {
         $shop = shop::getInstance();
         $shop->registerDeliveryMethod($this->name, $this);
     }
 }
예제 #2
0
 /**
  * Constructor
  */
 protected function __construct()
 {
     global $section;
     parent::__construct(__FILE__);
     // register backend
     if (class_exists('backend')) {
         $backend = backend::getInstance();
         Events::connect('backend', 'user-create', 'handleUserCreate', $this);
         Events::connect('backend', 'user-delete', 'handleUserDelete', $this);
     }
     // connect to shop events
     if (class_exists('shop')) {
         $shop = shop::getInstance();
         Events::connect('shop', 'transaction-completed', 'handleTransactionCompleted', $this);
         Events::connect('shop', 'recurring-payment', 'handleRecurringPayment', $this);
         Events::connect('shop', 'recurring-payment-suspended', 'handleRecurringPaymentSuspended', $this);
     }
 }
예제 #3
0
 /**
  * Make new payment form with specified items and return
  * boolean stating the success of initial payment process.
  * 
  * @param array $data
  * @param array $items
  * @param string $return_url
  * @param string $cancel_url
  * @return string
  */
 public function new_payment($data, $items, $return_url, $cancel_url)
 {
     global $language;
     $description = '';
     $tmp_items = array_slice($items, 0, 5);
     $tmp_names = array();
     foreach ($tmp_items as $item) {
         $tmp_names[] = $item['name'][$language];
     }
     $description = implode(', ', $tmp_names);
     // add dots if there are more than 5 items
     if (count($items) > 5) {
         $description .= ', ...';
     }
     // get proper currency code
     $shop_module = shop::getInstance();
     $currency = $shop_module->getDefaultCurrency();
     if (array_key_exists($currency, $this->currency_aliases)) {
         $currency = $this->currency_aliases[$currency];
     }
     $currency_code = -1;
     if (array_key_exists($currency, $this->currency)) {
         $currency_code = $this->currency[$currency];
     }
     // prepare basic parameters
     $params = array('currency' => $currency_code, 'TranzilaToken' => $data['uid'], 'sum' => $data['total'] + $data['shipping'] + $data['handling'], 'cred_type' => 1, 'pdesc' => $description);
     // prepare items for checkout
     foreach ($items as $item) {
         $item = array_shift($items);
     }
     // create HTML form
     $result = '';
     foreach ($params as $key => $value) {
         $result .= "<input type=\"hidden\" name=\"{$key}\" value=\"{$value}\">";
     }
     return $result;
 }
예제 #4
0
 /**
  * Complete checkout and charge money.
  */
 public function completeCheckout()
 {
     global $language;
     $shop = shop::getInstance();
     $return_url = fix_chars($_REQUEST['return_url']);
     $recurring = isset($_REQUEST['type']) && $_REQUEST['type'] == 'recurring';
     $transaction_uid = $_SESSION['transaction']['uid'];
     // get billing information
     $billing = array();
     $fields = array('billing_full_name', 'billing_card_type', 'billing_credit_card', 'billing_expire_month', 'billing_expire_year', 'billing_cvv');
     foreach ($fields as $field) {
         if (isset($_REQUEST[$field])) {
             $billing[$field] = fix_chars($_REQUEST[$field]);
         }
     }
     // create recurring profile
     if ($recurring) {
         $request_id = 0;
         $plan_name = $_SESSION['recurring_plan'];
         $manager = PayPal_PlansManager::getInstance();
         $plan = $manager->getSingleItem($manager->getFieldNames(), array('text_id' => $plan_name));
         $current_plan = $shop->getRecurringPlan();
         // cancel existing recurring payment if exists
         if (!is_null($current_plan)) {
             $plans = $this->get_recurring_plans();
             $current_group = null;
             // get plan data
             if (isset($plans[$current_plan->plan_name])) {
                 $current_group = $plans[$current_plan->plan_name]['group'];
             }
             // cancel current plan
             if (!is_null($current_group) && $current_group == $plan->group_name) {
                 $shop->cancelTransaction($current_plan->transaction);
             }
         }
         // generate params for description
         $plan_params = array('price' => $plan->price, 'period' => $plan->interval_count, 'unit' => $plan->interval, 'setup' => $plan->setup_price, 'trial_period' => $plan->trial_count, 'trial_unit' => $plan->trial);
         // charge one time setup fee
         // TODO: Charge one time setup fee.
         // create recurring payments profile
         $recurring_fields = $fields;
         // set buyer information
         $name = explode(' ', $billing['billing_full_name']);
         $recurring_fields['CREDITCARDTYPE'] = $this->card_type[$billing['billing_card_type']];
         $recurring_fields['ACCT'] = $billing['billing_credit_card'];
         $recurring_fields['EXPDATE'] = $billing['billing_expire_month'] . $billing['billing_expire_year'];
         $recurring_fields['FIRSTNAME'] = $name[0];
         $recurring_fields['LASTNAME'] = $name[1];
         // set starting date of the profile
         $start_timestamp = strtotime($plan->start_time);
         if ($start_timestamp < time()) {
             $start_timestamp = time();
         }
         $recurring_fields['PROFILESTARTDATE'] = strftime('%Y-%m-%dT%T%z', $start_timestamp);
         // set description
         $recurring_fields['DESC'] = $shop->formatRecurring($plan_params);
         // set currency
         $recurring_fields['AMT'] = $plan->price;
         $recurring_fields['CURRENCYCODE'] = $shop->getDefaultCurrency();
         // billing period
         $recurring_fields['BILLINGPERIOD'] = $this->units[$plan->interval];
         $recurring_fields['BILLINGFREQUENCY'] = $plan->interval_count;
         // trial period
         if ($plan->trial_count > 0) {
             $recurring_fields['TRIALBILLINGPERIOD'] = $this->units[$plan->trial];
             $recurring_fields['TRIALBILLINGFREQUENCY'] = $plan->trial_count;
             $recurring_fields['TRIALTOTALBILLINGCYCLES'] = 1;
         }
         // make api call
         $response = PayPal_Helper::callAPI(PayPal_Helper::METHOD_CreateRecurringPaymentsProfile, $recurring_fields);
         if ($response['ACK'] == 'Success' || $response['ACK'] == 'SuccessWithWarning') {
             // update transaction token
             $shop->setTransactionToken($transaction_uid, fix_chars($response['PROFILEID']));
             // update transaction status
             if ($response['PROFILESTATUS'] == 'ActiveProfile') {
                 $shop->setTransactionStatus($transaction_uid, TransactionStatus::COMPLETED);
             }
         } else {
             // report error
             $error_code = urldecode($response['L_ERRORCODE0']);
             $error_long = urldecode($response['L_LONGMESSAGE0']);
             trigger_error("PayPal_Express: ({$error_code}) - {$error_long}", E_USER_ERROR);
         }
         // redirect user
         header('Location: ' . $return_url, true, 302);
     }
 }
예제 #5
0
 /**
  * Get available delivery types for selected items. Each type needs
  * to return estimated delivery time, cost and name of service.
  *
  * Example of items array:
  * 		$items = array(
  * 					array(
  * 						'package'		=> 0, // number identifying package
  * 						'properties'	=> array(),
  * 						'package_type'	=> 0,
  * 						'width'			=> 0.2,
  * 						'height'		=> 0.5,
  * 						'length'		=> 1,
  * 						'weight'		=> 0,
  * 						'units'			=> 1,
  * 						'count'			=> 1
  * 					)
  * 				);
  *
  * Example of shipper array:
  * 		$shipper = array(
  * 					'street'	=> array(),
  * 					'city'		=> '',
  * 					'zip_code'	=> '',
  * 					'state'		=> '',
  * 					'country'	=> ''
  * 				);
  *
  * Example of recipient array:
  * 		$recipient = array(
  * 					'street'	=> array(),
  * 					'city'		=> '',
  * 					'zip_code'	=> '',
  * 					'state'		=> '',
  * 					'country'	=> ''
  * 				);
  *
  * Example of result array:
  *		$result = array(
  *					'normal' => array('Normal', 19.95, 'USD', 1364040000, 1365040000),
  *					'express' => array('Express', 33.23, 'USD', 1363040000, 1364040000),
  *					'express_no_estimate' => array('Express', 8.00, 'USD', false, false)
  *				);
  *
  * @param array $items
  * @param array $shipper
  * @param array $recipient
  * @param string $transaction_id
  * @param string $preferred_currency
  * @return array
  */
 public function getDeliveryTypes($items, $shipper, $recipient, $transaction_id, $preferred_currency)
 {
     $shop = shop::getInstance();
     $manager = IntervalManager::getInstance();
     $time_manager = IntervalTimeManager::getInstance();
     $days = array();
     $result = array();
     // load all delivery intervals
     $intervals = $manager->getItems($manager->getFieldNames(), array());
     if (count($intervals) == 0) {
         return $result;
     }
     foreach ($intervals as $interval) {
         // get hours
         $times = $time_manager->getItems($time_manager->getFieldNames(), array('interval' => $interval->id));
         // make sure there are hours defined in this interval
         if (count($times) == 0) {
             continue;
         }
         // collect delivery hours
         for ($i = 0; $i < 7; $i++) {
             if ($interval->days[$i] == '1') {
                 if (!isset($days[$i])) {
                     $days[$i] = array();
                 }
                 foreach ($times as $time) {
                     $days[$i][] = $time;
                 }
             }
         }
     }
     // calculate shipping dates for specified number of days
     $today = mktime(0, 0, 0);
     $date_format = $this->parent->getLanguageConstant('format_date_short');
     $time_format = $this->parent->getLanguageConstant('format_time_short');
     $currency = $shop->getDefaultCurrency();
     for ($i = 0; $i < $this->days_to_show; $i++) {
         $current_date = $today + $i * (24 * 60 * 60);
         $day_of_week = (int) date('N', $current_date) - 1;
         // skip day if there are no deliveries
         if (!isset($days[$day_of_week])) {
             continue;
         }
         // add intervals
         foreach ($days[$day_of_week] as $time) {
             $start = strtotime($time->start, $current_date);
             $end = strtotime($time->end, $current_date);
             // skip past intervals
             if (time() > $start) {
                 continue;
             }
             // add new delivery date
             $key = date($date_format . ' ' . $time_format, $start);
             $result[$key] = array($this->parent->getLanguageConstant('label_' . ($day_of_week + 1)), $time->amount, $currency, $start, $end);
         }
     }
     return $result;
 }
예제 #6
0
 /**
  * Get available delivery types for selected items. Each type needs
  * to return estimated delivery time, cost and name of service.
  *
  * @param array $items
  * @param array $shipper
  * @param array $recipient
  * @param string $transaction_id
  * @return array
  */
 public function getDeliveryTypes($items, $shipper, $recipient, $transaction_id, $preferred_currency)
 {
     $shop = shop::getInstance();
     $debug = $shop->isDebug();
     $result = array();
     $request = array();
     $client = new SoapClient($this->wsdl[FedEx_DeliveryMethod::RATE_SERVICE], array('trace' => $debug));
     if (empty($shipper)) {
         throw new Exception('Missing shipper information!');
     }
     if (empty($recipient)) {
         throw new Exception('Missing recipient information!');
     }
     // populate request header
     $this->_populateCredentials($request);
     $this->_populateClientDetails($request);
     $this->_populateTransactionDetails($request, $transaction_id);
     $this->_populateVersionInformation($request, FedEx_DeliveryMethod::RATE_SERVICE);
     // add remaining request information
     $request['ReturnTransitAndCommit'] = true;
     // request tranzit time and commit data
     $request['RequestedShipment'] = array('RateRequestTypes' => 'PREFERRED');
     $request['RequestedShipment']['DropoffType'] = 'REGULAR_PICKUP';
     $request['RequestedShipment']['ShipTimestamp'] = date('c');
     $request['RequestedShipment']['PackagingType'] = 'YOUR_PACKAGING';
     $request['RequestedShipment']['PreferredCurrency'] = $preferred_currency;
     $request['RequestedShipment']['Shipper'] = array('Contact' => array(), 'Address' => array('StreetLines' => $shipper['street'], 'City' => $shipper['city'], 'PostalCode' => $shipper['zip_code'], 'StateOrProvinceCode' => $shipper['state'], 'CountryCode' => $shipper['country']));
     $request['RequestedShipment']['Recipient'] = array('Contact' => array(), 'Address' => array('StreetLines' => $recipient['street'], 'City' => $recipient['city'], 'PostalCode' => $recipient['zip_code'], 'StateOrProvinceCode' => strlen($recipient['state']) >= 2 ? '' : $recipient['state'], 'CountryCode' => $recipient['country']));
     $request['RequestedShipment']['ShippingChargesPayment'] = array('PaymentType' => 'SENDER', 'Payor' => array('ResponsibleParty' => array('AccountNumber' => $this->parent->settings['fedex_account'], 'CountryCode' => $shipper['country'])));
     // get package id's and count items for each package
     $packages = array();
     foreach ($items as $item) {
         $package_id = $item['package'];
         if (array_key_exists($package_id, $packages)) {
             $packages[$package_id]++;
         } else {
             $packages[$package_id] = 1;
         }
     }
     // append all the items to list
     $fedex_items = array();
     foreach ($items as $item) {
         $new_item = array('Weight' => array('Value' => $item['weight'], 'Units' => 'KG'), 'Dimensions' => array('Width' => $item['width'], 'Height' => $item['height'], 'Length' => $item['length'], 'Units' => 'CM'));
         $new_item['SequenceNumber'] = $item['package'];
         $new_item['GroupPackageCount'] = $packages[$item['package']];
         $fedex_items[] = $new_item;
     }
     $request['RequestedShipment']['PackageCount'] = count($packages);
     $request['RequestedShipment']['RequestedPackageLineItems'] = $fedex_items;
     // get response from server
     $response = $client->getRates($request);
     if (count($response->RateReplyDetails) > 0) {
         foreach ($response->RateReplyDetails as $type) {
             // extract data from response
             $id = $type->ServiceType;
             $name = $this->parent->getLanguageConstant($id);
             $timestamp = strtotime($type->DeliveryTimestamp);
             $amount = $type->RatedShipmentDetails[0]->ShipmentRateDetail->TotalNetCharge->Amount;
             $currency = $type->RatedShipmentDetails[0]->ShipmentRateDetail->TotalNetCharge->Currency;
             // add new delivery type to result
             $result[] = array(!empty($name) ? $name : $id, $amount, $currency, null, $timestamp ? $timestamp : null);
         }
     }
     return $result;
 }
예제 #7
0
 /**
  * Show price for this delivery method.
  *
  * @param array $tag_params
  * @param array $children
  */
 private function show_price($tag_params, $children)
 {
     $shop = shop::getInstance();
     $template = $this->loadTemplate($tag_params, 'price.xml');
     // prepare parameters
     $params = array('price' => 10, 'currency' => $shop->getDefaultCurrency());
     // parse template
     $template->restoreXML();
     $template->setLocalParams($params);
     $template->parse();
 }
예제 #8
0
 /**
  * Charge specified amount with specified token and transaction.
  */
 public function chargeToken()
 {
     $transaction_uid = fix_chars($_REQUEST['transaction_uid']);
     $stripe_token = fix_chars($_REQUEST['stripe_token']);
     $manager = ShopTransactionsManager::getInstance();
     $currency_manager = ShopCurrenciesManager::getInstance();
     $transaction = null;
     // make sure we are working on same transaction for current user
     if (isset($_SESSION['transaction']) && $_SESSION['transaction']['uid'] == $transaction_uid) {
         $transaction = $manager->getSingleItem($manager->getFieldNames(), array('uid' => $transaction_uid));
     }
     if (is_object($transaction)) {
         $currency = $currency_manager->getSingleItem(array('currency'), array('id' => $transaction->currency));
         try {
             // create charge
             Stripe::setApiKey($this->getPrivateKey());
             $charge = Stripe_Charge::create(array('amount' => $transaction->total * 100, 'currency' => $currency->currency, 'card' => $stripe_token, 'description' => null));
         } catch (Stripe_CardError $error) {
         }
         // update transaction status
         if (is_object($charge) && $charge->paid) {
             $shop = shop::getInstance();
             $shop->setTransactionToken($transaction_uid, $charge->id);
             $shop->setTransactionStatus($transaction_uid, TransactionStatus::COMPLETED);
         }
     }
 }
예제 #9
0
파일: paypal.php 프로젝트: tareqy/Caracal
 /**
  * Handle recurring payment IPN.
  *
  * @param object $transaction
  * @param string $type
  * @param float $amount
  * @return boolean
  */
 private function handleRecurringIPN($transaction, $type, $amount)
 {
     $result = false;
     $shop = shop::getInstance();
     $plan_manager = ShopTransactionPlansManager::getInstance();
     // get plan associated with this transaction
     $plan = $plan_manager->getSingleItem($plan_manager->getFieldNames(), array('transaction' => $transaction->id));
     if (!is_object($plan)) {
         trigger_error('PayPal: Unable to handle IPN, unable to get plan for transaction: ' . $transaction->id, E_USER_WARNING);
         return $result;
     }
     // notification type to status relation
     $status = array('recurring_payment' => RecurringPayment::ACTIVE, 'recurring_payment_expired' => RecurringPayment::EXPIRED, 'recurring_payment_failed' => RecurringPayment::FAILED, 'recurring_payment_profile_created' => RecurringPayment::PENDING, 'recurring_payment_profile_cancel' => RecurringPayment::CANCELED, 'recurring_payment_skipped' => RecurringPayment::SKIPPED, 'recurring_payment_suspended' => RecurringPayment::SUSPENDED, 'recurring_payment_suspended_due_to_max_failed_payment' => RecurringPayment::SUSPENDED);
     // add new recurring payment
     $result = $shop->addRecurringPayment($plan->id, $amount, $status[$type]);
     return $result;
 }
예제 #10
0
 /**
  * Complete checkout and charge money.
  */
 public function completeCheckout()
 {
     global $language;
     // prepare data for new recurring profile
     $shop = shop::getInstance();
     $token = escape_chars($_REQUEST['token']);
     $payer_id = escape_chars($_REQUEST['payer_id']);
     $return_url = fix_chars($_REQUEST['return_url']);
     $recurring = isset($_REQUEST['type']) && $_REQUEST['type'] == 'recurring';
     $transaction_uid = $_SESSION['transaction']['uid'];
     // get buyer information
     $fields = array('TOKEN' => $token);
     $response = PayPal_Helper::callAPI(PayPal_Helper::METHOD_GetExpressCheckoutDetails, $fields);
     // update transaction status and buyer
     if ($response['ACK'] == 'Success' || $response['ACK'] == 'SuccessWithWarning') {
         $buyer = array('first_name' => $response['FIRSTNAME'], 'last_name' => $response['LASTNAME'], 'email' => $response['EMAIL'], 'uid' => $response['PAYERID']);
         $shop->updateBuyerInformation($transaction_uid, $buyer);
     } else {
         // report error
         $error_code = urldecode($response['L_ERRORCODE0']);
         $error_long = urldecode($response['L_LONGMESSAGE0']);
         trigger_error("PayPal_Express: ({$error_code}) - {$error_long}", E_USER_ERROR);
     }
     // create recurring profile
     if ($recurring) {
         $request_id = 0;
         $plan_name = $_SESSION['recurring_plan'];
         $manager = PayPal_PlansManager::getInstance();
         $plan = $manager->getSingleItem($manager->getFieldNames(), array('text_id' => $plan_name));
         $current_plan = $shop->getRecurringPlan();
         // cancel existing recurring payment if exists
         if (!is_null($current_plan)) {
             $plans = $this->get_recurring_plans();
             $current_group = null;
             // get plan data
             if (isset($plans[$current_plan->plan_name])) {
                 $current_group = $plans[$current_plan->plan_name]['group'];
             }
             // cancel current plan
             if (!is_null($current_group) && $current_group == $plan->group_name) {
                 $shop->cancelTransaction($current_plan->transaction);
             }
         }
         // generate params for description
         $plan_params = array('price' => $plan->price, 'period' => $plan->interval_count, 'unit' => $plan->interval, 'setup' => $plan->setup_price, 'trial_period' => $plan->trial_count, 'trial_unit' => $plan->trial);
         // charge one time setup fee
         if (is_object($plan) && $plan->setup_price > 0) {
             $setup_fields = $fields;
             $setup_fields["PAYMENTREQUEST_{$request_id}_AMT"] = $plan->setup_price;
             $setup_fields["PAYMENTREQUEST_{$request_id}_CURRENCYCODE"] = $shop->getDefaultCurrency();
             $setup_fields["PAYMENTREQUEST_{$request_id}_DESC"] = $this->parent->getLanguageConstant('api_setup_fee');
             $setup_fields["PAYMENTREQUEST_{$request_id}_INVNUM"] = $_SESSION['transaction']['uid'];
             $setup_fields["PAYMENTREQUEST_{$request_id}_PAYMENTACTION"] = 'Sale';
             $response = PayPal_Helper::callAPI(PayPal_Helper::METHOD_DoExpressCheckoutPayment, $setup_fields);
         }
         // create recurring payments profile
         $recurring_fields = $fields;
         // set starting date of the profile
         $start_timestamp = strtotime($plan->start_time);
         if ($start_timestamp < time()) {
             $start_timestamp = time();
         }
         $recurring_fields['PROFILESTARTDATE'] = strftime('%Y-%m-%dT%T%z', $start_timestamp);
         $recurring_fields['PAYERID'] = $payer_id;
         // set description
         $recurring_fields['DESC'] = $shop->formatRecurring($plan_params);
         // set currency
         $recurring_fields['AMT'] = $plan->price;
         $recurring_fields['CURRENCYCODE'] = $shop->getDefaultCurrency();
         // billing period
         $recurring_fields['BILLINGPERIOD'] = $this->units[$plan->interval];
         $recurring_fields['BILLINGFREQUENCY'] = $plan->interval_count;
         // trial period
         if ($plan->trial_count > 0) {
             $recurring_fields['TRIALBILLINGPERIOD'] = $this->units[$plan->trial];
             $recurring_fields['TRIALBILLINGFREQUENCY'] = $plan->trial_count;
             $recurring_fields['TRIALTOTALBILLINGCYCLES'] = 1;
         }
         // make api call
         $response = PayPal_Helper::callAPI(PayPal_Helper::METHOD_CreateRecurringPaymentsProfile, $recurring_fields);
         if ($response['ACK'] == 'Success' || $response['ACK'] == 'SuccessWithWarning') {
             // update transaction token
             $shop->setTransactionToken($transaction_uid, fix_chars($response['PROFILEID']));
             // update transaction status
             if ($response['PROFILESTATUS'] == 'ActiveProfile') {
                 $shop->setTransactionStatus($transaction_uid, TransactionStatus::COMPLETED);
             }
         } else {
             // report error
             $error_code = urldecode($response['L_ERRORCODE0']);
             $error_long = urldecode($response['L_LONGMESSAGE0']);
             trigger_error("PayPal_Express: ({$error_code}) - {$error_long}", E_USER_ERROR);
         }
         // redirect user
         header('Location: ' . $return_url, true, 302);
     }
 }