Php Authroize.Net缺少接受托管iFrame页的令牌或令牌无效

Php Authroize.Net缺少接受托管iFrame页的令牌或令牌无效,php,token,authorize.net,Php,Token,Authorize.net,在这里,Authorize.Net非常糟糕的文档和错误报告。我正在尝试实现一个接受托管的页面来处理信用卡。我能够生成令牌,但当我将令牌传递到表单(在iFrame中)时,我得到一个错误缺少或无效令牌 令牌的创建没有任何问题,但是当试图使用它时,它是在事情偏离正轨的情况下创建的 在chrome InSpector控制台中,我得到两个返回的javascript错误: ERROR TypeError: Cannot read property 'billTo' of null ERROR TypeErr

在这里,Authorize.Net非常糟糕的文档和错误报告。我正在尝试实现一个
接受托管的
页面来处理信用卡。我能够生成令牌,但当我将令牌传递到表单(在iFrame中)时,我得到一个错误
缺少或无效令牌

令牌的创建没有任何问题,但是当试图使用它时,它是在事情偏离正轨的情况下创建的

在chrome InSpector控制台中,我得到两个返回的javascript错误:

ERROR TypeError: Cannot read property 'billTo' of null
ERROR TypeError: Cannot read property 'offsetHeight' of null
因此,打印出我的
$request
json我能够验证传递给创建令牌的json对象是否正确:

{
  "merchantAuthentication": {"name":"xxxxxxxx","transactionKey":"yyyyyyyyyyyy"},
  "clientId":"sdk-php-2.0.0-ALPHA",
  "refId":"ref1608564012",
  "transactionRequest": {
    "transactionType":"authCaptureTransaction",
    "amount":"360.00",
    "order":  {"invoiceNumber":"11373-0","description":"2020-11-01 bill for All Regions\/All Sites"},
    "customer":{"type":"business","id":"1002","email":"pjohnson@gmail.com"},
    "billTo":{"firstName":"Preston","lastName":"Johnson","company":"Backyard Grill","address":"123 Main St","city":"Tampa","state":"FL","zip":"33611","country":"USA"},
    "shipTo":{"firstName":"Preston","lastName":"Johnson","company":"Backyard Grill","address":"123 Main St","city":"Tampa","state":"FL","zip":"33611","country":"USA"}
  },
  "hostedPaymentSettings":
    {"setting":[
      {"settingName":"hostedPaymentReturnOptions","settingValue":"{ \"url\": \"https:\/\/portal.attendago.com\/adminInvoicePaid.html\", \"cancelUrl\": \"https:\/\/portal.attendago.com\/adminInvoicePay.html?invID=11373-0\", \"showReceipt\":true }"},
      {"settingName":"hostedPaymentButtonOptions","settingValue":"{ \"text\": \"Submit Payment\" }"},
      {"settingName":"hostedPaymentStyleOptions","settingValue":"{ \"bgColor\": \"#192a67\" }"},
      {"settingName":"hostedPaymentPaymentOptions","settingValue":"{ \"cardCodeRequired\":true, \"showCreditCard\":true, \"showBankAccount\":true }"},
      {"settingName":"hostedPaymentShippingAddressOptions","settingValue":"{ \"show\":false, \"required\":true }"},
      {"settingName":"hostedPaymentBillingAddressOptions","settingValue":"{ \"show\":true, \"required\":true }"},
      {"settingName":"hostedPaymentCustomerOptions","settingValue":"{ \"showEmail\":true, \"requiredEmail\":true, \"addPaymentProfile\":false }"},
      {"settingName":"hostedPaymentOrderOptions","settingValue":"{ \"show\":false }"},
      {"settingName":"hostedPaymentIFrameCommunicatorUrl","settingValue":"{ \"url\": \"https:\/\/portal.attendago.com\/adminInvoiceFrame.html\" }"}
  ]}
}
以下是我创建令牌的函数:

