Example #1
0
 /**
  *   Get the form variables for the purchase button.
  *
  *   @uses   PaymentGw::_Supports()
  *   @uses   _encButton()
  *   @uses   getActionUrl()
  *   @return string      HTML for purchase button
  */
 public function CheckoutButton($cart)
 {
     global $_PP_CONF, $_USER, $_TABLES;
     if (!$this->_Supports('checkout')) {
         return '';
     }
     $cartItems = $cart->Cart();
     $cartID = $cart->CartID();
     $custom_arr = array('uid' => $_USER['uid'], 'transtype' => 'cart_upload', 'cart_id' => $cartID);
     $fields = array('cmd' => '_cart', 'upload' => '1', 'cancel_return' => PAYPAL_URL . '/index.php?view=cart', 'return' => PAYPAL_URL . '/index.php?thanks=paypal', 'rm' => '2', 'paymentaction' => 'sale', 'notify_url' => $this->ipn_url, 'currency_code' => $this->currency_code, 'custom' => str_replace('"', '\'', serialize($custom_arr)));
     $address = $cart->getAddress('shipto');
     if (!empty($address)) {
         list($fname, $lname) = explode(' ', $address['name']);
         $fields['first_name'] = htmlspecialchars($fname);
         $fields['last_name'] = htmlspecialchars($lname);
         $fields['address1'] = htmlspecialchars($address['address1']);
         $fields['address2'] = htmlspecialchars($address['address2']);
         $fields['city'] = htmlspecialchars($address['city']);
         $fields['state'] = htmlspecialchars($address['state']);
         $fields['country'] = htmlspecialchars($address['country']);
         $fields['zip'] = htmlspecialchars($address['zip']);
     }
     $i = 1;
     $total_amount = 0;
     $shipping = 0;
     $weight = 0;
     foreach ($cartItems as $cart_item_id => $item) {
         //$opt_str = '';
         list($db_item_id, $options) = explode('|', $item['item_id']);
         if (is_numeric($db_item_id)) {
             $P = new Product($db_item_id);
             $db_item_id = DB_escapeString($db_item_id);
             $oc = 0;
             if (is_array($item['options'])) {
                 $opts = explode(',', $options);
                 foreach ($opts as $optval) {
                     $opt_info = $P->getOption($optval);
                     if ($opt_info) {
                         $opt_str .= ', ' . $opt_info['value'];
                         $fields['on' . $oc . '_' . $i] = $opt_info['name'];
                         $fields['os' . $oc . '_' . $i] = $opt_info['value'];
                         $oc++;
                     }
                 }
                 //$item['descrip'] .= $opt_str;
             } else {
                 $opts = array();
             }
             $fields['amount_' . $i] = $P->getPrice($opts, $item['quantity']);
             if ($P->taxable == 0) {
                 $fields['tax_' . $i] = '0.00';
             }
         } else {
             // Plugin item
             $fields['amount_' . $i] = $item['price'];
         }
         //$fields['item_number_' . $i] = htmlspecialchars($item['item_id']);
         $fields['item_number_' . $i] = (int) $cart_item_id;
         $fields['item_name_' . $i] = htmlspecialchars($item['descrip']);
         $total_amount += $item['price'];
         if (is_array($item['extras']['custom'])) {
             foreach ($item['extras']['custom'] as $id => $val) {
                 $fields['on' . $oc . '_' . $i] = $P->getCustom($id);
                 $fields['os' . $oc . '_' . $i] = $val;
                 $oc++;
             }
         }
         $fields['quantity_' . $i] = $item['quantity'];
         if (isset($item['shipping'])) {
             $fields['shipping_' . $i] = $item['shipping'];
             $shipping += $item['shipping'];
         }
         if (isset($item['weight']) && $item['weight'] > 0) {
             $weight += $item['weight'];
         }
         if (isset($item['tax'])) {
             $fields['tax_' . $i] = $item['tax'];
         } elseif (isset($item['options']['tax'])) {
             $fields['tax_' . $i] = $item['options']['tax'];
         }
         $i++;
     }
     if ($shipping > 0) {
         $total_amount += $shipping;
     }
     if ($weight > 0) {
         $fields['weight_cart'] = $weight;
         $fields['weight_unit'] = $_PP_CONF['weight_unit'] == 'kgs' ? 'kgs' : 'lbs';
     }
     // Set the business e-mail address based on the total puchase amount
     // There must be an address configured; if not then this gateway can't
     // be used for this purchase
     $this->setReceiver($total_amount);
     $fields['business'] = $this->receiver_email;
     if (empty($fields['business'])) {
         return '';
     }
     $gatewayVars = array();
     $enc_btn = '';
     if ($this->config['encrypt']) {
         $enc_btn = self::_encButton($fields);
         if (!empty($enc_btn)) {
             $gatewayVars[] = '<input type="hidden" name="cmd" value="_s-xclick" />';
             $gatewayVars[] = '<input type="hidden" name="encrypted" ' . 'value="' . $enc_btn . '" />';
         }
     }
     if (empty($enc_btn)) {
         // If we didn't get an encrypted button, set the plaintext vars
         foreach ($fields as $name => $value) {
             $gatewayVars[] = '<input type="hidden" name="' . $name . '" value="' . $value . '" />';
         }
     }
     $gateway_vars = implode("\n", $gatewayVars);
     $T = new Template(PAYPAL_PI_PATH . '/templates/buttons/' . $this->gw_name);
     $T->set_file(array('btn' => 'btn_checkout.thtml'));
     $T->set_var('paypal_url', $this->getActionUrl());
     $T->set_var('gateway_vars', $gateway_vars);
     $retval = $T->parse('', 'btn');
     return $retval;
 }
