Giter Club home page Giter Club logo

omnipay-authorizenet's Introduction

Omnipay: Authorize.Net

Authorize.Net driver for the Omnipay PHP payment processing library

Build Status Latest Stable Version Total Downloads

Omnipay is a framework agnostic, multi-gateway payment processing library for PHP 5.3+. This package implements Authorize.Net support for Omnipay.

Installation

Omnipay is installed via Composer. To install, simply require league/omnipay and omnipay/authorizenet with Composer:

composer require league/omnipay omnipay/authorizenet:"3.x@dev"

Basic Usage

The following gateways are provided by this package:

  • AuthorizeNet_AIM
  • AuthorizeNet_CIM
  • AuthorizeNet_SIM
  • AuthorizeNet_DPM

In addition, Accept.JS is supported by the AIM driver and CIM (create card). More details are provided below.

For general usage instructions, please see the main Omnipay repository.

Accept.JS

This gateway uses a JavaScript script to tokenize credit card details at the front end, i.e. in the payment form. Just the tokenized version of the credit card is then sent back to the merchant site, where it is used as a proxy for the credit card.

The card is tokenized into two values returned in opaqueData object from Accept.JS:

  • dataDescriptor - the type of opaque data, e.g. "COMMON.ACCEPT.INAPP.PAYMENT"
  • dataValue - the value for the opaque data, e.g. "eyJjb2RlIjoiNT... {256 characters} ...idiI6IjEuMSJ9"

These two values must be POSTed back to the merchant application, usually as a part of the payment form. Make sure the raw credit card details are NOT posted back to your site. How this is handled is beyond this short note, but examples are always welcomed in the documentation.

On the server, the tokenized details are passed into the payment or authorize request object. You will still need to pass in the CreditCard object, as that contains details of the payee and recipient, but just leave the credit card details of that object blank. For example:

// $gateway is an instantiation of the AIM driver.
// $dataDescriptor and $dataValue come from the payment form at the front end.

use Omnipay\Common\CreditCard;

$request = $gateway->purchase(
    [
        'notifyUrl' => '...',
        'amount' => $amount,
        //
        'opaqueDataDescriptor' => $dataDescriptor,
        'opaqueDataValue' => $dataValue,
        //
        'card' => new CreditCard([
            'firstName' => 'Anne',
            'lastName' => 'Payee',
            ...
        ]),
        ...
    ]
);

CIM Create Card feature usage: Accept.js must be implemented on your frontend payment form, once Accept.js 'tokenizes' the customer's card, just send the two opaque fields and remove the Card's (Number, Expiration and CVV) from your post request.

Accept.js goal is to remove the need of Card information from ever going into your server so be sure to remove that data before posting to your server.

The create card feature on CIM will automatically create a Customer Profile and a Payment Profile with the 'tokenized' card for each customer you request it for on your authorize.net account, you can use these Payment Profiles later to request payments from your customers.

In order to create a Customer & Payment Profile pass the opaque fields and the card array with the billing information to the createCard method on the CIM driver:

// $gateway is an instantiation of the CIM driver. //Omnipay::create( 'AuthorizeNet_CIM' )
// $dataDescriptor and $dataValue come from the payment form at the front end.

$request = $gateway->createCard(
    [
        'opaqueDataDescriptor' => $dataDescriptor,
        'opaqueDataValue' => $dataValue,
        'name' => $name,
        'email' => $email, //Authorize.net will use the email to identify the CustomerProfile 
        'customerType' => 'individual',
        'customerId' => $user_customer_id,//a customer ID generated by your system or send null
        'description' => 'MEMBER',//whichever description you wish to send
        'forceCardUpdate' => true
        'card' => [
            'billingFirstName' => $name,
            'billingLastName' => $last_name,
            'billingAddress1' => $address,
            'billingCity' => $city,
            'billingState' => $state,
            'billingPostcode' => $zipcode,
            'billingPhone' => '',
            //... may include shipping info but do not include card (number, cvv or expiration)
        ],
    ]
);
$response = $request->send();
$data = $response->getData();

