Платежный шлюз Ач интеграции, получаю ошибку "неверный товар или пароль" в PHP на TESTMODE


Я интегрирую ACH, используя " платежный шлюз (Forte) http://www.forte.net/Developers ". У меня есть скачать API отсюда " http://www.phpclasses.org/browse/file/42423.html " .

Я получаю следующий ответ об ошибке "недопустимый MERCH или PASSWD". Не знаю, что именно пошло не так. Я поставил ID мерчанта правильно это то же самое, которое обеспечивается PaymentGateways песочнице учетной записи следующего демо-терминала ссылка.

Https://sandbox.paymentsgateway.net/vt3/login.aspx

Однако я не уверен, какой пароль следует использовать,поэтому я использую стандартный вход в демо-терминал.

Любая помощь будет действительно оценена.

Вот мой код:

<?php
**// FILE NAME : test_pg_webservice.php**

require_once('pg_webservice.php');

$client = new ClientRecord;
$client->FirstName = "Mahendra";
$client->LastName = "Kshirsagar";
$client->CompanyName = "Test company";
$client->Address1 = "123 avenue street";
$client->City = 'Miami';
$client->State = "FL";
$client->PostalCode = "12434";
$client->PhoneNumber = '789-987-7899';
$client->EmailAddress = 'mahendra008@gmail.com';
$client->ShiptoFirstName = '';
$client->ShiptoLastName = '';
$client->ShiptoCompanyName = "";
$client->ShiptoAddress1 = "";
$client->ShiptoPhoneNumber = "";
$client->ConsumerID = uniqid();
//$client->Status = '1';
$ticket = new Authentication;

$webServ = new PG_WebService;
$webServ->insertNewClient($client);
$client_id = $webServ->insertNewClient($client);

//echo "Client id: ".$client_id;
//echo "nnnnnnError array: ";
//print_r($webServ->getError());
//echo "nnnnnn";

$paymentMethod = new PaymentMethod;
$paymentMethod->AcctHolderName = "Mahendra Kshirsagar";
$paymentMethod->ClientID = $client_id;//$client_id;
$paymentMethod->EcAccountNumber = '12345678';
$paymentMethod->EcAccountTRN = '021000021';
$paymentMethod->EcAccountType = EcAccountType::SAVE;
$paymentMethod->Note = 'New payment method using bank data';
$paymentMethod->IsDefault = TRUE;

$paymentMethod_id = $webServ->insertNewPaymentMethod($paymentMethod);
//echo "Payment method id: ".$paymentMethod_id;
//echo "nnnnnnError array: ";
//print_r($webServ->getError());

$agiTrxObj = new AGI_Transaction;
$agiTrxObj->pg_client_id = $client_id;
$agiTrxObj->pg_payment_method_id = $paymentMethod_id;
$agiTrxObj->pg_transaction_type = EFT_TRXType::SALE;
$agiTrxObj->pg_total_amount = 0.1;
$agiTrxObj->ecom_billto_postal_name_first = 'Avinash';
$agiTrxObj->ecom_billto_postal_name_last = 'Kshirsagar';

$resp = $webServ->agiDoTransaction($agiTrxObj);
//echo "Response: ".$resp;
echo "<pre>";
print_r($webServ->getError());
print_r($webServ->getAgiTrxResponseArr());
echo "</pre>";

Ниже приведен файл класса:

<?php 
**// FILE NAME: pg_webservice.php**    
require_once('nusoap/lib/nusoap.php');

class PG_WebService {

    const CLIENTS_URL_LIVE = 'https://ws.paymentsgateway.net/Service/v1/Client.wsdl';
    const CLIENTS_URL_TEST = 'https://sandbox.paymentsgateway.net/WS/Client.wsdl';

    const MERCHANTS_URL_LIVE = 'https://ws.paymentsgateway.net/Service/v1/Merchant.wsdl';
    const MERCHANTS_URL_TEST = 'https://sandbox.paymentsgateway.net/WS/Merchant.wsdl';

    const TRANSACTIONS_URL_LIVE = 'https://ws.paymentsgateway.net/Service/v1/Transaction.wsdl';
    const TRANSACTIONS_URL_TEST = 'https://sandbox.paymentsgateway.net/WS/Transaction.wsdl';

    const AGI_DO_TRX_URL_LIVE = 'https://ws.paymentsgateway.net/pg/paymentsgateway.asmx?wsdl';
    const AGI_DO_TRX_URL_TEST = 'https://ws.paymentsgateway.net/pgtest/paymentsgateway.asmx?wsdl';

