问题
I'm getting an Authorization Failed response from 2Checkout when using OmniPay API.
I had successfully hooked up Stripe with OmniPay, so then I went about hooking up 2Checkout. When you go to do that, the initial package on Github warns you to get the newer version from a user collizo4sky. So, I did, and then got it to work slightly without fatal error.
In my web form, I generate a token properly and the sandbox logs at 2Checkout confirm this. I then use this code in OmniPay to attempt to charge the card:
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());
}
However, the message comes back with "Authorization Failed". So, I went into the source code of the OmniPay API for collizo4sky's package in this path...
omnipay/vendor/collizo4sky/omnipay-2checkout/src/Message/TokenPurchaseRequest.php
...and added some log file debugging of the sendData() class method. This is what it responded with, and note that I changed some of the values for obvious privacy reasons:
array (
'sellerId' => '901414261',
'privateKey' => 'EAEC8615-4C48-4D98-B7E5-4B6D8865E1BA',
'merchantOrderId' => 65639323,
'token' => 'FDI1ZTM3N2UtY2VkZS00NTM1LWE5MTctYzI4MjA5YWI4Yjhm',
'currency' => 'USD',
'total' => '519.00',
)
Yes, the sellerID and the privateKey came from the sandbox account, as did the publishable key when I generated the token in the web form in the first place.
So, anyway, when this is submitted to the sandbox URL, it returns with this response:
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"}}
What am I doing wrong?
EDIT:
I then tried using the 2Checkout-supported PHP library that they provide. I did the exact same transaction and it too returns "Authorization Failed".
I'm wondering if it's a setting on my account even though I'm using a sandbox? I mean, I have not yet been approved in production, and was trying to get the sandbox going until then so that I could do a demo.
I also regenerated API keys in the sandbox and tried again, and that failed.
The credit card I used was the one they provide on the sandbox under the sandbox API keys, and I used a CVV of 123 with 12/18 as the expiration date. I then thought maybe it wanted a 4 digit year, so I updated that and tried again, and that failed too with the same consistent error of "Authorization Failed".
When I check on what "Authorization Failed" means, it appears that it's the credit card that's the problem.
My gut feeling so far is telling me that I'm doing everything correct and that it's a flag on my account that's the issue. I mean, if my regular account is not yet approved, will the sandbox still work?
回答1:
The only way that I could get a transaction to go through was to set the Demo mode to "Off" manually in the sandbox settings under Account > Site Management, and then to pass in at least a billing address. I'd love to find out how to not have the billing address requirement (such as for digital download goods), but have not found a way to do so just yet, or if that's even possible.
Please note that if you set Demo Mode to "On", plus don't send a billing address, the transaction will go through okay but then it won't appear as a sale under the Sales tab. That's not very useful, because when you go live you want an actual sale that you can refund, and Demo Mode doesn't simulate an actual charge, merely an authorization of that card. (At least that's what I've figured out.)
On the transactionId
parameter, I took a shortcut for purposes here. Please make it a unique number in your system (like some number generated with UNIX time) or you could end up with a potential collision.
I also tried commenting out just the email, or just the phone, or both, and that didn't work -- you'll get "Parameter Error". Then, I tried sending in only these fields under card
: billingName
, email
, billingPostcode
, and billingCountry
-- and that failed with "Parameter Error" too. So then I added billingState
-- "Parameter Error". Then, added billingCity
-- "Parameter Error". So, in order for the transaction to go through, unless someone can show me some setting override or technique, the Billing Address is required, and must also include email and phone, to my wild surprise. That's a showstopper for some people, I'm sure, such as those trying to sell non-tangibles like digital downloads. Note also that I tried the official 2Checkout-created PHP API and tried all these tests again with that, and again, received "Parameter Error" unless the full billing address (including email and phone too) was utilized. This full billing address requirement with also email and billing phone is going to be a bummer for some businesses, I'm sure.
EDIT: This answer, if I'm guessing right, is an official answer from someone working at 2Checkout, itself? It sure does look that way. Anyway, he says that the billing address is definitely required because, as he states, "This is a requirement of our banking partners for address verification."
EDIT2: You'll need to experiment with a real live transaction, but I discovered in at least sandbox mode that, if I pass an empty string for the phoneNumber
field on the official 2Checkout PHP library, or the billingPhone
in the OmniPay API, then the transaction goes through okay. They just want to see that parameter, although it can be empty. But don't take my word for it -- test it on a live transaction (and refund yourself) to reconfirm, as I was only doing this in the sandbox. This answer seems to officially confirm from 2Checkout itself that they allow this.
Fixed code:
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());
}
来源:https://stackoverflow.com/questions/36784642/2checkout-omnipay-authorization-failed