Example #2
0
 /**
  *   Create and populate an Order record for this purchase.
  *   Gets the billto and shipto addresses from the cart, if any.
  *   Items are saved in the purchases table by handlePurchase().
  *
  *   This function is called only by our own handlePurchase() function,
  *   but is made "protected" so a derived class can use it if necessary.
  *
  *   @return string  Order ID, to link to the purchases table
  */
 protected function CreateOrder()
 {
     global $_TABLES, $_PP_CONF;
     // See if an order already exists for this transaction.
     // If so, load it and update the status. If not, continue on
     // and create a new order
     $order_id = DB_getItem($_TABLES['paypal.orders'], 'order_id', "pmt_txn_id='" . DB_escapeString($this->pp_data['txn_id']) . "'");
     if (!empty($order_id)) {
         $this->Order = new ppOrder($order_id);
         if ($this->Order->order_id != '') {
             $this->Order->log_user = $this->gw->Description();
             $this->Order->UpdateStatus($this->pp_data['status']);
         }
         return 2;
     }
     $this->Order = new ppOrder();
     USES_paypal_class_cart();
     if (isset($this->pp_data['custom']['cart_id'])) {
         $cart = new ppCart($this->pp_data['custom']['cart_id']);
         if (!$_PP_CONF['sys_test_ipn'] && !$cart->hasItems()) {
             return 1;
             // shouldn't normally be empty except during testing
         }
     } else {
         $cart = NULL;
     }
     $uid = (int) $this->pp_data['custom']['uid'];
     $this->Order->uid = $uid;
     $this->Order->buyer_email = $this->pp_data['payer_email'];
     $this->Order->status = !empty($this->pp_data['status']) ? $this->pp_data['status'] : 'pending';
     if ($uid > 1) {
         USES_paypal_class_userinfo();
         $U = new ppUserInfo($uid);
     }
     // Get the billing and shipping addresses from the cart record,
     // if any.  There may not be a cart in the database if it was
     // removed by a previous IPN, e.g. this is the 'completed' message
     // and we already processed a 'pending' message
     if ($cart) {
         $BillTo = $cart->getAddress('billto');
     }
     if (empty($BillTo) && $uid > 1) {
         $BillTo = $U->getDefaultAddress('billto');
     }
     if (is_array($BillTo)) {
         $this->Order->setBilling($BillTo);
     }
     $ShipTo = $this->pp_data['shipto'];
     if (empty($ShipTo)) {
         if ($cart) {
             $ShipTo = $cart->getAddress('shipto');
         }
         if (empty($ShipTo) && $uid > 1) {
             $ShipTo = $U->getDefaultAddress('shipto');
         }
     }
     if (is_array($ShipTo)) {
         $this->Order->setShipping($ShipTo);
     }
     if (isset($this->pp_data['shipto']['phone'])) {
         $this->Order->phone = $this->pp_data['shipto']['phone'];
     }
     $this->Order->pmt_method = $this->gw_id;
     $this->Order->pmt_txn_id = $this->pp_data['txn_id'];
     $this->Order->tax = $this->pp_data['pmt_tax'];
     $this->Order->shipping = $this->pp_data['pmt_shipping'];
     $this->Order->handling = $this->pp_data['pmt_handling'];
     $this->Order->buyer_email = $this->pp_data['payer_email'];
     $this->Order->log_user = $this->gw->Description();
     if ($cart) {
         $this->Order->instructions = $cart->getInstructions();
     }
     $order_id = $this->Order->Save();
     $db_order_id = DB_escapeString($order_id);
     $this->Order->items = array();
     foreach ($this->items as $id => $item) {
         $options = DB_escapeString($item['options']);
         $option_desc = array();
         list($item_number, $options) = explode('|', $item['item_number']);
         if (is_numeric($item_number)) {
             // For Paypal catalog options, check for options and append
             // to the description.  Update quantity on hand if tracking
             // is enabled.  These actions don't apply to items from
             // other plugins.
             $P = new Product($item['item_id']);
             $item['short_description'] = $P->short_description;
             if (!empty($options)) {
                 // options is expected as CSV
                 $sql = "SELECT attr_name, attr_value\n                            FROM {$_TABLES['paypal.prod_attr']}\n                            WHERE attr_id IN ({$options})";
                 $optres = DB_query($sql);
                 $opt_str = '';
                 while ($O = DB_fetchArray($optres, false)) {
                     $opt_str .= ', ' . $O['attr_value'];
                     $option_desc[] = $O['attr_name'] . ': ' . $O['attr_value'];
                 }
             }
             // Get the product record and custom strings
             if (isset($item['extras']['custom']) && is_array($item['extras']['custom']) && !empty($item['extras']['custom'])) {
                 foreach ($item['extras']['custom'] as $cust_id => $cust_val) {
                     $option_desc[] = $P->getCustom($cust_id) . ': ' . $cust_val;
                 }
             }
         }
         $sql = "INSERT INTO {$_TABLES['paypal.purchases']} SET\n                    order_id = '{$db_order_id}',\n                    product_id = '{$item['item_number']}',\n                    description = '" . DB_escapeString($item['short_description']) . "',\n                    quantity = '{$item['quantity']}',\n                    user_id = '{$this->pp_data['custom']['uid']}',\n                    txn_type = '{$this->pp_data['custom']['transtype']}',\n                    txn_id = '{$this->pp_data['txn_id']}',\n                    purchase_date = '{$this->sql_date}',\n                    status = 'paid',\n                    token = '" . md5(time()) . "',\n                    price = " . (double) $item['price'] . ",\n                    options = '{$options}',\n                    options_text = '" . DB_escapeString(json_encode($option_desc)) . "'";
         // add an expiration date if appropriate
         if (is_numeric($item['expiration']) && $item['expiration'] > 0) {
             $sql .= ", expiration = DATE_ADD('{$this->sql_date}', INTERVAL {$item['expiration']} DAY)";
         }
         PAYPAL_debug($sql);
         DB_query($sql);
     }
     // foreach item
     // Reload the order to get the items
     $this->Order->Load();
     // If this was a user's cart, then clear that also
     if (isset($this->pp_data['custom']['cart_id']) && !empty($this->pp_data['custom']['cart_id'])) {
         if (!$_PP_CONF['sys_test_ipn']) {
             DB_delete($_TABLES['paypal.cart'], 'cart_id', $this->pp_data['custom']['cart_id']);
             PAYPAL_debug('Cart ' . $this->pp_data['custom']['cart_id'] . ' deleted');
         }
     } else {
         PAYPAL_debug('no cart to delete');
     }
     return 0;
 }