    private $clientEndPointURL = '';
    private $merchantEndPointURL = '';
    private $trxEndPointURL = '';
    private $agiDoTrxURL = '';

    private $agiTrxResponseArr = array();
    private $allErrors = array();
    private $errorArray = array('error'=>FALSE, 'msg'=>'');

    private $ticket;

    public function __construct(){
        $this->ticket = new Authentication;
        $this->init();
    }

    private function init(){
        $mode = Const_AuthParam::ENV_MODE;
        switch($mode){
            case 'test':
                $this->isTestMode = TRUE;
                $this->clientEndPointURL = self::CLIENTS_URL_TEST;
                $this->merchantEndPointURL = self::MERCHANTS_URL_TEST;
                $this->trxEndPointURL = self::TRANSACTIONS_URL_TEST;
                $this->agiDoTrxURL = self::AGI_DO_TRX_URL_TEST;
                break;
            case 'live':
                $this->isTestMode = FALSE;
                $this->clientEndPointURL = self::CLIENTS_URL_LIVE;
                $this->merchantEndPointURL = self::MERCHANTS_URL_LIVE;
                $this->trxEndPointURL = self::TRANSACTIONS_URL_LIVE;
                $this->agiDoTrxURL = self::AGI_DO_TRX_URL_LIVE;
                break;
            default:
                break;
        }
    }

    /**
    * @param client An instance of 'ClientRecord' class.
    * 
    * @return client_id Return the id of created client. If client_id is -1 then an error has happen.
    */
    public function insertNewClient(ClientRecord $client){
        $createClientParams = array('ticket'=>NULL, 'client'=>NULL);
        $createClientParams['ticket'] = $this->ticket;
        $createClientParams['client'] = $client;

        $nuSoapClient = $this->getNuSoapClientInstance($this->clientEndPointURL);
        $err = $nuSoapClient->getError();
        if ($err) {
            // Show error
            $this->setError(TRUE, 'Constructor error: ' . $err);
            $client_ID = -1;
        } else {
            $nuSoapClient->call("createClient", $createClientParams);
            if($nuSoapClient->fault){
                $client_ID = -1;
                $faultString = $nuSoapClient->faultstring;
                if(is_array($faultString))
                    $faultString = end($faultString);
                $this->setError(TRUE, $faultString);
            }
            else{
                $client_ID = $nuSoapClient->responseData;
                if(!is_numeric($client_ID)){
                    $client_ID = $this->parseXML($client_ID);
                }
            }
        }

        return $client_ID;
    }

    public function insertNewPaymentMethod(PaymentMethod $paymentMethod){
        $paymentMethod_ID = -1;
        if(!isset($paymentMethod->ClientID)){
            $this->setError(TRUE, 'You must assign a clientID to the new payment method !');
            return $paymentMethod_ID;
        }
        if(!isset($paymentMethod->AcctHolderName) || trim($paymentMethod->AcctHolderName) == ''){
            $this->setError(TRUE, 'Account holder name (AcctHolderName) is required');
            return $paymentMethod_ID;
        }
        if(!isset($paymentMethod->EcAccountTRN) || trim($paymentMethod->EcAccountTRN) == ''){
            $this->setError(TRUE, 'Transaction routing number(EcAccountTRN) is required');
            return $paymentMethod_ID;
        }

        $createPaymentMethodParams = array('ticket'=>$this->ticket, 'payment'=>$paymentMethod);

        $nuSoapClient = $this->getNuSoapClientInstance($this->clientEndPointURL);
        $err = $nuSoapClient->getError();
        if($err){
            $this->setError(TRUE, 'Constructor error: ' . $err);
            $paymentMethod_ID = -1;
        } else {
            $nuSoapClient->call('createPaymentMethod', $createPaymentMethodParams);
            if($nuSoapClient->fault){
                $faultString = $nuSoapClient->faultstring;
                if(is_array($faultString))
                    $faultString = end($faultString);
                $this->setError(TRUE, $faultString);
                $paymentMethod_ID = -1;
            }
            else{
                $paymentMethod_ID = $nuSoapClient->responseData;
                if(!is_numeric($paymentMethod_ID)){
                    $paymentMethod_ID = $this->parseXML($paymentMethod_ID);
                }
            }
        }

        return $paymentMethod_ID;
    }