$data['paymentProfile']['customerProfileId'];
$data['paymentProfile']['customerPaymentProfileId'];

// Now you can use these 2 fields to reference this customer and this payment profile for later use with 
// the rest of the CIM driver features as usual.

DPM and SIM Signatures

DPM and SIM used to sign their requests with the transactionKey using the mdh HMAC algorithm. From early 2019, this algorithm is being removed completely. Instead, the SHA-512 HMAC algorithm is used to sign the DPM and SIM requests, and to validate the received notifications.

To start using the SHA-512 signing, set your signatureKey in the gateway:

$gateway->setSignatureKey('48D2C629E4A...{100}...E7CA3C4E6CD7223D');

The signatureKey can be generated in the API Credentials & Keys section of your account setings.

Support

If you are having general issues with Omnipay, we suggest posting on Stack Overflow. Be sure to add the omnipay tag so it can be easily found.

If you want to keep up to date with release anouncements, discuss ideas for the project, or ask more detailed questions, there is also a mailing list which you can subscribe to.

If you believe you have found a bug, please report it using the GitHub issue tracker, or better yet, fork the library and submit a pull request.

omnipay-authorizenet's People

Contributors

acicali avatar aderuwe avatar alberto1el avatar amacneil avatar amsross avatar anush avatar architech99 avatar balexander avatar barryvdh avatar bojanzelic avatar delatbabel avatar eileenmcnaughton avatar felixmaier1989 avatar greydnls avatar hillelcoren avatar judgej avatar juzerali avatar kotrakrishna avatar manuelpayano avatar mark-h avatar megaphonejon avatar mikealmond avatar mwisner avatar odolbin-altexsoft avatar philsturgeon avatar rherriman avatar rushi avatar sachinsudheendra avatar vinceg avatar vincentavn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

omnipay-authorizenet's Issues

DPM Gateway Support

The Direct Post Method has been around for a while. It is similar to SIM in functionality and operation, but the credit card form exists on the merchant site and POSTs direct to Authorize.Net.

I have forked and written a driver for this, which we are using in production. It needs some tests before I create a pull request for it, but hopefully it will be useful.

Support for createCard method

Like other payment gateway libraries this library doesn't support createCard method. Is there support coming, or is it that AuthorizeNet doesn't support creating a card?

Support notifyUrl for the callback (SIM and DPM)

This is a simple one: the callback URL is set with SIM/DPMAuthorizeRequest::setReturnUrl()

That is historic, AFAIK, and is more appropriately served with setNotifyUrl() now.

This is assuming the URLs are what I think they are:

  • The notify URL is a callback URL, where the gateway calls your site outside of the user session.
  • The return URL is where the gateway returns the user at the end of the authorisation, putting the user back on the merchant site in their session.

We can keep the return URL support for legacy users (maybe deprecate it), but support the notify URL as an alternative.

Transaction ID

Hello,

I am trying to integrate Omnipay into CodeIgniter - I'm a seasoned PHP developer, but I am having some difficulty getting a transaction id from a Purchase or Authorization using the Authorize.net module. If I run the ->getData() method on the response, I get a large array of values, which can be a little overwhelming. Could you tell me which index is the TransactionID or if there is a method defined to get the transaction id from the response?

Thanks,

Kyle

Laravel 5.6 failed

Installation request for omnipay/authorizenet ~2.5.1 -> satisfiable by omnipay/authorizenet[2.5.1].
- Can only install one of: symfony/http-foundation[v3.4.4, 4.0.x-dev].
- Can only install one of: symfony/http-foundation[v3.4.5, 4.0.x-dev].
- Can only install one of: symfony/http-foundation[v3.4.6, 4.0.x-dev].
- Can only install one of: symfony/http-foundation[v3.4.7, 4.0.x-dev].
- Can only install one of: symfony/http-foundation[v3.4.8, 4.0.x-dev].
- laravel/framework 5.6.x-dev requires symfony/http-foundation ~4.0 -> satisfiable by symfony/http-foundation[v4.0.9, 4.0.x-dev, 4.1.x-dev, 4.2.x-dev, v4.0.0, v4.0.0-BETA1, v4.0.0-BETA2, v4.0.0-BETA3, v4.0.0-BETA4, v4.0.0-RC1, v4.0.0-RC2, v4.0.1, v4.0.2, v4.0.3, v4.0.4, v4.0.5, v4.0.6, v4.0.7, v4.0.8, v4.1.0-BETA1].