function getCustomerToken($ss) {
    $ii = $ss['invoiceData'] ;
    if (isSet($ss['payMethods'])) {
      $pp = $ss['payMethods'] ;
    }
    
    ////////////////////////////////////////////////
    /// global objects needed for all transactions
    ////////////////////////////////////////////////
    
    // Create a merchantAuthenticationType, pulled from constants file
    $merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
    $merchantAuthentication->setName(\AuthorizeConstants::sandboxID);  // loginID / sandboxID
    $merchantAuthentication->setTransactionKey(\AuthorizeConstants::sandboxKey);  // loginKey / sandboxKey
    
    // Set the transaction's refId
    $refId = 'ref' . time();
    
    // Set order information
    $order = new AnetAPI\OrderType();
    $order->setInvoiceNumber($ss['invoiceID']);
    if (strpos($ii['invName'], "S") !== false) {
      $invDesc = $ii['servMonth']. " bill for Site " .$ii['venue'] ;
    } else if (strpos($ii['invName'], "R") !== false) {
      $invDesc = $ii['servMonth']. " bill for Region " .$ii['venue'] ;
    } else {
      $invDesc = $ii['servMonth']. " bill for " .$ii['venue'] ;
    }
    $order->setDescription($invDesc);    
    
    // Set the customer's identifying information
    $customerData = new AnetAPI\CustomerDataType();
    $customerData->setType("business");
    $customerData->setId($ii['cID']);
    $customerData->setEmail($ii['cEmail']);
    
    // Set the Bill To info for new payment type
    $billTo = new AnetAPI\CustomerAddressType();
    $billTo->setFirstName($ii['cFirstName']);
    $billTo->setLastName($ii['cLastName']);
    $billTo->setCompany($ii['cName']);
    $billTo->setAddress($ii['cAddress']. " " .$ii['cAddress1']);
    $billTo->setCity($ii['cCity']);
    $billTo->setState($ii['cState']);
    $billTo->setZip($ii['cZip']);
    $billTo->setCountry("USA");
    //$billTo->setFaxNumber('8005551212') ;
    //$billTo->setPhoneNumber($ii['cPhone']);
    
    // set shipping profile
    $shippingProfiles[] = $billTo ;
    
    //create a transaction
    $transactionRequestType = new AnetAPI\TransactionRequestType();
    $transactionRequestType->setTransactionType("authCaptureTransaction");
    $transactionRequestType->setAmount($ss['balance']);
    $transactionRequestType->setCustomer($customerData) ;
    $transactionRequestType->setOrder($order) ;
    if (isSet($ss['authMerchID'])) {
      $profileType = new AnetAPI\CustomerProfilePaymentType();
      $profileType->setCustomerProfileId($ss['authMerchID']) ;
      $transactionRequestType->setProfile($profileType) ;
    } else {
      $transactionRequestType->setBillTo($billTo) ;
      $transactionRequestType->setShipTo($billTo) ;
    }

    // Set Hosted Form options
    $setting0 = new AnetAPI\SettingType();
    $setting0->setSettingName("hostedPaymentReturnOptions");
    $setting0->setSettingValue( "{ \"url\": \"https://portal.mysdomain.com/adminInvoicePaid.html\", \"cancelUrl\": \"https://portal.mydomain.com/adminInvoicePay.html?invID=" .$ss['invoiceID']. "\", \"showReceipt\":true }" );
    
    $setting1 = new AnetAPI\SettingType();
    $setting1->setSettingName("hostedPaymentButtonOptions");
    $setting1->setSettingValue("{ \"text\": \"Submit Payment\" }");

    $setting2 = new AnetAPI\SettingType();
    $setting2->setSettingName("hostedPaymentStyleOptions");
    $setting2->setSettingValue("{ \"bgColor\": \"#192a67\" }");

    $setting3 = new AnetAPI\SettingType();
    $setting3->setSettingName("hostedPaymentPaymentOptions");
    $setting3->setSettingValue("{ \"cardCodeRequired\":true, \"showCreditCard\":true, \"showBankAccount\":true }");
    
    $setting4 = new AnetAPI\SettingType();
    $setting4->setSettingName("hostedPaymentShippingAddressOptions");
    $setting4->setSettingValue("{ \"show\":false, \"required\":true }");
    
    $setting5 = new AnetAPI\SettingType();
    $setting5->setSettingName("hostedPaymentBillingAddressOptions");
    $setting5->setSettingValue("{ \"show\":true, \"required\":true }");
    
    $setting6 = new AnetAPI\SettingType();
    $setting6->setSettingName("hostedPaymentCustomerOptions");
    $setting6->setSettingValue("{ \"showEmail\":true, \"requiredEmail\":true, \"addPaymentProfile\":false }");
    
    $setting7 = new AnetAPI\SettingType();
    $setting7->setSettingName("hostedPaymentOrderOptions");
    $setting7->setSettingValue("{ \"show\":false }");
    
    $setting8 = new AnetAPI\SettingType();
    $setting8->setSettingName("hostedPaymentIFrameCommunicatorUrl");
    $setting8->setSettingValue("{ \"url\": \"https://portal.mydomain.com/adminInvoiceFrame.html\" }");

    // Build transaction request
    $request = new AnetAPI\GetHostedPaymentPageRequest();
    $request->setMerchantAuthentication($merchantAuthentication);
    $request->setRefId($refId);
    $request->setTransactionRequest($transactionRequestType);

    $request->addToHostedPaymentSettings($setting0);
    $request->addToHostedPaymentSettings($setting1);
    $request->addToHostedPaymentSettings($setting2);
    $request->addToHostedPaymentSettings($setting3);
    $request->addToHostedPaymentSettings($setting4);
    $request->addToHostedPaymentSettings($setting5);
    $request->addToHostedPaymentSettings($setting6);
    $request->addToHostedPaymentSettings($setting7);
    $request->addToHostedPaymentSettings($setting8);

    //execute request
    $controller = new AnetController\GetHostedPaymentPageController($request);
    $response = $controller->executeWithApiResponse(\net\authorize\api\constants\ANetEnvironment::SANDBOX);
    
    $gToken=[] ;
    if (($response != null) && ($response->getMessages()->getResultCode() == "Ok")) {
        //echo $response->getToken()."\n";
        $gToken["Error"]  = 0 ;
        $gToken["Token"] = $response->getToken() ;
    } else {
        //echo "ERROR :  Failed to get hosted payment page token\n";
        $errorMessages = $response->getMessages()->getMessage();
        //echo "RESPONSE : " . $errorMessages[0]->getCode() . "  " .$errorMessages[0]->getText() . "\n";
        $gToken["Error"]  = 1 ;
        $gToken["errMsg"] = $errorMessages[0]->getCode() . ":  " .$errorMessages[0]->getText() ;
    }
    return array($gToken,$request);
}
***更新***


