예제 #1
0
 /**
  * Perform verification of the payment, this is called from the payment gatewa
  *
  * @return	bool	Whether the payment is valid
  */
 public function verify_payment()
 {
     $this->registry->input->clean_array_gpc('p', array('serial-number' => vB_Cleaner::TYPE_NOHTML));
     if (!$this->registry->GPC['serial-number']) {
         $this->sendHeader(false);
         $this->error_code = 'missing_serial_number';
         return false;
     }
     if (!$this->test()) {
         $this->sendHeader(false);
         $this->error_code = 'Payment processor not configured';
         return false;
     }
     $xml = new vB_XML_Builder();
     $xml->add_group('notification-history-request', array('xmlns' => 'http://checkout.google.com/schema/2'));
     $xml->add_tag('serial-number', $this->registry->GPC['serial-number']);
     $xml->close_group('notification-history-request');
     $xmlString = $xml->fetch_xml();
     $submitUrl = ($this->settings['sandbox'] ? $this->sandboxNotifyUrl : $this->productionNotifyUrl) . trim($this->settings['google_merchant_id']);
     $headers = array('Authorization: Basic ' . base64_encode(trim($this->settings['google_merchant_id']) . ':' . trim($this->settings['google_merchant_key'])), 'Content-Type: application/xml; charset=UTF-8', 'Accept: application/xml; charset=UTF-8');
     $vurl = new vB_vURL();
     $vurl->set_option(VURL_URL, $submitUrl);
     $vurl->set_option(VURL_USERAGENT, 'vBulletin/' . SIMPLE_VERSION);
     $vurl->set_option(VURL_HTTPHEADER, $headers);
     $vurl->set_option(VURL_POST, 1);
     $vurl->set_option(VURL_POSTFIELDS, $xmlString);
     $vurl->set_option(VURL_RETURNTRANSFER, 1);
     $vurl->set_option(VURL_CLOSECONNECTION, 1);
     $result = $vurl->exec();
     $xmlobj = new vB_XML_Parser($result);
     $xmlobj->include_first_tag = true;
     $parsed_xml = $xmlobj->parse();
     if ($parsed_xml === false or !is_array($parsed_xml)) {
         $this->error_code = 'xml_parse_failed';
         $this->sendHeader(false);
         return false;
     }
     $data = each($parsed_xml);
     $notificationType = $data['key'];
     $parsed_xml = $data['value'];
     $this->transaction_id = isset($parsed_xml['google-order-number']) ? $parsed_xml['google-order-number'] : false;
     $hash = isset($parsed_xml['order-summary']['shopping-cart']['items']['item']['merchant-item-id']) ? $parsed_xml['order-summary']['shopping-cart']['items']['item']['merchant-item-id'] : false;
     $order_state = isset($parsed_xml['order-summary']['financial-order-state']) ? $parsed_xml['order-summary']['financial-order-state'] : false;
     $totalcost = isset($parsed_xml['order-summary']['total-charge-amount']['value']) ? floatval($parsed_xml['order-summary']['total-charge-amount']['value']) : 0;
     $tax = isset($parsed_xml['order-summary']['order-adjustment']['total-tax']['value']) ? floatval($parsed_xml['order-summary']['order-adjustment']['total-tax']['value']) : 0;
     $currency = isset($parsed_xml['order-summary']['total-charge-amount']['currency']) ? strtolower($parsed_xml['order-summary']['total-charge-amount']['currency']) : 0;
     $cost = $totalcost - $tax;
     if ($this->transaction_id and $hash) {
         $this->paymentinfo = vB::getDbAssertor()->getRow('vBForum:getPaymentinfo', array('hash' => $hash));
         if (!empty($this->paymentinfo)) {
             $sub = vB::getDbAssertor()->getRow('vBForum:subscription', array('subscriptionid' => $this->paymentinfo['subscriptionid']));
             $subcost = unserialize($sub['cost']);
             if ($subcost) {
                 $this->paymentinfo['currency'] = $currency;
                 $this->paymentinfo['amount'] = $cost;
                 switch ($notificationType) {
                     case 'charge-amount-notification':
                         if ($cost == floatval($subcost["{$this->paymentinfo[subscriptionsubid]}"]['cost'][$currency])) {
                             $this->type = 1;
                         } else {
                             $this->error_code = 'invalid_payment_amount - XML: ' . $result . htmlspecialchars_uni(' SubmitURL: ' . $submitUrl . ' Headers: ' . implode(' ', $headers));
                         }
                         break;
                     case 'refund-amount-notification':
                     case 'chargeback-amount-notification':
                         $this->type = 2;
                         break;
                     case 'new-order-notification':
                     case 'risk-information-notification':
                     case 'authorization-amount-notification':
                         $this->error_code = 'ignored_status_update';
                         $this->type = 3;
                         break;
                     default:
                 }
                 if ($this->type == 0 and $this->error_code == '') {
                     switch ($order_state) {
                         case 'CANCELLED':
                         case 'CANCELLED_BY_GOOGLE':
                             $this->type = 2;
                             break;
                             // Ignore these states
                         // Ignore these states
                         case 'PAYMENT_DECLINED':
                         case 'REVIEWING':
                         case 'CHARGEABLE':
                         case 'CHARGING':
                         case 'CHARGED':
                             $this->type = 3;
                             $this->error_code = 'ignored_status_update';
                         default:
                     }
                 }
             } else {
                 $this->error_code = 'invalid_subscription - XML: ' . $result . htmlspecialchars_uni(' SubmitURL: ' . $submitUrl . ' Headers: ' . implode(' ', $headers));
             }
         } else {
             $this->error_code = 'invalid_payment - XML: ' . $result . htmlspecialchars_uni(' SubmitURL: ' . $submitUrl . ' Headers: ' . implode(' ', $headers));
         }
         $this->sendHeader(true);
     } else {
         $this->error_code = 'invalid_XML_response - XML: ' . $result . htmlspecialchars_uni(' SubmitURL: ' . $submitUrl . ' Headers: ' . implode(' ', $headers));
         $this->sendHeader(false);
         return false;
     }
     $xml = new vB_XML_Builder();
     $xml->add_group('notification-acknowledgment', array('xmlns' => 'http://checkout.google.com/schema/2', 'serial-number' => $this->registry->GPC['serial-number']));
     $xml->close_group();
     $xml->send_content_type_header();
     $xml->send_content_length_header();
     echo $xml->fetch_xml();
     return $this->type > 0 and $this->type < 3;
 }