academe / omnipay-authorizenetapi Goto Github PK
View Code? Open in Web Editor NEWOmnipay 3.x implementation of Authorize.Net API
License: MIT License
Omnipay 3.x implementation of Authorize.Net API
License: MIT License
Hi,
I'm passing CAVV and ECI to Authorize using the following two functions of an authorization:
setAuthenticationValue()
setAuthenticationIndicator()
But Authorize.net provides null when running getCavvResultCode() on the completed transaction. The only thing I could think it might be is that Authorize.net says the two values are called cardholderAuthenticationValue and cardholderAuthenticationIndicator
not authenticationValue
and authenticationIndicator
(which is what the SDK uses as the parameter name)
Any help regarding this is greatly appreciated.
Seems that the only part of the Customer Model you populate is the email address, even though there's other attributes in your model and common ways in omnipay to send them
https://github.com/academe/omnipay-authorizenetapi/blob/master/src/Message/AuthorizeRequest.php#L90
https://github.com/academe/authorizenet-objects/blob/master/src/Request/Model/Customer.php
In particular I need to be able to set Customer->id (normally in omnipay, including in your AIM/SIM version) you set this with customerId
key in the array sent to the purchase method.
Your other gateway for the AIM/SIM integration method you accept customerId, why not in the API version?
https://github.com/thephpleague/omnipay-authorizenet/blob/c109d81bc2cdbee8705fe9e4f99ba55841485286/src/Message/AIMAbstractRequest.php#L298
We have symfony/property-access v4.4.41 loaded along with the academe/omnipay-authorizenetapi v3.1.2 and that creates a warning as below.
Package symfony/inflector is abandoned, you should avoid using it. Use EnglishInflector from the String component instead.
symfony/property-access v5 has removed symfony/inflector from the list of dependency.
Could you update the symfony/property-access dependency from 3 to 4?
Please add support for specifying the tax, shipping, and duty amounts. If there's already a way to do this, please provide an example. Thanks!
Hello @judgej ,
I'm interested in contributing to the authorize.net plugin for omnipay, but perhaps you could clarify some things for me first?
Do academe/omnipay-authorizenetapi and thephpleague/omnipay-authorizenet complement each other or should one be used over the other?
I'm unsure which I should be contributing to. Thanks.
Do some.
This is a REST API for adding/removing/viewing registered webhooks, and for fetching historic webhook data.
It appears to use HAL for record discovery/paging and is RESTful in nature, unlike the remaining payments API and webhook notification API.
It is not essential for Omnipay support, but seems to be an important addition to the Authorize.Net gateway.
Reading the Authorize.net docs, it says we need to generate a public client key, when using Accept.js.
I don't see this method in any of the omnipay authorize.net libraries.
I note in reading some of the issues, people are exposing their apiLoginId and transactionKey client side, this makes me somewhat nervous exposing these details.
Is there something I am missing? Should we consider adding a helper method into the driver to generate a public client key?
This is not supported directly with the gateway API, but could be bolted on through the notify URI. If the notify URI is automatically modified to add the transactionId
as a query parameter, then the acceptNotification
could read that. Several things to consider:
nofityUrl
is optional; it can be set at the account level and optionally overridden by the merchant site at run-time. Only if overridden does this become possible.Some research to see what other people are doing here:
I'm using a sandbox acct in auth.net and sending a customerId, like so...
$response = $gateway->purchase([
...
'transactionId' => '12345',
'customerType' => \Academe\AuthorizeNet\Request\Model\Customer::CUSTOMER_TYPE_INDIVIDUAL,
'opaqueDataDescriptor' => $opaqueDataDescriptor,
'opaqueDataValue' => $opaqueDataValue,
...
])->send();
...but the value transactionId is not populating in auth.net in the transaction details (neither is the customerType value). Is this a known issue or is there anything I am missing?
Any assistance is appreciated :)
The notification message comes with a signature in the header, for example:
X-Anet-Signature: sha512=8EB900743516AC9415516FF0A1813BB38FBB5CCE6D4256B3FC56BD1FE661258F8CEF6AED0899B9095DFB66596E3F71340CD7A0BB44930618D383266242C70499
This should be used to validate the notification has not been tampered with.
Some details:
The documentation does lack some details about how the notification is actually verified. I think the SDK is probably the main source of information for this.
These webhooks are signed by a HTTP header. It is very important the merchant site can trust the webhooks it is sent.
I noticed there is no way to create a customer or card profile in this package. Is that something that we can have support for? Right now I have to use a 3rd-party package that I had to fork and edit. It's not ideal for this situation and I am already using this package.
An example would be from: https://github.com/thephpleague/omnipay-authorizenet
But this project looks to be both abandoned and has current bugs.
object(Omnipay\AuthorizeNetApi\Message\FetchTransactionResponse)[53]
protected 'transactionIndex' => string 'transaction' (length=11)
protected 'parsedData' =>
object(Academe\AuthorizeNet\Response\Response)[44]
protected 'refId' => null
protected 'messages' =>
object(Academe\AuthorizeNet\Response\Collections\Messages)[37]
protected 'items' =>
array (size=1)
...
protected 'objectName' => null
protected 'objectNameSuffix' => string '' (length=0)
protected 'data' =>
array (size=2)
...
protected 'transaction' => null
protected 'transactionResponse' => null
protected 'token' => null
protected 'resultCode' => string 'Error' (length=5)
protected 'objectName' => null
protected 'objectNameSuffix' => string '' (length=0)
protected 'data' =>
array (size=1)
'messages' =>
array (size=2)
...
protected 'accessor' => null
protected 'request' =>
object(Omnipay\AuthorizeNetApi\Message\FetchTransactionRequest)[33]
protected 'endpointSandbox' => string 'https://apitest.authorize.net/xml/v1/request.api' (length=48)
protected 'endpointLive' => string 'https://api.authorize.net/xml/v1/request.api' (length=44)
protected 'parameters' =>
object(Symfony\Component\HttpFoundation\ParameterBag)[35]
protected 'parameters' =>
it's a response var_dump of a fetching request.
The AcceptNotification
is a requirement for some gateway methods. It has some debugging stuff in too.
The notification system for the current Authorize.Net API is implemented via a set of webhooks, as documented here:
https://developer.authorize.net/api/reference/features/webhooks.html
They are POSTs with a JSON payload. There are also APIs to fetch past webhooks that may have been missed. The webhooks can even be managed through the API - created, deleted, inspected etc. - so a merchant application can set up its own webhooks on installation.
More details here, and some work needed on the underlying package handling the webhook models and collections of those models:
Hello!
I'm having some difficulty with the createCard method. It works just fine for new customers: it will create both a new customer profile and an associate customer payment profile. However, it will not add new payment profiles to an existing customer profile. Instead, the response says the customer record already exists.
I'm doing the above with opaque data. I'd like to do the same for adding new payment profiles to existing customer profiles. Is not not possible with the createCard method?
EDIT: I should add, ANY insight would be appreciated.
EDIT2: thephpleague/omnipay-authorizenet#121 seems related
EDIT3: Got it. For anyone else, it's createAdditionalCard()
on the CIM gateway.
Thanks
here's a relevant snippet:
$payload = [
"opaqueDataDescriptor" => $data['dataDescriptor'],
"opaqueDataValue" => $data['dataValue'],
"name" => $this->user_model->fullname,
"email" => $this->user_model->email,
'customerType' => 'individual',
"customerId" => 'M_'.$this->user_model->id,
"description" => "...",
'forceCardUpdate' => true,
'card' => [
'billingFirstName' => $address_model->firstname,
'billingLastName' => $address_model->lastname,
'billingAddress1' => $address_model->address_line1,
'billingAddress2' => $address_model->address_line2,
'billingCity' => $address_model->city,
'billingState' => $address_model->state,
'billingPostcode' => $address_model->zip,
'billingCountry' => $address_model->country
]
];
$customerProfileId = empty($this->user_model->authorizenet_customer_id) ? NULL : $this->user_model->authorizenet_customer_id;
if (null != $customerProfileId) {
// $payload["customerProfileId"] = $customerProfileId;
}
$request = $this->gateway_CIM->createCard($payload);
if (null != $paymentProfileId) {
$request->setCustomerPaymentProfileId($paymentProfileId);
}
try {
$response = $request->send();
...
I'm trying to make payments with saved payment profiles (not the one-time nonce (Opaque Data) provided by Accept.js).
I'm first using AuthorizeNet_CIM->createCard() with the Opaque Data from my checkout form:
CIM returns:
paymentProfile
These values are stored permanently, and then I need to process two separate payments (which is why I can't use the Opaque Data as that is a one-time token).
What fields must I submit along with amount, currency, and transactionId to get the AuthorizeNetApi_Api->purchase() method to complete a successful transaction?
this my code
try {
$creditCard = new \Omnipay\Common\CreditCard([
'number' => $data['cardNumber'],
'expiryMonth' => $data['expiration_month'],
'expiryYear' => $data['expiration_year'],
'cvv' => $data['cvv'],
]);
$transactionId = 'ref' . time();
$response = $this->gateway->authorize([
'amount' => $data['amount'],
'currency' => 'USD',
'transactionId' => $transactionId,
'card' => $creditCard,
'customer_id' => auth()->user()->customer->id,
])->send();
if ($response->isSuccessful()) {
$transactionReference = $response->getTransactionReference();
$response = $this->gateway->capture([
'amount' => $data['amount'],
'currency' => 'USD',
'transactionReference' => $transactionReference,
])->send();
$transaction_id = $response->getTransactionReference();
$paymentMethod = $response->getData()['transactionResponse']['accountType'];
$isPaymentExist = Invoice::where('transaction_id', $transaction_id)->first();
if (!$isPaymentExist) {
$payment = new Invoice();
$payment->price = $data['amount'];
$payment->transaction_id = $transaction_id;
$payment->order_id = $data['order_id'];
$payment->customer_id = auth()->user()->customer->id;
$payment->payment_date = date('yy/m/d');
$payment->payment_method = $paymentMethod ?? 'Online';
$payment->due_date = date('yy/m/d');
$payment->save();
}
return back()->with('success', "Payment is successful. Your transaction id is: " . $transaction_id);
} else {
// not successful
return back()->withErrors(Lang::get($response->getMessage()));
}
} catch (Exception $e) {
return back()->withErrors($e->getMessage());
}
returned $transaction_id is always zero , the mode of authorize.net is test ,
Is that correct ?
[JDJ: edited for formatting]
Error: The VITAL identification numbers are incorrect. Call Merchant Service Provider.
But we've been running fine for months, until this month.
Using the CreditCard
class with authorize
and purchase
methods.
When use setIFrameCommunicatorUrlUrl in Request there is a problem with response from Authorize.net, {"messages":{"resultCode":"Error","message":[{"code":"E00013","text":"Setting Name 'hostedPaymentFrameCommunicatorUrl' is invalid for this method."}]}}
Problem can be solved if const SETTING_NAME_FRAME_COMMUNICATOR_URL = 'FrameCommunicatorUrl'; change to const SETTING_NAME_FRAME_COMMUNICATOR_URL = 'IFrameCommunicatorUrl';
Reference:
https://developer.authorize.net/api/reference/features/errorandresponsecodes.html
I believe statusCode 252 and 253 should register a successful response.
The message from Authorize.net is
Your order has been received. Thank you for your business!
The documentation linked above says:
CODE: 252
EXPLANATION: Your order has been received. Thank you for your business!
OTHER SUGGESTIONS: The transaction was accepted, but is being held for merchant review.
The merchant may customize the customer response in the Merchant Interface.
What do you think?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.