0

我已经下载了Direct Payment Sample_REST-JSON_PHP.zip。我成功整合了我的商家信息,但是在进行支付操作时x_pay_simple.html出现以下错误

{
   "error": {
       "cause": "INVALID_REQUEST",
       "explanation": "Missing parameter. value: null - reason: A 3DS Authentication ID value or 3DS Authentication Details is required for the transaction source used for this transaction",
       "field": "3DSecure",
       "validationType": "MISSING"
   },
   "result": "ERROR"
}

我阅读了文档,了解到 3DSecure 是从网关生成的,我认为添加支付和 3Dsecure 是在 1 个用例中完成的。

如何将 3DSecure 添加到我的实施中?

这是 HTML:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>
<link rel="stylesheet" type="text/css" href="./assets/paymentstyle.css" />

<head>
    <title>API Example Code</title>
    <meta http-equiv="Content-Type" content="text/html, charset=iso-8859-1">
</head>

<body>

    <h1>PHP Example - REST (JSON)</h1>
    <h3>Simple Pay Operation</h3>
    <p><a href="index.html">Return to the Home Page</a></p>

    <form action="./process.php" method="post">

    <table width="60%" align="center" cellpadding="5" border="0">

        <!-- Credit Card Fields -->
        <tr class="title">
            <td colspan="2" height="25"><P><strong>URL Fields</strong></P></td>
        </tr>

        <tr>
            <td colspan="2" height="25"><P class="desc">Order and Transaction IDs are required and used to calculate the URL along with the version and merchant ID. In your integration, you would calculate these fields within your code (process.php based on this example) and not expose these to the card holder on this page, or pass them as hidden fields.</P></td>
        </tr>

         <tr class="shade">
             <td align="right" width="50%"><strong>version </strong></td>
             <td width="50%"><input type="text" readonly="readonly" name="version" value="34" size="8" maxlength="80" /></td>
         </tr>

         <tr>
             <td align="right" width="50%"><strong>order.id</strong></td>
             <td><input type="text" name="orderId" value="" size="20" maxlength="60"/></td>
         </tr>

         <tr class="shade">
              <td align="right" width="50%"><strong>transaction.id</strong></td>
            <td><input type="text" name="transactionId" value="" size="20" maxlength="60"/></td>
         </tr>





         <tr><td colspan="2"></td></tr>

         <tr class="title">
             <td colspan="2" height="25"><P><strong>&nbsp;Transaction Fields</strong></P></td>
         </tr>

         <tr>
             <td align="right" width="50%"><strong>method </strong></td>
             <td width="50%"><input type="text" readonly="readonly" name="method" value="PUT" size="20" maxlength="80"/> ** See Note 1 Below</td>
         </tr>

         <tr class="shade">
             <td align="right" width="50%"><strong>apiOperation </strong></td>
             <td width="50%"><input type="text" readonly="readonly" name="apiOperation" value="PAY" size="20" maxlength="80"/></td>
         </tr>




        <tr>
            <td align="right"><strong>sourceOfFunds.type </strong></td>
            <td><input type="text" name="sourceOfFunds[type]" value="CARD" size="19" maxlength="80"/></td>
        </tr>

         <tr class="shade">
             <td align="right"><strong>sourceOfFunds.provided.card.number </strong></td>
             <td><input type="text" name="sourceOfFunds[provided][card][number]" value="" size="19" maxlength="80"/></td>
         </tr>

         <tr>
             <td align="right"><strong>sourceOfFunds.provided.card.expiry.month </strong></td>
             <td><input type="text" name="sourceOfFunds[provided][card][expiry][month]" value="" size="1" maxlength="2"/></td>
         </tr>

         <tr class="shade">
             <td align="right"><strong>sourceOfFunds.provided.card.expiry.year </strong></td>
             <td><input type="text" name="sourceOfFunds[provided][card][expiry][year]" value="" size="1" maxlength="2"/></td>
         </tr>

         <tr>
             <td align="right"><strong>sourceOfFunds.provided.card.securityCode </strong></td>
             <td><input type="text" name="sourceOfFunds[provided][card][securityCode]" value="" size="8" maxlength="4"/></td>
         </tr>

         <tr class="shade">
             <td align="right"><strong>order.amount </strong></td>
             <td><input type="text" name="order[amount]" value="" size="8" maxlength="13"/></td>
         </tr>

         <tr>
             <td align="right"><strong>order.currency </strong></td>
             <td><input type="text" name="order[currency]" value="SAR" size="8" maxlength="3"/></td>
         </tr>

         <tr>
             <td colspan="2"><center><input type="submit" name="submit" value="Process Payment"/></center></td>
         </tr>

         <tr><td colspan="2"></td></tr>

         <tr>
             <td colspan="2" height="25"><P class="desc"><strong>Note 1:</strong> This field is used by this example to set the HTTP Method for sending the transaction. In your integration, you should determine the HTTP Method in your code (process.php based on this example) and never display it to the card holder or pass it as a hidden field.</P></td>
         </tr>

    </table>


    </form>
    <br/><br/>

