/**
  * @return Payment_Model_DbTable_Orders
  */
 public static function getInstance()
 {
     if (is_null(self::$_instance)) {
         self::$_instance = new self();
     }
     return self::$_instance;
 }
 public function handlePayment($data)
 {
     if (array_key_exists('test_ipn', $data) && 1 === (int) $data['test_ipn']) {
         $url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
     } else {
         $url = 'https://www.paypal.com/cgi-bin/webscr';
     }
     $req = 'cmd=_notify-validate';
     //collect the variables sent by PayPal
     foreach ($data as $key => $value) {
         $value = urlencode(stripslashes($value));
         $req .= "&{$key}={$value}";
     }
     list($status, $response) = $this->curlPost($url, $req);
     if ($status == 200 && $response == 'VERIFIED') {
         try {
             if (!isset($data['mc_gross']) || !isset($data['txn_id'])) {
                 throw new Exception('Payment_Manager::handlePayment() either mc_gross or txn_id is empty');
             }
             // get list of payment items
             // calculate price to be paid
             $items = array();
             $price_to_be_paid = 0.0;
             foreach ($data as $key => $value) {
                 if (preg_match('/^item_number/', $key)) {
                     $item = $this->getHandlerByCode($value);
                     if (!empty($item)) {
                         $items[] = $item;
                         $price_to_be_paid += $item->getItemPrice();
                     }
                 }
             }
             if ($data['mc_gross'] < $price_to_be_paid) {
                 throw new Exception('Payment_Manager::handlePayment() total payment (' . $data['mc_gross'] . ') is less than price to be paid (' . $price_to_be_paid . ')');
             }
             // all good! proceed...
             $orderModel = Payment_Model_DbTable_Orders::getInstance();
             $id_order = $orderModel->createOrderFromParams($data, $items);
         } catch (Exception $ex) {
             file_put_contents('payment-error.log', json_encode($ex) . PHP_EOL, FILE_APPEND);
         }
     } else {
         // not good. ignore, or log for investigation...
         file_put_contents('payment-error.log', json_encode($data) . PHP_EOL, FILE_APPEND);
     }
 }