    public function agiDoTransaction(AGI_Transaction $agiTrxParams){
        $trxResponse = -1;
        $nuSoapClient = $this->getNuSoapClientInstance($this->agiDoTrxURL);
        $err = $nuSoapClient->getError();
        if($err){
            $this->setError(TRUE, 'Constructor error: ' . $err);
            $trxResponse = -1;
        } else {
            $agiTrxParamsArr = get_object_vars($agiTrxParams);
            $nuSoapClient->call('ExecuteSocketQuery', $agiTrxParamsArr);
            if($nuSoapClient->fault){
                $this->setError(TRUE, $nuSoapClient->faultstring);
                $trxResponse = -1;
            }
            else{
                $trxResponse = $nuSoapClient->responseData;
            }
        }
        $trxResponseArr = array();
        if($trxResponse != -1)
            $this->agiTrxResponseArr = $this->responseStr2Array($trxResponse);

        if(array_key_exists('pg_response_code', $this->agiTrxResponseArr)){
            if($this->agiTrxResponseArr['pg_response_code'] == 'A01'){
                $returnMsg = "Transactio completed successfully";
                $this->setError(FALSE, $returnMsg);
            }
            else{
                $this->setError(TRUE, $this->agiTrxResponseArr['pg_response_description']);
            }
        }
        return $this->agiTrxResponseArr;
    }

    public function getError(){
        return $this->errorArray;
    }

    public function getAllErrors(){
        return $this->allErrors;
    }

    public function getAgiTrxResponseArr(){
        return $this->agiTrxResponseArr;
    }

    private function getNuSoapClientInstance($url){
        $nuSoapClient = new nusoap_client($url, TRUE);
        //$nuSoapClient->setDebugLevel(9);echo $nuSoapClient->getDebug();
        $nuSoapClient->soap_defencoding = 'UTF-8';
        $nuSoapClient->decode_utf8 = FALSE;

        return $nuSoapClient;
    }

    private function responseStr2Array($responseStr){
        $responseStr = $this->parseXML($responseStr);

        $tempArr = explode("n", $responseStr);
        $responseArr = array();
        if(!empty($tempArr)){
            foreach($tempArr as $val){
                $tempVal = explode("=", $val);
                if(count($tempVal) == 2)
                    $responseArr[$tempVal[0]] = $tempVal[1];
            }
        }
        return $responseArr;
    }

    private function parseXML($soapXmlStr){
        $xmlObj = simplexml_load_string($soapXmlStr);

        $responseStr = $soapXmlStr;

        if($xmlObj instanceof SimpleXMLElement){

            $xmlObj->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
            $xmlObj->registerXPathNamespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance');
            $xmlObj->registerXPathNamespace('xsd', 'http://www.w3.org/2001/XMLSchema');

            $result = $xmlObj->xpath("//soap:Envelope/soap:Body");
            foreach($result as $child){
                foreach($child->children() as $child1)
                    //print_r($child1->children());
                    foreach($child1 as $res)
                        $responseStr = trim((string)$res);
            }

        }
        return $responseStr;
    }

    private function setError($isError, $msgError){
        if(is_bool($isError)){
            $this->errorArray['error'] = $isError;
            $this->errorArray['msg'] = $msgError;

            array_push($this->allErrors, $this->errorArray);
        }
    }

}


class Const_AuthParam {
    const APILoginID = 'xxx';
    const SecureTransactionKey = "xxx";
    const MERCHANT_ID = "xxx";
    const PASSWORD = 'xxx';

    const ENV_MODE = 'test';//'live'
}

/**
*   Electronic Funds Transfer (EFT) transaction types. Its used like enum type.
*/
class EFT_TRXType {
    const SALE = '20'; //Customer is charged
    const AUTH_ONLY = '21'; //Authorization only, CAPTURE transaction required  
    const CAPTURE = '22'; //Completes AUTH ONLY transaction 
    const CREDIT = '23'; //Customer is credited
    const VOID_TRXType = '24'; //Cancels non-settled transactions  
    const FORCE = '25'; //Customer charged (no validation checks)  
    const VERIFY_ONLY = '26'; //Verification only, no customer charge
}


class EcAccountType {
    const SAVE = 'SAVINGS';
    const CHECK = 'CHECKING';
}


/**
* The Authentication object contains the ApiLoginID and SecureTransactionKey used to identify and authenticate the requestor. 
* Both fields may be maintained in the Virtual Terminal’s "Gateway Settings" section.
*/
class Authentication{   
    public $APILoginID ;
    public $UTCTime = '';
    public $TSHash = ''; //HMACMD5 (APILoginID + "|" + UTCTime, SecureTransactionKey)