</body>

进程.php

<?php
    /* Main controller page
    1. Create 1 MerchantConfiguration object for each merchant ID
    2. Create 1 Parser object
    3. Call Parser object FormRequest method to form the request that will be sent to the payment server
    4. Parse the formed reqest to SendTransaction method to attempt to send the transaction to the payment server
    5. Store the received transaction response in a variable
    6. Include receipt page which will output the response HTML and parse the server response

    */

    include "configuration.php";
    include "connection.php";


    // This is used to set the HTTP operation for sending the transaction
    // In your integration, you should never pass this in, but set the value here based on your requirements
    if (array_key_exists("method", $_POST))
      $method = $_POST["method"];


    // The following section allows the example code to setup the custom/changing components to the URI
    // In your integration, you should never pass these in, but set the values here based on your requirements
    $customUri = "";
    if (array_key_exists("orderId", $_POST))
      $customUri .= "/order/" . $_POST["orderId"];

    if (array_key_exists("transactionId", $_POST))
      $customUri .= "/transaction/" . $_POST["transactionId"];


    // Add any HTML/$_POST field names that you want to unset to this array
    // If you have any other fields in the HTTP POST, you need to process them here and remove from $_POST
    // After this, $_POST should only contain fields that are being sent as part of the transaction
    $unsetNames = array("orderId", "transactionId", "submit", "method");

    // loop through each field in the unsetNames array
    // unset the field if the key exists
    foreach ($unsetNames as $fieldName) {
      if (array_key_exists($fieldName, $_POST))
        unset($_POST[$fieldName]);
    }

    // Creates the Merchant Object from config. If you are using multiple merchant ID's,
    // you can pass in another configArray each time, instead of using the one from configuration.php
    $merchantObj = new Merchant($configArray);

    // The Parser object is used to process the response from the gateway and handle the connections
    $parserObj = new Parser($merchantObj);

    // In your integration, you should never pass this in, but store the value in configuration
    // If you wish to use multiple versions, you can set the version as is being done below
    if (array_key_exists("version", $_POST)) {
      $merchantObj->SetVersion($_POST["version"]);
      unset($_POST["version"]);
    }

    // form transaction request
    $request = $parserObj->ParseRequest($_POST);

    // if no post received from HTML page (parseRequest returns "" upon receiving an empty $_POST)
    if ($request == "")
      die();

    // print the request pre-send to server if in debug mode
    // this is used for debugging only. This would not be used in your integration, as DEBUG should be set to FALSE
    if ($merchantObj->GetDebug())
      echo $request . "<br/><br/>";

    // forms the requestUrl and assigns it to the merchantObj gatewayUrl member
    // returns what was assigned to the gatewayUrl member for echoing if in debug mode
    $requestUrl = $parserObj->FormRequestUrl($merchantObj, $customUri);

    // this is used for debugging only. This would not be used in your integration, as DEBUG should be set to FALSE
    if ($merchantObj->GetDebug())
      echo $requestUrl . "<br/><br/>";


    // attempt sending of transaction
    // $response is used in receipt page, do not change variable name
    $response = $parserObj->SendTransaction($merchantObj, $request, $method);

    // print response received from server if in debug mode
    // this is used for debugging only. This would not be used in your integration, as DEBUG should be set to FALSE
    if ($merchantObj->GetDebug()) {
      // replace the newline chars with html newlines
      $response = str_replace("\n", "<br/>", $response);
      echo $response . "<br/><br/>";
      die();
    }


    // the receipt page is included and displayed here.
    // in your integration, you would most likely also want process the transaction response, and make appropriate updates
    // you can see how to parse and retrieve the results and other fields in the transaction at the top of receipt.php
    include "receipt.php";

    ?>

收据.php

    <?php

//Rima - start
include "process.php";
//Rima - end


$errorMessage = "";
$errorCode = "";
$gatewayCode = "";
$result = "";

$tmpArray = array();

// [Snippet] howToDecodeResponse - start
// $response is defined in process.php as the server response
$responseArray = json_decode($response, TRUE);
// [Snippet] howToDecodeResponse - end

// either a HTML error was received
// or response is a curl error
if ($responseArray == NULL) {
  print("JSON decode failed. Please review server response (enable debug in config.php).");
  die();
}

// [Snippet] howToParseResponse - start
if (array_key_exists("result", $responseArray))
  $result = $responseArray["result"];
// [Snippet] howToParseResponse - end