The problem is laravel 5.6 require Symfony 4 package . any solution?

AIM Request - pass customer email

Hello. Thanks for developing this library, I'm using it with great success. However, I would like to be able to pass the customer's email along with the purchase transaction API call (which triggers an automated payment receipt email from Authorize.net to each customer).

I forked the repo and modified AIMAbstractRequest to set $req->customer->email in the appropriate place. Is this something you're interested in integrating into your library?

deleteCard with cardReference

deleting cards does not work when your provide a cardReference string.

In order to fix this, please add these three lines at the top of the getData() method in CIMDeletePaymentProfileRequest.

$cardRef = $this->getCardReference(false);
$this->setCustomerProfileId($cardRef->getCustomerProfileId());
$this->setCustomerPaymentProfileId($cardRef->getPaymentProfileId());

Place these before the call to validate(). This will parse the string and get the customerProfileId and customerPaymentProfileId from the card reference json string.

Can submit a pull request if needed, let me know.

Transaction ID

Which method should I use to get the transaction ID? I am already getting the authorization code, but don't I need both to settle? Thank you.

Akamai SureRoute

Authorize.net has been sending us emails saying that they strongly recommend that we update to use their new Akamai SureRoute service. Initially they were saying that after June 30th the old URL's would route automatically to the new service but now they are saying that they aren't going to do that anymore so if you want to use that service, you need to change the URL's that you are sending your messages to. The page they directed us to in order to make the necessary changes is http://www.authorize.net/support/akamaifaqs/.
They are saying that there could be firewall issues that each merchant will need to consider if they are whitelisting IP addresses on outbound connections so if this change is made, you'll probably want to make it an option instead of just changing the URL's.

XML schema errors on payment submission

I'm currently working on a SilverStripe Omnipay implementation (https://github.com/silverstripe/silverstripe-omnipay) and I'm running into an error with the Authorize.net Omnipay module.

To start, upon testing submissions, I got the following error:

Warning] simplexml_load_string(): namespace warning : xmlns: URI AnetApi/xml/v1/schema/AnetApiSchema.xsd is not absolute

After digging a little, I updated AIMResponse.php on line 27 with the following:

$xml = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOWARNING);

This got rid of the error but revealed another problem. Here's the value of the $xml variable, which is a SimpleXMLElement Object response from the call to Authorize.net:

SimpleXMLElement Object (
  [messages] => SimpleXMLElement Object (
    [resultCode] => Error
    [message] => SimpleXMLElement Object (
      [code] => E00003
      [text] => The element 'transactionRequest' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' has invalid child element 'billTo' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'. List of possible elements expected: 'cardholderAuthentication, retail, employeeId, transactionSettings, userFields' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'.
    )
  )
)

And here is the SimpleXMLElement Object value from the getData() method in AIMAuthorizeRequest.php:

SimpleXMLElement Object (
  [@attributes] => Array (
    [xmlns] => AnetApi/xml/v1/schema/AnetApiSchema.xsd
  )
  [merchantAuthentication] => SimpleXMLElement Object (
    [name] => SimpleXMLElement Object ( )
    [transactionKey] => SimpleXMLElement Object ( )
  )
  [refId] => 14-14
  [transactionRequest] => SimpleXMLElement Object (
    [transactionType] => authCaptureTransaction
    [amount] => 125.00
    [payment] => SimpleXMLElement Object (
      [creditCard] => SimpleXMLElement Object (
        [cardNumber] => 4111111111111111
        [expirationDate] => 0120
        [cardCode] => 123
      )
    )
    [customerIP] => 192.168.0.1
    [billTo] => SimpleXMLElement Object (
      [firstName] => John
      [lastName] => Doe
      [company] => SimpleXMLElement Object ( )
      [address] => 5555 Main Street
      [city] => New York
      [state] => New York
      [zip] => 10001
      [country] => US
    )
    [shipTo] => SimpleXMLElement Object (
      [firstName] => John
      [lastName] => Doe
      [company] => SimpleXMLElement Object ( )
      [address] => 5555 Main Street
      [city] => New York
      [state] => New York
      [zip] => 10001
      [country] => US
    )
    [transactionSettings] => SimpleXMLElement Object (
      [setting] => SimpleXMLElement Object (
        [settingName] => testRequest
        [settingValue] => false
      )
    )
  )
)

Don't see anything out of the ordinary so...I'm confused. Any idea on what could be causing these errors? Thx in advance! :)

When charging a token, cardReference is ran through "json_decode" and if not a json string get standard php error.

TL;DR:
Charge token,
'cardReference' => json_decode($token),

