2Checkout OmniPay - 授权失败

2Checkout OmniPay - Authorization Failed

我在使用 OmniPay API 时收到来自 2Checkout 的授权失败响应。

我已经成功地将 Stripe 与 OmniPay 连接起来,所以我开始着手连接 2Checkout。当您这样做时,Github 上的初始包会警告您获取 the newer version from a user collizo4sky。所以,我做到了,然后让它在没有致命错误的情况下稍微工作。

在我的网络表单中,我正确生成了一个令牌,2Checkout 的沙箱日志证实了这一点。然后我在 OmniPay 中使用此代码尝试对卡收费:

use Omnipay\Omnipay;
$sMerchantTransID = rand(11111111,99999999);
$oGateway = Omnipay::create('TwoCheckoutPlus_Token');
$oGateway->setPrivateKey($config->TWOCHECKOUT_PRIVATE_KEY);
$oGateway->setAccountNumber($config->TWOCHECKOUT_SELLERID);
$oGateway->setTestMode(true);
$oResponse = $oGateway->purchase(array(
    'amount' => $sPrice,
    'currency' => 'USD',
    'token' => $sToken,
    'transactionId' => $sMerchantTransID
))->send();
if (!$oResponse->isSuccessful()) {
    die('ERROR: ' . $oResponse->getMessage());
}

但是,消息返回 "Authorization Failed"。所以,我进入了 OmniPay 的源代码 API for collizo4sky's package in this path...

omnipay/vendor/collizo4sky/omnipay-2checkout/src/Message/TokenPurchaseRequest.php

...并添加了 sendData() class 方法的一些日志文件调试。这是它的回应,请注意,出于明显的隐私原因,我更改了一些值:

array (
  'sellerId' => '901414261',
  'privateKey' => 'EAEC8615-4C48-4D98-B7E5-4B6D8865E1BA',
  'merchantOrderId' => 65639323,
  'token' => 'FDI1ZTM3N2UtY2VkZS00NTM1LWE5MTctYzI4MjA5YWI4Yjhm',
  'currency' => 'USD',
  'total' => '519.00',
)

是的,sellerID 和 privateKey 来自沙盒帐户,当我首先在 Web 表单中生成令牌时,可发布密钥也是如此。

所以,无论如何,当它被提交到沙箱 URL 时,它 returns 的响应是:

HTTP/1.1 400 Bad Request
Server: Apache-Coyote/1.1
Cache-Control: no-cache, no-store, must-revalidate
Date: Fri, 22 Apr 2016 03:30:37 GMT
Expires: 0
Pragma: no-cache
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked

{"validationErrors":null,"response":null,"exception":{"errorMsg":"Authorization Failed","httpStatus":"400","exception":false,"errorCode":"600"}}

我做错了什么?

编辑:

然后我尝试使用他们提供的 2Checkout-supported PHP library。我做了完全相同的交易而且它也是 returns "Authorization Failed".

我想知道这是否是我帐户上的设置,即使我使用的是沙盒?我的意思是,我还没有在生产中获得批准,并且一直试图让沙箱运行到那时,以便我可以做一个演示。

我还在沙盒中重新生成了 API 密钥并再次尝试,但失败了。

我使用的信用卡是他们在沙箱 API 密钥下的沙箱中提供的信用卡,我使用的 CVV 为 123,有效期为 12/18。然后我想也许它想要一个 4 位数的年份,所以我更新了它并再次尝试,但同样失败了 "Authorization Failed".

当我查看 "Authorization Failed" 的含义时,似乎是信用卡问题。

到目前为止,我的直觉告诉我,我所做的一切都是正确的,这是我帐户上的一个标志,这就是问题所在。我的意思是,如果我的常规帐户尚未获得批准,沙盒是否仍然有效?

我可以让交易通过的唯一方法是在帐户 > 站点管理下的沙箱设置中手动将演示模式设置为 "Off",然后至少传递一个账单地址.我很想知道如何没有帐单地址要求(例如数字下载商品),但还没有找到这样做的方法,或者如果这可能的话。

请注意,如果您将演示模式设置为 "On",并且不发送账单地址,交易将顺利进行,但不会在“销售”选项卡下显示为销售。这不是很有用,因为当你上线时你想要一个可以退款的实际销售,而演示模式不模拟实际收费,只是该卡的授权。 (至少我是这么想的。)

transactionId参数上,为了这里的目的,我采取了快捷方式。请使其成为您系统中的唯一编号(例如使用 UNIX 时间生成的某些编号),否则您可能会遇到潜在的冲突。

我也试过只注释掉电子邮件,或者只注释掉 phone,或者两者都注释掉,但这没有用——你会得到 "Parameter Error"。然后,我尝试仅发送 card 下的这些字段:billingNameemailbillingPostcodebillingCountry——但失败了 "Parameter Error" 也。然后我添加了 billingState -- "Parameter Error"。然后,添加了billingCity——"Parameter Error"。因此,为了完成交易,除非有人能告诉我一些设置覆盖或技术,否则账单地址是必需的,并且还必须包括电子邮件和 phone,令我惊讶的是。这对某些人来说是个阻碍,我敢肯定,比如那些试图销售数字下载等无形资产的人。另请注意,我尝试了 official 2Checkout-created PHP API 并再次尝试了所有这些测试,并且再次收到 "Parameter Error" 除非使用了完整的帐单地址(包括电子邮件和 phone)。 这个完整的帐单地址要求以及电子邮件和帐单 phone 对某些企业来说将是一个无赖,我敢肯定。

编辑: This answer,如果我猜对了,是 2Checkout 工作人员的官方回答吗?它看起来确实是那样的。无论如何,他说账单地址是绝对必需的,因为正如他所说,"This is a requirement of our banking partners for address verification."

EDIT2: 你需要试验一个真实的实时交易,但我至少在沙盒模式下发现,如果我为 phoneNumber 官方 2Checkout PHP 库 或 OmniPay API 中的 billingPhone 字段,然后交易顺利进行。他们只想查看该参数,尽管它可以为空。但不要相信我的话——在实时交易中对其进行测试(并自行退款)以再次确认,因为我只是在沙盒中这样做。 This answer 似乎从 2Checkout 本身正式确认他们允许这样做。

固定码:

use Omnipay\Omnipay;
$sMerchantTransID = rand(11111111,99999999);
$oGateway = Omnipay::create('TwoCheckoutPlus_Token');
$oGateway->setPrivateKey($config->TWOCHECKOUT_PRIVATE_KEY);
$oGateway->setAccountNumber($config->TWOCHECKOUT_SELLERID);
$oGateway->setTestMode(true); // turns on Sandbox access
$oResponse = $oGateway->purchase(array(
    'amount' => $sPrice,
    'currency' => 'USD',
    'token' => $sToken,
    'transactionId' => $sMerchantTransID,
    'card' => array(
        'billingName' => $sName,
        'billingAddress1' => $sStreet1,
        'billingAddress2' => $sStreet2,
        'billingCity' => $sCity,
        'billingState' => $sState,
        'billingPostcode' => $sZip,
        'billingCountry' => $sCountry,
        'email' => $sEmail,
        'billingPhone' => $sPhone
    )
))->send();
if (!$oResponse->isSuccessful()) {
    die('ERROR: ' . $oResponse->getMessage());
}