Skip to content
This repository has been archived by the owner on Oct 30, 2020. It is now read-only.

Commit

Permalink
Adds CVD and AVS support
Browse files Browse the repository at this point in the history
  • Loading branch information
Craig Paul committed Oct 20, 2016
1 parent 009e307 commit 6a5b54b
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 4 deletions.
30 changes: 29 additions & 1 deletion src/Gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,42 @@
/**
* CraigPaul\Moneris\Gateway
*
* @property bool $avs
* @property-read array $avsCodes
* @property bool $cvd
* @property-read array $cvdCodes
* @property-read string $environment
* @property-read string $id
* @property-read string $token
* @property-read string $environment
*/
class Gateway
{
use Gettable;

/**
* Determine if we will use the Address Verification Service.
*
* @var bool
*/
protected $avs = false;

/**
* @var array
*/
protected $avsCodes = ['A', 'B', 'D', 'M', 'P', 'W', 'X', 'Y', 'Z'];

/**
* Determine if we will use the Card Validation Digits.
*
* @var bool
*/
protected $cvd = false;

/**
* @var array
*/
protected $cvdCodes = ['M', 'Y', 'P', 'S', 'U'];

/**
* The environment used for connecting to the Moneris API.
*
Expand Down
12 changes: 11 additions & 1 deletion src/Moneris.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ public static function create(string $id, string $token, array $params = [])
*/
public function connect()
{
return new Gateway($this->id, $this->token, $this->environment);
$gateway = new Gateway($this->id, $this->token, $this->environment);

if (isset($this->params['avs'])) {
$gateway->avs = boolval($this->params['avs']);
}

if (isset($this->params['cvd'])) {
$gateway->cvd = boolval($this->params['cvd']);
}

return $gateway;
}
}
77 changes: 75 additions & 2 deletions src/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
/**
* CraigPaul\Moneris\Response
*
* @property bool $failedAvs
* @property bool $failedCvd
* @property null|int $status
* @property bool $successful
* @property \CraigPaul\Moneris\Transaction $transaction
Expand All @@ -18,7 +20,9 @@ class Response
const ERROR = -23;
const INVALID_TRANSACTION_DATA = 0;

const GLOBAL_ERROR_RECEIPT = -3;
const FAILED_ATTEMPT = -1;
const CREATE_TRANSACTION_RECORD = -2;
const GLOBAL_ERROR_RECEIPT = -3;

const SYSTEM_UNAVAILABLE = -14;
const CARD_EXPIRED = -15;
Expand All @@ -29,7 +33,33 @@ class Response
const DECLINED = -20;
const NOT_AUTHORIZED = -21;

const CVD = -4;
const CVD = -4;
const CVD_NO_MATCH = -5;
const CVD_NOT_PROCESSED = -6;
const CVD_MISSING = -7;
const CVD_NOT_SUPPORTED = -8;

const AVS = -9;
const AVS_POSTAL_CODE = -10;
const AVS_ADDRESS = -11;
const AVS_NO_MATCH = -12;
const AVS_TIMEOUT = -13;

const POST_FRAUD = -22;

/**
* Determine if we have failed Address Verification Service verification.
*
* @var bool
*/
protected $failedAvs = false;

/**
* Determine if we have failed Card Validation Digits verification.
*
* @var bool
*/
protected $failedCvd = false;

/**
* The status code.
Expand Down Expand Up @@ -132,6 +162,7 @@ public function validate()
{
/** @var \SimpleXMLElement $receipt */
$receipt = $this->transaction->response->receipt;
$gateway = $this->transaction->gateway;

if ($receipt->ReceiptId === 'Global Error Receipt') {
$this->status = Response::GLOBAL_ERROR_RECEIPT;
Expand All @@ -149,6 +180,48 @@ public function validate()
return $this;
}

$code = isset($receipt->AvsResultCode) ? (string)$receipt->AvsResultCode : false;

if ($gateway->avs && $code && $code !== 'null' && !in_array($code, $gateway->avsCodes)) {
switch ($code) {
case 'B':
case 'C':
$this->status = Response::AVS_POSTAL_CODE;
break;
case 'G':
case 'I':
case 'P':
case 'S':
case 'U':
case 'Z':
$this->status = Response::AVS_ADDRESS;
break;
case 'N':
$this->status = Response::AVS_NO_MATCH;
break;
case 'R':
$this->status = Response::AVS_TIMEOUT;
break;
default:
$this->status = Response::AVS;
}

$this->failedAvs = true;
$this->successful = false;

return $this;
}

$code = isset($receipt->CvdResultCode) ? (string)$receipt->CvdResultCode : null;

if ($gateway->avs && !is_null($code) && $code !== 'null' && !in_array($code{1}, $gateway->cvdCodes)) {
$this->status = Response::CVD;
$this->failedCvd = true;
$this->successful = false;

return $this;
}

$this->successful = true;

return $this;
Expand Down
34 changes: 34 additions & 0 deletions src/Transaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,32 @@ public function toXml()
$xml->addChild('api_token', $gateway->token);

$type = $xml->addChild($params['type']);
$efraud = in_array(
$params['type'],
['purchase', 'preauth', 'card_verification', 'cavv_purchase', 'cavv_preauth']
);
unset($params['type']);

if ($gateway->cvd && $efraud) {
$cvd = $type->addChild('cvd_info');
$cvd->addChild('cvd_indicator', '1');
$cvd->addChild('cvd_value', $params['cvd']);
unset($params['cvd']);
}

if ($gateway->avs && $efraud) {
$avs = $type->addChild('avs_info');

foreach ($params as $key => $value) {
if (substr($key, 0, 4) !== 'avs_') {
continue;
}

$avs->addChild($key, $value);
unset($params[$key]);
}
}

foreach ($params as $key => $value) {
$type->addChild($key, $value);
}
Expand Down Expand Up @@ -147,6 +171,16 @@ public function valid()
$errors[] = Validator::set($params, 'amount') ? null : 'Amount not provided.';
$errors[] = Validator::set($params, 'expdate') ? null : 'Expiry date not provided.';

if ($this->gateway->avs) {
$errors[] = Validator::set($params, 'avs_street_number') ? null : 'Street number not provided.';
$errors[] = Validator::set($params, 'avs_street_name') ? null : 'Street name not provided.';
$errors[] = Validator::set($params, 'avs_zipcode') ? null : 'Postal/Zip code not provided.';
}

if ($this->gateway->cvd) {
$errors[] = Validator::set($params, 'cvd') ? null : 'CVD not provided.';
}

break;
default:
$errors[] = $params['type'].' is not a supported transaction type.';
Expand Down

0 comments on commit 6a5b54b

Please sign in to comment.