From 2ff74dcf86f5a6dfd4a1b81a2ea7b2f28891c755 Mon Sep 17 00:00:00 2001 From: nmc9 Date: Mon, 27 Jul 2020 15:09:22 -0400 Subject: [PATCH 1/6] Update composer.json --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 225064e..e9dbd92 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,6 @@ "require": { "php": "^5.6|^7", "omnipay/common": "~3.0", - "php-http/guzzle6-adapter": "^1.1" }, "require-dev": { "omnipay/tests": "~3.1" From d08344144e7f54f0ec3a9b72da4c7e293e46aafd Mon Sep 17 00:00:00 2001 From: nmc9 Date: Mon, 27 Jul 2020 15:10:26 -0400 Subject: [PATCH 2/6] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e9dbd92..8ee25e5 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ }, "require": { "php": "^5.6|^7", - "omnipay/common": "~3.0", + "omnipay/common": "~3.0" }, "require-dev": { "omnipay/tests": "~3.1" From 1c608ce32306c7fd719933fe2b53ac28121f7ccb Mon Sep 17 00:00:00 2001 From: nmc9 Date: Mon, 27 Jul 2020 15:11:37 -0400 Subject: [PATCH 3/6] Update composer.json --- composer.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 8ee25e5..263b3d6 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { - "name": "omnipay/firstdata", + "name": "nmc9/omnipay-firstdata", "type": "library", - "description": "First Data driver for the Omnipay payment processing library", + "description": "First Data driver for the Omnipay payment processing library that includes ACH", "keywords": [ "first data", "firstdata", @@ -9,7 +9,8 @@ "merchant", "omnipay", "pay", - "payment" + "payment", + "ach" ], "homepage": "https://github.com/thephpleague/omnipay-firstdata", "license": "MIT", From ad11da0e360bbd06d627687dc257b735b623bca9 Mon Sep 17 00:00:00 2001 From: Nick Caruso Date: Tue, 20 Oct 2020 09:13:20 -0400 Subject: [PATCH 4/6] test card complete onto ach --- demos/Feature/DemoPayeezyACHGatewayTest.php | 215 +++ demos/Feature/DemoPayeezyGatewayTest.php | 143 ++ phpunit.xml.demo.dist | 33 + phpunit.xml.dist | 20 +- src/Ach.php | 1532 +++++++++++++++++ src/AchHelper.php | 95 + src/Exception/InvalidAchException.php | 14 + .../InvalidAuthResponseException.php | 18 + src/Message/PayeezyAbstractRequest.php | 196 ++- src/Message/PayeezyPurchaseRequest.php | 70 +- src/Message/PayeezyResponse.php | 56 + test.php | 10 + tests/AchTest.bak | 599 +++++++ tests/Json/PayeezePurchaseFailExp.json | 31 + .../Json/PayeezePurchaseFailExpWithEmail.json | 32 + tests/Json/PayeezePurchaseSuccess.json | 34 + tests/Message/PayeezyAuthorizeRequestTest.php | 34 +- tests/Message/PayeezyPurchaseRequestTest.php | 53 +- tests/Message/PayeezyPurchaseResponseTest.php | 22 +- tests/Mock/PayeezePurchaseError.txt | 1 + tests/PayeezyGatewayTest.php | 23 + 21 files changed, 3198 insertions(+), 33 deletions(-) create mode 100644 demos/Feature/DemoPayeezyACHGatewayTest.php create mode 100644 demos/Feature/DemoPayeezyGatewayTest.php create mode 100644 phpunit.xml.demo.dist create mode 100644 src/Ach.php create mode 100644 src/AchHelper.php create mode 100644 src/Exception/InvalidAchException.php create mode 100644 src/Exception/InvalidAuthResponseException.php create mode 100644 test.php create mode 100644 tests/AchTest.bak create mode 100644 tests/Json/PayeezePurchaseFailExp.json create mode 100644 tests/Json/PayeezePurchaseFailExpWithEmail.json create mode 100644 tests/Json/PayeezePurchaseSuccess.json create mode 100644 tests/Mock/PayeezePurchaseError.txt diff --git a/demos/Feature/DemoPayeezyACHGatewayTest.php b/demos/Feature/DemoPayeezyACHGatewayTest.php new file mode 100644 index 0000000..9098f81 --- /dev/null +++ b/demos/Feature/DemoPayeezyACHGatewayTest.php @@ -0,0 +1,215 @@ +gateway = Omnipay::create('FirstData_Payeezy'); + $this->gateway->initialize([ + 'gatewayId' => $_ENV['DEMO_GATEWAYID'], + 'password' => $_ENV['DEMO_PASSWORD'], + 'hmac' => $_ENV['DEMO_HMAC'], + 'keyId' => $_ENV['DEMO_KEYID'], + 'testMode' => true, + ]); + + } + + public function test_ach_purchase_with_address_and_cvv() + { + + // * * checkType -> + // * * accountNumber -> + // * * routingNumber -> + // * * checkNumber + // * * customerIDType -> + // * * License -> + // * * LicenseState -> + // * * ssn -> + // * * taxId -> + // * * militaryId -> + // * + // * * customerID -> + // * * ecommerceFlag + // * * releaseType -> + // * * vip -> + // * * clerk -> + // * * device -> + // * * micr -> + $ach = new Ach([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + 'routingNumber' => '4111', + 'accountNumber' => '2020', + 'checkNumber' => '123', + 'billingAddress1' => '1 Scrubby Creek Road', + 'billingCountry' => 'AU', + 'billingCity' => 'Scrubby Creek', + 'billingPostcode' => '4999', + 'billingState' => 'QLD', + ]); + + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + 'amount' => '10.00', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'ach' => $ach, + // 'paymentMethod' => "ach" + ])->send(); + + $this->assertTrue($response->isSuccessful()); + + $this->assertNotNull($response->getAuthorizationNumber()); + $this->assertNull($response->getCardReference()); + + $this->assertNotNull($response->getTransactionTag()); + $this->assertNotNull($response->getTransactionReference()); + $this->assertNotNull($response->getSequenceNo()); + + $this->assertEquals($response->getCode(),"00"); + $this->assertEquals($response->getMessage(),"Approved"); + $this->assertEquals($response->getBankCode(),"100"); + $this->assertEquals($response->getExactMessage(),"Transaction Normal"); + $this->assertEquals($response->getBankMessage(),"Approved"); + } + + + /** + * Everything was successful + */ + public function test_ach_purchase() + { + $card = new CreditCard([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + 'number' => '4111111111111111', + 'expiryMonth' => '12', + 'expiryYear' => '2026', + 'cvv' => '123', + ]); + + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + 'amount' => '10.00', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'card' => $card, + ])->send(); + + $this->assertTrue($response->isSuccessful()); + + $this->assertNotNull($response->getAuthorizationNumber()); + $this->assertNull($response->getCardReference()); + + $this->assertNotNull($response->getTransactionTag()); + $this->assertNotNull($response->getTransactionReference()); + $this->assertNotNull($response->getSequenceNo()); + + $this->assertEquals($response->getCode(),"00"); + $this->assertEquals($response->getMessage(),"Approved"); + $this->assertEquals($response->getBankCode(),"100"); + $this->assertEquals($response->getExactMessage(),"Transaction Normal"); + $this->assertEquals($response->getBankMessage(),"Approved"); + } + + /** + * An exception was thrown before the request was made because of invalid input + */ + public function test_ach_purchase_exception() + { + $this->expectException(InvalidRequestException::class); + $this->expectExceptionMessage("The amount parameter is required"); + $card = new CreditCard([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + 'number' => '4111111111111111', + 'expiryMonth' => '12', + 'expiryYear' => '2019', + 'cvv' => '123', + ]); + + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + // 'amount' => '10.00', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'card' => $card, + ])->send(); + } + + /** + * An exception was thrown because the response came back in a bad format + */ + public function test_ach_purchase_error() + { + + $this->expectException(InvalidResponseException::class); + $this->expectExceptionMessage("Bad Request (27) - Invalid Card Holder"); + $card = new CreditCard([ + 'firstName' => 'test', + 'lastName' => '', + 'number' => '4111111111111111', + 'expiryMonth' => '12', + 'expiryYear' => '2026', + 'cvv' => '123', + ]); + + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + 'amount' => '5000.27', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'card' => $card, + ])->send(); + } + + /** + * No exception thrown but the payment was unsuccessful + */ + public function test_ach_purchase_failure() + { + $card = new CreditCard([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + 'number' => '4111111111111111', + 'expiryMonth' => '12', + 'expiryYear' => '2026', + 'cvv' => '123', + ]); + + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + 'amount' => '5605.00', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'card' => $card, + ])->send(); + + $this->assertFalse($response->isSuccessful()); + + $this->assertNull($response->getAuthorizationNumber()); + $this->assertNull($response->getCardReference()); + + $this->assertNotNull($response->getTransactionTag()); + $this->assertNotNull($response->getTransactionReference()); + $this->assertNotNull($response->getSequenceNo()); + + $this->assertEquals($response->getCode(),"00"); + $this->assertEquals($response->getMessage(),"Invalid Expiration Date"); + $this->assertEquals($response->getBankCode(),"605"); + $this->assertEquals($response->getExactMessage(),"Transaction Normal"); + $this->assertEquals($response->getBankMessage(),"Invalid Expiration Date"); + } +} diff --git a/demos/Feature/DemoPayeezyGatewayTest.php b/demos/Feature/DemoPayeezyGatewayTest.php new file mode 100644 index 0000000..e8b4841 --- /dev/null +++ b/demos/Feature/DemoPayeezyGatewayTest.php @@ -0,0 +1,143 @@ +gateway = Omnipay::create('FirstData_Payeezy'); + $this->gateway->initialize([ + 'gatewayId' => $_ENV['DEMO_GATEWAYID'], + 'password' => $_ENV['DEMO_PASSWORD'], + 'hmac' => $_ENV['DEMO_HMAC'], + 'keyId' => $_ENV['DEMO_KEYID'], + 'testMode' => true, + ]); + + } + + public function test_purchase() + { + + $card = new CreditCard([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + 'number' => '4111111111111111', + 'expiryMonth' => '12', + 'expiryYear' => '2026', + 'cvv' => '123', + ]); + + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + 'amount' => '10.00', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'card' => $card, + ])->send(); + + $this->assertTrue($response->isSuccessful()); + + $this->assertNotNull($response->getAuthorizationNumber()); + $this->assertNull($response->getCardReference()); + + $this->assertNotNull($response->getTransactionTag()); + $this->assertNotNull($response->getTransactionReference()); + $this->assertNotNull($response->getSequenceNo()); + + $this->assertEquals($response->getCode(),"00"); + $this->assertEquals($response->getMessage(),"Approved"); + $this->assertEquals($response->getBankCode(),"100"); + $this->assertEquals($response->getExactMessage(),"Transaction Normal"); + $this->assertEquals($response->getBankMessage(),"Approved"); + } + + public function test_purchase_exception() + { + $this->expectException(InvalidRequestException::class); + $this->expectExceptionMessage("The amount parameter is required"); + $card = new CreditCard([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + 'number' => '4111111111111111', + 'expiryMonth' => '12', + 'expiryYear' => '2019', + 'cvv' => '123', + ]); + + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + // 'amount' => '10.00', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'card' => $card, + ])->send(); + } + + public function test_purchase_error() + { + + $this->expectException(InvalidResponseException::class); + $this->expectExceptionMessage("Bad Request (27) - Invalid Card Holder"); + $card = new CreditCard([ + 'firstName' => 'test', + 'lastName' => '', + 'number' => '4111111111111111', + 'expiryMonth' => '12', + 'expiryYear' => '2026', + 'cvv' => '123', + ]); + + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + 'amount' => '5000.27', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'card' => $card, + ])->send(); + } + + public function test_purchase_failure() + { + $card = new CreditCard([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + 'number' => '4111111111111111', + 'expiryMonth' => '12', + 'expiryYear' => '2026', + 'cvv' => '123', + ]); + + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + 'amount' => '5605.00', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'card' => $card, + ])->send(); + + $this->assertFalse($response->isSuccessful()); + + $this->assertNull($response->getAuthorizationNumber()); + $this->assertNull($response->getCardReference()); + + $this->assertNotNull($response->getTransactionTag()); + $this->assertNotNull($response->getTransactionReference()); + $this->assertNotNull($response->getSequenceNo()); + + $this->assertEquals($response->getCode(),"00"); + $this->assertEquals($response->getMessage(),"Invalid Expiration Date"); + $this->assertEquals($response->getBankCode(),"605"); + $this->assertEquals($response->getExactMessage(),"Transaction Normal"); + $this->assertEquals($response->getBankMessage(),"Invalid Expiration Date"); + } +} diff --git a/phpunit.xml.demo.dist b/phpunit.xml.demo.dist new file mode 100644 index 0000000..5466bb3 --- /dev/null +++ b/phpunit.xml.demo.dist @@ -0,0 +1,33 @@ + + + + + ./demos/ + + + ./tests/ + + + + + ./src + + + + + + + + + + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 535809e..9a74bf3 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,14 +1,14 @@ + backupStaticAttributes="false" + bootstrap="vendor/autoload.php" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + processIsolation="false" + stopOnFailure="false" + syntaxCheck="false"> ./tests/ @@ -19,4 +19,6 @@ ./src + + diff --git a/src/Ach.php b/src/Ach.php new file mode 100644 index 0000000..9e8005d --- /dev/null +++ b/src/Ach.php @@ -0,0 +1,1532 @@ + + * // Define ach parameters, which should look like this + * $parameters = [ + * 'firstName' => 'Bobby', + * 'lastName' => 'Tables', + * 'accountNumber' => '856667', + * 'routingNumber' => '072403004', + * 'checkNumber' => '1002', + * 'email' => 'testach@gmail.com', + * ]; + * + * // Create an ach object + * $ach = new Ach($parameters); + * + * + * The full list of ach attributes that may be set via the parameter to + * *new* is as follows: + * + * * checkType + * * accountNumber + * * routingNumber + * * checkNumber + * * driversLicense + * * driversLicenseState + * * ssn + * * taxId + * * militaryId + * + * * customer + * * ecommerceFlag + * * releaseType + * * vip + * * clerk + * * device + * * micr + * + * * title + * * firstName + * * lastName + * * name + * * company + * * address1 + * * address2 + * * city + * * postcode + * * state + * * country + * * phone + * * phoneExtension + * * fax + * * cvv + * * billingTitle + * * billingName + * * billingFirstName + * * billingLastName + * * billingCompany + * * billingAddress1 + * * billingAddress2 + * * billingCity + * * billingPostcode + * * billingState + * * billingCountry + * * billingPhone + * * billingFax + * * shippingTitle + * * shippingName + * * shippingFirstName + * * shippingLastName + * * shippingCompany + * * shippingAddress1 + * * shippingAddress2 + * * shippingCity + * * shippingPostcode + * * shippingState + * * shippingCountry + * * shippingPhone + * * shippingFax + * * email + * * birthday + * * gender + * + * If any unknown parameters are passed in, they will be ignored. No error is thrown. + */ +class Ach +{ + use ParametersTrait; + + /** + * Create a new Ach object using the specified parameters + * + * @param array $parameters An array of parameters to set on the new object + */ + public function __construct($parameters = null) + { + $this->initialize($parameters); + } + + + /** + * Initialize the object with parameters. + * + * If any unknown parameters passed, they will be ignored. + * + * @param array $parameters An associative array of parameters + * @return $this + */ + public function initialize(array $parameters = null) + { + $this->parameters = new ParameterBag; + + Helper::initialize($this, $parameters); + + return $this; + } + + /** + * Validate this credit ach. If the ach is invalid, InvalidAchException is thrown. + * + * This method is called internally by gateways to avoid wasting time with an API call + * when the credit ach is clearly invalid. + * + * Generally if you want to validate the credit ach yourself with custom error + * messages, you should use your framework's validation library, not this method. + * + * @return void + * @throws Exception\InvalidRequestException + * @throws InvalidAchException + */ + public function validate() + { + $requiredParameters = array( + 'firstName' => 'first name', + 'lastName' => 'last name', + 'routingNumber' => 'routing number', + 'accountNumber' => 'account number', + // 'checkNumber' => 'check number' // number => 'cehck number' + ); + + var_dump($requiredParameters); + die(); + + foreach ($requiredParameters as $key => $val) { + if (!$this->getParameter($key)) { + throw new InvalidAchException("The $val is required"); + } + } + + if (!AchHelper::validateRoutingNumber($this->getRoutingNumber())) { + throw new InvalidAchException('Routing Number is invalid'); + } + + if (!AchHelper::validateIBAN($this->getAccountNumber())) { + throw new InvalidAchException('Account Number is invalid'); + } + } + + /** + * Get the ach routing number. + * + * @return string + */ + public function getRoutingNumber() + { + return $this->getParameter('routingNumber'); + } + + /** + * Sets the ach routing number. + * + * @param string $value + * @return $this + */ + public function setRoutingNumber($value) + { + return $this->setParameter('routingNumber', $value); + } + + /** + * Get the ach account number. + * + * @return string + */ + public function getAccountNumber() + { + return $this->getParameter('accountNumber'); + } + + /** + * Sets the ach account number. + * + * @param string $value + * @return $this + */ + public function setAccountNumber($value) + { + return $this->setParameter('accountNumber', $value); + } + + /** + * Get the ach check number. + * + * @return string + */ + public function getCheckNumber() + { + return $this->getParameter('checkNumber'); + } + + /** + * Sets the ach check number. + * + * @param string $value + * @return $this + */ + public function setCheckNumber($value) + { + return $this->setParameter('checkNumber', $value); + } + + /** + * Get the ach check type. + * + * @return string + */ + public function getCheckType() + { + return $this->getParameter('checkType'); + } + + /** + * Sets the ach check type. + * + * @param string $value + * @return $this + */ + public function setCheckType($value) + { + return $this->setParameter('checkType', $value); + } + + /** + * Get the ach drivers license. + * + * @return string + */ + public function getLicense() + { + return $this->getParameter('license'); + } + + /** + * Sets the ach drivers license. + * + * @param string $value + * @return $this + */ + public function setLicense($value) + { + return $this->setParameter('license', $value); + } + + /** + * Get the ach drivers license state. + * + * @return string + */ + public function getLicenseState() + { + return $this->getParameter('licenseState'); + } + + /** + * Sets the ach drivers license state. + * + * @param string $value + * @return $this + */ + public function setLicenseState($value) + { + return $this->setParameter('licenseState', $value); + } + + /** + * Get the ach social security number. + * + * @return string + */ + public function getSocialSecurityNumber() + { + return $this->getParameter('ssn'); + } + + /** + * Sets the ach social security number. + * + * @param string $value + * @return $this + */ + public function setSocialSecurityNumber($value) + { + return $this->setParameter('ssn', $value); + } + + /** + * Get the ach tax ID. + * + * @return string + */ + public function getTaxID() + { + return $this->getParameter('taxId'); + } + + /** + * Sets the ach tax ID. + * + * @param string $value + * @return $this + */ + public function setTaxID($value) + { + return $this->setParameter('taxId', $value); + } + + /** + * Get the ach military ID. + * + * @return string + */ + public function getMilitaryID() + { + return $this->getParameter('militaryId'); + } + + /** + * Sets the ach military ID. + * + * @param string $value + * @return $this + */ + public function setMilitaryID($value) + { + return $this->setParameter('militaryId', $value); + } + + /** + * Get the ach customer ID. + * + * @return string + */ + public function getCustomer() + { + return $this->getParameter('customer'); + } + + /** + * Sets the ach customer ID. + * + * @param string $value + * @return $this + */ + public function setCustomer($value) + { + return $this->setParameter('customer', $value); + } + + /** + * Get the ach e-comerce flag. + * + * @return string + */ + public function getEcommerceFlag() + { + return $this->getParameter('ecommerceFlag'); + } + + /** + * Sets the ach e-comerce flag. + * + * @param string $value + * @return $this + */ + public function setEcommerceFlag($value) + { + return $this->setParameter('ecommerceFlag', $value); + } + + /** + * Get the ach vip. + * + * @return string + */ + public function getVIP() + { + return $this->getParameter('vip'); + } + + /** + * Sets the ach vip. + * + * @param string $value + * @return $this + */ + public function setVIP($value) + { + return $this->setParameter('vip', $value); + } + + /** + * Get the ach release Type. + * + * @return string + */ + public function getReleaseType() + { + return $this->getParameter('releaseType'); + } + + /** + * Sets the ach release Type. + * + * @param string $value + * @return $this + */ + public function setReleaseType($value) + { + return $this->setParameter('releaseType', $value); + } + + /** + * Get the ach clerk. + * + * @return string + */ + public function getClerk() + { + return $this->getParameter('clerk'); + } + + /** + * Sets the ach clerk. + * + * @param string $value + * @return $this + */ + public function setClerk($value) + { + return $this->setParameter('clerk', $value); + } + + /** + * Get the ach device. + * + * @return string + */ + public function getDevice() + { + return $this->getParameter('device'); + } + + /** + * Sets the ach Device. + * + * @param string $value + * @return $this + */ + public function setDevice($value) + { + return $this->setParameter('device', $value); + } + + /** + * Get the ach micr. + * + * @return string + */ + public function getMicr() + { + return $this->getParameter('micr'); + } + + /** + * Sets the ach micr. + * + * @param string $value + * @return $this + */ + public function setMicr($value) + { + return $this->setParameter('micr', $value); + } + + /** + * Get Ach Title. + * + * @return string + */ + public function getTitle() + { + return $this->getBillingTitle(); + } + + /** + * Set Ach Title. + * + * @param string $value Parameter value + * @return $this + */ + public function setTitle($value) + { + $this->setBillingTitle($value); + $this->setShippingTitle($value); + + return $this; + } + + /** + * Get Ach First Name. + * + * @return string + */ + public function getFirstName() + { + return $this->getBillingFirstName(); + } + + /** + * Set Ach First Name (Billing and Shipping). + * + * @param string $value Parameter value + * @return $this + */ + public function setFirstName($value) + { + $this->setBillingFirstName($value); + $this->setShippingFirstName($value); + + return $this; + } + + /** + * Get Ach Last Name. + * + * @return string + */ + public function getLastName() + { + return $this->getBillingLastName(); + } + + /** + * Set Ach Last Name (Billing and Shipping). + * + * @param string $value Parameter value + * @return $this + */ + public function setLastName($value) + { + $this->setBillingLastName($value); + $this->setShippingLastName($value); + + return $this; + } + + /** + * Get Ach Name. + * + * @return string + */ + public function getName() + { + return $this->getBillingName(); + } + + /** + * Set Ach Name (Billing and Shipping). + * + * @param string $value Parameter value + * @return $this + */ + public function setName($value) + { + $this->setBillingName($value); + $this->setShippingName($value); + + return $this; + } + + /** + * Get the ach billing title. + * + * @return string + */ + public function getBillingTitle() + { + return $this->getParameter('billingTitle'); + } + + /** + * Sets the ach billing title. + * + * @param string $value + * @return $this + */ + public function setBillingTitle($value) + { + return $this->setParameter('billingTitle', $value); + } + + /** + * Get the ach billing name. + * + * @return string + */ + public function getBillingName() + { + return trim($this->getBillingFirstName() . ' ' . $this->getBillingLastName()); + } + + /** + * Split the full name in the first and last name. + * + * @param $fullName + * @return array with first and lastname + */ + protected function listFirstLastName($fullName) + { + $names = explode(' ', $fullName, 2); + + return [$names[0], isset($names[1]) ? $names[1] : null]; + } + + /** + * Sets the ach billing name. + * + * @param string $value + * @return $this + */ + public function setBillingName($value) + { + $names = $this->listFirstLastName($value); + + $this->setBillingFirstName($names[0]); + $this->setBillingLastName($names[1]); + + return $this; + } + + /** + * Get the first part of the ach billing name. + * + * @return string + */ + public function getBillingFirstName() + { + return $this->getParameter('billingFirstName'); + } + + /** + * Sets the first part of the ach billing name. + * + * @param string $value + * @return $this + */ + public function setBillingFirstName($value) + { + return $this->setParameter('billingFirstName', $value); + } + + /** + * Get the last part of the ach billing name. + * + * @return string + */ + public function getBillingLastName() + { + return $this->getParameter('billingLastName'); + } + + /** + * Sets the last part of the ach billing name. + * + * @param string $value + * @return $this + */ + public function setBillingLastName($value) + { + return $this->setParameter('billingLastName', $value); + } + + /** + * Get the billing company name. + * + * @return string + */ + public function getBillingCompany() + { + return $this->getParameter('billingCompany'); + } + + /** + * Sets the billing company name. + * + * @param string $value + * @return $this + */ + public function setBillingCompany($value) + { + return $this->setParameter('billingCompany', $value); + } + + /** + * Get the billing address, line 1. + * + * @return string + */ + public function getBillingAddress1() + { + return $this->getParameter('billingAddress1'); + } + + /** + * Sets the billing address, line 1. + * + * @param string $value + * @return $this + */ + public function setBillingAddress1($value) + { + return $this->setParameter('billingAddress1', $value); + } + + /** + * Get the billing address, line 2. + * + * @return string + */ + public function getBillingAddress2() + { + return $this->getParameter('billingAddress2'); + } + + /** + * Sets the billing address, line 2. + * + * @param string $value + * @return $this + */ + public function setBillingAddress2($value) + { + return $this->setParameter('billingAddress2', $value); + } + + /** + * Get the billing city. + * + * @return string + */ + public function getBillingCity() + { + return $this->getParameter('billingCity'); + } + + /** + * Sets billing city. + * + * @param string $value + * @return $this + */ + public function setBillingCity($value) + { + return $this->setParameter('billingCity', $value); + } + + /** + * Get the billing postcode. + * + * @return string + */ + public function getBillingPostcode() + { + return $this->getParameter('billingPostcode'); + } + + /** + * Sets the billing postcode. + * + * @param string $value + * @return $this + */ + public function setBillingPostcode($value) + { + return $this->setParameter('billingPostcode', $value); + } + + /** + * Get the billing state. + * + * @return string + */ + public function getBillingState() + { + return $this->getParameter('billingState'); + } + + /** + * Sets the billing state. + * + * @param string $value + * @return $this + */ + public function setBillingState($value) + { + return $this->setParameter('billingState', $value); + } + + /** + * Get the billing country name. + * + * @return string + */ + public function getBillingCountry() + { + return $this->getParameter('billingCountry'); + } + + /** + * Sets the billing country name. + * + * @param string $value + * @return $this + */ + public function setBillingCountry($value) + { + return $this->setParameter('billingCountry', $value); + } + + /** + * Get the billing phone number. + * + * @return string + */ + public function getBillingPhone() + { + return $this->getParameter('billingPhone'); + } + + /** + * Sets the billing phone number. + * + * @param string $value + * @return $this + */ + public function setBillingPhone($value) + { + return $this->setParameter('billingPhone', $value); + } + + /** + * Get the billing phone number extension. + * + * @return string + */ + public function getBillingPhoneExtension() + { + return $this->getParameter('billingPhoneExtension'); + } + + /** + * Sets the billing phone number extension. + * + * @param string $value + * @return $this + */ + public function setBillingPhoneExtension($value) + { + return $this->setParameter('billingPhoneExtension', $value); + } + + /** + * Get the billing fax number. + * + * @return string + */ + public function getBillingFax() + { + return $this->getParameter('billingFax'); + } + + /** + * Sets the billing fax number. + * + * @param string $value + * @return $this + */ + public function setBillingFax($value) + { + return $this->setParameter('billingFax', $value); + } + + /** + * Get the title of the ach shipping name. + * + * @return string + */ + public function getShippingTitle() + { + return $this->getParameter('shippingTitle'); + } + + /** + * Sets the title of the ach shipping name. + * + * @param string $value + * @return $this + */ + public function setShippingTitle($value) + { + return $this->setParameter('shippingTitle', $value); + } + + /** + * Get the ach shipping name. + * + * @return string + */ + public function getShippingName() + { + return trim($this->getShippingFirstName() . ' ' . $this->getShippingLastName()); + } + + /** + * Sets the ach shipping name. + * + * @param string $value + * @return $this + */ + public function setShippingName($value) + { + $names = $this->listFirstLastName($value); + + $this->setShippingFirstName($names[0]); + $this->setShippingLastName($names[1]); + + return $this; + } + + /** + * Get the first part of the ach shipping name. + * + * @return string + */ + public function getShippingFirstName() + { + return $this->getParameter('shippingFirstName'); + } + + /** + * Sets the first part of the ach shipping name. + * + * @param string $value + * @return $this + */ + public function setShippingFirstName($value) + { + return $this->setParameter('shippingFirstName', $value); + } + + /** + * Get the last part of the ach shipping name. + * + * @return string + */ + public function getShippingLastName() + { + return $this->getParameter('shippingLastName'); + } + + /** + * Sets the last part of the ach shipping name. + * + * @param string $value + * @return $this + */ + public function setShippingLastName($value) + { + return $this->setParameter('shippingLastName', $value); + } + + /** + * Get the shipping company name. + * + * @return string + */ + public function getShippingCompany() + { + return $this->getParameter('shippingCompany'); + } + + /** + * Sets the shipping company name. + * + * @param string $value + * @return $this + */ + public function setShippingCompany($value) + { + return $this->setParameter('shippingCompany', $value); + } + + /** + * Get the shipping address, line 1. + * + * @return string + */ + public function getShippingAddress1() + { + return $this->getParameter('shippingAddress1'); + } + + /** + * Sets the shipping address, line 1. + * + * @param string $value + * @return $this + */ + public function setShippingAddress1($value) + { + return $this->setParameter('shippingAddress1', $value); + } + + /** + * Get the shipping address, line 2. + * + * @return string + */ + public function getShippingAddress2() + { + return $this->getParameter('shippingAddress2'); + } + + /** + * Sets the shipping address, line 2. + * + * @param string $value + * @return $this + */ + public function setShippingAddress2($value) + { + return $this->setParameter('shippingAddress2', $value); + } + + /** + * Get the shipping city. + * + * @return string + */ + public function getShippingCity() + { + return $this->getParameter('shippingCity'); + } + + /** + * Sets the shipping city. + * + * @param string $value + * @return $this + */ + public function setShippingCity($value) + { + return $this->setParameter('shippingCity', $value); + } + + /** + * Get the shipping postcode. + * + * @return string + */ + public function getShippingPostcode() + { + return $this->getParameter('shippingPostcode'); + } + + /** + * Sets the shipping postcode. + * + * @param string $value + * @return $this + */ + public function setShippingPostcode($value) + { + return $this->setParameter('shippingPostcode', $value); + } + + /** + * Get the shipping state. + * + * @return string + */ + public function getShippingState() + { + return $this->getParameter('shippingState'); + } + + /** + * Sets the shipping state. + * + * @param string $value + * @return $this + */ + public function setShippingState($value) + { + return $this->setParameter('shippingState', $value); + } + + /** + * Get the shipping country. + * + * @return string + */ + public function getShippingCountry() + { + return $this->getParameter('shippingCountry'); + } + + /** + * Sets the shipping country. + * + * @param string $value + * @return $this + */ + public function setShippingCountry($value) + { + return $this->setParameter('shippingCountry', $value); + } + + /** + * Get the shipping phone number. + * + * @return string + */ + public function getShippingPhone() + { + return $this->getParameter('shippingPhone'); + } + + /** + * Sets the shipping phone number. + * + * @param string $value + * @return $this + */ + public function setShippingPhone($value) + { + return $this->setParameter('shippingPhone', $value); + } + + /** + * Get the shipping phone number extension. + * + * @return string + */ + public function getShippingPhoneExtension() + { + return $this->getParameter('shippingPhoneExtension'); + } + + /** + * Sets the shipping phone number extension. + * + * @param string $value + * @return $this + */ + public function setShippingPhoneExtension($value) + { + return $this->setParameter('shippingPhoneExtension', $value); + } + + /** + * Get the shipping fax number. + * + * @return string + */ + public function getShippingFax() + { + return $this->getParameter('shippingFax'); + } + + /** + * Sets the shipping fax number. + * + * @param string $value + * @return $this + */ + public function setShippingFax($value) + { + return $this->setParameter('shippingFax', $value); + } + + /** + * Get the billing address, line 1. + * + * @return string + */ + public function getAddress1() + { + return $this->getParameter('billingAddress1'); + } + + /** + * Sets the billing and shipping address, line 1. + * + * @param string $value + * @return $this + */ + public function setAddress1($value) + { + $this->setParameter('billingAddress1', $value); + $this->setParameter('shippingAddress1', $value); + + return $this; + } + + /** + * Get the billing address, line 2. + * + * @return string + */ + public function getAddress2() + { + return $this->getParameter('billingAddress2'); + } + + /** + * Sets the billing and shipping address, line 2. + * + * @param string $value + * @return $this + */ + public function setAddress2($value) + { + $this->setParameter('billingAddress2', $value); + $this->setParameter('shippingAddress2', $value); + + return $this; + } + + /** + * Get the billing city. + * + * @return string + */ + public function getCity() + { + return $this->getParameter('billingCity'); + } + + /** + * Sets the billing and shipping city. + * + * @param string $value + * @return $this + */ + public function setCity($value) + { + $this->setParameter('billingCity', $value); + $this->setParameter('shippingCity', $value); + + return $this; + } + + /** + * Get the billing postcode. + * + * @return string + */ + public function getPostcode() + { + return $this->getParameter('billingPostcode'); + } + + /** + * Sets the billing and shipping postcode. + * + * @param string $value + * @return $this + */ + public function setPostcode($value) + { + $this->setParameter('billingPostcode', $value); + $this->setParameter('shippingPostcode', $value); + + return $this; + } + + /** + * Get the billing state. + * + * @return string + */ + public function getState() + { + return $this->getParameter('billingState'); + } + + /** + * Sets the billing and shipping state. + * + * @param string $value + * @return $this + */ + public function setState($value) + { + $this->setParameter('billingState', $value); + $this->setParameter('shippingState', $value); + + return $this; + } + + /** + * Get the billing country. + * + * @return string + */ + public function getCountry() + { + return $this->getParameter('billingCountry'); + } + + /** + * Sets the billing and shipping country. + * + * @param string $value + * @return $this + */ + public function setCountry($value) + { + $this->setParameter('billingCountry', $value); + $this->setParameter('shippingCountry', $value); + + return $this; + } + + /** + * Get the billing phone number. + * + * @return string + */ + public function getPhone() + { + return $this->getParameter('billingPhone'); + } + + /** + * Sets the billing and shipping phone number. + * + * @param string $value + * @return $this + */ + public function setPhone($value) + { + $this->setParameter('billingPhone', $value); + $this->setParameter('shippingPhone', $value); + + return $this; + } + + /** + * Get the billing phone number extension. + * + * @return string + */ + public function getPhoneExtension() + { + return $this->getParameter('billingPhoneExtension'); + } + + /** + * Sets the billing and shipping phone number extension. + * + * @param string $value + * @return $this + */ + public function setPhoneExtension($value) + { + $this->setParameter('billingPhoneExtension', $value); + $this->setParameter('shippingPhoneExtension', $value); + + return $this; + } + + /** + * Get the billing fax number.. + * + * @return string + */ + public function getFax() + { + return $this->getParameter('billingFax'); + } + + /** + * Sets the billing and shipping fax number. + * + * @param string $value + * @return $this + */ + public function setFax($value) + { + $this->setParameter('billingFax', $value); + $this->setParameter('shippingFax', $value); + + return $this; + } + + /** + * Get the ach billing company name. + * + * @return string + */ + public function getCompany() + { + return $this->getParameter('billingCompany'); + } + + /** + * Sets the billing and shipping company name. + * + * @param string $value + * @return $this + */ + public function setCompany($value) + { + $this->setParameter('billingCompany', $value); + $this->setParameter('shippingCompany', $value); + + return $this; + } + + /** + * Get the achholder's email address. + * + * @return string + */ + public function getEmail() + { + return $this->getParameter('email'); + } + + /** + * Sets the achholder's email address. + * + * @param string $value + * @return $this + */ + public function setEmail($value) + { + return $this->setParameter('email', $value); + } + + /** + * Get the achholder's birthday. + * + * @return string + */ + public function getBirthday($format = 'Y-m-d') + { + $value = $this->getParameter('birthday'); + + return $value ? $value->format($format) : null; + } + + /** + * Sets the achholder's birthday. + * + * @param string $value + * @return $this + */ + public function setBirthday($value) + { + if ($value) { + $value = new DateTime($value, new DateTimeZone('UTC')); + } else { + $value = null; + } + + return $this->setParameter('birthday', $value); + } + + /** + * Get the achholder's gender. + * + * @return string + */ + public function getGender() + { + return $this->getParameter('gender'); + } + + /** + * Sets the achholder's gender. + * + * @param string $value + * @return $this + */ + public function setGender($value) + { + return $this->setParameter('gender', $value); + } +} diff --git a/src/AchHelper.php b/src/AchHelper.php new file mode 100644 index 0000000..c4428d0 --- /dev/null +++ b/src/AchHelper.php @@ -0,0 +1,95 @@ +28,'ad'=>24,'at'=>20,'az'=>28,'bh'=>22,'be'=>16,'ba'=>20,'br'=>29,'bg'=>22,'cr'=>21,'hr'=>21,'cy'=>28,'cz'=>24, + 'dk'=>18,'do'=>28,'ee'=>20,'fo'=>18,'fi'=>18,'fr'=>27,'ge'=>22,'de'=>22,'gi'=>23,'gr'=>27,'gl'=>18,'gt'=>28,'hu'=>28, + 'is'=>26,'ie'=>22,'il'=>23,'it'=>27,'jo'=>30,'kz'=>20,'kw'=>30,'lv'=>21,'lb'=>28,'li'=>21,'lt'=>20,'lu'=>20,'mk'=>19, + 'mt'=>31,'mr'=>27,'mu'=>30,'mc'=>27,'md'=>24,'me'=>22,'nl'=>18,'no'=>15,'pk'=>24,'ps'=>29,'pl'=>28,'pt'=>25,'qa'=>29, + 'ro'=>24,'sm'=>27,'sa'=>24,'rs'=>22,'sk'=>24,'si'=>19,'es'=>24,'se'=>24,'ch'=>21,'tn'=>24,'tr'=>26,'ae'=>23,'gb'=>22,'vg'=>24 + ); + // subsitution scheme for letters + $Chars = array( + 'a'=>10,'b'=>11,'c'=>12,'d'=>13,'e'=>14,'f'=>15,'g'=>16,'h'=>17,'i'=>18,'j'=>19,'k'=>20,'l'=>21,'m'=>22, + 'n'=>23,'o'=>24,'p'=>25,'q'=>26,'r'=>27,'s'=>28,'t'=>29,'u'=>30,'v'=>31,'w'=>32,'x'=>33,'y'=>34,'z'=>35 + ); + + // Check input country code is known + if (!isset($Countries[ substr($iban,0,2) ])) return false; + + // Check total length for given country code + if (strlen($iban) != $Countries[ substr($iban,0,2) ]) { return false; } + + // Move first 4 chars to end + $MovedChar = substr($iban, 4) . substr($iban,0,4); + + // Replace letters by their numeric variant + $MovedCharArray = str_split($MovedChar); + $NewString = ""; + foreach ($MovedCharArray as $k => $v) { + if ( !is_numeric($MovedCharArray[$k]) ) { + // if any other cahracter then the known letters, its bogus + if(!isset($Chars[$MovedCharArray[$k]])) return false; + $MovedCharArray[$k] = $Chars[$MovedCharArray[$k]]; + } + $NewString .= $MovedCharArray[$k]; + } + + // Now we just need to validate the checksum + // http://au2.php.net/manual/en/function.bcmod.php#38474 + $x = $NewString; $y = "97"; + $take = 5; $mod = ""; + do { + $a = (int)$mod . substr($x, 0, $take); + $x = substr($x, $take); + $mod = $a % $y; + } + while (strlen($x)); + return (int)$mod == 1; + } +} diff --git a/src/Exception/InvalidAchException.php b/src/Exception/InvalidAchException.php new file mode 100644 index 0000000..e20d2ce --- /dev/null +++ b/src/Exception/InvalidAchException.php @@ -0,0 +1,14 @@ + 'JCB', ); + /** + * Get Api Version + * + * There are mulitple versions of the gateway + * + * @return string + */ + public function getApiVersion() + { + return $this->apiVersion; + } + + /** + * Set The Api Version + * + * There are mulitple versions of the gateway + * + * @return PayeezyAbstractRequest provides a fluent interface. + */ + public function setApiVersion($value) + { + $this->apiVersion = $value; + return $this; + } + /** * Get Gateway ID * @@ -185,6 +219,126 @@ public function getTransactionType() return $this->transactionType; } + /** + * Set customerIdType + * + * @param int $customerIdType + * + * @return PayeezyAbstractRequest provides a fluent interface. + */ + public function setCustomerIdType($customerIdType) + { + $this->customerIdType = $customerIdType; + return $this; + } + + /** + * Get customerIdType + * + * @return int + */ + public function getCustomerIdType() + { + return $this->customerIdType; + } + + /** + * Set transaction type + * + * @param int $transactionType + * + * @return PayeezyAbstractRequest provides a fluent interface. + */ + public function setPaymentMethod($paymentMethod) + { + $this->paymentMethod = $paymentMethod; + return $this; + } + + /** + * Get transaction type + * + * @return int + */ + public function getPaymentMethod() + { + return $this->paymentMethod; + } + + /** + * Sets the card. + * + * @param CreditCard $value + * @return $this + */ + public function setCard($value) + { + $card = parent::setCard($value); + $this->setPaymentMethod('card'); + return $card; + } + + /** + * Get transaction type + * + * @return bool + */ + public function isCard() + { + return $this->paymentMethod == 'card'; + } + + /** + * Get transaction type + * + * @return bool + */ + public function isAch() + { + return $this->paymentMethod == 'ach' || $this->paymentMethod == 'check'; + } + + /** + * Get the ach. + * + * @return Ach + */ + public function getAch() + { + return $this->getParameter('ach'); + } + + /** + * Sets the card. + * + * @param Ach $value + * @return $this + */ + public function setAch($value) + { + if ($value && !$value instanceof Ach) { + $value = new Ach($value); + } + $this->paymentMethod = 'ach'; + return $this->setParameter('ach', $value); + } + + /** + * Get the card or ach depending on the payment method. + * + * @return CreditCard + */ + public function getPaymentObject() + { + if($this->isCard()){ + return $this->getCard(); + }else if($this->isAch()){ + return $this->getAch(); + } + throw new InvalidRequestException('Invalid Payment Method (Must be "card" or "check")'); + } + + /** * Get the base transaction data. * @@ -286,15 +440,43 @@ public static function getCardType($type) */ public function getAVSHash() { + $paymentObject = $this->getPaymentObject(); $parts = array(); - $parts[] = $this->getCard()->getAddress1(); - $parts[] = $this->getCard()->getPostcode(); - $parts[] = $this->getCard()->getCity(); - $parts[] = $this->getCard()->getState(); - $parts[] = $this->getCard()->getCountry(); + $parts[] = $paymentObject->getAddress1(); + $parts[] = $paymentObject->getPostcode(); + $parts[] = $paymentObject->getCity(); + $parts[] = $paymentObject->getState(); + $parts[] = $paymentObject->getCountry(); return implode('|', $parts); } + /** + * Get the AVS Hash. + * + * Important Note about v12 or higher of the Web Service API: Merchants wishing to use + * V12 or higher of the API must implement the API HMAC hash security calculation. + * Further information on this subject can be found at the link below. + * + * @link https://support.payeezy.com/entries/22069302-api-security-hmac-hash + * + * @return string + */ + public function getAddress() + { + + $paymentObject = $this->getPaymentObject(); + $parts = array(); + $parts['address1'] = $paymentObject->getAddress1(); + $parts['address2'] = $paymentObject->getAddress2(); + $parts['zip'] = $paymentObject->getPostcode(); + $parts['city'] = $paymentObject->getCity(); + $parts['state'] = $paymentObject->getState(); + $parts['country_code'] = $paymentObject->getCountry(); + $parts['phone_number'] = $paymentObject->getPhone(); + $parts['phone_type'] = "N"; + return $parts; + } + /** * @return array */ @@ -345,7 +527,7 @@ public function sendData($data) */ protected function getEndpoint() { - return ($this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint) . self::API_VERSION; + return ($this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint) . 'v' . $this->apiVersion; } /** diff --git a/src/Message/PayeezyPurchaseRequest.php b/src/Message/PayeezyPurchaseRequest.php index 228ad32..03caef9 100644 --- a/src/Message/PayeezyPurchaseRequest.php +++ b/src/Message/PayeezyPurchaseRequest.php @@ -4,6 +4,8 @@ */ namespace Omnipay\FirstData\Message; +use Omnipay\Common\Exception\InvalidRequestException; + /** * First Data Payeezy Purchase Request * @@ -85,6 +87,16 @@ public function getData() { $data = parent::getData(); + if($this->paymentMethod == "card"){ + return $this->getCardData($data); + }else if ($this->paymentMethod == "ach" || $this->paymentMethod == "check"){ + return $this->getAchData($data); + } + throw new InvalidRequestException('Invalid Payment Method (Must be "card" or "check")'); + + } + + protected function getCardData($data){ $this->validate('amount', 'card'); $data['amount'] = $this->getAmount(); @@ -97,16 +109,49 @@ public function getData() $data['transarmor_token'] = $this->getCardReference(); $data['credit_card_type'] = $this->getTokenCardType(); } else { + $this->getCard()->validate(); $data['credit_card_type'] = self::getCardType($this->getCard()->getBrand()); $data['cc_number'] = $this->getCard()->getNumber(); - $data['cc_verification_str2'] = $this->getCard()->getCvv(); - $data['cc_verification_str1'] = $this->getAVSHash(); - $data['cvd_presence_ind'] = 1; $data['cvd_code'] = $this->getCard()->getCvv(); + $data['cvd_code'] = $this->getCard()->getCvv(); + + $this->appendAVS($data); + $this->appendCvv($data); } $data['cardholder_name'] = $this->getCard()->getName(); $data['cc_expiry'] = $this->getCard()->getExpiryDate('my'); + $data['client_ip'] = $this->getClientIp(); + $data['client_email'] = $this->getCard()->getEmail(); + $data['language'] = strtoupper($this->getCard()->getCountry()); + + return $data; + } + + protected function getAchData($data){ + $this->validate('amount', 'card'); + + + $data['amount'] = $this->getAmount(); + $data['currency_code'] = $this->getCurrency(); + $data['reference_no'] = $this->getTransactionId(); + + // add credit card details + if ($this->getCardReference()) { + $this->validate('tokenCardType'); + $data['transarmor_token'] = $this->getCardReference(); + $data['credit_card_type'] = $this->getTokenCardType(); + } else { + $data['credit_card_type'] = self::getCardType($this->getAch()->getBrand()); + $data['cc_number'] = $this->getCard()->getNumber(); + $data['cvd_code'] = $this->getCard()->getCvv(); + $data['cvd_code'] = $this->getCard()->getCvv(); + + $this->appendAVS($data); + $this->appendCvv($data); + } + $data['cardholder_name'] = $this->getCard()->getName(); + $data['cc_expiry'] = $this->getCard()->getExpiryDate('my'); $data['client_ip'] = $this->getClientIp(); $data['client_email'] = $this->getCard()->getEmail(); @@ -124,4 +169,23 @@ public function setTokenCardType($value) { return $this->setParameter('tokenCardType', $value); } + + protected function appendCvv(&$data){ + $data['cvd_presence_ind'] = 1; + if($this->getApiVersion() <= 13){ + $data['cc_verification_str2'] = $this->getCard()->getCvv(); + }else{ + $data['cvd_code'] = $this->getCard()->getCvv(); + } + } + + protected function appendAVS(&$data) + { + if($this->getApiVersion() <= 13){ + $data['cc_verification_str1'] = $this->getAVSHash(); + }else{ + $data['address'] = $this->getAddress(); + } + } } + diff --git a/src/Message/PayeezyResponse.php b/src/Message/PayeezyResponse.php index 4710d73..65cdcb8 100644 --- a/src/Message/PayeezyResponse.php +++ b/src/Message/PayeezyResponse.php @@ -5,6 +5,7 @@ namespace Omnipay\FirstData\Message; +use Omnipay\Common\Exception\InvalidResponseException; use Omnipay\Common\Message\AbstractResponse; use Omnipay\Common\Message\RequestInterface; @@ -26,6 +27,13 @@ public function __construct(RequestInterface $request, $data) { $this->request = $request; $this->data = json_decode($data, true); + + if($this->data === "Unauthorized Request. Bad or missing credentials."){ + throw new InvalidAuthResponseException("Unauthorized Request. Bad or missing credentials."); + } + if($this->data == null){ + throw new InvalidResponseException($data ?? "No Response"); + } } public function isSuccessful() @@ -118,8 +126,41 @@ public function getCardReference() return $this->getDataItem('transarmor_token'); } + /** + * Get Message + * + * A human readable message response and if not then the bank message. + * + * @return string + */ public function getMessage() { + $message = $this->getDataItem('bank_message'); + if (empty($message)) { + $message = $this->getDataItem('exact_message'); + } + return $message; + } + + /** + * Get Bank Response Message + * + * A message provided by the financial institution describing the Response code above. + * + * @return string + */ + public function getBankMessage(){ + return $this->getDataItem('bank_message'); + } + + /** + * Get the Exact Message. + * + * Message that accompanies the Exact_Resp_code. + * + * @return string + */ + public function getExactMessage(){ return $this->getDataItem('exact_message'); } @@ -136,4 +177,19 @@ public function getCode() { return $this->getDataItem('exact_resp_code'); } + + /** + * Get the bank response code. + * + * This is a 2 or 3 digit code, provided by the financial institution, indicating the + * approval status of a transaction. The meaning of these codes is defined by the + * various financial institutions and is not under the control of the Payeezy Gateway. + * + * @return string + */ + public function getBankCode() + { + return $this->getDataItem('bank_resp_code'); + } + } diff --git a/test.php b/test.php new file mode 100644 index 0000000..a4dfdd6 --- /dev/null +++ b/test.php @@ -0,0 +1,10 @@ +index(); diff --git a/tests/AchTest.bak b/tests/AchTest.bak new file mode 100644 index 0000000..cfd243e --- /dev/null +++ b/tests/AchTest.bak @@ -0,0 +1,599 @@ +ach = new Ach; + $this->ach->setNumber('4111111111111111'); + $this->ach->setFirstName('Example'); + $this->ach->setLastName('Customer'); + $this->ach->setExpiryMonth('4'); + $this->ach->setExpiryYear(gmdate('Y')+2); + $this->ach->setCvv('123'); + } + + public function testConstructWithParams() + { + $ach = new Ach(array('name' => 'Test Customer')); + $this->assertSame('Test Customer', $ach->getName()); + } + + public function testInitializeWithParams() + { + $ach = new Ach; + $ach->initialize(array('name' => 'Test Customer')); + $this->assertSame('Test Customer', $ach->getName()); + } + + public function testGetParamters() + { + $ach = new Ach(array( + 'name' => 'Example Customer', + 'number' => '1234', + 'expiryMonth' => 6, + 'expiryYear' => 2016, + )); + + $parameters = $ach->getParameters(); + $this->assertSame('Example', $parameters['billingFirstName']); + $this->assertSame('Customer', $parameters['billingLastName']); + $this->assertSame('1234', $parameters['number']); + $this->assertSame(6, $parameters['expiryMonth']); + $this->assertSame(2016, $parameters['expiryYear']); + } + + /** + * @doesNotPerformAssertions + */ + public function testValidateFixture() + { + $this->ach->validate(); + } + + /** + * @expectedException \Omnipay\FirstData\Exception\InvalidAchException + * @expectedExceptionMessage The credit ach number is required + */ + public function testValidateNumberRequired() + { + $this->ach->setNumber(null); + $this->ach->validate(); + } + + /** + * @expectedException \Omnipay\FirstData\Exception\InvalidAchException + * @expectedExceptionMessage The expiration month is required + */ + public function testValidateExpiryMonthRequired() + { + $this->ach->setExpiryMonth(null); + $this->ach->validate(); + } + + /** + * @expectedException \Omnipay\FirstData\Exception\InvalidAchException + * @expectedExceptionMessage The expiration year is required + */ + public function testValidateExpiryYearRequired() + { + $this->ach->setExpiryYear(null); + $this->ach->validate(); + } + + /** + * @expectedException \Omnipay\FirstData\Exception\InvalidAchException + * @expectedExceptionMessage Card has expired + */ + public function testValidateExpiryDate() + { + $this->ach->setExpiryYear(gmdate('Y')-1); + $this->ach->validate(); + } + + /** + * @expectedException \Omnipay\FirstData\Exception\InvalidAchException + * @expectedExceptionMessage Card number is invalid + */ + public function testValidateNumber() + { + $this->ach->setNumber('4111111111111110'); + $this->ach->validate(); + } + + public function testTitle() + { + $this->ach->setTitle('Mr.'); + $this->assertEquals('Mr.', $this->ach->getTitle()); + } + + public function testFirstName() + { + $this->ach->setFirstName('Bob'); + $this->assertEquals('Bob', $this->ach->getFirstName()); + } + + public function testLastName() + { + $this->ach->setLastName('Smith'); + $this->assertEquals('Smith', $this->ach->getLastName()); + } + + public function testGetName() + { + $this->ach->setFirstName('Bob'); + $this->ach->setLastName('Smith'); + $this->assertEquals('Bob Smith', $this->ach->getName()); + } + + public function testSetName() + { + $this->ach->setName('Bob Smith'); + $this->assertEquals('Bob', $this->ach->getFirstName()); + $this->assertEquals('Smith', $this->ach->getLastName()); + } + + public function testSetNameWithOneName() + { + $this->ach->setName('Bob'); + $this->assertEquals('Bob', $this->ach->getFirstName()); + $this->assertEquals('', $this->ach->getLastName()); + } + + public function testSetNameWithMultipleNames() + { + $this->ach->setName('Bob John Smith'); + $this->assertEquals('Bob', $this->ach->getFirstName()); + $this->assertEquals('John Smith', $this->ach->getLastName()); + } + + public function testNumber() + { + $this->ach->setNumber('4000000000000000'); + $this->assertEquals('4000000000000000', $this->ach->getNumber()); + } + + public function testSetNumberStripsNonDigits() + { + $this->ach->setNumber('4000 0000 00b00 0000'); + $this->assertEquals('4000000000000000', $this->ach->getNumber()); + } + + public function testGetNumberLastFourNull() + { + $this->ach->setNumber(null); + $this->assertNull($this->ach->getNumberLastFour()); + } + + public function testGetNumberLastFour() + { + $this->ach->setNumber('4000000000001234'); + $this->assertSame('1234', $this->ach->getNumberLastFour()); + } + + public function testGetNumberLastFourNonDigits() + { + $this->ach->setNumber('4000 0000 0000 12x34'); + $this->assertSame('1234', $this->ach->getNumberLastFour()); + } + + public function testGetNumberMasked() + { + $this->ach->setNumber('4000000000001234'); + + $this->assertSame('XXXXXXXXXXXX1234', $this->ach->getNumberMasked()); + } + + public function testGetNumberMaskedNonDigits() + { + $this->ach->setNumber('4000 0000 0000 12x34'); + + $this->assertSame('XXXXXXXXXXXX1234', $this->ach->getNumberMasked()); + } + + public function testExpiryMonth() + { + $this->ach->setExpiryMonth(9); + $this->assertSame(9, $this->ach->getExpiryMonth()); + } + + public function testExpiryMonthLeadingZeros() + { + $this->ach->setExpiryMonth('09'); + $this->assertSame(9, $this->ach->getExpiryMonth()); + } + + public function testExpiryYear() + { + $this->ach->setExpiryYear(2012); + $this->assertSame(2012, $this->ach->getExpiryYear()); + } + + public function testExpiryYearTwoDigits() + { + $this->ach->setExpiryYear('12'); + $this->assertSame(2012, $this->ach->getExpiryYear()); + } + + public function testExpiryDate() + { + $this->assertSame($this->ach, $this->ach->setExpiryMonth('09')); + $this->assertSame($this->ach, $this->ach->setExpiryYear('2012')); + $this->assertSame('092012', $this->ach->getExpiryDate('mY')); + } + + public function testStartMonth() + { + $this->ach->setStartMonth(9); + $this->assertSame(9, $this->ach->getStartMonth()); + } + + public function testStartMonthLeadingZeros() + { + $this->ach->setStartMonth('09'); + $this->assertSame(9, $this->ach->getStartMonth()); + } + + public function testStartYear() + { + $this->ach->setStartYear(2012); + $this->assertSame(2012, $this->ach->getStartYear()); + } + + public function testStartYearTwoDigits() + { + $this->ach->setStartYear('12'); + $this->assertSame(2012, $this->ach->getStartYear()); + } + + public function testStartDate() + { + $this->ach->setStartMonth('11'); + $this->ach->setStartYear('2012'); + $this->assertEquals('112012', $this->ach->getStartDate('mY')); + } + + public function testCvv() + { + $this->ach->setCvv('456'); + $this->assertEquals('456', $this->ach->getCvv()); + } + + public function testTracks() + { + $this->ach->setTracks('%B4242424242424242^SMITH/JOHN ^1520126100000000000000444000000?;4242424242424242=15201269999944401?'); + $this->assertSame('%B4242424242424242^SMITH/JOHN ^1520126100000000000000444000000?;4242424242424242=15201269999944401?', $this->ach->getTracks()); + } + + public function testShouldReturnTrack1() + { + $this->ach->setTracks('%B4242424242424242^SMITH/JOHN ^1520126100000000000000444000000?;4242424242424242=15201269999944401?'); + $actual = $this->ach->getTrack1(); + $this->assertEquals('%B4242424242424242^SMITH/JOHN ^1520126100000000000000444000000?', $actual); + } + + public function testShouldReturnTrack2() + { + $this->ach->setTracks('%B4242424242424242^SMITH/JOHN ^1520126100000000000000444000000?;4242424242424242=15201269999944401?'); + $actual = $this->ach->getTrack2(); + $this->assertEquals(';4242424242424242=15201269999944401?', $actual); + } + + public function testShouldReturnNoTrack() + { + $this->ach->setTracks(null); + $actual = $this->ach->getTrack2(); + $this->assertNull($actual); + } + + public function testIssueNumber() + { + $this->ach->setIssueNumber('12'); + $this->assertSame('12', $this->ach->getIssueNumber()); + } + + public function testBillingTitle() + { + $this->ach->setBillingTitle('Mrs.'); + $this->assertEquals('Mrs.', $this->ach->getBillingTitle()); + $this->assertEquals('Mrs.', $this->ach->getTitle()); + } + + public function testBillingFirstName() + { + $this->ach->setBillingFirstName('Bob'); + $this->assertEquals('Bob', $this->ach->getBillingFirstName()); + $this->assertEquals('Bob', $this->ach->getFirstName()); + } + + public function testBillingLastName() + { + $this->ach->setBillingLastName('Smith'); + $this->assertEquals('Smith', $this->ach->getBillingLastName()); + $this->assertEquals('Smith', $this->ach->getLastName()); + } + + public function testBillingName() + { + $this->ach->setBillingFirstName('Bob'); + $this->ach->setBillingLastName('Smith'); + $this->assertEquals('Bob Smith', $this->ach->getBillingName()); + + $this->ach->setBillingName('John Foo'); + $this->assertEquals('John', $this->ach->getBillingFirstName()); + $this->assertEquals('Foo', $this->ach->getBillingLastName()); + } + + public function testBillingCompany() + { + $this->ach->setBillingCompany('SuperSoft'); + $this->assertEquals('SuperSoft', $this->ach->getBillingCompany()); + $this->assertEquals('SuperSoft', $this->ach->getCompany()); + } + + public function testBillingAddress1() + { + $this->ach->setBillingAddress1('31 Spooner St'); + $this->assertEquals('31 Spooner St', $this->ach->getBillingAddress1()); + $this->assertEquals('31 Spooner St', $this->ach->getAddress1()); + } + + public function testBillingAddress2() + { + $this->ach->setBillingAddress2('Suburb'); + $this->assertEquals('Suburb', $this->ach->getBillingAddress2()); + $this->assertEquals('Suburb', $this->ach->getAddress2()); + } + + public function testBillingCity() + { + $this->ach->setBillingCity('Quahog'); + $this->assertEquals('Quahog', $this->ach->getBillingCity()); + $this->assertEquals('Quahog', $this->ach->getCity()); + } + + public function testBillingPostcode() + { + $this->ach->setBillingPostcode('12345'); + $this->assertEquals('12345', $this->ach->getBillingPostcode()); + $this->assertEquals('12345', $this->ach->getPostcode()); + } + + public function testBillingState() + { + $this->ach->setBillingState('RI'); + $this->assertEquals('RI', $this->ach->getBillingState()); + $this->assertEquals('RI', $this->ach->getState()); + } + + public function testBillingCountry() + { + $this->ach->setBillingCountry('US'); + $this->assertEquals('US', $this->ach->getBillingCountry()); + $this->assertEquals('US', $this->ach->getCountry()); + } + + public function testBillingPhone() + { + $this->ach->setBillingPhone('12345'); + $this->assertSame('12345', $this->ach->getBillingPhone()); + $this->assertSame('12345', $this->ach->getPhone()); + } + + public function testBillingPhoneExtension() + { + $this->ach->setBillingPhoneExtension('001'); + $this->assertSame('001', $this->ach->getBillingPhoneExtension()); + $this->assertSame('001', $this->ach->getPhoneExtension()); + } + + public function testBillingFax() + { + $this->ach->setBillingFax('54321'); + $this->assertSame('54321', $this->ach->getBillingFax()); + $this->assertSame('54321', $this->ach->getFax()); + } + + public function testShippingTitle() + { + $this->ach->setShippingTitle('Dr.'); + $this->assertEquals('Dr.', $this->ach->getShippingTitle()); + } + + public function testShippingFirstName() + { + $this->ach->setShippingFirstName('James'); + $this->assertEquals('James', $this->ach->getShippingFirstName()); + } + + public function testShippingLastName() + { + $this->ach->setShippingLastName('Doctor'); + $this->assertEquals('Doctor', $this->ach->getShippingLastName()); + } + + public function testShippingName() + { + $this->ach->setShippingFirstName('Bob'); + $this->ach->setShippingLastName('Smith'); + $this->assertEquals('Bob Smith', $this->ach->getShippingName()); + + $this->ach->setShippingName('John Foo'); + $this->assertEquals('John', $this->ach->getShippingFirstName()); + $this->assertEquals('Foo', $this->ach->getShippingLastName()); + } + + public function testShippingCompany() + { + $this->ach->setShippingCompany('SuperSoft'); + $this->assertEquals('SuperSoft', $this->ach->getShippingCompany()); + } + + public function testShippingAddress1() + { + $this->ach->setShippingAddress1('31 Spooner St'); + $this->assertEquals('31 Spooner St', $this->ach->getShippingAddress1()); + } + + public function testShippingAddress2() + { + $this->ach->setShippingAddress2('Suburb'); + $this->assertEquals('Suburb', $this->ach->getShippingAddress2()); + } + + public function testShippingCity() + { + $this->ach->setShippingCity('Quahog'); + $this->assertEquals('Quahog', $this->ach->getShippingCity()); + } + + public function testShippingPostcode() + { + $this->ach->setShippingPostcode('12345'); + $this->assertEquals('12345', $this->ach->getShippingPostcode()); + } + + public function testShippingState() + { + $this->ach->setShippingState('RI'); + $this->assertEquals('RI', $this->ach->getShippingState()); + } + + public function testShippingCountry() + { + $this->ach->setShippingCountry('US'); + $this->assertEquals('US', $this->ach->getShippingCountry()); + } + + public function testShippingPhone() + { + $this->ach->setShippingPhone('12345'); + $this->assertEquals('12345', $this->ach->getShippingPhone()); + } + + public function testShippingPhoneExtension() + { + $this->ach->setShippingPhoneExtension('001'); + $this->assertEquals('001', $this->ach->getShippingPhoneExtension()); + } + + public function testShippingFax() + { + $this->ach->setShippingFax('54321'); + $this->assertEquals('54321', $this->ach->getShippingFax()); + } + + public function testCompany() + { + $this->ach->setCompany('FooBar'); + $this->assertEquals('FooBar', $this->ach->getCompany()); + $this->assertEquals('FooBar', $this->ach->getBillingCompany()); + $this->assertEquals('FooBar', $this->ach->getShippingCompany()); + } + + public function testAddress1() + { + $this->ach->setAddress1('31 Spooner St'); + $this->assertEquals('31 Spooner St', $this->ach->getAddress1()); + $this->assertEquals('31 Spooner St', $this->ach->getBillingAddress1()); + $this->assertEquals('31 Spooner St', $this->ach->getShippingAddress1()); + } + + public function testAddress2() + { + $this->ach->setAddress2('Suburb'); + $this->assertEquals('Suburb', $this->ach->getAddress2()); + $this->assertEquals('Suburb', $this->ach->getBillingAddress2()); + $this->assertEquals('Suburb', $this->ach->getShippingAddress2()); + } + + public function testCity() + { + $this->ach->setCity('Quahog'); + $this->assertEquals('Quahog', $this->ach->getCity()); + $this->assertEquals('Quahog', $this->ach->getBillingCity()); + $this->assertEquals('Quahog', $this->ach->getShippingCity()); + } + + public function testPostcode() + { + $this->ach->setPostcode('12345'); + $this->assertEquals('12345', $this->ach->getPostcode()); + $this->assertEquals('12345', $this->ach->getBillingPostcode()); + $this->assertEquals('12345', $this->ach->getShippingPostcode()); + } + + public function testState() + { + $this->ach->setState('RI'); + $this->assertEquals('RI', $this->ach->getState()); + $this->assertEquals('RI', $this->ach->getBillingState()); + $this->assertEquals('RI', $this->ach->getShippingState()); + } + + public function testCountry() + { + $this->ach->setCountry('US'); + $this->assertEquals('US', $this->ach->getCountry()); + $this->assertEquals('US', $this->ach->getBillingCountry()); + $this->assertEquals('US', $this->ach->getShippingCountry()); + } + + public function testPhone() + { + $this->ach->setPhone('12345'); + $this->assertEquals('12345', $this->ach->getPhone()); + $this->assertEquals('12345', $this->ach->getBillingPhone()); + $this->assertEquals('12345', $this->ach->getShippingPhone()); + } + + public function testPhoneExtension() + { + $this->ach->setPhoneExtension('001'); + $this->assertEquals('001', $this->ach->getPhoneExtension()); + $this->assertEquals('001', $this->ach->getBillingPhoneExtension()); + $this->assertEquals('001', $this->ach->getShippingPhoneExtension()); + } + + public function testFax() + { + $this->ach->setFax('54321'); + $this->assertEquals('54321', $this->ach->getFax()); + $this->assertEquals('54321', $this->ach->getBillingFax()); + $this->assertEquals('54321', $this->ach->getShippingFax()); + } + + public function testEmail() + { + $this->ach->setEmail('adrian@example.com'); + $this->assertEquals('adrian@example.com', $this->ach->getEmail()); + } + + public function testBirthday() + { + $this->ach->setBirthday('01-02-2000'); + $this->assertEquals('2000-02-01', $this->ach->getBirthday()); + $this->assertEquals('01/02/2000', $this->ach->getBirthday('d/m/Y')); + } + + public function testBirthdayEmpty() + { + $this->ach->setBirthday(''); + $this->assertNull($this->ach->getBirthday()); + } + + public function testGender() + { + $this->ach->setGender('female'); + $this->assertEquals('female', $this->ach->getGender()); + } + +} diff --git a/tests/Json/PayeezePurchaseFailExp.json b/tests/Json/PayeezePurchaseFailExp.json new file mode 100644 index 0000000..311798d --- /dev/null +++ b/tests/Json/PayeezePurchaseFailExp.json @@ -0,0 +1,31 @@ +{ + "transaction_error": 0, + "transaction_approved": 0, + "exact_resp_code": "00", + "exact_message": "Transaction Normal", + "bank_resp_code": "605", + "bank_message": "Invalid Expiration Date", + "sequence_no": "000025", + "retrieval_ref_no": "200728", + "merchant_name": "Diversified Technology Corp DEMO0804", + "merchant_address": "95 E10th St", + "merchant_city": "Bloomsburg", + "merchant_province": "Pennsylvania", + "merchant_country": "United States", + "merchant_postal": "17815", + "ctr": "========== TRANSACTION RECORD ==========\nDiversified Technology Corp DEMO0804\n95 E10th St\nBloomsburg, PA 17815\nUnited States\n\n\nTYPE: Purchase\n\nACCT: Visa $ 10.00 USD\n\nCARDHOLDER NAME : Example Customer\nCARD NUMBER : ############1111\nDATE/TIME : 28 Jul 20 09:43:01\nREFERENCE # : 03 000025 M\nAUTHOR. # : \nTRANS. REF. : 12345\n\n Transaction not approved 605\n\n\nPlease retain this copy for your records.\n========================================", + "gateway_id": "HE6692-83", + "transaction_type": "00", + "amount": 10.0, + "cc_number": "############1111", + "transaction_tag": 4549764827, + "cc_expiry": "0120", + "cardholder_name": "Example Customer", + "cvd_presence_ind": 1, + "reference_no": "12345", + "client_ip": "1.2.3.4", + "currency_code": "USD", + "partial_redemption": 0, + "credit_card_type": "Visa", + "cvd_code": "123" +} diff --git a/tests/Json/PayeezePurchaseFailExpWithEmail.json b/tests/Json/PayeezePurchaseFailExpWithEmail.json new file mode 100644 index 0000000..aa0b44e --- /dev/null +++ b/tests/Json/PayeezePurchaseFailExpWithEmail.json @@ -0,0 +1,32 @@ +{ + "transaction_error": 0, + "transaction_approved": 0, + "exact_resp_code": "00", + "exact_message": "Transaction Normal", + "bank_resp_code": "605", + "bank_message": "Invalid Expiration Date", + "sequence_no": "000026", + "retrieval_ref_no": "200728", + "merchant_name": "Diversified Technology Corp DEMO0804", + "merchant_address": "95 E10th St", + "merchant_city": "Bloomsburg", + "merchant_province": "Pennsylvania", + "merchant_country": "United States", + "merchant_postal": "17815", + "ctr": "========== TRANSACTION RECORD ==========\nDiversified Technology Corp DEMO0804\n95 E10th St\nBloomsburg, PA 17815\nUnited States\n\n\nTYPE: Purchase\n\nACCT: Visa $ 10.00 USD\n\nCARDHOLDER NAME : Example Customer\nCARD NUMBER : ############1111\nDATE/TIME : 28 Jul 20 10:13:06\nREFERENCE # : 03 000026 M\nAUTHOR. # : \nTRANS. REF. : 12345\n\n Transaction not approved 605\n\n\nPlease retain this copy for your records.\n========================================", + "gateway_id": "HE6692-83", + "transaction_type": "00", + "amount": 10.0, + "cc_number": "############1111", + "transaction_tag": 4549769786, + "cc_expiry": "0120", + "cardholder_name": "Example Customer", + "cvd_presence_ind": 1, + "reference_no": "12345", + "client_ip": "1.2.3.4", + "client_email": "customer@example.com", + "currency_code": "USD", + "partial_redemption": 0, + "credit_card_type": "Visa", + "cvd_code": "123" +} diff --git a/tests/Json/PayeezePurchaseSuccess.json b/tests/Json/PayeezePurchaseSuccess.json new file mode 100644 index 0000000..e5749de --- /dev/null +++ b/tests/Json/PayeezePurchaseSuccess.json @@ -0,0 +1,34 @@ +{ + "transaction_error": 0, + "transaction_approved": 1, + "exact_resp_code": "00", + "exact_message": "Transaction Normal", + "bank_resp_code": "100", + "bank_message": "Approved", + "sequence_no": "000027", + "cvv2": "M", + "retrieval_ref_no": "200728", + "merchant_name": "PriceWaiter DEMO0243", + "merchant_address": "95 E10th St", + "merchant_city": "Bloomsburg", + "merchant_province": "Pennsylvania", + "merchant_country": "United States", + "merchant_postal": "17815", + "ctr": "========== TRANSACTION RECORD ==========", + "gateway_id": "HE6692-83", + "transaction_type": "00", + "amount": 10.0, + "cc_number": "############1111", + "transaction_tag": 4549770020, + "authorization_num": "ET173315", + "cc_expiry": "1220", + "cardholder_name": "Example Customer", + "cvd_presence_ind": 1, + "reference_no": "12345", + "client_ip": "1.2.3.4", + "client_email": "customer@example.com", + "currency_code": "USD", + "partial_redemption": 0, + "credit_card_type": "Visa", + "cvd_code": "123" +} diff --git a/tests/Message/PayeezyAuthorizeRequestTest.php b/tests/Message/PayeezyAuthorizeRequestTest.php index fdbe5fe..d7dd3b5 100644 --- a/tests/Message/PayeezyAuthorizeRequestTest.php +++ b/tests/Message/PayeezyAuthorizeRequestTest.php @@ -6,6 +6,27 @@ class PayeezyAuthorizeRequestTest extends TestCase { + public function testAuthorizeSuccessV13() + { + $request = new PayeezyAuthorizeRequest($this->getHttpClient(), $this->getHttpRequest()); + $request->setApiVersion(13) + ->initialize( + array( + 'amount' => '12.00', + 'card' => $this->getValidCard(), + ) + ); + $this->assertEquals(13,$request->getApiVersion()); + + $data = $request->getData(); + $this->assertEquals('01', $data['transaction_type']); + $this->assertEquals('4111111111111111', $data['cc_number']); + $this->assertEquals('Visa', $data['credit_card_type']); + $this->assertEquals('12.00', $data['amount']); + $this->assertNotNull($data['cc_verification_str2']); + $this->assertEquals('123 Billing St|12345|Billstown|CA|US', $data['cc_verification_str1']); + } + public function testAuthorizeSuccess() { $request = new PayeezyAuthorizeRequest($this->getHttpClient(), $this->getHttpRequest()); @@ -15,12 +36,23 @@ public function testAuthorizeSuccess() 'card' => $this->getValidCard(), ) ); + $this->assertEquals(14,$request->getApiVersion()); $data = $request->getData(); $this->assertEquals('01', $data['transaction_type']); $this->assertEquals('4111111111111111', $data['cc_number']); $this->assertEquals('Visa', $data['credit_card_type']); $this->assertEquals('12.00', $data['amount']); - $this->assertEquals('123 Billing St|12345|Billstown|CA|US', $data['cc_verification_str1']); + $this->assertNotNull($data['cvd_code']); + $this->assertEquals([ + 'address1' => '123 Billing St', + 'zip' => '12345', + 'address2' => 'Billsville', + 'city' => 'Billstown', + 'phone_type' => 'N', + 'state' => 'CA', + 'country_code' => 'US', + 'phone_number' => '(555) 123-4567' + ], $data['address']); } } diff --git a/tests/Message/PayeezyPurchaseRequestTest.php b/tests/Message/PayeezyPurchaseRequestTest.php index 98326b4..93b99cc 100644 --- a/tests/Message/PayeezyPurchaseRequestTest.php +++ b/tests/Message/PayeezyPurchaseRequestTest.php @@ -7,35 +7,68 @@ class PayeezyPurchaseRequestTest extends TestCase { - public function testPurchaseSuccess() + public function testPurchaseSuccessV13() { $request = new PayeezyPurchaseRequest($this->getHttpClient(), $this->getHttpRequest()); - $request->initialize( - array( - 'amount' => '12.00', - 'card' => $this->getValidCard(), - ) - ); + $request->setApiVersion(13) + ->initialize([ + 'amount' => '12.00', + 'card' => $this->getValidCard(), + ]); + $this->assertEquals(13,$request->getApiVersion()); $data = $request->getData(); $this->assertEquals('00', $data['transaction_type']); $this->assertEquals('4111111111111111', $data['cc_number']); $this->assertEquals('Visa', $data['credit_card_type']); $this->assertEquals('12.00', $data['amount']); + $this->assertNotNull($data['cc_verification_str2']); + $this->assertEquals('123 Billing St|12345|Billstown|CA|US', $data['cc_verification_str1']); } + public function testPurchaseSuccess() + { + $request = new PayeezyPurchaseRequest($this->getHttpClient(), $this->getHttpRequest()); + $request->initialize([ + 'amount' => '12.00', + 'card' => $this->getValidCard(), + ]); + + $this->assertEquals(14,$request->getApiVersion()); + $data = $request->getData(); + $this->assertEquals('00', $data['transaction_type']); + $this->assertEquals('4111111111111111', $data['cc_number']); + $this->assertEquals('Visa', $data['credit_card_type']); + $this->assertEquals('12.00', $data['amount']); + $this->assertNotNull($data['cvd_code']); + + $this->assertEquals([ + 'address1' => '123 Billing St', + 'zip' => '12345', + 'address2' => 'Billsville', + 'city' => 'Billstown', + 'phone_type' => 'N', + 'state' => 'CA', + 'country_code' => 'US', + 'phone_number' => '(555) 123-4567' + ], $data['address']); + } + + + public function testPurchaseSuccessMaestroType() { - $options = array( + $options = [ 'amount' => '12.00', 'card' => $this->getValidCard(), - ); + ]; $options['card']['number'] = '6304000000000000'; $request = new PayeezyPurchaseRequest($this->getHttpClient(), $this->getHttpRequest()); - $request->initialize($options); + $request->setApiVersion(13) + ->initialize($options); $data = $request->getData(); $this->assertEquals('00', $data['transaction_type']); diff --git a/tests/Message/PayeezyPurchaseResponseTest.php b/tests/Message/PayeezyPurchaseResponseTest.php index fdb5457..5f2cab2 100644 --- a/tests/Message/PayeezyPurchaseResponseTest.php +++ b/tests/Message/PayeezyPurchaseResponseTest.php @@ -12,16 +12,23 @@ public function testPurchaseSuccess() $response = new PayeezyResponse($this->getMockRequest(), json_encode(array( 'amount' => 1000, 'exact_resp_code' => 00, + 'bank_resp_code' => 100, 'exact_message' => 'Transaction Normal', 'reference_no' => 'abc123', 'authorization_num' => 'auth1234', + 'bank_message' => "Approved", 'transaction_approved' => 1, ))); $this->assertTrue($response->isSuccessful()); $this->assertEquals('auth1234::', $response->getTransactionReference()); - $this->assertSame('Transaction Normal', $response->getMessage()); + $this->assertSame('Approved', $response->getMessage()); + $this->assertSame('Approved', $response->getBankMessage()); + $this->assertSame('Transaction Normal', $response->getExactMessage()); + $this->assertEquals('00', $response->getCode()); + $this->assertEquals('100', $response->getBankCode()); + } public function testPurchaseError() @@ -29,16 +36,22 @@ public function testPurchaseError() $response = new PayeezyResponse($this->getMockRequest(), json_encode(array( 'amount' => 1000, 'exact_resp_code' => 22, - 'exact_message' => 'Invalid Credit Card Number', + 'bank_resp_code' => 605, + 'exact_message' => 'Transaction Normal', 'reference_no' => 'abc123', 'authorization_num' => 'auth1234', + 'bank_message' => 'Invalid Expiration Date', 'transaction_approved' => 0, ))); $this->assertFalse($response->isSuccessful()); $this->assertEquals('auth1234::', $response->getTransactionReference()); - $this->assertSame('Invalid Credit Card Number', $response->getMessage()); + $this->assertSame('Invalid Expiration Date', $response->getMessage()); + $this->assertSame('Invalid Expiration Date', $response->getBankMessage()); + $this->assertSame('Transaction Normal', $response->getExactMessage()); $this->assertEquals('22', $response->getCode()); + $this->assertEquals('605', $response->getBankCode()); + } public function testBankError() @@ -46,6 +59,7 @@ public function testBankError() $response = new PayeezyResponse($this->getMockRequest(), json_encode(array( 'amount' => 1000, 'exact_resp_code' => 00, + 'bank_resp_code' => 605, 'reference_no' => 'abc123', 'authorization_num' => '', 'transaction_approved' => 0, @@ -54,5 +68,7 @@ public function testBankError() $this->assertFalse($response->isSuccessful()); $this->assertEquals('::', $response->getTransactionReference()); $this->assertEquals('00', $response->getCode()); + $this->assertEquals('605', $response->getBankCode()); + } } diff --git a/tests/Mock/PayeezePurchaseError.txt b/tests/Mock/PayeezePurchaseError.txt new file mode 100644 index 0000000..9091e3d --- /dev/null +++ b/tests/Mock/PayeezePurchaseError.txt @@ -0,0 +1 @@ +Unauthorized Request. Bad or missing credentials. diff --git a/tests/PayeezyGatewayTest.php b/tests/PayeezyGatewayTest.php index 8eb03bb..340548b 100644 --- a/tests/PayeezyGatewayTest.php +++ b/tests/PayeezyGatewayTest.php @@ -2,6 +2,9 @@ namespace Omnipay\FirstData; +use Omnipay\Common\CreditCard; +use Omnipay\Common\Exception\InvalidCreditCardException; +use Omnipay\Common\Exception\InvalidRequestException; use Omnipay\Tests\GatewayTestCase; class PayeezyGatewayTest extends GatewayTestCase @@ -58,4 +61,24 @@ public function testAuthorizeSuccess() $this->assertFalse($response->isRedirect()); $this->assertEquals('ET181147::28513493', $response->getTransactionReference()); } + + public function testPurchaseFailureMissingAmount(){ + + $this->expectException(InvalidRequestException::class); + + unset($this->options['amount']); + $response = $this->gateway->purchase($this->options)->send(); + } + + public function testPurchaseFailureInvalidCard(){ + $this->expectException(InvalidCreditCardException::class); + $this->options['card'] = new CreditCard([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + 'expiryMonth' => '12', + 'expiryYear' => '2019', + 'cvv' => '123', + ]); + $response = $this->gateway->purchase($this->options)->send(); + } } From e290f03b235b65c018e5d6c1b03b743ed599e5ce Mon Sep 17 00:00:00 2001 From: Nick Caruso Date: Wed, 21 Oct 2020 14:18:15 -0400 Subject: [PATCH 5/6] Added Ach to Payeezy Gateway Upgraded for use with Omnipay V3 Added Ach class and helper Added methods to the response Added and improved tests Added demo tests for use with test gateway credentials --- composer.json | 5 - demos/Feature/DemoPayeezyACHGatewayTest.php | 260 +++++++++++--- demos/Feature/DemoPayeezyGatewayTest.php | 101 +++++- src/Ach.php | 45 ++- src/AchHelper.php | 6 +- src/Message/AchResponseHelper.php | 101 ++++++ src/Message/PayeezyAbstractRequest.php | 31 +- src/Message/PayeezyPurchaseRequest.php | 83 +++-- src/Message/PayeezyResponse.php | 4 + src/Message/ResponseHelper.php | 173 ++++++++++ test.php | 10 - tests/{AchTest.bak => AchTest.php} | 321 ++++++++---------- tests/Json/PayeezeAchPurchaseSuccess.json | 30 ++ .../Json/PayeezePurchaseFailExpWithEmail.json | 2 +- tests/Mock/PurchaseAchSuccess.txt | 5 + tests/PayeezyAchGatewayTest.php | 183 ++++++++++ tests/PayeezyGatewayTest.php | 1 + 17 files changed, 1079 insertions(+), 282 deletions(-) create mode 100644 src/Message/AchResponseHelper.php create mode 100644 src/Message/ResponseHelper.php delete mode 100644 test.php rename tests/{AchTest.bak => AchTest.php} (71%) create mode 100644 tests/Json/PayeezeAchPurchaseSuccess.json create mode 100644 tests/Mock/PurchaseAchSuccess.txt create mode 100644 tests/PayeezyAchGatewayTest.php diff --git a/composer.json b/composer.json index 225064e..ec959cb 100644 --- a/composer.json +++ b/composer.json @@ -34,10 +34,5 @@ "require-dev": { "omnipay/tests": "~3.1" }, - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, "prefer-stable": true } diff --git a/demos/Feature/DemoPayeezyACHGatewayTest.php b/demos/Feature/DemoPayeezyACHGatewayTest.php index 9098f81..d43202f 100644 --- a/demos/Feature/DemoPayeezyACHGatewayTest.php +++ b/demos/Feature/DemoPayeezyACHGatewayTest.php @@ -6,11 +6,12 @@ use Omnipay\Common\Exception\InvalidRequestException; use Omnipay\Common\Exception\InvalidResponseException; use Omnipay\FirstData\Ach; +use Omnipay\FirstData\Exception\InvalidAchException; use Omnipay\Omnipay; use Omnipay\Tests\GatewayTestCase; use PHPUnit\Framework\TestCase; -class DemoPayeezyAchGateway extends TestCase +class DemoPayeezyAchGatewayTest extends TestCase { public function setUp() { @@ -26,22 +27,69 @@ public function setUp() } - public function test_ach_purchase_with_address_and_cvv() + /** + * Everything was successful + */ + public function test_ach_purchase_was_successful() { + $ach = new Ach([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + 'routingNumber' => '021000021', + 'accountNumber' => '2020', + 'checkNumber' => '123', + // 'checkType' => 'P', + ]); - // * * checkType -> - // * * accountNumber -> - // * * routingNumber -> + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + 'amount' => '10.00', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'ach' => $ach, + ])->send(); + + $this->assertTrue($response->isSuccessful()); + + $this->assertNotNull($response->getAuthorizationNumber()); + $this->assertNull($response->getCardReference()); + + $this->assertNotNull($response->getTransactionTag()); + $this->assertNotNull($response->getTransactionReference()); + $this->assertNotNull($response->getSequenceNo()); + + $this->assertEquals($response->getCode(),"00"); + $this->assertEquals($response->getMessage(),"Approved"); + $this->assertEquals($response->getBankCode(),"100"); + $this->assertEquals($response->getExactMessage(),"Transaction Normal"); + $this->assertEquals($response->getBankMessage(),"Approved"); + + $this->assertEquals($response->getCardType(),"Telecheck"); + $this->assertNull($response->getCardNumber()); + $this->assertEquals($response->getCheckNumber(),2020); + + + $this->assertNull($response->getEmail()); + + + } + + public function test_ach_purchase_with_additional_fields() + { + + // * * checkType + // * * accountNumber + // * * routingNumber // * * checkNumber // * * customerIDType -> - // * * License -> - // * * LicenseState -> + // * * license -> + // * * licenseState -> // * * ssn -> // * * taxId -> // * * militaryId -> // * - // * * customerID -> - // * * ecommerceFlag + // * * customer -> + // * * ecommerceFlag -> // * * releaseType -> // * * vip -> // * * clerk -> @@ -50,14 +98,23 @@ public function test_ach_purchase_with_address_and_cvv() $ach = new Ach([ 'firstName' => 'Example', 'lastName' => 'Customer', - 'routingNumber' => '4111', + 'routingNumber' => '021000021', 'accountNumber' => '2020', 'checkNumber' => '123', - 'billingAddress1' => '1 Scrubby Creek Road', - 'billingCountry' => 'AU', - 'billingCity' => 'Scrubby Creek', - 'billingPostcode' => '4999', - 'billingState' => 'QLD', + 'address1' => '1 Scrubby Creek Road', + 'country' => 'AU', + 'city' => 'Scrubby Creek', + 'postcode' => '4999', + 'state' => 'PA', + 'phone' => '5551234567', + 'email' => 'example@email.com', + 'checkType' => 'C', + 'release_type' => 'D', + 'vip' => false, + 'clerk' => 'AAAA', + 'device' => 'BBBB', + 'micr' => 'CCCC', + 'ecommerce_flag' => 7, ]); $response = $this->gateway->purchase([ @@ -65,8 +122,8 @@ public function test_ach_purchase_with_address_and_cvv() 'amount' => '10.00', 'transactionId' => 12345, 'clientIp' => "1.2.3.4", - 'ach' => $ach, - // 'paymentMethod' => "ach" + 'ach' => $ach, + // 'customerIDType' => 0 ])->send(); $this->assertTrue($response->isSuccessful()); @@ -83,21 +140,47 @@ public function test_ach_purchase_with_address_and_cvv() $this->assertEquals($response->getBankCode(),"100"); $this->assertEquals($response->getExactMessage(),"Transaction Normal"); $this->assertEquals($response->getBankMessage(),"Approved"); - } + $this->assertEquals($response->getCardType(),"Telecheck"); + $this->assertNull($response->getCardNumber()); + $this->assertEquals($response->getCheckNumber(),123); - /** - * Everything was successful - */ - public function test_ach_purchase() + $this->assertNotNull($response->getAddress()); + $this->assertEquals($response->getEmail(),"example@email.com"); + $this->assertEquals($response->getAddress1(), '1 Scrubby Creek Road'); + $this->assertNull($response->getAddress2()); + $this->assertEquals($response->getCountry(), 'AU'); + $this->assertEquals($response->getCity(), 'Scrubby Creek'); + $this->assertEquals($response->getPostCode(), '4999'); + $this->assertEquals($response->getState(), 'PA'); + $this->assertEquals($response->getPhone(), '5551234567'); + + $this->assertEquals($response->getCheckType(),"C"); + + $this->assertEquals($response->getCheckType(),"C"); + $this->assertEquals($response->getReleaseType(),'D'); + $this->assertEquals($response->getVip(),false); + $this->assertEquals($response->getClerk(),'AAAA'); + $this->assertEquals($response->getEcommerceFlag(),7); + $this->assertNotNull($response->getCtr()); + } + + public function test_ach_purchase_with_address() { - $card = new CreditCard([ + $ach = new Ach([ 'firstName' => 'Example', 'lastName' => 'Customer', - 'number' => '4111111111111111', - 'expiryMonth' => '12', - 'expiryYear' => '2026', - 'cvv' => '123', + 'routingNumber' => '021000021', + 'accountNumber' => '2020', + 'checkNumber' => '123', + 'checkType' => 'P', + 'address1' => '1 Scrubby Creek Road', + 'country' => 'AU', + 'city' => 'Scrubby Creek', + 'postcode' => '4999', + 'state' => 'PA', + 'phone' => '5551234567', + 'email' => 'example@email.com' ]); $response = $this->gateway->purchase([ @@ -105,9 +188,11 @@ public function test_ach_purchase() 'amount' => '10.00', 'transactionId' => 12345, 'clientIp' => "1.2.3.4", - 'card' => $card, + 'ach' => $ach, + // 'customerIDType' => 0 ])->send(); + $this->assertTrue($response->isSuccessful()); $this->assertNotNull($response->getAuthorizationNumber()); @@ -122,6 +207,51 @@ public function test_ach_purchase() $this->assertEquals($response->getBankCode(),"100"); $this->assertEquals($response->getExactMessage(),"Transaction Normal"); $this->assertEquals($response->getBankMessage(),"Approved"); + + $this->assertEquals($response->getCardType(),"Telecheck"); + $this->assertNull($response->getCardNumber()); + $this->assertEquals($response->getCheckNumber(),2020); + + $this->assertNotNull($response->getAddress()); + $this->assertEquals($response->getEmail(),"example@email.com"); + $this->assertEquals($response->getAddress1(), '1 Scrubby Creek Road'); + $this->assertNull($response->getAddress2()); + $this->assertEquals($response->getCountry(), 'AU'); + $this->assertEquals($response->getCity(), 'Scrubby Creek'); + $this->assertEquals($response->getPostCode(), '4999'); + $this->assertEquals($response->getState(), 'PA'); + $this->assertEquals($response->getPhone(), '5551234567'); + } + + public function test_ach_purchase_with_auth() + { + $ach = new Ach([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + 'routingNumber' => '021000021', + 'accountNumber' => '2020', + 'checkNumber' => '123', + 'checkType' => 'P', + 'address1' => '1 Scrubby Creek Road', + 'country' => 'AU', + 'city' => 'Scrubby Creek', + 'postcode' => '4999', + 'state' => 'PA', + 'phone' => '5551234567', + 'email' => 'example@email.com', + 'license' => '123456', + 'license_state' => 'PA', + ]); + + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + 'amount' => '10.00', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'ach' => $ach, + ])->send(); + + $this->assertTrue($response->isSuccessful()); } /** @@ -131,13 +261,12 @@ public function test_ach_purchase_exception() { $this->expectException(InvalidRequestException::class); $this->expectExceptionMessage("The amount parameter is required"); - $card = new CreditCard([ + $ach = new Ach([ 'firstName' => 'Example', 'lastName' => 'Customer', - 'number' => '4111111111111111', - 'expiryMonth' => '12', - 'expiryYear' => '2019', - 'cvv' => '123', + 'routingNumber' => '021000021', + 'accountNumber' => '2020', + 'checkNumber' => '123', ]); $response = $this->gateway->purchase([ @@ -145,10 +274,35 @@ public function test_ach_purchase_exception() // 'amount' => '10.00', 'transactionId' => 12345, 'clientIp' => "1.2.3.4", - 'card' => $card, + 'ach' => $ach, ])->send(); + } + /** + * An exception was thrown before the request was made because of invalid input + */ + public function test_ach_purchase_ach_exception() + { + $this->expectException(InvalidAchException::class); + $this->expectExceptionMessage("The routing number is required"); + $ach = new Ach([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + // 'routingNumber' => '021000021', + 'accountNumber' => '2020', + 'checkNumber' => '123', + ]); + + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + 'amount' => '10.00', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'check' => $ach, + ])->send(); + + } /** * An exception was thrown because the response came back in a bad format */ @@ -156,22 +310,21 @@ public function test_ach_purchase_error() { $this->expectException(InvalidResponseException::class); - $this->expectExceptionMessage("Bad Request (27) - Invalid Card Holder"); - $card = new CreditCard([ - 'firstName' => 'test', - 'lastName' => '', - 'number' => '4111111111111111', - 'expiryMonth' => '12', - 'expiryYear' => '2026', - 'cvv' => '123', + $this->expectExceptionMessage("Bad Request (69) - Invalid Transaction Tag"); + $ach = new Ach([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + 'routingNumber' => '021000021', + 'accountNumber' => '2020', + 'checkNumber' => '123', ]); $response = $this->gateway->purchase([ 'description' => 'Your order for widgets', - 'amount' => '5000.27', + 'amount' => '5000.69', 'transactionId' => 12345, 'clientIp' => "1.2.3.4", - 'card' => $card, + 'ach' => $ach, ])->send(); } @@ -180,21 +333,20 @@ public function test_ach_purchase_error() */ public function test_ach_purchase_failure() { - $card = new CreditCard([ + $ach = new Ach([ 'firstName' => 'Example', 'lastName' => 'Customer', - 'number' => '4111111111111111', - 'expiryMonth' => '12', - 'expiryYear' => '2026', - 'cvv' => '123', + 'routingNumber' => '021000021', + 'accountNumber' => '2020', + 'checkNumber' => '123', ]); $response = $this->gateway->purchase([ 'description' => 'Your order for widgets', - 'amount' => '5605.00', + 'amount' => '5299.00', 'transactionId' => 12345, 'clientIp' => "1.2.3.4", - 'card' => $card, + 'ach' => $ach, ])->send(); $this->assertFalse($response->isSuccessful()); @@ -207,9 +359,9 @@ public function test_ach_purchase_failure() $this->assertNotNull($response->getSequenceNo()); $this->assertEquals($response->getCode(),"00"); - $this->assertEquals($response->getMessage(),"Invalid Expiration Date"); - $this->assertEquals($response->getBankCode(),"605"); + $this->assertEquals($response->getMessage(),"Transaction not approved"); + $this->assertEquals($response->getBankCode(),"299"); $this->assertEquals($response->getExactMessage(),"Transaction Normal"); - $this->assertEquals($response->getBankMessage(),"Invalid Expiration Date"); + $this->assertEquals($response->getBankMessage(),"Transaction not approved"); } } diff --git a/demos/Feature/DemoPayeezyGatewayTest.php b/demos/Feature/DemoPayeezyGatewayTest.php index e8b4841..edab16b 100644 --- a/demos/Feature/DemoPayeezyGatewayTest.php +++ b/demos/Feature/DemoPayeezyGatewayTest.php @@ -3,6 +3,7 @@ namespace Omnipay\FirstData\Feature; use Omnipay\Common\CreditCard; +use Omnipay\Common\Exception\InvalidCreditCardException; use Omnipay\Common\Exception\InvalidRequestException; use Omnipay\Common\Exception\InvalidResponseException; use Omnipay\Omnipay; @@ -25,9 +26,52 @@ public function setUp() } - public function test_purchase() + /** + * Everything was successful + */ + public function test_purchase_success() { + $card = new CreditCard([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + 'number' => '4111111111111111', + 'expiryMonth' => '12', + 'expiryYear' => '2026', + 'cvv' => '123', + ]); + + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + 'amount' => '10.00', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'card' => $card, + ])->send(); + + $this->assertTrue($response->isSuccessful()); + + $this->assertNotNull($response->getAuthorizationNumber()); + $this->assertNull($response->getCardReference()); + $this->assertNotNull($response->getTransactionTag()); + $this->assertNotNull($response->getTransactionReference()); + $this->assertNotNull($response->getSequenceNo()); + + $this->assertEquals($response->getCode(),"00"); + $this->assertEquals($response->getMessage(),"Approved"); + $this->assertEquals($response->getBankCode(),"100"); + $this->assertEquals($response->getExactMessage(),"Transaction Normal"); + $this->assertEquals($response->getBankMessage(),"Approved"); + + $this->assertEquals($response->getCardType(),"Visa"); + $this->assertEquals($response->getCardNumber(),"############1111"); + } + + /** + * Everything was successful + */ + public function test_purchase_success_with_address() + { $card = new CreditCard([ 'firstName' => 'Example', 'lastName' => 'Customer', @@ -35,6 +79,13 @@ public function test_purchase() 'expiryMonth' => '12', 'expiryYear' => '2026', 'cvv' => '123', + 'address1' => '1 Scrubby Creek Road', + 'country' => 'AU', + 'city' => 'Scrubby Creek', + 'postcode' => '4999', + 'state' => 'PA', + 'phone' => '5551234567', + 'email' => 'example@email.com' ]); $response = $this->gateway->purchase([ @@ -59,8 +110,26 @@ public function test_purchase() $this->assertEquals($response->getBankCode(),"100"); $this->assertEquals($response->getExactMessage(),"Transaction Normal"); $this->assertEquals($response->getBankMessage(),"Approved"); + + $this->assertEquals($response->getCardType(),"Visa"); + $this->assertEquals($response->getCardNumber(),"############1111"); + $this->assertNotNull($response->getAddress()); + + $this->assertEquals($response->getEmail(),"example@email.com"); + $this->assertEquals($response->getAddress1(), '1 Scrubby Creek Road'); + $this->assertNull($response->getAddress2()); + $this->assertEquals($response->getCountry(), 'AU'); + $this->assertEquals($response->getCity(), 'Scrubby Creek'); + $this->assertEquals($response->getPostCode(), '4999'); + $this->assertEquals($response->getState(), 'PA'); + $this->assertEquals($response->getPhone(), '5551234567'); + } + + /** + * An exception was thrown before the request was made because of invalid input + */ public function test_purchase_exception() { $this->expectException(InvalidRequestException::class); @@ -83,6 +152,33 @@ public function test_purchase_exception() ])->send(); } + /** + * An exception was thrown before the request was made because of invalid card + */ + public function test_purchase_credit_card_exception() + { + $this->expectException(InvalidCreditCardException::class); + $this->expectExceptionMessage("The credit card number is required"); + $card = new CreditCard([ + 'firstName' => 'Example', + 'lastName' => 'Customer', + // 'number' => '4111111111111111', + 'expiryMonth' => '12', + 'expiryYear' => '2019', + 'cvv' => '123', + ]); + + $response = $this->gateway->purchase([ + 'description' => 'Your order for widgets', + 'amount' => '10.00', + 'transactionId' => 12345, + 'clientIp' => "1.2.3.4", + 'card' => $card, + ])->send(); + } + /** + * An exception was thrown because the response came back in a bad format + */ public function test_purchase_error() { @@ -106,6 +202,9 @@ public function test_purchase_error() ])->send(); } + /** + * No exception thrown but the payment was unsuccessful + */ public function test_purchase_failure() { $card = new CreditCard([ diff --git a/src/Ach.php b/src/Ach.php index 9e8005d..a85cccb 100644 --- a/src/Ach.php +++ b/src/Ach.php @@ -42,6 +42,7 @@ * * accountNumber * * routingNumber * * checkNumber + * * * driversLicense * * driversLicenseState * * ssn @@ -151,15 +152,13 @@ public function initialize(array $parameters = null) public function validate() { $requiredParameters = array( - 'firstName' => 'first name', - 'lastName' => 'last name', + 'billingFirstName' => 'first name', + 'billingLastName' => 'last name', 'routingNumber' => 'routing number', 'accountNumber' => 'account number', // 'checkNumber' => 'check number' // number => 'cehck number' ); - var_dump($requiredParameters); - die(); foreach ($requiredParameters as $key => $val) { if (!$this->getParameter($key)) { @@ -170,10 +169,6 @@ public function validate() if (!AchHelper::validateRoutingNumber($this->getRoutingNumber())) { throw new InvalidAchException('Routing Number is invalid'); } - - if (!AchHelper::validateIBAN($this->getAccountNumber())) { - throw new InvalidAchException('Account Number is invalid'); - } } /** @@ -323,6 +318,27 @@ public function setSocialSecurityNumber($value) return $this->setParameter('ssn', $value); } + /** + * Get the ach social security number. + * + * @return string + */ + public function getSSN() + { + return $this->getParameter('ssn'); + } + + /** + * Sets the ach social security number. + * + * @param string $value + * @return $this + */ + public function setSSN($value) + { + return $this->setParameter('ssn', $value); + } + /** * Get the ach tax ID. * @@ -1460,7 +1476,7 @@ public function setCompany($value) } /** - * Get the achholder's email address. + * Get the ach email address. * * @return string */ @@ -1470,7 +1486,7 @@ public function getEmail() } /** - * Sets the achholder's email address. + * Sets the ach email address. * * @param string $value * @return $this @@ -1481,7 +1497,7 @@ public function setEmail($value) } /** - * Get the achholder's birthday. + * Get the ach birthday. * * @return string */ @@ -1493,7 +1509,7 @@ public function getBirthday($format = 'Y-m-d') } /** - * Sets the achholder's birthday. + * Sets the ach birthday. * * @param string $value * @return $this @@ -1510,7 +1526,7 @@ public function setBirthday($value) } /** - * Get the achholder's gender. + * Get the ach gender. * * @return string */ @@ -1520,7 +1536,7 @@ public function getGender() } /** - * Sets the achholder's gender. + * Sets the ach gender. * * @param string $value * @return $this @@ -1529,4 +1545,5 @@ public function setGender($value) { return $this->setParameter('gender', $value); } + } diff --git a/src/AchHelper.php b/src/AchHelper.php index c4428d0..d6a8159 100644 --- a/src/AchHelper.php +++ b/src/AchHelper.php @@ -16,11 +16,12 @@ class AchHelper * @return string */ public static function validateRoutingNumber($routingNumber = 0) { + + $routingNumber = preg_replace('[\D]', '', $routingNumber); //only digits if(strlen($routingNumber) != 9) { return false; } - $checkSum = 0; for ($i = 0, $j = strlen($routingNumber); $i < $j; $i+= 3 ) { //loop through routingNumber character by character @@ -28,8 +29,7 @@ public static function validateRoutingNumber($routingNumber = 0) { $checkSum += ($routingNumber[$i+1] * 7); $checkSum += ($routingNumber[$i+2]); } - - return ($checkSum != 0 and ($checkSum % 10) == 0); + return ($checkSum != 0 && ($checkSum % 10) == 0); } diff --git a/src/Message/AchResponseHelper.php b/src/Message/AchResponseHelper.php new file mode 100644 index 0000000..10f3eb3 --- /dev/null +++ b/src/Message/AchResponseHelper.php @@ -0,0 +1,101 @@ +getDataItem('check_number'); + } + + /** + * Get the check type + * + * @return string + */ + public function getCheckType() + { + return $this->getDataItem('check_type'); + } + + /** + * Get the release type + * + * @return char + */ + public function getReleaseType() + { + return $this->getDataItem('release_type'); + } + + /** + * Get the vip + * + * @return boolean + */ + public function getVip() + { + return $this->getDataItem('vip'); + } + + /** + * Get the clerk ID + * + * @return boolean + */ + public function getClerk() + { + return $this->getDataItem('clerk_id'); + } + + /** + * Get the MICR + * + * @return boolean + */ + public function getMicr() + { + return $this->getDataItem('micr'); + } + + /** + * Get the E-commerce Flag + * + * @return boolean + */ + public function getEcommerceFlag() + { + return $this->getDataItem('ecommerce_flag'); + } + + /** + * Get text of receipt + * + * @return boolean + */ + public function getCtr() + { + return $this->getDataItem('ctr'); + } +} diff --git a/src/Message/PayeezyAbstractRequest.php b/src/Message/PayeezyAbstractRequest.php index 993f584..94d2be3 100644 --- a/src/Message/PayeezyAbstractRequest.php +++ b/src/Message/PayeezyAbstractRequest.php @@ -309,7 +309,7 @@ public function getAch() } /** - * Sets the card. + * Sets the ach. * * @param Ach $value * @return $this @@ -319,8 +319,31 @@ public function setAch($value) if ($value && !$value instanceof Ach) { $value = new Ach($value); } - $this->paymentMethod = 'ach'; - return $this->setParameter('ach', $value); + + $ach = $this->setParameter('ach', $value); + $this->setPaymentMethod('ach'); + return $ach; + } + + /** + * Get the ach. + * + * @return Ach + */ + public function getCheck() + { + return $this->getAch(); + } + + /** + * Sets the ach. + * + * @param Ach $value + * @return $this + */ + public function setCheck($value) + { + return $this->setAch($value); } /** @@ -465,7 +488,7 @@ public function getAddress() { $paymentObject = $this->getPaymentObject(); - $parts = array(); + $parts = array(); $parts['address1'] = $paymentObject->getAddress1(); $parts['address2'] = $paymentObject->getAddress2(); $parts['zip'] = $paymentObject->getPostcode(); diff --git a/src/Message/PayeezyPurchaseRequest.php b/src/Message/PayeezyPurchaseRequest.php index 03caef9..9f47a99 100644 --- a/src/Message/PayeezyPurchaseRequest.php +++ b/src/Message/PayeezyPurchaseRequest.php @@ -81,7 +81,14 @@ */ class PayeezyPurchaseRequest extends PayeezyAbstractRequest { + protected $action = self::TRAN_PURCHASE; + const CUSTOMER_ID_TYPE = [ + 0 => "license", + 1 => "ssn", + 2 => "taxId", + 3 => "militaryId" + ]; public function getData() { @@ -112,8 +119,6 @@ protected function getCardData($data){ $this->getCard()->validate(); $data['credit_card_type'] = self::getCardType($this->getCard()->getBrand()); $data['cc_number'] = $this->getCard()->getNumber(); - $data['cvd_code'] = $this->getCard()->getCvv(); - $data['cvd_code'] = $this->getCard()->getCvv(); $this->appendAVS($data); $this->appendCvv($data); @@ -129,37 +134,35 @@ protected function getCardData($data){ } protected function getAchData($data){ - $this->validate('amount', 'card'); + $this->validate('amount', 'ach'); + $this->getAch()->validate(); $data['amount'] = $this->getAmount(); $data['currency_code'] = $this->getCurrency(); $data['reference_no'] = $this->getTransactionId(); - // add credit card details - if ($this->getCardReference()) { - $this->validate('tokenCardType'); - $data['transarmor_token'] = $this->getCardReference(); - $data['credit_card_type'] = $this->getTokenCardType(); - } else { - $data['credit_card_type'] = self::getCardType($this->getAch()->getBrand()); - $data['cc_number'] = $this->getCard()->getNumber(); - $data['cvd_code'] = $this->getCard()->getCvv(); - $data['cvd_code'] = $this->getCard()->getCvv(); + $data['account_number'] = $this->getAch()->getAccountNumber(); + $data['routing_number'] = $this->getAch()->getRoutingNumber(); + $data['cardholder_name'] = $this->getAch()->getName(); - $this->appendAVS($data); - $this->appendCvv($data); - } - $data['cardholder_name'] = $this->getCard()->getName(); - $data['cc_expiry'] = $this->getCard()->getExpiryDate('my'); + $data['check_type'] = $this->getAch()->getCheckType(); + $data['check_number'] = $this->getAch()->getCheckNumber(); + + + $this->appendAch($data); + $this->appendAchAuth($data); + $this->appendAVS($data); $data['client_ip'] = $this->getClientIp(); - $data['client_email'] = $this->getCard()->getEmail(); - $data['language'] = strtoupper($this->getCard()->getCountry()); + $data['client_email'] = $this->getAch()->getEmail(); + $data['language'] = strtoupper($this->getAch()->getCountry()); return $data; } + + public function getTokenCardType() { return $this->getParameter('tokenCardType'); @@ -172,6 +175,7 @@ public function setTokenCardType($value) protected function appendCvv(&$data){ $data['cvd_presence_ind'] = 1; + if($this->getApiVersion() <= 13){ $data['cc_verification_str2'] = $this->getCard()->getCvv(); }else{ @@ -187,5 +191,44 @@ protected function appendAVS(&$data) $data['address'] = $this->getAddress(); } } + + protected function appendAch(&$data){ + $data['release_type'] = $this->getAch()->getReleaseType(); + $data['vip'] = $this->getAch()->getVip(); + $data['clerk_id'] = $this->getAch()->getClerk(); + $data['device_id'] = $this->getAch()->getDevice(); + $data['micr'] = $this->getAch()->getMicr(); + $data['ecommerce_flag'] = $this->getAch()->getEcommerceFlag(); + } + + protected function appendAchAuth(&$data){ + $license = $this->getAch()->getLicense(); + if($license){ + $data['customer_id_type'] = 0; + $data['customer_id_number'] = $license; + return $data; + } + + $SSN = $this->getAch()->getSSN(); + if($SSN){ + $data['customer_id_type'] = 1; + $data['customer_id_number'] = $SSN; + return $data; + } + + $taxId = $this->getAch()->getTaxID(); + if($taxId){ + $data['customer_id_type'] = 2; + $data['customer_id_number'] = $taxId; + return $data; + } + + $militaryId = $this->getAch()->getMilitaryId(); + if($militaryId){ + $data['customer_id_type'] = 3; + $data['customer_id_number'] = $militaryId; + return $data; + } + } } diff --git a/src/Message/PayeezyResponse.php b/src/Message/PayeezyResponse.php index 65cdcb8..391c3ca 100644 --- a/src/Message/PayeezyResponse.php +++ b/src/Message/PayeezyResponse.php @@ -8,6 +8,8 @@ use Omnipay\Common\Exception\InvalidResponseException; use Omnipay\Common\Message\AbstractResponse; use Omnipay\Common\Message\RequestInterface; +use Omnipay\FirstData\Message\AchResponseHelper; +use Omnipay\FirstData\Message\ResponseHelper; /** * First Data Payeezy Response @@ -23,6 +25,8 @@ */ class PayeezyResponse extends AbstractResponse { + use ResponseHelper, AchResponseHelper; + public function __construct(RequestInterface $request, $data) { $this->request = $request; diff --git a/src/Message/ResponseHelper.php b/src/Message/ResponseHelper.php new file mode 100644 index 0000000..5551886 --- /dev/null +++ b/src/Message/ResponseHelper.php @@ -0,0 +1,173 @@ +getDataItem('client_email'); + } + + /** + * Get the credit card number + * + * @return string + */ + public function getCardNumber() + { + return $this->getDataItem('cc_number'); + } + + /** + * Get the credit card type + * + * @return string + */ + public function getCardType() + { + return $this->getDataItem('credit_card_type'); + } + + /** + * Get the amount payed + * + * @return float + */ + public function getAmount() + { + return $this->getDataItem('amount'); + } + + /** + * Get the address array + * + * + * @return array + */ + public function getAddress() + { + return $this->getDataItem('address'); + } + + /** + * Get specified address part + * + * @return mixed + */ + public function getAddressPart($part) + { + $address = $this->getAddress(); + if($address != null && isset($address[$part])){ + return $address[$part]; + } + return null; + } + + + /** + * Get address line 1 + * + * @return string + */ + public function getAddress1() + { + return $this->getAddressPart("address1"); + } + + /** + * Get address line 2 + * + * @return string + */ + public function getAddress2() + { + return $this->getAddressPart("address2"); + } + + /** + * Get address city + * + * @return string + */ + public function getCity() + { + return $this->getAddressPart("city"); + } + + /** + * Get address state + * + * @return string + */ + public function getState() + { + return $this->getAddressPart("state"); + } + + /** + * Get address zipcode + * + * @return string + */ + public function getPostCode() + { + return $this->getAddressPart("zip"); + } + + /** + * Get address country code + * + * @return string + */ + public function getCountry() + { + return $this->getAddressPart("country_code"); + } + + /** + * Get phone type + * Only the following values are accepted: + * H = Home + * W = Work + * D = Day + * N = Night + * PhoneType is required when the PhoneNumber field is populated in a transaction request. Otherwise, it is optional. + * @return string + */ + public function getPhoneType(){ + return $this->getAddressPart("phone_type"); + } + + + /** + * Get phone number + * Non digits will be removed before processing. When phone_number is used, phone_type must be provided. + * + * @return string + */ + public function getPhone() + { + return $this->getAddressPart('phone_number'); + } +} diff --git a/test.php b/test.php deleted file mode 100644 index a4dfdd6..0000000 --- a/test.php +++ /dev/null @@ -1,10 +0,0 @@ -index(); diff --git a/tests/AchTest.bak b/tests/AchTest.php similarity index 71% rename from tests/AchTest.bak rename to tests/AchTest.php index cfd243e..ceb6240 100644 --- a/tests/AchTest.bak +++ b/tests/AchTest.php @@ -12,13 +12,19 @@ class AchTest extends TestCase public function setUp() { + // [ + // 'firstName' => 'Example', + // 'lastName' => 'Customer', + // 'routingNumber' => '021000021', + // 'accountNumber' => '2020', + // 'checkNumber' => '123', + // ] $this->ach = new Ach; - $this->ach->setNumber('4111111111111111'); + $this->ach->setRoutingNumber('021000021'); + $this->ach->setAccountNumber('2020'); $this->ach->setFirstName('Example'); $this->ach->setLastName('Customer'); - $this->ach->setExpiryMonth('4'); - $this->ach->setExpiryYear(gmdate('Y')+2); - $this->ach->setCvv('123'); + $this->ach->setCheckNumber('123'); } public function testConstructWithParams() @@ -38,17 +44,13 @@ public function testGetParamters() { $ach = new Ach(array( 'name' => 'Example Customer', - 'number' => '1234', - 'expiryMonth' => 6, - 'expiryYear' => 2016, + 'checkNumber' => '123', )); $parameters = $ach->getParameters(); $this->assertSame('Example', $parameters['billingFirstName']); $this->assertSame('Customer', $parameters['billingLastName']); - $this->assertSame('1234', $parameters['number']); - $this->assertSame(6, $parameters['expiryMonth']); - $this->assertSame(2016, $parameters['expiryYear']); + $this->assertSame('123', $parameters['checkNumber']); } /** @@ -61,51 +63,51 @@ public function testValidateFixture() /** * @expectedException \Omnipay\FirstData\Exception\InvalidAchException - * @expectedExceptionMessage The credit ach number is required + * @expectedExceptionMessage The routing number is required */ - public function testValidateNumberRequired() + public function testValidateRoutingNumberRequired() { - $this->ach->setNumber(null); + $this->ach->setRoutingNumber(null); $this->ach->validate(); } /** * @expectedException \Omnipay\FirstData\Exception\InvalidAchException - * @expectedExceptionMessage The expiration month is required + * @expectedExceptionMessage The account number is required */ - public function testValidateExpiryMonthRequired() + public function testValidateAccountNumberRequired() { - $this->ach->setExpiryMonth(null); + $this->ach->setAccountNumber(null); $this->ach->validate(); } /** * @expectedException \Omnipay\FirstData\Exception\InvalidAchException - * @expectedExceptionMessage The expiration year is required + * @expectedExceptionMessage The first name is required */ - public function testValidateExpiryYearRequired() + public function testValidateFirstNameRequired() { - $this->ach->setExpiryYear(null); + $this->ach->setFirstName(null); $this->ach->validate(); } /** * @expectedException \Omnipay\FirstData\Exception\InvalidAchException - * @expectedExceptionMessage Card has expired + * @expectedExceptionMessage The last name is required */ - public function testValidateExpiryDate() + public function testValidateLastNameRequired() { - $this->ach->setExpiryYear(gmdate('Y')-1); + $this->ach->setLastName(null); $this->ach->validate(); } /** * @expectedException \Omnipay\FirstData\Exception\InvalidAchException - * @expectedExceptionMessage Card number is invalid + * @expectedExceptionMessage Routing Number is invalid */ - public function testValidateNumber() + public function testValidateRoutingNumber() { - $this->ach->setNumber('4111111111111110'); + $this->ach->setRoutingNumber('021000020'); $this->ach->validate(); } @@ -155,151 +157,6 @@ public function testSetNameWithMultipleNames() $this->assertEquals('John Smith', $this->ach->getLastName()); } - public function testNumber() - { - $this->ach->setNumber('4000000000000000'); - $this->assertEquals('4000000000000000', $this->ach->getNumber()); - } - - public function testSetNumberStripsNonDigits() - { - $this->ach->setNumber('4000 0000 00b00 0000'); - $this->assertEquals('4000000000000000', $this->ach->getNumber()); - } - - public function testGetNumberLastFourNull() - { - $this->ach->setNumber(null); - $this->assertNull($this->ach->getNumberLastFour()); - } - - public function testGetNumberLastFour() - { - $this->ach->setNumber('4000000000001234'); - $this->assertSame('1234', $this->ach->getNumberLastFour()); - } - - public function testGetNumberLastFourNonDigits() - { - $this->ach->setNumber('4000 0000 0000 12x34'); - $this->assertSame('1234', $this->ach->getNumberLastFour()); - } - - public function testGetNumberMasked() - { - $this->ach->setNumber('4000000000001234'); - - $this->assertSame('XXXXXXXXXXXX1234', $this->ach->getNumberMasked()); - } - - public function testGetNumberMaskedNonDigits() - { - $this->ach->setNumber('4000 0000 0000 12x34'); - - $this->assertSame('XXXXXXXXXXXX1234', $this->ach->getNumberMasked()); - } - - public function testExpiryMonth() - { - $this->ach->setExpiryMonth(9); - $this->assertSame(9, $this->ach->getExpiryMonth()); - } - - public function testExpiryMonthLeadingZeros() - { - $this->ach->setExpiryMonth('09'); - $this->assertSame(9, $this->ach->getExpiryMonth()); - } - - public function testExpiryYear() - { - $this->ach->setExpiryYear(2012); - $this->assertSame(2012, $this->ach->getExpiryYear()); - } - - public function testExpiryYearTwoDigits() - { - $this->ach->setExpiryYear('12'); - $this->assertSame(2012, $this->ach->getExpiryYear()); - } - - public function testExpiryDate() - { - $this->assertSame($this->ach, $this->ach->setExpiryMonth('09')); - $this->assertSame($this->ach, $this->ach->setExpiryYear('2012')); - $this->assertSame('092012', $this->ach->getExpiryDate('mY')); - } - - public function testStartMonth() - { - $this->ach->setStartMonth(9); - $this->assertSame(9, $this->ach->getStartMonth()); - } - - public function testStartMonthLeadingZeros() - { - $this->ach->setStartMonth('09'); - $this->assertSame(9, $this->ach->getStartMonth()); - } - - public function testStartYear() - { - $this->ach->setStartYear(2012); - $this->assertSame(2012, $this->ach->getStartYear()); - } - - public function testStartYearTwoDigits() - { - $this->ach->setStartYear('12'); - $this->assertSame(2012, $this->ach->getStartYear()); - } - - public function testStartDate() - { - $this->ach->setStartMonth('11'); - $this->ach->setStartYear('2012'); - $this->assertEquals('112012', $this->ach->getStartDate('mY')); - } - - public function testCvv() - { - $this->ach->setCvv('456'); - $this->assertEquals('456', $this->ach->getCvv()); - } - - public function testTracks() - { - $this->ach->setTracks('%B4242424242424242^SMITH/JOHN ^1520126100000000000000444000000?;4242424242424242=15201269999944401?'); - $this->assertSame('%B4242424242424242^SMITH/JOHN ^1520126100000000000000444000000?;4242424242424242=15201269999944401?', $this->ach->getTracks()); - } - - public function testShouldReturnTrack1() - { - $this->ach->setTracks('%B4242424242424242^SMITH/JOHN ^1520126100000000000000444000000?;4242424242424242=15201269999944401?'); - $actual = $this->ach->getTrack1(); - $this->assertEquals('%B4242424242424242^SMITH/JOHN ^1520126100000000000000444000000?', $actual); - } - - public function testShouldReturnTrack2() - { - $this->ach->setTracks('%B4242424242424242^SMITH/JOHN ^1520126100000000000000444000000?;4242424242424242=15201269999944401?'); - $actual = $this->ach->getTrack2(); - $this->assertEquals(';4242424242424242=15201269999944401?', $actual); - } - - public function testShouldReturnNoTrack() - { - $this->ach->setTracks(null); - $actual = $this->ach->getTrack2(); - $this->assertNull($actual); - } - - public function testIssueNumber() - { - $this->ach->setIssueNumber('12'); - $this->assertSame('12', $this->ach->getIssueNumber()); - } - public function testBillingTitle() { $this->ach->setBillingTitle('Mrs.'); @@ -596,4 +453,128 @@ public function testGender() $this->assertEquals('female', $this->ach->getGender()); } + /** + * Ach Specific starts here + */ + public function testCheckNumber() + { + $this->ach->setCheckNumber('123'); + $this->assertEquals('123', $this->ach->getCheckNumber()); + + $ach = new Ach(array('checkNumber' => '123')); + $this->assertEquals('123', $ach->getCheckNumber()); + } + + public function testCheckType() + { + $this->ach->setCheckType('P'); + $this->assertEquals('P', $this->ach->getCheckType()); + + $ach = new Ach(array('checkType' => 'P')); + $this->assertEquals('P', $ach->getCheckType()); + } + + public function testReleaseType() + { + $this->ach->setReleaseType('R'); + $this->assertEquals('R', $this->ach->getReleaseType()); + + $ach = new Ach(array('releaseType' => 'R')); + $this->assertEquals('R', $ach->getReleaseType()); + } + + public function testVIP() + { + $this->ach->setVIP(true); + $this->assertEquals(true, $this->ach->getVIP()); + + $ach = new Ach(array('vip' => true)); + $this->assertEquals(true, $ach->getVIP()); + } + + public function testClerk() + { + $this->ach->setClerk("ABCD"); + $this->assertEquals("ABCD", $this->ach->getClerk()); + + $ach = new Ach(array('clerk' => "ABCD")); + $this->assertEquals("ABCD", $ach->getClerk()); + } + + public function testDevice() + { + $this->ach->setDevice("ABCD"); + $this->assertEquals("ABCD", $this->ach->getDevice()); + + $ach = new Ach(array('device' => "ABCD")); + $this->assertEquals("ABCD", $ach->getDevice()); + } + + public function testMicr() + { + $this->ach->setMicr("ABCD"); + $this->assertEquals("ABCD", $this->ach->getMicr()); + + $ach = new Ach(array('micr' => "ABCD")); + $this->assertEquals("ABCD", $ach->getMicr()); + } + + public function testEcommerceFlag() + { + $this->ach->setEcommerceFlag(7); + $this->assertEquals(7, $this->ach->getEcommerceFlag()); + + $ach = new Ach(array('ecommerce_flag' => 7)); + $this->assertEquals(7, $ach->getEcommerceFlag()); + } + + public function testDriversLicense() + { + $this->ach->setLicense("123ABC"); + $this->assertEquals("123ABC", $this->ach->getLicense()); + + $ach = new Ach(array('license' => "123ABC")); + $this->assertEquals("123ABC", $ach->getLicense()); + } + + public function testDriversLicenseState() + { + $this->ach->setLicenseState("PA"); + $this->assertEquals("PA", $this->ach->getLicenseState()); + + $ach = new Ach(array('license_state' => "PA")); + $this->assertEquals("PA", $ach->getLicenseState()); + } + + public function testSSN() + { + $this->ach->setSSN("123ABC"); + $this->assertEquals("123ABC", $this->ach->getSSN()); + + $this->ach->setSocialSecurityNumber("123ABC"); + $this->assertEquals("123ABC", $this->ach->getSocialSecurityNumber()); + + $ach = new Ach(array('ssn' => "123ABC")); + $this->assertEquals("123ABC", $ach->getSSN()); + $this->assertEquals("123ABC", $ach->getSocialSecurityNumber()); + + } + + public function testTaxID() + { + $this->ach->setTaxID("123ABC"); + $this->assertEquals("123ABC", $this->ach->getTaxID()); + + $ach = new Ach(array('taxId' => "123ABC")); + $this->assertEquals("123ABC", $ach->getTaxID()); + } + + public function testMilitaryID() + { + $this->ach->setMilitaryID("123ABC"); + $this->assertEquals("123ABC", $this->ach->getMilitaryID()); + + $ach = new Ach(array('militaryId' => "123ABC")); + $this->assertEquals("123ABC", $ach->getMilitaryID()); + } } diff --git a/tests/Json/PayeezeAchPurchaseSuccess.json b/tests/Json/PayeezeAchPurchaseSuccess.json new file mode 100644 index 0000000..4440b89 --- /dev/null +++ b/tests/Json/PayeezeAchPurchaseSuccess.json @@ -0,0 +1,30 @@ +{ + "transaction_error": 0, + "transaction_approved": 1, + "exact_resp_code": "00", + "exact_message": "Transaction Normal", + "bank_resp_code": "100", + "bank_message": "Approved", + "sequence_no": "000027", + "retrieval_ref_no": "200728", + "merchant_name": "PriceWaiter DEMO0243", + "merchant_address": "95 E10th St", + "merchant_city": "Bloomsburg", + "merchant_province": "Pennsylvania", + "merchant_country": "United States", + "merchant_postal": "17815", + "ctr": "========== TRANSACTION RECORD ==========", + "gateway_id": "HE6692-83", + "transaction_type": "00", + "amount": 10.0, + "transaction_tag": 4549770020, + "authorization_num": "ET173315", + "reference_no": "12345", + "client_ip": "1.2.3.4", + "client_email": "customer@example.com", + "currency_code": "USD", + "credit_card_type": "Telecheck", + "ecommerce_flag": "0", + "check_number": "123", + "customer_name": "Example Customer" +} diff --git a/tests/Json/PayeezePurchaseFailExpWithEmail.json b/tests/Json/PayeezePurchaseFailExpWithEmail.json index aa0b44e..ed4cdff 100644 --- a/tests/Json/PayeezePurchaseFailExpWithEmail.json +++ b/tests/Json/PayeezePurchaseFailExpWithEmail.json @@ -13,7 +13,7 @@ "merchant_province": "Pennsylvania", "merchant_country": "United States", "merchant_postal": "17815", - "ctr": "========== TRANSACTION RECORD ==========\nDiversified Technology Corp DEMO0804\n95 E10th St\nBloomsburg, PA 17815\nUnited States\n\n\nTYPE: Purchase\n\nACCT: Visa $ 10.00 USD\n\nCARDHOLDER NAME : Example Customer\nCARD NUMBER : ############1111\nDATE/TIME : 28 Jul 20 10:13:06\nREFERENCE # : 03 000026 M\nAUTHOR. # : \nTRANS. REF. : 12345\n\n Transaction not approved 605\n\n\nPlease retain this copy for your records.\n========================================", + "ctr": "========== TRANSACTION RECORD ==========", "gateway_id": "HE6692-83", "transaction_type": "00", "amount": 10.0, diff --git a/tests/Mock/PurchaseAchSuccess.txt b/tests/Mock/PurchaseAchSuccess.txt new file mode 100644 index 0000000..420e867 --- /dev/null +++ b/tests/Mock/PurchaseAchSuccess.txt @@ -0,0 +1,5 @@ +HTTP/1.1 201 OK +Date: Tue, 11 Feb 2014 02:34:58 GMT +Content-type: text/html; charset=utf-8 + +{"transaction_error":0,"transaction_approved":1,"exact_resp_code":"00","exact_message":"Transaction Normal","bank_resp_code":"100","bank_message":"Approved","sequence_no":"000027","retrieval_ref_no":"200728","merchant_name":"PriceWaiter DEMO0243","merchant_address":"95 E10th St","merchant_city":"Bloomsburg","merchant_province":"Pennsylvania","merchant_country":"United States","merchant_postal":"17815","ctr":"========== TRANSACTION RECORD ==========","gateway_id":"HE6692-83","transaction_type":"00","amount":10,"transaction_tag":4549770020,"authorization_num":"ET173315","reference_no":"12345","client_ip":"1.2.3.4","client_email":"customer@example.com","currency_code":"USD","credit_card_type":"Telecheck","ecommerce_flag":"0","check_number":"123","customer_name":"Example Customer"} diff --git a/tests/PayeezyAchGatewayTest.php b/tests/PayeezyAchGatewayTest.php new file mode 100644 index 0000000..6fbda0e --- /dev/null +++ b/tests/PayeezyAchGatewayTest.php @@ -0,0 +1,183 @@ +gateway = new PayeezyGateway($this->getHttpClient(), $this->getHttpRequest()); + $this->gateway->setGatewayId('1234'); + $this->gateway->setPassword('abcde'); + + $this->options = array( + 'amount' => '13.00', + 'ach' => $this->getValidAch(), + 'transactionId' => 'order2', + 'currency' => 'USD', + 'testMode' => true, + ); + } + + public function testPurchaseAchSuccess() + { + $this->setMockHttpResponse('PurchaseAchSuccess.txt'); + + $response = $this->gateway->purchase($this->options)->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertFalse($response->isRedirect()); + $this->assertEquals('ET173315::4549770020', $response->getTransactionReference()); + $this->assertEquals('000027', $response->getSequenceNo()); + $this->assertEmpty($response->getCardReference()); + } + + public function testAuthorizeSuccess() + { + $this->setMockHttpResponse('PurchaseAchSuccess.txt'); + + $response = $this->gateway->authorize($this->options)->send(); + + $this->assertTrue($response->isSuccessful()); + $this->assertFalse($response->isRedirect()); + $this->assertEquals('ET173315::4549770020', $response->getTransactionReference()); + } + + public function testPurchaseFailureMissingAmount(){ + + $this->expectException(InvalidRequestException::class); + + unset($this->options['amount']); + $response = $this->gateway->purchase($this->options)->send(); + } + + public function testPurchaseFailureInvalidAch(){ + $this->expectException(InvalidAchException::class); + $this->options['ach'] = new Ach([ + 'firstName' => 'Example', + 'lastName' => 'User', + ]); + $response = $this->gateway->purchase($this->options)->send(); + } + + public function testPurchaseAchWithLicense(){ + $this->options['ach'] = $this->getValidAch(); + $this->options['ach']['license'] = "123456"; + $this->options['ach']['license_state'] = "PA"; + $request = $this->gateway->purchase($this->options)->getData(); + + $this->assertEquals($request['customer_id_type'],0); + $this->assertEquals($request['customer_id_number'],"123456"); + } + + + + public function testPurchaseAchWithSsn(){ + $this->options['ach'] = $this->getValidAch(); + $this->options['ach']['ssn'] = "123456789"; + $request = $this->gateway->purchase($this->options)->getData(); + + $this->assertEquals($request['customer_id_type'],1); + $this->assertEquals($request['customer_id_number'],"123456789"); + } + + public function testPurchaseAchWithTaxId(){ + $this->options['ach'] = $this->getValidAch(); + $this->options['ach']['taxId'] = "123456"; + $request = $this->gateway->purchase($this->options)->getData(); + + $this->assertEquals($request['customer_id_type'],2); + $this->assertEquals($request['customer_id_number'],"123456"); + } + + public function testPurchaseAchWithMilitaryId(){ + $this->options['ach'] = $this->getValidAch(); + $this->options['ach']['militaryId'] = "123456"; + $request = $this->gateway->purchase($this->options)->getData(); + + $this->assertEquals($request['customer_id_type'],3); + $this->assertEquals($request['customer_id_number'],"123456"); + } + + public function testPurchaseAchWithMultipleAuths(){ + $ach = new Ach($this->getValidAch()); + $ach->setMilitaryId("123456"); + $ach->setLicense('ABCDEF'); + $this->options['ach'] = $ach; + $request = $this->gateway->purchase($this->options) + ->getData(); + + $this->assertEquals($request['customer_id_type'],0); + $this->assertEquals($request['customer_id_number'],"ABCDEF"); + } + + public function testPurchaseAchWithChangedAuths(){ + $ach = new Ach($this->getValidAch()); + $ach->setLicense('ABCDEF'); + $ach->setMilitaryId("123456"); + $ach->setLicense(null); + + $this->options['ach'] = $ach; + $request = $this->gateway->purchase($this->options) + ->getData(); + + $this->assertEquals($request['customer_id_type'],3); + $this->assertEquals($request['customer_id_number'],"123456"); + } + + public function testPurchaseAchWithRemovedAuth(){ + $ach = new Ach($this->getValidAch()); + $ach->setLicense('ABCDEF'); + $ach->setLicense(NULL); + + $this->options['ach'] = $ach; + $request = $this->gateway->purchase($this->options) + ->getData(); + + $this->assertFalse(isset($request['customer_id_type'])); + $this->assertFalse(isset($request['customer_id_number'])); + } + + + /** + * Helper method used by gateway test classes to generate a valid test credit card + */ + private function getValidAch() + { + return array( + 'firstName' => 'Example', + 'lastName' => 'User', + 'routingNumber' => '021000021', + 'accountNumber' => '123456789', + 'checkNumber' => rand(100,999), + 'billingAddress1' => '123 Billing St', + 'billingAddress2' => 'Billsville', + 'billingCity' => 'Billstown', + 'billingPostcode' => '12345', + 'billingState' => 'CA', + 'billingCountry' => 'US', + 'billingPhone' => '(555) 123-4567', + 'shippingAddress1' => '123 Shipping St', + 'shippingAddress2' => 'Shipsville', + 'shippingCity' => 'Shipstown', + 'shippingPostcode' => '54321', + 'shippingState' => 'NY', + 'shippingCountry' => 'US', + 'shippingPhone' => '(555) 987-6543', + ); + } +} diff --git a/tests/PayeezyGatewayTest.php b/tests/PayeezyGatewayTest.php index 340548b..5d13bd9 100644 --- a/tests/PayeezyGatewayTest.php +++ b/tests/PayeezyGatewayTest.php @@ -81,4 +81,5 @@ public function testPurchaseFailureInvalidCard(){ ]); $response = $this->gateway->purchase($this->options)->send(); } + } From 807941ba204b3b55a747a0ae7ab5d34d9f5732ea Mon Sep 17 00:00:00 2001 From: Nick Caruso Date: Wed, 21 Oct 2020 15:05:33 -0400 Subject: [PATCH 6/6] upgrade api to version 31. No breaking changed --- composer.json | 2 +- src/Message/PayeezyAbstractRequest.php | 2 +- tests/Message/PayeezyAuthorizeRequestTest.php | 2 +- tests/Message/PayeezyPurchaseRequestTest.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 7682135..5b720fe 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "nmc9/omnipay-firstdata", + "name": "omnipay/omnipay-firstdata", "type": "library", "description": "First Data driver for the Omnipay payment processing library that includes ACH", "keywords": [ diff --git a/src/Message/PayeezyAbstractRequest.php b/src/Message/PayeezyAbstractRequest.php index 94d2be3..47b06f5 100644 --- a/src/Message/PayeezyAbstractRequest.php +++ b/src/Message/PayeezyAbstractRequest.php @@ -20,7 +20,7 @@ abstract class PayeezyAbstractRequest extends \Omnipay\Common\Message\AbstractRe const CONTENT_TYPE = 'application/json; charset=UTF-8'; /** API version to use. See the note about the hashing requirements for v12 or higher. */ - protected $apiVersion = 14; + protected $apiVersion = 31; /** @var string live endpoint URL base */ protected $liveEndpoint = 'https://api.globalgatewaye4.firstdata.com/transaction/'; diff --git a/tests/Message/PayeezyAuthorizeRequestTest.php b/tests/Message/PayeezyAuthorizeRequestTest.php index d7dd3b5..42f3b6e 100644 --- a/tests/Message/PayeezyAuthorizeRequestTest.php +++ b/tests/Message/PayeezyAuthorizeRequestTest.php @@ -36,7 +36,7 @@ public function testAuthorizeSuccess() 'card' => $this->getValidCard(), ) ); - $this->assertEquals(14,$request->getApiVersion()); + $this->assertEquals(31,$request->getApiVersion()); $data = $request->getData(); $this->assertEquals('01', $data['transaction_type']); diff --git a/tests/Message/PayeezyPurchaseRequestTest.php b/tests/Message/PayeezyPurchaseRequestTest.php index 93b99cc..0f9508f 100644 --- a/tests/Message/PayeezyPurchaseRequestTest.php +++ b/tests/Message/PayeezyPurchaseRequestTest.php @@ -35,7 +35,7 @@ public function testPurchaseSuccess() 'card' => $this->getValidCard(), ]); - $this->assertEquals(14,$request->getApiVersion()); + $this->assertEquals(31,$request->getApiVersion()); $data = $request->getData(); $this->assertEquals('00', $data['transaction_type']); $this->assertEquals('4111111111111111', $data['cc_number']);