    public function __construct()
    {
        $this->APILoginID = Const_AuthParam::APILoginID;
        $time = time() + 62135596800;
        $addedtime = $time . '0000000';
        $this->UTCTime = $addedtime;
        $this->setTsHash();
    }

    /**
    * The hash generated by the transaction signing fields: APILoginID, UTCTime.
    */
    private function setTsHash(){
        $strToHash = $this->APILoginID."|".$this->UTCTime;
        $this->TSHash = hash_hmac("md5", $strToHash, Const_AuthParam::SecureTransactionKey, FALSE);
    }
}

class PaymentMethod{
    public $MerchantID;
    public $ClientID;
    public $PaymentMethodID;
    public $AcctHolderName;
    public $CcCardNumber;
    public $CcExpirationDate;
    public $CcCardType;
    public $CcProcurementCard;
    public $EcAccountNumber;
    public $EcAccountTRN;
    public $EcAccountType;
    public $Note;
    public $IsDefault;

    public function __construct(){
        $this->MerchantID = Const_AuthParam::MERCHANT_ID;
        if(!is_numeric($this->PaymentMethodID))
            $this->PaymentMethodID = 0;
    }
}

class ClientRecord {
    public $MerchantID;
    public $ClientID;
    public $FirstName;
    public $LastName;
    public $CompanyName;
    public $Address1;
    public $Address2;
    public $City;
    public $State;
    public $PostalCode;
    public $PhoneNumber;
    public $CountryCode;
    public $EmailAddress;
    public $FaxNumber;
    public $ShiptoFirstName;
    public $ShiptoLastName;
    public $ShiptoCompanyName;
    public $ShiptoAddress1;
    public $ShiptoAddress2;
    public $ShiptoCity;
    public $ShiptoState;
    public $ShiptoPostalCode;
    public $ShiptoCountryCode;
    public $ShiptoPhoneNumber ;
    public $ShiptoFaxNumber ;
    public $ConsumerID ;
    public $Status ;

    public function __construct(){
        $this->MerchantID = Const_AuthParam::MERCHANT_ID;
        if(!is_numeric($this->ClientID))
            $this->ClientID = 0;
    }
}

class Transaction {
    public $MerchantID;
    public $Amount;
    public $SalesTaxAmount;
    public $ConvenienceFee ;
    public $ConvenienceFeePrincipal ;
    public $DebitCredit;
    public $EnteredBy;
    public $IPAddress;
    public $TransactionID;
    public $UpdatedDate;
    //Bill to
    public $BilltoFirstName;
    public $BilltoLastName;
    public $BilltoCompanyName;
    public $BilltoAddress ;
    public $BilltoAddress2 ;
    public $BilltoCity ;
    public $BilltoState ;
    public $BilltoPostalCode ;
    public $BilltoEmailAddress ;
    public $BilltoPhone ;
    //Ship to
    public $ShiptoName ;
    public $ShiptoCompanyName ;
    public $ShiptoAddresss ;
    public $ShiptoAddress2 ;
    public $ShiptoCity ;
    public $ShiptoState ;
    public $ShiptoPostalCode ;
    public $ShiptoFreightAmount ;
    //Defined Fields
    public $ConsumerOrderID ;
    public $ConsumerID ;
    public $WalletID ;
    public $MerchantData1 ;
    public $MerchantData2 ;
    public $MerchantData3 ;
    public $MerchantData4 ;
    public $MerchantData5 ;
    public $MerchantData6 ;
    public $MerchantData7 ;
    public $MerchantData8 ;
    public $MerchantData9 ;
    //eCheck Info
    public $OriginationDate ;
    public $AttemptNumber ;
    public $AcctTRN ;
    public $AccountType ;
    public $CheckNo ;
    public $EntryClassCode ;
    public $EntryDescription ;
    public $ItemDescription ;
    //Credit Card Info
    public $CardType ;
    public $CardExpDate ;
    public $CardHolderName ;

    function __construct() {
        $this->MerchantID = Const_AuthParam::MERCHANT_ID;
        if(!is_numeric($this->TransactionID))
            $this->TransactionID = 0;
    }
}

