Example #1
0
 /**
  *   Constructor.
  *   Set up the pp_data array.
  */
 function __construct($A = array())
 {
     $this->gw_id = 'amazon';
     parent::__construct($A);
     list($ccode, $amount) = preg_split('/\\ +/', $A['transactionAmount']);
     $this->pp_data['txn_id'] = $A['transactionId'];
     $this->pp_data['payer_email'] = $A['buyerEmail'];
     $this->pp_data['payer_name'] = $A['buyerName'];
     $this->pp_data['pmt_date'] = strftime('%d %b %Y %H:%M:%S', $A['transactionDate']);
     $this->pp_data['pmt_gross'] = (double) $amount;
     $this->pp_data['gw_name'] = $this->gw->Description();
     $this->pp_data['pmt_status'] = $A['status'];
     // Check a couple of vars to see if a shipping address was supplied
     if (isset($A['addressLine1']) || isset($A['city'])) {
         $this->pp_data['shipto'] = array('name' => $A['addressName'], 'address1' => $A['addressLine1'], 'address2' => $A['addressLine2'], 'city' => $A['city'], 'state' => $A['state'], 'country' => $A['country'], 'zip' => $A['zip'], 'phone' => $A['phoneNumber']);
     }
     $custom = explode(';', $A['referenceId']);
     foreach ($custom as $name => $temp) {
         list($name, $value) = explode(':', $temp);
         $this->pp_data['custom'][$name] = $value;
     }
     if ($this->pp_data['custom']['transtype'] == 'cart') {
         USES_paypal_class_cart();
         $cart = new ppCart($this->pp_data['custom']['cart_id']);
         foreach ($cart->Cart() as $itm_id => $data) {
             $this->AddItem($itm_id, $data['quantity'], $data['price']);
         }
     } else {
         $items = explode('::', $A['paymentReason']);
         foreach ($items as $item) {
             list($itm_id, $price, $qty) = explode(';', $item);
             $this->AddItem($itm_id, $qty, $price);
         }
     }
 }
