使用PHP和CURL的Barclaycard ePDQ API不想工作,没有响应,不确定CURL是否正常工作?

I've been putting this off for a while as I just don't seem to have a clue with what I'm doing. I'm trying to use PHP and Curl to talk to the Barclaycard ePDQ MPI. I've done this before using the HSBC XML API but the Barclaycard ePDQ MPI seems to be giving me a few headaches. I have a form which posts card details/address details and the to a page that contains the following functions Please note that I have SSL set up on the domain, CURL is installed on the server, I had the HSBC XML API working just fine on the same box/URL.

<?php
    function process_card($users_ip, $Temp_Order_ID, $User_NameX, $First_Name, $Surname, $Address_Line1, $Address_Line2, $Town, $Country, $Postcode, $CardNumber, $CardExpiryDate, $issue_node, $CardCVV, $totalCost ) {

    if ($CardCVV == "")
        $cvvindicator = 0;
    else
        $cvvindicator=1;

    global $status;
    //$amount = $amount * 100;

        $xml = '
    <?XML version="1.0" encoding="UTF-8"?>
    <EngineDocList>
        <DocVersion>1.0</DocVersion>
        <EngineDoc>
        <IPAddress>' . $users_ip . '</IPAddress>
            <ContentType>OrderFormDoc</ContentType>
            <User>
                <Name>XXXXX</Name>
                <Password>XXXXXXX</Password>
                <ClientId DataType="S32">12345</ClientId>
            </User>
            <Instructions>
                <Pipeline>Payment</Pipeline>
            </Instructions>
            <OrderFormDoc>
                <Mode>T</Mode>
                <Id>' . $Temp_Order_ID. '</Id>
                <Consumer>
                    <Email>' . $User_NameX . '</Email>
                    <BillTo>
                        <Location>
                            <Address>
                                <FirstName>' . $First_Name . '</FirstName>
                                <LastName>' . $Surname .'</LastName>
                                <Street1>' . $Address_Line1 . '</Street1>
                                <Street2>' . $Address_Line2 . '</Street2>
                                <Street3></Street3>
                                <City>' . $Town . '</City>
                                <StateProv>' . $Country . '</StateProv>
                                <PostalCode>' . $Postcode . '</PostalCode>
                                <Country>' . getCuntCode($Country) . '</Country>
                            </Address>
                        </Location>
                    </BillTo>
                    <ShipTo>
                        <Location>
                            <Address>
                                <FirstName>' . $First_Name . '</FirstName>
                                <LastName>' . $Surname .'</LastName>
                                <Street1>' . $Address_Line1 . '</Street1>
                                <Street2>' . $Address_Line2 . '</Street2>
                                <Street3></Street3>
                                <City>' . $Town . '</City>
                                <StateProv>' . $Country . '</StateProv>
                                <PostalCode>' . $Postcode . '</PostalCode>
                                <Country>' . getCuntCode($Country) . '</Country>
                            </Address>
                        </Location>
                    </ShipTo>
                    <PaymentMech>
                        <CreditCard>
                            <Type DataType="S32">1</Type>
                            <Number>' . $CardNumber . '</Number>
                            <Expires DataType="ExpirationDate" Locale="826">' . $CardExpiryDate . '</Expires>
                            ' . $issue_node . ' 
                            <Cvv2Indicator>' . $cvvindicator . '</Cvv2Indicator>
                            <Cvv2Val>' . $CardCVV . '</Cvv2Val>
                        </CreditCard>
                    </PaymentMech>
                </Consumer>
                <Transaction>
                    <Type>Auth</Type>
                    <CurrentTotals>
                        <Totals>
                            <Total DataType="Money" Currency="826">' . $totalCost . '</Total>
                        </Totals>
                    </CurrentTotals>
                    <CardholderPresentCode DataType="S32"></CardholderPresentCode>
                    <PayerSecurityLevel DataType="S32"></PayerSecurityLevel>
                    <PayerAuthenticationCode></PayerAuthenticationCode>
                    <PayerTxnId></PayerTxnId>
                </Transaction>
            </OrderFormDoc>
        </EngineDoc>
    </EngineDocList>';

        $url = "https://secure2.epdq.co.uk:11500";

        $params = array("CLRCMRC_XML" => $xml);
        $params = formatData($params);

        $response = post_to_epdq($url, $xml);   
        $auth_code = strstr($response, "<AuthCode>");

        echo "auth_code=" . $auth_code;

        if ($auth_code <> "") {

            $splt = split("</AuthCode>", $auth_code);
            $status = strip_tags($splt[0]);
            return $xml . "<hr/>" . $response . "Good";
        } else {

            $error = strstr($response, "<Text>");
            $splt = split("</Text>", $error);
            $status = strip_tags($splt[0]);
            return $xml . "<hr/>" . $response . "Bad";

        }
    }

    function post_to_epdq($url, $data) {


        set_time_limit(120);
        $output = array();
        $curlSession = curl_init();
        curl_setopt($curlSession, CURLOPT_URL, $url);
        curl_setopt($curlSession, CURLOPT_PORT, 443);
        curl_setopt($curlSession, CURLOPT_HEADER, 0);
        curl_setopt($curlSession, CURLOPT_POST, 1);
        curl_setopt($curlSession, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curlSession, CURLOPT_TIMEOUT, 60);
        #$response = split(chr(10),curl_exec ($curlSession));

        $response = curl_exec($curlSession);

        if (curl_error($curlSession)) {
            $this->error = curl_error($curlSession);
            return "ERROR";
        }

        curl_close($curlSession);
        return $response;
    }

    function formatData($data) {

        $output = "";
        foreach ($data as $key => $value)
            $output .= "&" . $key . "=" . urlencode($value);
            $output = substr($output, 1);
            return $output;
    }

