2Checkout OmniPay - 授权失败

时间:2016-04-22 04:07:37

标签: php payment-gateway payment-processing omnipay 2checkout

使用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());
}

然而,该消息以“授权失败”返回。所以,我在这条路径中为collizo4sky的软件包进入了OmniPay API的源代码......

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

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

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

是的,卖家ID和privateKey来自沙箱帐户,当我首先在网络表单中生成令牌时,可发布的密钥也是如此。

因此,无论如何,当提交到沙箱URL时,它会返回此响应:

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。我做了完全相同的交易,它也返回“授权失败”。

即使我正在使用沙盒,我想知道它是否是我帐户的设置?我的意思是,我还没有在生产中获得批准,并试图让沙箱继续运行,以便我可以进行演示。

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

我使用的信用卡是他们在沙箱API密钥下的沙盒上提供的信用卡,我使用了123的CVV,12/18作为到期日。然后我想也许它想要一个4位数的年份,所以我更新了它并再次尝试,并且因为“授权失败”的相同一致错误也失败了。

当我检查“授权失败”的含义时,看来信用卡就是问题所在。

到目前为止,我的直觉告诉我,我正在做的一切都是正确的,而且这是我账户上的一面旗帜,这就是问题所在。我的意思是,如果我的常规帐户尚未批准,沙箱是否仍然可以使用?

1 个答案:

答案 0 :(得分:3)

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

请注意,如果您将演示模式设置为"开",再加上不发送结算地址,交易将会正常运行,但之后它不会显示为促销在“销售”选项卡下。这不是很有用,因为当你上线时,你想要一个可以退款的实际销售,并且演示模式不会模拟实际的费用,只是该卡的授权。 (至少那是我所知道的。)

transactionId参数上,我在此处使用了一个快捷方式。请在系统中将其设为唯一编号(例如,使用UNIX时间生成的某个编号),否则最终可能会发生冲突。

我也尝试过只发送电子邮件,或只是电话,或两者兼而有之,但这些都没有用 - 你会得到"参数错误"。然后,我尝试仅在cardbillingNameemailbillingPostcodebillingCountry下的这些字段中发送 - 并且"参数错误"太。然后我添加了billingState - "参数错误"。然后,添加billingCity - "参数错误"。因此,为了使交易顺利进行,除非有人可以向我显示一些设置覆盖或技术,否则需要结算地址,并且还必须包含电子邮件和电话,令我惊讶不已。对于某些人来说,这是一个显而易见的事情,我敢肯定,比如那些试图销售数字下载等非有形产品的人。另请注意,我尝试了official 2Checkout-created PHP API并再次尝试了所有这些测试,并再次收到"参数错误"除非使用完整的帐单地址(包括电子邮件和电话)。 对于某些商家来说,这个完整的帐单地址要求以及电子邮件和结算电话对我来说都是一件好事。我很有信心。

编辑: This answer,如果我猜对了,是2Checkout工作人员的正式回答吗?确实看起来那样。无论如何,他说明确要求账单地址,因为他说,"这是我们的银行合作伙伴要求进行地址验证的要求。"

EDIT2:您需要尝试真实的实时交易,但我发现至少在沙盒模式下,如果我为phoneNumber字段传递一个空字符串在official 2Checkout PHP library或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());
}