예제 #1
0
파일: Valutec.php 프로젝트: phpsmith/IS4C
 private function handleResponseAuth($authResult)
 {
     $xml = new xmlData($authResult["response"]);
     $request = $this->last_request;
     $this->last_paycard_transaction_id = $request->last_paycard_transaction_id;
     $response = new PaycardResponse($request, $authResult);
     // initialize
     $dbTrans = Database::tDataConnect();
     $program = 'Gift';
     $validResponse = $xml->isValid() ? 1 : 0;
     $errorMsg = $xml->get_first("ERRORMSG");
     $balance = $xml->get("BALANCE");
     if ($validResponse) {
         /*
                     tendering more than the available balance returns an "NSF" error message, 
                     but no Balance field however, the available balance is buried in the 
                     RawOutput field, so we can dig it out and fill in the missing Balance field
                     -- as of 1/22/08, valutec appears to now be returning the Balance field normally 
                     (in its own XML field, not in RawOutput), but we still need to append it to 
                     the Message so the cashier can see it
         */
         if ($errorMsg && substr($errorMsg, 0, 3) == "NSF") {
             if (!$balance || $balance === "") {
                 $rawOutput = $xml->get("RAWOUTPUT");
                 $begin = strpos($rawOutput, "%1cBAL%3a");
                 if ($begin !== false) {
                     $end = strpos($rawOutput, "%1c", $begin + 1);
                     if ($end !== false && $end > $begin) {
                         $balance = trim(urldecode(substr($rawOutput, $begin + 9, $end - $begin - 9)));
                     }
                 }
             } else {
                 if ($balance && $balance !== "") {
                     $errorMsg = "NSF, BAL: " . PaycardLib::paycard_moneyFormat($balance);
                 }
             }
         }
         // verify that echo'd fields match our request
         if ($xml->get('TRANSACTIONTYPE') && $xml->get('TRANSACTIONTYPE') == $program && $xml->get('IDENTIFIER') && $xml->get('IDENTIFIER') == $identifier && $xml->get('AUTHORIZED')) {
             $validResponse = 1;
             // response was parsed normally, echo'd fields match, and other required fields are present
         } else {
             $validResponse = 4;
             // response was parsed as XML but fields didn't match
         }
     }
     $response->setBalance($balance);
     $resultCode = 0;
     $apprNumber = $xml->get('AUTHORIZATIONCODE');
     $response->setApprovalNum($apprNumber);
     $rMsg = '';
     if ($apprNumber != '' && $xml->get('AUTHORIZED') == 'true') {
         $validResponse = 1;
         $resultCode = 1;
         $rMsg = 'Approved';
     } else {
         $rMsg = substr($xml->get_first('ERRORMSG'), 0, 100);
     }
     $response->setResultMsg($rMsg);
     $response->setResultCode($resultCode);
     $response->setResponseCode($resultCode);
     $response->setNormalizedCode($resultCode);
     $response->setValid($validResponse);
     try {
         $response->saveResponse();
     } catch (Exception $ex) {
     }
     // check for communication errors (any cURL error or any HTTP code besides 200)
     if ($authResult['curlErr'] != CURLE_OK || $authResult['curlHTTP'] != 200) {
         if ($authResult['curlHTTP'] == '0') {
             CoreLocal::set("boxMsg", "No response from processor<br />\n                                The transaction did not go through");
             return PaycardLib::PAYCARD_ERR_PROC;
         }
         return $this->setErrorMsg(PaycardLib::PAYCARD_ERR_COMM);
     }
     // check for data errors (any failure to parse response XML or echo'd field mismatch
     if ($validResponse != 1) {
         // invalid server response, we don't know if the transaction was processed (use carbon)
         return $this->setErrorMsg(PaycardLib::PAYCARD_ERR_DATA);
     }
     $amtUsed = $xml->get('CARDAMOUNTUSED');
     if ($amtUsed) {
         $request->changeAmount($amtUsed);
     }
     // put the parsed response into session so the caller, receipt printer, etc can get the data they need
     CoreLocal::set("paycard_response", array());
     CoreLocal::set("paycard_response", $xml->array_dump());
     $temp = CoreLocal::get("paycard_response");
     $temp["Balance"] = $temp["BALANCE"];
     CoreLocal::set("paycard_response", $temp);
     // comm successful, check the Authorized, AuthorizationCode and ErrorMsg fields
     if ($xml->get('AUTHORIZED') == 'true' && $xml->get('AUTHORIZATIONCODE') != '' && $xml->get_first('ERRORMSG') == '') {
         return PaycardLib::PAYCARD_ERR_OK;
         // authorization approved, no error
     }
     // the authorizor gave us some failure code
     // authorization failed, response fields in $_SESSION["paycard_response"]
     CoreLocal::set("boxMsg", "Processor error: " . $errorMsg);
     return PaycardLib::PAYCARD_ERR_PROC;
 }