Example #2
0
 /**
  *   Process an incoming IPN transaction
  *   Do the following:
  *       1. Verify IPN
  *       2. Log IPN
  *       3. Check that transaction is complete
  *       4. Check that transaction is unique
  *       5. Check for valid receiver email address
  *       6. Process IPN
  *
  *   @uses   BaseIPN::AddItem()
  *   @uses   BaseIPN::handleFailure()
  *   @uses   BaseIPN::handlePurchase()
  *   @uses   BaseIPN::isUniqueTxnId()
  *   @uses   BaseIPN::isSufficientFunds()
  *   @uses   BaseIPN::Log()
  *   @uses   Verify()
  *   @uses   isStatusCompleted()
  *   @param  array   $in     POST variables of transaction
  *   @return boolean true if processing valid and completed, false otherwise
  */
 public function Process()
 {
     // If no data has been received, then there's nothing to do.
     if (empty($this->ipn_data)) {
         return false;
     }
     if (!$this->Verify()) {
         $logId = $this->Log(false);
         $this->handleFailure(PAYPAL_FAILURE_VERIFY, "({$logId}) Verification failed");
         return false;
     } else {
         $logId = $this->Log(true);
     }
     // Set the custom data field to the exploded value.  This has to
     // be done after Verify() or the Paypal verification will fail.
     $this->pp_data['custom'] = $this->custom;
     switch ($this->ipn_data['txn_type']) {
         case 'web_accept':
             //usually buy now
         //usually buy now
         case 'send_money':
             //usually donation/send money
             // Process Buy Now & Send Money
             $fees_paid = $this->ipn_data['tax'] + $this->pp_data['pmt_shipping'] + $this->pp_data['pmt_handling'];
             if (!empty($this->ipn_data['item_number'])) {
                 if (!isset($this->ipn_data['quantity']) || (double) $this->ipn_data['quantity'] == 0) {
                     $this->ipn_data['quantity'] = 1;
                 }
                 $payment_gross = $this->pp_data['pmt_gross'] - $fees_paid;
                 $unit_price = $payment_gross / $this->ipn_data['quantity'];
                 $this->AddItem($this->ipn_data['item_number'], $this->ipn_data['quantity'], $unit_price, $this->ipn_data['item_name'], $this->pp_data['pmt_shipping'], $this->pp_data['pmt_handling']);
                 $currency = $this->pp_data['currency'];
                 PAYPAL_debug("Net Settled: {$payment_gross} {$currency}");
                 if ($this->isSufficientFunds()) {
                     $this->handlePurchase();
                 } else {
                     $this->handleFailure(PAYPAL_FAILURE_FUNDS, "({$logId}) Insufficient funds for purchase");
                     return false;
                 }
             }
             break;
         case 'cart':
             // shopping cart
             $fees_paid = $this->pp_data['pmt_tax'] + $this->pp_data['pmt_shipping'] + $this->pp_data['pmt_handling'];
             USES_paypal_class_cart();
             if (empty($this->pp_data['custom']['cart_id'])) {
                 $this->handleFailure(NULL, 'Missing Cart ID');
                 return false;
             }
             // Create a cart and read the info from the cart table.
             // Actual items purchased and prices will come from the IPN.
             $ppCart = new ppCart($this->pp_data['custom']['cart_id']);
             $Cart = $ppCart->Cart();
             $items = array();
             for ($i = 1; $i <= $this->ipn_data['num_cart_items']; $i++) {
                 // PayPal returns the total price as mc_gross_X, so divide
                 // by the quantity to get back to a unit price.
                 if (!isset($this->ipn_data["quantity{$i}"]) || (double) $this->ipn_data["quantity{$i}"] == 0) {
                     $this->ipn_data["quantity{$i}"] = 1;
                 }
                 $item_gross = $this->ipn_data["mc_gross_{$i}"];
                 if (isset($this->ipn_data["mc_shipping{$i}"])) {
                     $item_shipping = (double) $this->ipn_data["mc_shipping{$i}"];
                     $item_gross -= $item_shipping;
                 } else {
                     $item_shipping = 0;
                 }
                 if (isset($this->ipn_data["tax{$i}"])) {
                     $item_tax = (double) $this->ipn_data["tax{$i}"];
                     $item_gross -= $item_tax;
                 } else {
                     $item_tax = 0;
                 }
                 if (isset($this->ipn_data["mc_handling{$i}"])) {
                     $item_handling = (double) $this->ipn_data["mc_handling{$i}"];
                     $item_gross -= $item_handling;
                 } else {
                     $item_handling = 0;
                 }
                 $unit_price = $item_gross / (double) $this->ipn_data["quantity{$i}"];
                 // Add the item to the array for the order creation.
                 // IPN item numbers are indexes into the cart, so get the
                 // actual product ID from the cart
                 $this->AddItem($Cart[$this->ipn_data["item_number{$i}"]]['item_id'], $this->ipn_data["quantity{$i}"], $unit_price, $this->ipn_data["item_name{$i}"], $item_shipping, $item_handling, $item_tax, $Cart[$this->ipn_data["item_number{$i}"]]['extras']);
             }
             $payment_gross = $this->ipn_data['mc_gross'] - $fees_paid;
             PAYPAL_debug("Received {$payment_gross} gross payment");
             //$currency = $this->ipn_data['mc_currency'];
             if ($this->isSufficientFunds()) {
                 $this->handlePurchase();
             } else {
                 $this->handleFailure(PAYPAL_FAILURE_FUNDS, "({$logId}) Insufficient/incorrect funds for purchase");
                 return false;
             }
             break;
             // other, unknown, unsupported
         // other, unknown, unsupported
         default:
             switch ($this->ipn_data['reason_code']) {
                 case 'refund':
                     $this->handleRefund();
                     break;
                 default:
                     $this->handleFailure(PAYPAL_FAILURE_UNKNOWN, "({$logId}) Unknown transaction type");
                     return false;
                     break;
             }
             break;
     }
     return true;
 }