查看网络控制台日志,有一个到
https://test.authorize.net/payment/payment
-但是密钥
令牌
为空,这可能是导致错误
令牌丢失或无效的原因。在我的表单中,我可以验证令牌是否存在。但是,当我单击
触发弹出iFrame
按钮时,我可以直观地看到
标记正在从隐藏表单字段中删除。

打开弹出iFrame的代码,从Authorize.net代码示例中逐字复制的代码有这段代码
$(“#popupToken”).val($(“#inputtoken”).val()-这是在将令牌值提交到支付网关之前擦除/删除令牌值-见鬼?!为什么他们自己的示例代码会这样做?对此进行评论,修复了它

AuthorizeNetPopup.openPopup = function () {
  var popup = document.getElementById("divAuthorizeNetPopup");
  var popupScreen = document.getElementById("divAuthorizeNetPopupScreen");
  var ifrm = document.getElementById("iframeAuthorizeNet");
  var form = document.forms["formAuthorizeNetPopup"];
  //$("#popupToken").val($("#inputtoken").val());   // WTH authorize????
  form.action = "https://test.authorize.net/payment/payment";
  ifrm.style.width = "442px";
  ifrm.style.height = "578px";

  form.submit();

  popup.style.display = "";
  popupScreen.style.display = "";
  centerPopup();
  };