예제 #2
0
 /**
   Examine XML response from Datacap transaction,
   log results, determine next step
   @return [int] PaycardLib error code
 */
 public function handleResponseDataCap($xml)
 {
     $rawXml = $xml;
     $ref = $this->refnum(CoreLocal::get('paycard_id'));
     if (CoreLocal::get('LastEmvReqType') == 'void') {
         $request = new PaycardVoidRequest($ref);
     } elseif (CoreLocal::get('LastEmvReqType') == 'gift') {
         $request = new PaycardGiftRequest($ref);
     } else {
         $request = new PaycardRequest($ref);
     }
     $id_set = CoreLocal::get('LastEmvPcId');
     $request->last_paycard_transaction_id = $id_set[0];
     $request->last_req_id = $id_set[1];
     $this->last_paycard_transaction_id = $request->last_paycard_transaction_id;
     $response = new PaycardResponse($request, array('curlTime' => 0, 'curlErr' => 0, 'curlHTTP' => 200));
     $xml = new BetterXmlData($xml);
     $validResponse = 1;
     $responseCode = $xml->query('/RStream/CmdResponse/CmdStatus');
     $resultMsg = $responseCode;
     if ($responseCode) {
         $responseCode = $this->responseToNumber($responseCode);
     } else {
         $validResponse = -3;
     }
     $response->setResponseCode($responseCode);
     $resultCode = $xml->query('/RStream/CmdResponse/DSIXReturnCode');
     $response->setResultCode($resultCode);
     $apprNumber = $xml->query('/RStream/TranResponse/AuthCode');
     $response->setApprovalNum($apprNumber);
     $rMsg = $resultMsg;
     if ($resultMsg) {
         $rMsg = $resultMsg;
         if ($responseCode == 1) {
             // approved
             if ($apprNumber) {
                 $rMsg .= ' ' . $apprNumber;
             }
         } else {
             $processor_text = $xml->query('/RStream/CmdResponse/TextResponse');
             if ($processor_text) {
                 $rMsg = $processor_text;
             }
         }
     }
     $response->setResultMsg($rMsg);
     $xTransID = $xml->query('/RStream/TranResponse/RefNo');
     $response->setTransactionID($xTransID);
     if ($xTransID === false) {
         $validResponse = -3;
     }
     $issuer = $xml->query('/RStream/TranResponse/CardType');
     $resp_balance = $xml->query('/RStream/TranResponse/Balance');
     $ebtbalance = 0;
     if ($issuer == 'Foodstamp' && $resp_balance !== false) {
         $issuer = 'EBT';
         CoreLocal::set('EbtFsBalance', $resp_balance);
         $ebtbalance = $resp_balance;
     } elseif ($issuer == 'Cash' && $resp_balance !== false) {
         $issuer = 'EBT';
         CoreLocal::set('EbtCaBalance', $resp_balance);
         $ebtbalance = $resp_balance;
     } elseif ($xml->query('/RStream/TranResponse/TranType') == 'PrePaid' && $resp_balance !== false) {
         $issuer = 'NCG';
         $ebtbalance = $resp_balance;
         CoreLocal::set('GiftBalance', $resp_balance);
     }
     $response->setBalance($ebtbalance);
     $dbc = Database::tDataConnect();
     $tran_code = $xml->query('/RStream/TranResponse/TranCode');
     if (substr($tran_code, 0, 3) == 'EMV' && strpos($rawXml, 'x____') !== false) {
         CoreLocal::set('EmvSignature', true);
     } else {
         CoreLocal::set('EmvSignature', false);
     }
     if (substr($tran_code, 0, 3) == 'EMV') {
         $printData = $xml->query('/RStream/PrintData/*', false);
         if (strlen($printData) > 0) {
             $receiptID = $transID;
             if (CoreLocal::get('paycard_mode') == PaycardLib::PAYCARD_MODE_VOID) {
                 $receiptID++;
             }
             $printP = $dbc->prepare('
                 INSERT INTO EmvReceipt
                     (dateID, tdate, empNo, registerNo, transNo, transID, content)
                 VALUES 
                     (?, ?, ?, ?, ?, ?, ?)');
             $dbc->execute($printP, array(date('Ymd'), date('Y-m-d H:i:s'), $cashierNo, $laneNo, $transNo, $receiptID, $printData));
         }
     }
     // put normalized value in validResponse column
     $normalized = $validResponse == 0 ? 4 : 0;
     if ($responseCode == 1) {
         $normalized = 1;
     } else {
         if ($responseCode == 2) {
             $normalized = 2;
         } else {
             if ($responseCode == 0) {
                 $normalized = 3;
             }
         }
     }
     $response->setNormalizedCode($normalized);
     $response->setToken($xml->query('/RStream/TranResponse/RecordNo'), $xml->query('/RStream/TranResponse/ProcessData'), $xml->query('/RStream/TranResponse/AcqRefData'));
     try {
         $response->saveResponse();
     } catch (Exception $ex) {
         echo $ex->getMessage() . "\n";
     }
     /** handle partial auth **/
     if ($responseCode == 1) {
         $amt = $xml->query('/RStream/TranResponse/Amount/Authorize');
         if ($amt != abs(CoreLocal::get("paycard_amount"))) {
             $request->changeAmount($amt);
             CoreLocal::set("paycard_amount", $amt);
             CoreLocal::set("paycard_partial", True);
             UdpComm::udpSend('goodBeep');
         }
     }
     $pan = $xml->query('/RStream/TranResponse/AcctNo');
     $resp_name = $xml->query('/RStream/TranResponse/CardholderName');
     $name = $resp_name ? $resp_name : 'Cardholder';
     $issuer = $xml->query('/RStream/TranResponse/CardType');
     $request->updateCardInfo($pan, $name, $issuer);
     switch (strtoupper($xml->query('/RStream/CmdResponse/CmdStatus'))) {
         case 'APPROVED':
             return PaycardLib::PAYCARD_ERR_OK;
         case 'DECLINED':
             if ($issuer == 'EBT') {
                 // if EBT is declined but lists a balance less than the
                 // requested authorization, it may be possible to
                 // charge the card for a less amount.
                 TransRecord::addcomment("");
                 CoreLocal::set('boxMsg', sprintf('Card Balance: $%.2f', $ebtbalance));
             } elseif (substr($tran_code, 0, 3) == 'EMV') {
                 CoreLocal::set('paycard_amount', 0);
                 return PaycardLib::PAYCARD_ERR_OK;
             }
             UdpComm::udpSend('termReset');
             CoreLocal::set('ccTermState', 'swipe');
             // intentional fallthrough
         // intentional fallthrough
         case 'ERROR':
             CoreLocal::set("boxMsg", "");
             $texts = $xml->query('/RStream/CmdResponse/TextResponse');
             CoreLocal::set("boxMsg", "Error: {$texts}");
             $dsix = $xml->query('/RStream/CmdResponse/DSIXReturnCode');
             if ($dsix == '001007' || $dsix == '003007' || $dsix == '003010') {
                 /* These error codes indicate a potential connectivity
                  * error mid-transaction. Do not add a comment record to
                  * the transaction to avoid incrementing InvoiceNo
                  */
             } else {
                 TransRecord::addcomment("");
             }
             break;
         default:
             CoreLocal::set("boxMsg", "An unknown error occurred<br />at the gateway");
             TransRecord::addcomment("");
     }
     return PaycardLib::PAYCARD_ERR_PROC;
 }