class AGI_Transaction{
    public $pg_merchant_id;
    public $pg_password;
    public $pg_transaction_type ;
    public $pg_merchant_data_1 ;
    public $pg_merchant_data_2 ;
    public $pg_merchant_data_3 ;
    public $pg_merchant_data_4 ;
    public $pg_merchant_data_5 ;
    public $pg_merchant_data_6 ;
    public $pg_merchant_data_7 ;
    public $pg_merchant_data_8 ;
    public $pg_merchant_data_9 ;
    public $pg_total_amount ;
    public $pg_sales_tax_amount ;
    public $pg_consumer_id ;
    public $ecom_consumerorderid ;
    public $ecom_walletid ;
    public $pg_billto_postal_name_company ;
    public $ecom_billto_postal_name_first ;
    public $ecom_billto_postal_name_last ;
    public $ecom_billto_postal_street_line1 ;
    public $ecom_billto_postal_street_line2 ;
    public $ecom_billto_postal_city ;
    public $ecom_billto_postal_stateprov ;
    public $ecom_billto_postal_postalcode ;
    public $ecom_billto_postal_countrycode ;
    public $ecom_billto_telecom_phone_number ;
    public $ecom_billto_online_email ;
    public $pg_billto_ssn ;
    public $pg_billto_dl_number ;
    public $pg_billto_dl_state ;
    public $pg_billto_date_of_birth ;
    public $pg_entered_by ;
    public $pg_schedule_quantity ;
    public $pg_schedule_frequency ;
    public $pg_schedule_recurring_amount ;
    public $pg_schedule_start_date ;
    public $pg_customer_ip_address ;
    public $pg_preauth_no_decline_on_fail ;
    public $pg_preauth_decline_on_noanswer ;

    /**
    * Address Verification System (AVS) is used to verify if the address data (street line, city, state, zip) provided are correct.
    * 'pg_avs_method' have the format: x1x2x3x4x5 where:
    * x1 = Credit Card Account/Zipcode Check
    * x2 = Credit Card Account/Street Number Check
    * x3 = State/Zipcode Check
    * x4 = State/Area Code Check
    * x5 = Anonymous Email Check
    * Values that can take each 'x' are:
    * 0 = Do not perform check
    * 1 = Check only, do not decline fail
    * 2 = Check and decline on fail
    */
    public $pg_avs_method ;

    public $ecom_payment_card_type ;
    public $ecom_payment_card_name ;
    public $ecom_payment_card_number ;
    public $ecom_payment_card_expdate_month ;
    public $ecom_payment_card_expdate_year ;
    public $ecom_payment_card_verification ;
    public $pg_procurement_card ;
    public $pg_customer_acct_code ;
    public $pg_cc_swipe_data ;
    public $pg_mail_or_phone_order ;
    /**
    * Transit routing number (ABA) for customer’s account  
    */
    public $ecom_payment_check_trn ;

    public $ecom_payment_check_account ;
    public $ecom_payment_check_account_type ;
    public $ecom_payment_check_checkno ;
    public $pg_original_trace_number ;
    public $pg_original_authorization_code ;
    public $pg_client_id ;
    public $pg_payment_method_id ;

    function __construct() {
        $this->pg_merchant_id = Const_AuthParam::MERCHANT_ID;
        $this->pg_password = Const_AuthParam::PASSWORD;
    }
}

?>

Когда я запускаю test_pg_webservice.php я получаю следующий ответ.

Array
(
    [error] => 1
    [msg] => INVALID MERCH OR PASSWD
)
Array
(
    [pg_response_type] => E
    [pg_response_code] => E10
    [pg_response_description] => INVALID MERCH OR PASSWD
    [pg_trace_number] => 07D5114F-7429-41B2-BD36-01A0152DC644
    [pg_merchant_id] => 2000
    [pg_transaction_type] => 20
    [pg_total_amount] => 0.1
    [pg_client_id] => 1008213
    [pg_payment_method_id] => 1019484
)
Я не думаю, что с кодом что-то не так. Я думаю, что мой просто чего-то не хватает или может делать что-то неправильно.
1 2

1 ответ:

Наконец-то я это понял. Я использовал неверный MERCHANT_ID и пароль. Вот как это работает.

Как только вы зарегистрируетесь на "paymetsgateway.com " . Предполагается, что вы заполните форму заявки на получение сведений о песочнице. Форму заявки вы найдете здесь "http://www.paymentsgateway.com/testaccountform.aspx" . Хотя они сказали: "вы получите свои учетные данные по зарегистрированной электронной почте в течение 24 часов", это может занять более 48 часов.

Вы получите ваша песочница идентификатор продавца, идентификатор пользователя и пароль транзакции по электронной почте, которая будет удалена через 60 дней.

После того, как у вас есть все детали, вы можете использовать его в данном коде.

@duskwuff: Спасибо за ответы игрок:)