Got error from omnipay/auth.net code (php didn't throw exception):
"json_decode() expects parameter 1 to be string, array given"

It would be nice if the returned error was a little more appropriate for the cause of the error.
"Card Reference must be this, this or this. You submitted this."

The details:

I am writing code to charge a token through authorize.net. I am storing a previously generated card reference in my database as a json string.

This looks something like this:
{"customerProfileId":"#######","customerPaymentProfileId":"#######"}

When it came time to actually charge it, I decoded it:

    $purchaseDetails = [
        'amount' => $amount,
        'currency' => 'USD',
        'cardReference' => json_decode($token),
    ];

Than actually sending the charge:

    try {
        $responseFromGateway = $gateway->purchase($purchaseDetails)->send();
    } catch (Exception $e) {
        return $this->handleErrorReturn($e->getMessage(),$submitData);
    }

Ignore submit data, it is a master array I build, handleErrorReturn is just a method I can format errors in a more use friendly output, and log advanced details.

The problem is that I would land in the catch, and the message would be:
"json_decode() expects parameter 1 to be string, array given"

It isn't php blowing up, it's code inside omnipay or the auth.net plug in and because I was just recently decoding something it took me a second to realize my code was ok, that I didn't need to decode the token.

It would be nice if the returned error was a little more appropriate for the cause of the error.

"Card Reference must be this, this or this. You submitted this."

AuthorizeNet_CIM

Hi,

I am trying to setup a payment processor using omnipay-authorizenet AuthorizeNet_CIM.

I create the gateway object successfully and can make requests to the sandbox server.

Step 2 is to "create a card" for future use with Token Billing: $gateway->createCard() . This is successful.

From the general Omnipay Token Billing documentation:

createCard($options) - returns a response object which includes a cardReference, which can be used for future transactions.

I don't see a specific 'cardReference' in the above createCard() response object.

So I create a $cardRef array and grab the returned response CustomerProfileId and CustomerPaymentProfileId .

$profileResult['customerProfileId']=$response->getCustomerProfileId();

$profileResult['paymentProfileId']=$response->getCustomerPaymentProfileId();

Step 3 is a function to generate the purchase which fails:

`
function create_transaction($cardRef,$amount,$description,$invoice_number){

global $status, $gateway;

try {
	
	// Send purchase request
	$response = $gateway->purchase(
		array(
			'cardReference' => $cardRef ,				
			'amount' => $amount,
			'currency' => 'USD',				
			'description' => $_POST['description'],
			'transactionId' => $invoice_number
			
		)
	)->send();			
	if ($response->isSuccessful()) {
		
		// Payment was successful
		//echo 'Success: '.$response->getMessage();
		
		$status.='Success: '.$response->getMessage();

	} elseif ($response->isRedirect()) {
		
		// Redirect to offsite payment gateway
		$response->redirect();
	
	} else {		

		// Payment failed
		$status.='Transaction Failure: '.$response->getMessage();
		
	}		
	
} catch (Exception $e) {
	
	$status.='<strong>Error:</strong> '.$e->getMessage(). "<br/>";
	
}		

}
`
The purchase fails and when I look at the Response object it seems the Request is not populating [cardReference] => Omnipay\AuthorizeNet\Model\CardReference Object
(
[customerProfileId:Omnipay\AuthorizeNet\Model\CardReference:private] =>
[paymentProfileId:Omnipay\AuthorizeNet\Model\CardReference:private] =>
[shippingProfileId:Omnipay\AuthorizeNet\Model\CardReference:private] =>
)

I am obviously not passing the correct data to the purchase method.

Any help would be greatly appreciated.

Thanks

Skip

AIMResponse->getTransactionReference

Why is there a check to see if the transaction is successful in order to return the transaction reference object.

https://github.com/thephpleague/omnipay-authorizenet/blob/master/src/Message/AIMResponse.php#L120

Whether it's successful or not we should be able to still get that object since it provides valuable information. Right now it returns null which i can't even pull the response code, authcode etc when it fails. i have to to getData()->transactionResponse[0]->...

Thoughts?

Complete example please Authorize_AIM

Hi, I have this, but when I run it it does not work for me

<?
require_once '../../common/vendor/autoload.php';
use \Omnipay\Omnipay;

$amount = floatval(10);
$currency = 'USD';

$gateway = Omnipay::create('AuthorizeNet_AIM');
$gateway->setApiLoginId('LOGINID');
$gateway->setTransactionKey('TRANSACTIONKEY');
$gateway->setDeveloperMode(true);

try {
	$response = $gateway->purchase(
		array(
			'card' => array(
				'number' => 5424000000000015,
				'expiryMonth' => 12,
				'expiryYear' => 2020,
				'code' => 999,
				'cardCode' => 999
			),
			'amount' => $amount,
			'currency' => 'USD',
			'description' => 'Example',
			'transactionId' => '01AD'
		)
	)->send();
	echo $response->getMessage();
} catch (Exception $e) {
	print_r($e);
}

The server response is:

The 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:cardCode' element is invalid - The value XX is invalid according to its datatype 'AnetApi/xml/v1/schema/AnetApiSchema.xsd:cardCode' - The Pattern constraint failed.

I appreciate your help!

Edited: judgej code formatting characters.

Using AIM: Fatal error: Method Guzzle\Http\QueryString::__toString()

Using AuthorizeNet_AIM and getting this error when trying to process an order via Omnipay:

Fatal error: Method Guzzle\Http\QueryString::__toString() must not throw an exception in /var/www/mysite/lib/guzzle/guzzle/src/Guzzle/Http/Curl/CurlHandle.php on line 0

Anyone experienced this at all? SIM works no problem..

Authorize.net token billing integration with CIM?

It looks like Authorize.net has support for token billing with a feature called Customer Information Manager (CIM) that allows you to save customer information on their server, and later access it via a token.

Is there plans for Omnipay's token billing methods to support CIM for this gateway?

Array to string conversion in CIMAbstractResponse

The function getResultCode in the CIMAbstractResponse class (line 59) is doing an array to string conversion which now throws a fatal error in PHP 7.2.

$result should be evaluated before being casted to a string

Create Customer profile using AcceptJS token

I am trying to make a purchase and creating customer profile using the transaction ID.
https://developer.authorize.net/api/reference/index.html#customer-profiles-create-a-customer-profile-from-a-transaction

I am able to purchase but I have no idea how to create customer profile using the transactionID. It seems possible only when I have a card.

purchase is made using AIM, but I am guessing I have to use CIM at same time for customer profile and transactionID seems the only thing that can bridge both.

no usable examples?

I'm going out of my mind I guess. The main page for this module says to see the Omnipay documentation on how to use it.

However the documentation for Omnipay is about 1000% useless because it doesn't discuss how to create customer accounts and store the customer credit cards on Authorize.net and then finally to submit the payment using the credit card token. Is any of this possible? If so, where is the documentation or examples?

Please help.

Implement the notification handler

SIM and DPM use Complete* messages for handling the back-channel notifications. There is now a notification handler abstract in OmniPay Common that should be used for this purpose.

Backwards compatibility should be preserved for OmniPay 2.x, but the old messages can be deprecated and removed for 3.0, so it would be good to get it implemented before any 3.0 migration.

Incorrect response code.

Hello, I found a bug while implementing this module. All my test cards were passing, even the bad ones.

I found that the isSucessful() method is compared to the getCode() method, which takes the first item in the array--the first item in the array is not a status code, but appears to be a version code.

public function isSuccessful()
{
return '1' === $this->getCode();
}

Here's my array.

AIMResponse {#469 ▼
#request: AIMPurchaseRequestCustom {#465 ▶}
#data: array:22 [▼
0 => "1.0"
1 => "3"
2 => "8"
3 => "The credit card has expired."
4 => ""
5 => "P"
6 => ""
7 => "0"
8 => "116CD77DEE0CE79285A5A6A93E6357CE"
9 => ""
10 => ""
11 => ""
12 => ""
13 => ""
14 => ""
15 => ""
16 => ""
17 => ""
18 => ""
19 => ""
20 => "XXXX1001"
21 => "American Express"
]
}