Example #3
0
 /**
  *   Processes the purchase, for purchases made without an IPN message.
  *
  *   @param  array   $vals   Submitted values, e.g. $_POST
  */
 public function handlePurchase($vals = array())
 {
     global $_TABLES, $_CONF, $_PP_CONF;
     USES_paypal_functions();
     USES_paypal_class_cart();
     USES_paypal_class_order();
     USES_paypal_class_product();
     if (!empty($vals['cart_id'])) {
         $cart = new ppCart($vals['cart_id']);
         if (!$cart->hasItems()) {
             return;
         }
         // shouldn't be empty
         $items = $cart->Cart();
     } else {
         $cart = new ppCart();
     }
     // Create an order record to get the order ID
     $Order = $this->CreateOrder($vals, $cart);
     $db_order_id = DB_escapeString($Order->order_id);
     $prod_types = 0;
     // For each item purchased, record purchase in purchase table
     foreach ($items as $id => $item) {
         //COM_errorLog("Processing item: $id");
         list($item_number, $item_opts) = PAYPAL_explode_opts($id, true);
         // If the item number is numeric, assume it's an
         // inventory item.  Otherwise, it should be a plugin-supplied
         // item with the item number like pi_name:item_number:options
         if (PAYPAL_is_plugin_item($item_number)) {
             PAYPAL_debug("handlePurchase for Plugin item " . $item_number);
             // Initialize item info array to be used later
             $A = array();
             // Split the item number into component parts.  It could
             // be just a single string, depending on the plugin's needs.
             $pi_info = explode(':', $item['item_number']);
             PAYPAL_debug('Paymentgw::handlePurchase() pi_info: ' . print_r($pi_info, true));
             $status = LGLIB_invokeService($pi_info[0], 'productinfo', array($item_number, $item_opts), $product_info, $svc_msg);
             if ($status != PLG_RET_OK) {
                 $product_info = array();
             }
             if (!empty($product_info)) {
                 $items[$id]['name'] = $product_info['name'];
             }
             PAYPAL_debug("Paymentgw::handlePurchase() Got name " . $items[$id]['name']);
             $vars = array('item' => $item, 'ipn_data' => array());
             $status = LGLIB_invokeService($pi_info[0], 'handlePurchase', $vars, $A, $svc_msg);
             if ($status != PLG_RET_OK) {
                 $A = array();
             }
             // Mark what type of product this is
             $prod_types |= PP_PROD_VIRTUAL;
         } else {
             PAYPAL_debug("Paypal item " . $item_number);
             $P = new Product($item_number);
             $A = array('name' => $P->name, 'short_description' => $P->short_description, 'expiration' => $P->expiration, 'prod_type' => $P->prod_type, 'file' => $P->file, 'price' => $item['price']);
             if (!empty($item_opts)) {
                 $opts = explode(',', $itemopts);
                 $opt_str = $P->getOptionDesc($opts);
                 if (!empty($opt_str)) {
                     $A['short_description'] .= " ({$opt_str})";
                 }
                 $item_number .= '|' . $item_opts;
             }
             // Mark what type of product this is
             $prod_types |= $P->prod_type;
         }
         // An invalid item number, or nothing returned for a plugin
         if (empty($A)) {
             //$this->Error("Item {$item['item_number']} not found");
             continue;
         }
         // If it's a downloadable item, then get the full path to the file.
         // TODO: pp_data isn't available here, should be from $vals?
         if (!empty($A['file'])) {
             $this->items[$id]['file'] = $_PP_CONF['download_path'] . $A['file'];
             $token_base = $this->pp_data['txn_id'] . time() . rand(0, 99);
             $token = md5($token_base);
             $this->items[$id]['token'] = $token;
         } else {
             $token = '';
         }
         $items[$id]['prod_type'] = $A['prod_type'];
         // If a custom name was supplied by the gateway's IPN processor,
         // then use that.  Otherwise, plug in the name from inventory or
         // the plugin, for the notification email.
         if (empty($item['name'])) {
             $items[$id]['name'] = $A['short_description'];
         }
         // Add the purchase to the paypal purchase table
         $uid = isset($vals['uid']) ? (int) $vals['uid'] : $_USER['uid'];
         $sql = "INSERT INTO {$_TABLES['paypal.purchases']} SET \n                        order_id = '{$db_order_id}',\n                        product_id = '{$item_number}',\n                        description = '{$items[$id]['name']}',\n                        quantity = '{$item['quantity']}', \n                        user_id = '{$uid}', \n                        txn_type = '{$this->gw_id}',\n                        txn_id = '', \n                        purchase_date = '{$_PP_CONF['now']->toMySQL()}', \n                        status = 'complete',\n                        token = '{$token}',\n                        price = " . (double) $item['price'] . ",\n                        options = '" . DB_escapeString($item_opts) . "'";
         // add an expiration date if appropriate
         if (is_numeric($A['expiration']) && $A['expiration'] > 0) {
             $sql .= ", expiration = DATE_ADD('{$_PP_CONF['now']->toMySQL()}', INTERVAL {$A['expiration']} DAY)";
         }
         //echo $sql;die;
         PAYPAL_debug($sql);
         DB_query($sql);
     }
     // foreach item
     // If this was a user's cart, then clear that also
     if (isset($vals['cart_id']) && !empty($vals['cart_id'])) {
         DB_delete($_TABLES['paypal.cart'], 'cart_id', $vals['cart_id']);
     }
 }