Needless to say I validate the user input, generate their IP and determine a country code, I then call the above function:

process_card($users_ip,$Temp_Order_ID,$User_NameX,$First_Name,$Surname,$Address_Line1,$Address_Line2,$Town,$Country,$Postcode,$CardNumber, $CardExpiryDate, $issue_node, $CardCVV, $totalCost );

I don't get a response? I'm unsure if the port and url items are incorrect or if the whole CURL request is wrong. Nothing is returned from the request.

Sorry about this being a long post but this is really doing my head in!

Has anyone done this before?

Howdy, after some playing around here's the correct CURL set up you have to do...

I realise that the variables could be better and I should make this as an object but I just want to get a quick answer up there. The script also needs to sift through the different accept and error messages but this is what I've got so far...

$ch = curl_init();
$url = "https://secure2.epdq.co.uk:11500"; // Don't need to add curl_setopt($curlSession, CURLOPT_PORT, 443); as port is included
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $vars); // $vars is your XML 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

$data = curl_exec($ch);
curl_close ($ch);

$xml = new domDocument;
$xml->loadXML($data);

if (!$xml) {
    echo 'Error while parsing the document - Please Contact to determine if payment has gone though';
    exit;
}

$x = $xml->getElementsByTagName( "CcErrCode" );
$approved = $x->item(0)->nodeValue;

$xx = $xml->getElementsByTagName( "CcReturnMsg" );
$CcReturnMsg = $xx->item(0)->nodeValue;

if($approved) {

// the card is valid.
    $y = $xml->getElementsByTagName( "Id" );
    $BCardId = $y->item(1)->nodeValue;

    $z = $xml->getElementsByTagName( "MessageList" );
    $MessageList = $z->item(0)->nodeValue;

    $zz = $xml->getElementsByTagName( "AvsRespCode" );
    $AvsRespCode = $zz->item(0)->nodeValue;

    $zzz = $xml->getElementsByTagName( "AvsDisplay" );
    $AvsDisplay = $zzz->item(0)->nodeValue;

    $zzzz = $xml->getElementsByTagName( "ProcReturnMsg" );
    $ProcReturnMsg = $zzzz->item(0)->nodeValue;

     if($approved == "1"){
       echo "approved!<br />";
       echo "BCardId: " . $BCardId . ", MessageList=" . $MessageList . ", " . $AvsRespCode . ", " . $AvsDisplay . ", " . $ProcReturnMsg;
       die();
     }else{
       // raise that it's been partially accepted, 
       echo "partially approved";
       echo "BCardId: " . $BCardId . ", MessageList=" . $MessageList . ", " . $AvsRespCode . ", " . $AvsDisplay . ", " . $ProcReturnMsg;
       die();
     }

}else{
   echo "you have been completely knocked back";
   $zzzzz = $xml->getElementsByTagName( "Text" );
   $BCard_Text = $zzzzz->item(0)->nodeValue;
   echo "The reason:" . $BCard_Text;    
   die();
}

hope this helps other people who have to set this up!

I've managed to fix my problem now. It turned out that the CURL connection to the Barclays website was blocked by a firewall on the server which was why I was getting no error message back.

I modified the CURL code a bit to check for errors:

$data = curl_exec($ch); 

if(curl_errno($ch)) {
    print curl_error($ch);  
}

curl_close ($ch); 

This then says: couldn't connect to host at which point I tried it on another server and it got past this error.

The error I am getting now is: "Insufficient permissions to perform requested operation." I have tried all the accounts I have been given but if I log into the EPDQ control panel I seem to only be able to assign up to EPDQ Level 4 and CPI access with no mention of MPI and even though it says technical support is available from 8AM until 12PM, it is not. It is really just office hours for anything but the most basic queries.

Is there any advantage to using this over SagePay? SagePay allows you to send through the individual transaction details as well where Barclays only lets you send the total amount payable and they really do offer support out of office hours.

The only reason I am changing the site to MPI is the fact that with CPI the customer can close the browser before returning to the website so the order details and invoice are not sent so there is no way of knowing what has been purchased.

Thanks Robin