As you can see, the real status code is in key 1, not in key 0.
I've fixed it locally, but thought you'd like to know.

Thanks.

Check format of transaction response before using it

This is as a result of issue #30 where the transaction to Authorize.Net was being sent through another device and library, but the notify/callback was being handled by OmniPay. It turns out there are alternative transaction response formats that can be sent in this instance, but which OmniPay does not realise and ends up declaring the transaction as authorised.

To be valid, the first field of the response MUST be "1", "2", "3" or "4". Any other value should raise an immediate exception. A value of "1.0" is the normal response when the transaction was sent via a card reader.

This isn't urgent or something that will affect many people, but when it does, the results can be very misleading, resulting in expired cards being declared as authorised.

Add Line Items

Is there a way to use any of the additional request properties, such as order line items and shipping address? Those defined here: https://developer.authorize.net/api/reference/#payment-transactions

If not, is this going to be added? Without it, it is very limited functionality.

It would be a good idea to have a method to add generic properties into the request, so we are not limited to what is specifically defined in AIMAbstractRequest.

EDIT: Nevermind! I see there are CreditCard and ItemBag from the main OmniPay package that deal with this.

Temporary live enpoint URLs - hotfix needed?

Authorize.Net are in the process of moving their servers. This will involve some downtime on the current live endpoint URLs leading up to October 2015. This one, for example:

https://github.com/thephpleague/omnipay-authorizenet/blob/master/src/AIMGateway.php#L24

'liveEndpoint'      => 'https://secure.authorize.net/gateway/transact.dll',

To avoid the downtime, the URL can be changed to this now (from start of July), as this endpoint has already gone through the server migration process:

https://secure2.authorize.net/gateway/transact.dll

Should we change this? Note that the endpoint URL can be set by hand when creating the gateway, so the merchant site can override it to use the secure2 version. However, that would need a merchant site change, while doing so here would be a packageist "hotfix" change.

Obviously needs to be tested on a live site first - I'm happy to do that.

SIMcompleteAuthorizeResponse and SPMcompleteResponse should be redirects

This has niggled me for a while, but I could not put my finger on the problem. Just realised today, while writing a test harness, that the SIM/DPM "complete" respons messages just provide the transaction data and the result, but leave the merchant site entirely to decide what to do about that.

In fact, there is just one thing to do: a redirect. For Authorize.Net this redirect is not like the GET/POST methods offered by OmniPay Common. This is a HTML page that needs to be returned, containing a GET URL redirect. The redirect cannot use an auto-submitted POST, as that will generate browser security warnings if the final return page is not SSL (HTTPS).