// Form error string if error is triggered
if ($result == "FAIL") {
  if (array_key_exists("reason", $responseArray)) {
    $tmpArray = $responseArray["reason"];

    if (array_key_exists("explanation", $tmpArray)) {
      $errorMessage = rawurldecode($tmpArray["explanation"]);
    }
    else if (array_key_exists("supportCode", $tmpArray)) {
      $errorMessage = rawurldecode($tmpArray["supportCode"]);
    }
    else {
      $errorMessage = "Reason unspecified.";
    }

    if (array_key_exists("code", $tmpArray)) {
      $errorCode = "Error (" . $tmpArray["code"] . ")";
    }
    else {
      $errorCode = "Error (UNSPECIFIED)";
    }
  }
}

else {
  if (array_key_exists("response", $responseArray)) {
    $tmpArray = $responseArray["response"];
    if (array_key_exists("gatewayCode", $tmpArray)){
      $gatewayCode = rawurldecode($tmpArray["gatewayCode"]);

    }

  }
    else
      $gatewayCode = "Response not received.";
  }
}

?>
<!--    The following is a simple HTML page to display the response to the transaction.
      This should never be used in your integration -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <link rel="stylesheet" type="text/css" href="assets/paymentstyle.css" />
    <head>
      <title>API Example Code</title>
      <meta http-equiv="Content-Type" content="text/html, charset=iso-8859-1">
    </head>
    <body>
    <br/>
    <center><h1>PHP Example - REST (JSON)</h1></center>
    <center><h3>Receipt Page</h3></center><br/><br/>

  <table width="60%" align="center" cellpadding="5" border="0">

  <?php
    // echo HTML displaying Error headers if error is found
    if ($errorCode != "" || $errorMessage != "") {
  ?>
      <tr class="title">
             <td colspan="2" height="25"><P><strong>&nbsp;Error Response</strong></P></td>
         </tr>
         <tr>
             <td align="right" width="50%"><strong><i><?=$errorCode?>: </i></strong></td>
             <td width="50%"><?=$errorMessage?></td>
         </tr>
  <?php
    }

    else {
  ?>
      <tr class="title">
             <td colspan="2" height="25"><P><strong>&nbsp;<?=$gatewayCode?></strong></P></td>
         </tr>
         <tr>
             <td align="right" width="50%"><strong><i>Result: </i></strong></td>
             <td width="50%"><?=$result?></td>
         </tr>
  <?php
     }
  ?>
      <!-- Response Fields -->

         <tr class="title">
             <td colspan="2" height="20"><P><strong>&nbsp;JSON Response</strong></P></td>
         </tr>

  </table>

  <table width="50%" align="center" cellpadding="5" border="0">
    <tr>
      <td><p>The display of the below response is intended to be for this example only. In your integration, you should parse this      response to extract and use the response fields required.</p>
      </td>
    </tr>
     <tr>
       <td align="center" width="100%">
          <textarea rows="40" cols="118" name="outContent" id="outContent"><?=$response?></textarea>
      </td>
    </tr>

    <!-- The below Java Script & HTML formats the JSON output result to make it clean
         and readable. You should not use these scripts to format or expose the
         JSON response in your integration, but rather store/use any of the
         specific fields required for your integration -->
    <tr>
      <td align="center" width="100%">
        <p>Note: The above response has been formatted to make it easier to read. The reformatting also changes amounts to be strictly defined JSON numbers. This means 0's are removed from after the decimal place i.e. 1.00 is displayed as 1 and 1.10 is displayed as 1.1. <a href="javascript:displayRawJSON()">Click here to display the unformatted JSON Response</a></p>
      </td>
    </tr>
    <script type="text/javascript" src="./assets/json2.js"></script>
    <script type="text/javascript" src="./assets/jsonformatter.js"></script>
    <script type="text/javascript" src="./assets/jquery-1.3.2.js"></script>

    <script>
      var orginalJSON = $("#outContent").val();
      function FormatTextarea() {
        var sJSON = $("#outContent").val();
        var oJSON = JSON.parse(sJSON);
        sJSON = FormatJSON(oJSON);
        $("#outContent").val(sJSON);
      }
      FormatTextarea();

      function displayRawJSON() {
        $("#outContent").val(orginalJSON);
      }
    </script>

   </table>

  <br/><br/>
   </body>
</html>
4

1 回答 1

1

3-D Secure (3DS) 是在授权之前发生的单独工作流程。作为先决条件,您的商家帐户需要支持 3DS。在结帐时,首先您会收到 3DS 响应。如果卡支持 3DS 并且身份验证失败,那么您应该向持卡人显示错误消息。否则,如果 3DS 身份验证成功或未确定,则可以继续进行授权步骤。

3-D 安全认证有一个单独的集成文档

于 2018-04-15T15:03:58.733 回答