Return/Display Actual Reason Code messages? Customer gets no insight to reason for decline.

Is there a way (within Omnipay directives) to have Message\AIMResponse give meaningful error messages based on the return codes?

The reason this is coming us is that for some reason all of their error messages (errorText) just says The transaction has been declined but there's an additional errorCode that gives a clue as to why. The challenge is that all the customer sees when code uses $response->getMessage() is the decline, not the why. For example, here is their list of most common codes and what it means

https://support.authorize.net/authkb/index?page=content&id=A50

  • 2 General decline by card issuing bank or by Merchant Service Provider
  • 3 Referral to card issuing bank for verbal approval
  • 4 Card reported lost or stolen; pick up card if physically available
  • 27 Address Verification Service (AVS) mismatch; declined by account settings
  • 44 Card Code decline by payment processor
  • 45 AVS and Card Code mismatch; declined by account settings
  • 65 Card Code mismatch; declined by account settings
  • 250 Fraud Detection Suite (FDS) blocked IP address
  • 251 FDS filter triggered--filter set to decline
  • 254 FDS held for review; transaction declined after manual review

My thought would be to modify and replace/extend the getMessage function such that if a known error code is returned, display a readable message, otherwise, just show the errorText (and possibly the errorCode.

Or does this just have to be custom-coded to get the reasonCode and map it locally outside of Omnipay? (which would mean we'd have to add an additional response translation layer between all omnipay gateways and our code, instead of being able to hot swap em).
Not sure what the design directives would state here.

AIMResponse::getMessage() returns blank when an [authentication] error occurs.

It looks like the code is expecting the value to be returned as messages[0]->message[0]->description or errors[0]->error[0]->errorText. When testing it appears as messages[0]->message[0]->text.

Here's a sample response:

SimpleXMLElement {#1025 ▼
+"refId": "0001"
+"messages": SimpleXMLElement {#848 ▼
+"resultCode": "Error"
+"message": SimpleXMLElement {#851 ▼
+"code": "E00007"
+"text": "User authentication failed due to invalid authentication values."
}
}
+"transactionResponse": SimpleXMLElement {#849}
}

AimResponse - Trying to get property of non-object

The getResultCode is returning a "Trying to get property of non-object" exception because the "responseCode" doesn't exist in the data.

This is happening when entering an incorrect CVV length. So entering in 6 characters for the CVV would cause this to happen.

Restore use of invoice_num to its proper purpose

The invoice_num field is used to put the transactionId into. This stops it being used to hold the invoice number. We should stop using this field in this way.

https://github.com/thephpleague/omnipay-authorizenet/blob/master/src/Message/AbstractRequest.php#L112

This would be a BC break for sites that are expecting to see the transaction ID in this field, so this change should be reserved for v3.0

A custom field omnipay_transaction_id currently takes on this function for the notify handler, though custom fields are not stored in the transaction log on the Authorize.Net account as x_invoice_num would be. The application can decide how to use that field though, so they can carry on using it this way if they want.

Notify hash check for SIM is not correct

I've been calling this a "callback". It's not. It's the notify or notification call. Title changed to show this

SIM uses a callback (they call it a "relay response" to notify the site of the authorisation result. Within this callback is a hash to confirm the callback has legitimately come from Authorize.Net

The hash is coded by the remote gateway using:

  1. The login ID
  2. A shared secret
  3. The transaction reference
  4. The amount that has been authorised.

1, 2 and 4 are known by both ends in advance. 3 is in the notify POST data (x_trans_id) and is known for the first time by the marchant site in this notify POST. 1, 3 and 4 are sent in the POST data, so those three can be confirmed as not tampered using the shared secret, which is never sent in any POST request.

So the problem

SIMCompleteAuthorizeRequest() checks the hash using getHash(). Instead of looking at the POST data, it looks entirely at the values supplied by the merchant account. 1 and 2 are fine, but 3 and 4 are not.

The hash check reads $request->getTransactionId() to get the transaction reference. So the merchant site must presumably get x_trans_id from the post data (the reference) and push it into $request->setTransactionId().

This is essentially a mixup between transaction IDs and references.

CardReference can't set the cardCode

So here is a scenario:

a customer submits his credit card info on our form, we authorize and create a profile. at the end of the process he submits the form and we attempt to charge the card. We charge using the 'purchase' method under CIMGateway. The problem is we have the fraud suite enabled for CVV but we have no way of passing in the cardCode when we pass in the cardReference.

Example

$request = $this->getGateway()->purchase(['cardReference' => $cardReference, 'amount' => $amount, 'description' => $this->reservation->description]);
$data = $request->getData();

$data looks like this:


SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [xmlns] => AnetApi/xml/v1/schema/AnetApiSchema.xsd
        )

    [merchantAuthentication] => SimpleXMLElement Object
        (
            [name] => xxxx
            [transactionKey] => xxxx
        )

    [transactionRequest] => SimpleXMLElement Object
        (
            [transactionType] => authCaptureTransaction
            [amount] => 327.00
            [profile] => SimpleXMLElement Object
                (
                    [customerProfileId] => xxxx
                    [paymentProfile] => SimpleXMLElement Object
                        (
                            [paymentProfileId] => xxxx
                        )

                )

            [order] => SimpleXMLElement Object
                (
                    [description] => AVN Reservation: Hard Rock Hotel & Casino Las Vegas for 3 nights (Oct 27, 2016 - Oct 30, 2016)
                )

            [transactionSettings] => SimpleXMLElement Object
                (
                    [setting] => SimpleXMLElement Object
                        (
                            [settingName] => testRequest
                            [settingValue] => false
                        )

                )

        )

)

Based on the documentation we can pass in cardCode as part of the profile->paymentProfile object but i am not sure if this is possible with the way it's currently setup.

https://developer.authorize.net/api/reference/index.html#payment-transactions-capture-a-previously-authorized-amount

This is an issue since it prevents from being able to validate the CVV and requires to turn it off to make the purchase pass.

Any thoughts on this? i can also submit a PR for this.

I am thinking of forking this repository and maintaining it myself if i can't get these changes merged quickly.

Thanks for the help.

New API available - Accept.js

This new API makes use of JavaScript on the front end to build forms and (presumably) to avoid the need to send credit card numbers to your own server. It is an extension to the DPM API.

An example application is available here:

https://github.com/AuthorizeNet/accept-sample-app

I'm not sure what documentation is available apart from that. Authorize.Net are keen to help us incorporate this API into the gateway, so I'm opening this issue to log any discussions on what that may involve or any ideas or issues that anyone may have.

OmniPay has traditionally not got involved with the front end part of the UI, but most gateways are moving towards a very front-end centric approach (e.g. with "drop-in" forms generated through JavaScript, and card tokenisation APIs that can be used by the front end to avoid card numbers going anywhere near your server). How this fits into OmniPay 2.x or whether it should be something to expand OmniPay 3.0 with, is up for question. I personally don't have an answer for that at this time.

Can't set x_receipt_link_URL (should be returnUrl)

Further to #16 where the code change was made to set the x_relay_url from the notifyUrl instead of the returnUrl, a method needs to be in place to set the x_receipt_link_URL which is in effect the returnUrl for the SIM gateway.

This is a non-BC change for anyone who's currently using the returnUrl to set the x_relay_url.

References:

https://www.authorize.net/support/CNP/helpfiles/Account/Settings/Transaction_Format_Settings/Transaction_Response_Settings/Response_Receipt_URLs.htm

https://support.authorize.net/authkb/index?page=content&id=A587&actp=LIST

x_receipt_link_URL -- set to the URL where the customer should be sent after submitting payment. Parameterized URLs are not permitted.

https://support.authorize.net/authkb/index?page=content&id=A558

https://www.authorize.net/support/CNP/helpfiles/Account/Settings/Transaction_Format_Settings/Transaction_Response_Settings/Relay_Response.htm

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.