├── .gitignore
├── .styleci.yml
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── composer.json
├── phpunit.xml.dist
├── runtests-win.sh
├── runtests.sh
├── src
├── ConnectGateway.php
├── GlobalGateway.php
├── Message
│ ├── CompletePurchaseRequest.php
│ ├── CompletePurchaseResponse.php
│ ├── PayeezyAbstractRequest.php
│ ├── PayeezyAuthorizeRequest.php
│ ├── PayeezyCaptureRequest.php
│ ├── PayeezyPurchaseRequest.php
│ ├── PayeezyRefundRequest.php
│ ├── PayeezyResponse.php
│ ├── PayeezyVoidRequest.php
│ ├── PurchaseRequest.php
│ ├── PurchaseResponse.php
│ ├── WebserviceAbstractRequest.php
│ ├── WebserviceAuthorizeRequest.php
│ ├── WebserviceCaptureRequest.php
│ ├── WebservicePurchaseRequest.php
│ ├── WebserviceRefundRequest.php
│ ├── WebserviceResponse.php
│ └── WebserviceVoidRequest.php
├── PayeezyGateway.php
└── WebserviceGateway.php
└── tests
├── GatewayTest.php
├── Message
├── CompletePurchaseResponseTest.php
├── PayeezyAuthorizeRequestTest.php
├── PayeezyPurchaseRequestTest.php
├── PayeezyPurchaseResponseTest.php
├── PayeezyRefundRequestTest.php
├── PurchaseResponseTest.php
├── WebserviceCaptureRequestTest.php
├── WebservicePurchaseRequestTest.php
├── WebserviceRefundRequestTest.php
└── WebserviceVoidRequestTest.php
├── Mock
├── PurchaseSuccess.txt
├── RefundError.txt
├── RefundSuccess.txt
└── WebservicePurchaseSuccess.txt
├── PayeezyGatewayTest.php
└── WebserviceGatewayTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | composer.lock
3 | composer.phar
4 | phpunit.xml
5 | .directory
6 | .idea
7 | /documents
8 | dirlist.app
9 | dirlist.cache
10 | dirlist.vendor
11 |
--------------------------------------------------------------------------------
/.styleci.yml:
--------------------------------------------------------------------------------
1 | preset: psr2
2 |
3 | risky: false
4 |
5 | linting: true
6 |
7 | enabled:
8 | - long_array_syntax
9 | - align_double_arrow
10 | - binary_operator_spaces
11 | - no_empty_statement
12 | - no_singleline_whitespace_before_semicolons
13 | - no_whitespace_in_blank_line
14 | - align_equals
15 | - not_operator_with_successor_space
16 | - linebreak_after_opening_tag
17 | - ordered_imports
18 |
19 | finder:
20 | exclude:
21 | - "tests"
22 | name:
23 | - "*.php"
24 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 5.6
5 | - 7.0
6 | - 7.1
7 | - 7.2
8 | - 7.3
9 |
10 | # This triggers builds to run on the new TravisCI infrastructure.
11 | # See: http://docs.travis-ci.com/user/workers/container-based-infrastructure/
12 | sudo: false
13 |
14 | ## Cache composer
15 | cache:
16 | directories:
17 | - $HOME/.composer/cache
18 |
19 | env:
20 | global:
21 | - symfony="*"
22 |
23 | matrix:
24 | include:
25 | - php: 5.6
26 | env: symfony="^2.1"
27 | - php: 5.6
28 | env: symfony="^3"
29 | - php: 7.1
30 | env: symfony="^4"
31 |
32 | install:
33 | - if [[ $symfony != '*' ]]; then travis_retry composer require symfony/http-foundation:${symfony} --no-update --no-interaction; fi
34 |
35 | script: composer install --prefer-dist --no-interaction
36 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | * Fork the project.
4 | * Make your feature addition or bug fix.
5 | * Add tests for it. This is important so I don't break it in a future version unintentionally.
6 | * Commit just the modifications, do not mess with the composer.json or CHANGELOG.md files.
7 | * Ensure your code is nicely formatted in the [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
8 | style and that all tests pass.
9 | * Send the pull request.
10 | * Check that the Travis CI build passed. If not, rinse and repeat.
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012-2013 Adrian Macneil
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Omnipay: First Data
2 |
3 | **First Data driver for the Omnipay PHP payment processing library**
4 |
5 | [](https://travis-ci.org/thephpleague/omnipay-firstdata)
6 | [](https://packagist.org/packages/omnipay/firstdata)
7 | [](https://packagist.org/packages/omnipay/firstdata)
8 |
9 | [Omnipay](https://github.com/thephpleague/omnipay) is a framework agnostic, multi-gateway payment
10 | processing library for PHP. This package implements First Data support for Omnipay.
11 |
12 | ## Installation
13 |
14 | Omnipay is installed via [Composer](http://getcomposer.org/). To install, simply add it
15 | to your `composer.json` file:
16 |
17 | ```json
18 | {
19 | "require": {
20 | "omnipay/firstdata": "~3.0"
21 | }
22 | }
23 | ```
24 |
25 | And run composer to update your dependencies:
26 |
27 | $ curl -s http://getcomposer.org/installer | php
28 | $ php composer.phar update
29 |
30 | ## Basic Usage
31 |
32 | The following gateways are provided by this package:
33 |
34 | * FirstData_Connect
35 | * FirstData_Webservice
36 | * FirstData_Payeezy
37 |
38 | For general usage instructions, please see the main [Omnipay](https://github.com/thephpleague/omnipay)
39 | repository.
40 |
41 | ## References
42 |
43 | First Data Corporation is a global payment technology solutions company headquartered in Atlanta, Georgia,
44 | United States. First Data Corporation was incorporated in 1971. In 1980, American Express Information
45 | Services Corporation (ISC) bought 80% of First Data. First Data Corporation spun off from American Express
46 | and went public in 1992.
47 |
48 | The First Data Global Gateway Connect 2.0 is a simple payment solution for connecting an online store to
49 | the First Data Global Gateway. It provides redirect based payments (purchase() method with a corresponding
50 | completePurchase() method). It is referred to here as the "First Data Connect" gateway, currently at
51 | version 2.0.
52 |
53 | The Global Gateway was originally called the LinkPoint Gateway but since First Data's acquisition of
54 | LinkPoint it is now known as the First Data Global Gateway. As of this writing the Global Gateway version
55 | 9.0 is supported. It is referred to here as the "First Data Webservice" gateway, more correctly speaking
56 | it is the "First Data Global Web Services API", currently at version 9.0
57 |
58 | The First Data Global Gateway e4 (previously referred to as "First Data Global", and so if you see
59 | internet references to the First Data Global Gateway, they are probably referring to this one, distinguished
60 | by having URLs like "api.globalgatewaye4.firstdata.com") is now called the Payeezy Gateway and is
61 | referred to here as the "First Data Payeezy" Gateway.
62 |
63 | The Connect, Global, and Payeezy gateways are implemented here although each have gone through a number
64 | of API changes since their initial releases.
65 |
66 | The First Data APIs are listed here:
67 |
68 | https://www.firstdata.com/en_us/customer-center/merchants/first-data-global-gateway-api-software-landing.html
69 |
70 | ### First Data Connect 2.0
71 |
72 | The First Data Connect 2.0 Integration guide is here:
73 |
74 | https://www.firstdata.com/downloads/pdf/FDGG_Connect_2.0_Integration_Manual_v2.0.pdf
75 |
76 | ### First Data Global Web Services API 9.0
77 |
78 | The Global Webservice API description is here:
79 |
80 | https://www.firstdata.com/downloads/pdf/FDGG_Web_Service_API_v9.0.pdf
81 |
82 | The API manual for an older (v1.1) version of the same can be found here:
83 |
84 | https://www.firstdata.com/downloads/marketing-merchant/fd_globalgatewayapi_usermanual.pdf
85 |
86 | Reference code that implements connections to this gateway can be found at:
87 |
88 | * http://ashokks.com/First-Data-Global-Gateway-Web-Service-API-Complete-PHP-Example
89 |
90 | # First Data Payeezy Gateway
91 |
92 | API details for the Payeezy gateway are here:
93 |
94 | https://support.payeezy.com/hc/en-us
95 |
96 | and here:
97 |
98 | https://support.payeezy.com/hc/en-us/articles/204029989-First-Data-Payeezy-Gateway-Web-Service-API-Reference-Guide-
99 |
100 | Reference code that implements connections to this gateway can be found at:
101 |
102 | * https://github.com/VinceG/php-first-data-api
103 | * https://github.com/loganhenson/firstdata
104 |
105 | ## Support
106 |
107 | If you are having general issues with Omnipay, we suggest posting on
108 | [Stack Overflow](http://stackoverflow.com/). Be sure to add the
109 | [omnipay tag](http://stackoverflow.com/questions/tagged/omnipay) so it can be easily found.
110 |
111 | If you want to keep up to date with release anouncements, discuss ideas for the project,
112 | or ask more detailed questions, there is also a [mailing list](https://groups.google.com/forum/#!forum/omnipay) which
113 | you can subscribe to.
114 |
115 | If you believe you have found a bug, please report it using the [GitHub issue tracker](https://github.com/thephpleague/omnipay-firstdata/issues),
116 | or better yet, fork the library and submit a pull request.
117 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "omnipay/firstdata",
3 | "type": "library",
4 | "description": "First Data driver for the Omnipay payment processing library",
5 | "keywords": [
6 | "first data",
7 | "firstdata",
8 | "gateway",
9 | "merchant",
10 | "omnipay",
11 | "pay",
12 | "payment"
13 | ],
14 | "homepage": "https://github.com/thephpleague/omnipay-firstdata",
15 | "license": "MIT",
16 | "authors": [
17 | {
18 | "name": "Adrian Macneil",
19 | "email": "adrian@adrianmacneil.com"
20 | },
21 | {
22 | "name": "Omnipay Contributors",
23 | "homepage": "https://github.com/thephpleague/omnipay-firstdata/contributors"
24 | }
25 | ],
26 | "autoload": {
27 | "psr-4": { "Omnipay\\FirstData\\" : "src/" }
28 | },
29 | "require": {
30 | "php": "^5.6|^7",
31 | "omnipay/common": "~3.0",
32 | "php-http/guzzle6-adapter": "^1.1"
33 | },
34 | "require-dev": {
35 | "omnipay/tests": "~3.1"
36 | },
37 | "extra": {
38 | "branch-alias": {
39 | "dev-master": "3.0.x-dev"
40 | }
41 | },
42 | "prefer-stable": true
43 | }
44 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 | ./tests/
15 |
16 |
17 |
18 |
19 | ./src
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/runtests-win.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Command line runner for unit tests for composer projects
5 | # (c) Del 2015 http://www.babel.com.au/
6 | # No Rights Reserved
7 | #
8 |
9 | #
10 | # Ensure that dependencies are installed (including codeception and phpunit)
11 | #
12 | if [ -f composer.lock ]; then
13 | composer install
14 | else
15 | composer update
16 | fi
17 |
18 | #
19 | # Clean up after any previous test runs
20 | #
21 | mkdir -p documents
22 | rm -rf documents/coverage-html-new
23 | rm -f documents/coverage.xml
24 |
25 | #
26 | # Run phpunit
27 | #
28 | vendor/bin/phpunit --coverage-html documents/coverage-html-new --coverage-clover documents/coverage.xml --log-junit documents/phpunit.xml
29 |
30 | if [ -d documents/coverage-html-new ]; then
31 | rm -rf documents/coverage-html
32 | mv documents/coverage-html-new documents/coverage-html
33 | fi
34 |
35 |
--------------------------------------------------------------------------------
/runtests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Command line runner for unit tests for composer projects
5 | # (c) Del 2015 http://www.babel.com.au/
6 | # No Rights Reserved
7 | #
8 |
9 | #
10 | # Ensure that dependencies are installed (including codeception and phpunit)
11 | #
12 | if [ -f composer.lock ]; then
13 | /usr/local/bin/composer install
14 | else
15 | /usr/local/bin/composer update
16 | fi
17 |
18 | #
19 | # Clean up after any previous test runs
20 | #
21 | mkdir -p documents
22 | rm -rf documents/coverage-html-new
23 | rm -f documents/coverage.xml
24 |
25 | #
26 | # Run phpunit
27 | #
28 | vendor/bin/phpunit --coverage-html documents/coverage-html-new --coverage-clover documents/coverage.xml --log-junit documents/phpunit.xml
29 |
30 | if [ -d documents/coverage-html-new ]; then
31 | rm -rf documents/coverage-html
32 | mv documents/coverage-html-new documents/coverage-html
33 | fi
34 |
35 |
--------------------------------------------------------------------------------
/src/ConnectGateway.php:
--------------------------------------------------------------------------------
1 |
59 | * // Create a gateway for the First Data Connect Gateway
60 | * // (routes to GatewayFactory::create)
61 | * $gateway = Omnipay::create('FirstData_Connect');
62 | *
63 | * // Initialise the gateway
64 | * $gateway->initialize(array(
65 | * 'storeId' => '12341234',
66 | * 'sharedSecret' => 'IcantTELLyouITSaSECRET',
67 | * 'testMode' => true, // Or false when you are ready for live transactions
68 | * ));
69 | *
70 | * // Do a purchase transaction on the gateway
71 | * $transaction = $gateway->purchase(array(
72 | * 'description' => 'Your order for widgets',
73 | * 'amount' => '10.00',
74 | * 'transactionId' => 12345,
75 | * ));
76 | * $response = $transaction->send();
77 | * if ($response->isSuccessful()) {
78 | * echo "Purchase transaction was successful!\n";
79 | * $sale_id = $response->getTransactionReference();
80 | * echo "Transaction reference = " . $sale_id . "\n";
81 | * }
82 | *
83 | *
84 | * @link https://www.firstdata.com/downloads/pdf/FDGG_Connect_2.0_Integration_Manual_v2.0.pdf
85 | */
86 | class ConnectGateway extends AbstractGateway
87 | {
88 | public function getName()
89 | {
90 | return 'First Data Connect';
91 | }
92 |
93 | public function getDefaultParameters()
94 | {
95 | return array(
96 | 'storeId' => '',
97 | 'sharedSecret' => '',
98 | 'testMode' => false,
99 | );
100 | }
101 |
102 | /**
103 | * Set Store ID
104 | *
105 | * Calls to the Connect Gateway API are secured with a store ID and
106 | * shared secret.
107 | *
108 | * @return ConnectGateway provides a fluent interface
109 | */
110 | public function setStoreId($value)
111 | {
112 | return $this->setParameter('storeId', $value);
113 | }
114 |
115 | /**
116 | * Get Store ID
117 | *
118 | * Calls to the Connect Gateway API are secured with a store ID and
119 | * shared secret.
120 | *
121 | * @return string
122 | */
123 | public function getStoreId()
124 | {
125 | return $this->getParameter('storeId');
126 | }
127 |
128 | /**
129 | * Set Shared Secret
130 | *
131 | * Calls to the Connect Gateway API are secured with a store ID and
132 | * shared secret.
133 | *
134 | * @return ConnectGateway provides a fluent interface
135 | */
136 | public function setSharedSecret($value)
137 | {
138 | return $this->setParameter('sharedSecret', $value);
139 | }
140 |
141 | /**
142 | * Get Shared Secret
143 | *
144 | * Calls to the Connect Gateway API are secured with a store ID and
145 | * shared secret.
146 | *
147 | * @return string
148 | */
149 | public function getSharedSecret()
150 | {
151 | return $this->getParameter('sharedSecret');
152 | }
153 |
154 | /**
155 | * Create a purchase request.
156 | *
157 | * @param array $parameters
158 | * @return \Omnipay\FirstData\Message\PurchaseRequest
159 | */
160 | public function purchase(array $parameters = array())
161 | {
162 | return $this->createRequest('\Omnipay\FirstData\Message\PurchaseRequest', $parameters);
163 | }
164 |
165 | /**
166 | * Create a complete purchase request.
167 | *
168 | * @param array $parameters
169 | * @return \Omnipay\FirstData\Message\CompletePurchaseRequest
170 | */
171 | public function completePurchase(array $parameters = array())
172 | {
173 | return $this->createRequest('\Omnipay\FirstData\Message\CompletePurchaseRequest', $parameters);
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/src/GlobalGateway.php:
--------------------------------------------------------------------------------
1 | httpRequest->request->get('response_hash');
18 | $dateTime = (string) $this->httpRequest->request->get('txndatetime');
19 | $amount = (string) $this->httpRequest->request->get('chargetotal');
20 | $code = (string) $this->httpRequest->request->get('approval_code');
21 | $ourHash = $this->createResponseHash($amount, $dateTime, $code);
22 | if ($theirHash !== $ourHash) {
23 | throw new InvalidResponseException("Callback hash does not match expected value");
24 | }
25 |
26 | return $this->httpRequest->request->all();
27 | }
28 |
29 | public function sendData($data)
30 | {
31 | return $this->response = new CompletePurchaseResponse($this, $data);
32 | }
33 |
34 | /**
35 | * Generate a hash string that matches the format of the one returned by the payment gateway
36 | *
37 | * @param string $amount
38 | * @param string $dateTime
39 | * @param string $code
40 | * @return string
41 | */
42 | public function createResponseHash($amount, $dateTime, $code)
43 | {
44 | $this->validate('storeId', 'sharedSecret', 'currency');
45 |
46 | $storeId = $this->getStoreId();
47 | $sharedSecret = $this->getSharedSecret();
48 | $currency = $this->getCurrencyNumeric();
49 |
50 | $stringToHash = $sharedSecret . $code . $amount . $currency . $dateTime . $storeId;
51 | $ascii = bin2hex($stringToHash);
52 |
53 | return sha1($ascii);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Message/CompletePurchaseResponse.php:
--------------------------------------------------------------------------------
1 | data['status']) && $this->data['status'] == 'APPROVED';
18 | }
19 |
20 | public function getTransactionId()
21 | {
22 | return isset($this->data['oid']) ? $this->data['oid'] : null;
23 | }
24 |
25 | public function getTransactionReference()
26 | {
27 | return isset($this->data['refnumber']) ? $this->data['refnumber'] : null;
28 | }
29 |
30 | public function getMessage()
31 | {
32 | return isset($this->data['status']) ? $this->data['status'] : null;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Message/PayeezyAbstractRequest.php:
--------------------------------------------------------------------------------
1 | 'Visa',
54 | 'mastercard' => 'Mastercard',
55 | 'discover' => 'Discover',
56 | 'amex' => 'American Express',
57 | 'diners_club' => 'Diners Club',
58 | 'jcb' => 'JCB',
59 | );
60 |
61 | /**
62 | * Get Gateway ID
63 | *
64 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
65 | * password.
66 | *
67 | * @return string
68 | */
69 | public function getGatewayId()
70 | {
71 | return $this->getParameter('gatewayId');
72 | }
73 |
74 | /**
75 | * Set Gateway ID
76 | *
77 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
78 | * password.
79 | *
80 | * @return PayeezyAbstractRequest provides a fluent interface.
81 | */
82 | public function setGatewayId($value)
83 | {
84 | return $this->setParameter('gatewayId', $value);
85 | }
86 |
87 | /**
88 | * Get Password
89 | *
90 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
91 | * password.
92 | *
93 | * @return string
94 | */
95 | public function getPassword()
96 | {
97 | return $this->getParameter('password');
98 | }
99 |
100 | /**
101 | * Set Password
102 | *
103 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
104 | * password.
105 | *
106 | * @return PayeezyAbstractRequest provides a fluent interface.
107 | */
108 | public function setPassword($value)
109 | {
110 | return $this->setParameter('password', $value);
111 | }
112 |
113 | /**
114 | * Get Key Id
115 | *
116 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
117 | * password.
118 | *
119 | * @return mixed
120 | */
121 | public function getKeyId()
122 | {
123 | return $this->getParameter('keyId');
124 | }
125 |
126 | /**
127 | * Set Key Id
128 | *
129 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
130 | * password.
131 | *
132 | * @return PayeezyAbstractRequest provides a fluent interface.
133 | */
134 | public function setKeyId($value)
135 | {
136 | return $this->setParameter('keyId', $value);
137 | }
138 |
139 | /**
140 | * Get Hmac
141 | *
142 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
143 | * password.
144 | *
145 | * @return mixed
146 | */
147 | public function getHmac()
148 | {
149 | return $this->getParameter('hmac');
150 | }
151 |
152 | /**
153 | * Set Hmac
154 | *
155 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
156 | * password.
157 | *
158 | * @return PayeezyAbstractRequest provides a fluent interface.
159 | */
160 | public function setHmac($value)
161 | {
162 | return $this->setParameter('hmac', $value);
163 | }
164 |
165 | /**
166 | * Set transaction type
167 | *
168 | * @param int $transactionType
169 | *
170 | * @return PayeezyAbstractRequest provides a fluent interface.
171 | */
172 | public function setTransactionType($transactionType)
173 | {
174 | $this->transactionType = $transactionType;
175 | return $this;
176 | }
177 |
178 | /**
179 | * Get transaction type
180 | *
181 | * @return int
182 | */
183 | public function getTransactionType()
184 | {
185 | return $this->transactionType;
186 | }
187 |
188 | /**
189 | * Get the base transaction data.
190 | *
191 | * @return array
192 | */
193 | protected function getBaseData()
194 | {
195 | $data = array();
196 | $data['gateway_id'] = $this->getGatewayID();
197 | $data['password'] = $this->getPassword();
198 | $data['transaction_type'] = $this->getTransactionType();
199 |
200 | return $data;
201 | }
202 |
203 | /**
204 | * Get the transaction headers.
205 | *
206 | * @return array
207 | */
208 | protected function getHeaders()
209 | {
210 | return array(
211 | 'Content-Type' => self::CONTENT_TYPE,
212 | 'Accept' => 'application/json'
213 | );
214 | }
215 |
216 | /**
217 | * @return string
218 | */
219 | protected function getGge4Date()
220 | {
221 | return gmdate("Y-m-d") . 'T' . gmdate("H:i:s") . 'Z';
222 | }
223 |
224 | /**
225 | * Composes the hash string needed for the newer versions of the API
226 | *
227 | * @param $contentDigest
228 | * @param $gge4Date
229 | * @param $uri
230 | *
231 | * @return string
232 | */
233 | protected function buildHashString($contentDigest, $gge4Date, $uri)
234 | {
235 | return sprintf(
236 | "%s\n%s\n%s\n%s\n%s",
237 | self::METHOD_POST,
238 | self::CONTENT_TYPE,
239 | $contentDigest,
240 | $gge4Date,
241 | $uri
242 | );
243 | }
244 |
245 | /**
246 | * Composes the auth string needed for the newer versions of the API
247 | *
248 | * @param $hashString
249 | *
250 | * @return string
251 | */
252 | protected function buildAuthString($hashString)
253 | {
254 | return sprintf(
255 | 'GGE4_API %s:%s',
256 | $this->getKeyId(),
257 | base64_encode(hash_hmac("sha1", $hashString, $this->getHmac(), true))
258 | );
259 | }
260 |
261 | /**
262 | * Get the card type name, from the card type code.
263 | *
264 | * @param string $type
265 | *
266 | * @return string
267 | */
268 | public static function getCardType($type)
269 | {
270 | if (isset(self::$cardTypes[$type])) {
271 | return self::$cardTypes[$type];
272 | }
273 | return $type;
274 | }
275 |
276 | /**
277 | * Get the AVS Hash.
278 | *
279 | * Important Note about v12 or higher of the Web Service API: Merchants wishing to use
280 | * V12 or higher of the API must implement the API HMAC hash security calculation.
281 | * Further information on this subject can be found at the link below.
282 | *
283 | * @link https://support.payeezy.com/entries/22069302-api-security-hmac-hash
284 | *
285 | * @return string
286 | */
287 | public function getAVSHash()
288 | {
289 | $parts = array();
290 | $parts[] = $this->getCard()->getAddress1();
291 | $parts[] = $this->getCard()->getPostcode();
292 | $parts[] = $this->getCard()->getCity();
293 | $parts[] = $this->getCard()->getState();
294 | $parts[] = $this->getCard()->getCountry();
295 | return implode('|', $parts);
296 | }
297 |
298 | /**
299 | * @return array
300 | */
301 | public function getData()
302 | {
303 | $this->setTransactionType($this->action);
304 | $data = $this->getBaseData();
305 | return $data;
306 | }
307 |
308 | /**
309 | * @param mixed $data
310 | *
311 | * @return PayeezyResponse
312 | */
313 | public function sendData($data)
314 | {
315 | $headers = $this->getHeaders();
316 | $gge4Date = $this->getGge4Date();
317 | $endpoint = $this->getEndpoint();
318 |
319 | $url = parse_url($endpoint);
320 |
321 | $contentDigest = sha1(json_encode($data));
322 |
323 | $hashString = $this->buildHashString($contentDigest, $gge4Date, $url['path']);
324 |
325 | $authString = $this->buildAuthString($hashString);
326 |
327 | $headers["X-GGe4-Content-SHA1"] = $contentDigest;
328 | $headers["X-GGe4-Date"] = $gge4Date;
329 | $headers["Authorization"] = $authString;
330 |
331 | $httpResponse = $this->httpClient->request(
332 | self::METHOD_POST,
333 | $endpoint,
334 | $headers,
335 | json_encode($data)
336 | );
337 |
338 | return $this->createResponse($httpResponse->getBody()->getContents());
339 | }
340 |
341 | /**
342 | * Get the endpoint URL for the request.
343 | *
344 | * @return string
345 | */
346 | protected function getEndpoint()
347 | {
348 | return ($this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint) . self::API_VERSION;
349 | }
350 |
351 | /**
352 | * Create the response object.
353 | *
354 | * @param $data
355 | *
356 | * @return PayeezyResponse
357 | */
358 | protected function createResponse($data)
359 | {
360 | return $this->response = new PayeezyResponse($this, $data);
361 | }
362 | }
363 |
--------------------------------------------------------------------------------
/src/Message/PayeezyAuthorizeRequest.php:
--------------------------------------------------------------------------------
1 |
13 | * // Create a gateway for the First Data Payeezy Gateway
14 | * // (routes to GatewayFactory::create)
15 | * $gateway = Omnipay::create('FirstData_Payeezy');
16 | *
17 | * // Initialise the gateway
18 | * $gateway->initialize(array(
19 | * 'gatewayId' => '12341234',
20 | * 'password' => 'thisISmyPASSWORD',
21 | * 'testMode' => true, // Or false when you are ready for live transactions
22 | * ));
23 | *
24 | * // Create a credit card object
25 | * $card = new CreditCard(array(
26 | * 'firstName' => 'Example',
27 | * 'lastName' => 'Customer',
28 | * 'number' => '4222222222222222',
29 | * 'expiryMonth' => '01',
30 | * 'expiryYear' => '2020',
31 | * 'cvv' => '123',
32 | * 'email' => 'customer@example.com',
33 | * 'billingAddress1' => '1 Scrubby Creek Road',
34 | * 'billingCountry' => 'AU',
35 | * 'billingCity' => 'Scrubby Creek',
36 | * 'billingPostcode' => '4999',
37 | * 'billingState' => 'QLD',
38 | * ));
39 | *
40 | * // Do a purchase transaction on the gateway
41 | * $transaction = $gateway->purchase(array(
42 | * 'description' => 'Your order for widgets',
43 | * 'amount' => '10.00',
44 | * 'transactionId' => 12345,
45 | * 'clientIp' => $_SERVER['REMOTE_ADDR'],
46 | * 'card' => $card,
47 | * ));
48 | *
49 | * // USE A TRANS-ARMOR TOKEN TO PROCESS A PURCHASE:
50 | *
51 | * // Create a credit card object
52 | * $card = new CreditCard(array(
53 | * 'firstName' => 'Example',
54 | * 'lastName' => 'Customer',
55 | * 'expiryMonth' => '01',
56 | * 'expiryYear' => '2020',
57 | * ));
58 | *
59 | * // Do a purchase transaction on the gateway
60 | * $transaction = $gateway->purchase(array(
61 | * 'description' => 'Your order for widgets',
62 | * 'amount' => '10.00',
63 | * 'cardReference' => $yourStoredToken,
64 | * 'clientIp' => $_SERVER['REMOTE_ADDR'],
65 | * 'card' => $card,
66 | * 'tokenCardType' => 'visa', // MUST BE VALID CONST FROM \omnipay\common\CreditCard
67 | * ));
68 | *
69 | *
70 | *
71 | *
72 | * $response = $transaction->send();
73 | * if ($response->isSuccessful()) {
74 | * echo "Purchase transaction was successful!\n";
75 | * $sale_id = $response->getTransactionReference();
76 | * echo "Transaction reference = " . $sale_id . "\n";
77 | * }
78 | *
79 | */
80 | class PayeezyPurchaseRequest extends PayeezyAbstractRequest
81 | {
82 | protected $action = self::TRAN_PURCHASE;
83 |
84 | public function getData()
85 | {
86 | $data = parent::getData();
87 |
88 | $this->validate('amount', 'card');
89 |
90 | $data['amount'] = $this->getAmount();
91 | $data['currency_code'] = $this->getCurrency();
92 | $data['reference_no'] = $this->getTransactionId();
93 |
94 | // add credit card details
95 | if ($this->getCardReference()) {
96 | $this->validate('tokenCardType');
97 | $data['transarmor_token'] = $this->getCardReference();
98 | $data['credit_card_type'] = $this->getTokenCardType();
99 | } else {
100 | $data['credit_card_type'] = self::getCardType($this->getCard()->getBrand());
101 | $data['cc_number'] = $this->getCard()->getNumber();
102 | $data['cc_verification_str2'] = $this->getCard()->getCvv();
103 | $data['cc_verification_str1'] = $this->getAVSHash();
104 | $data['cvd_presence_ind'] = 1;
105 | $data['cvd_code'] = $this->getCard()->getCvv();
106 | }
107 | $data['cardholder_name'] = $this->getCard()->getName();
108 | $data['cc_expiry'] = $this->getCard()->getExpiryDate('my');
109 |
110 |
111 | $data['client_ip'] = $this->getClientIp();
112 | $data['client_email'] = $this->getCard()->getEmail();
113 | $data['language'] = strtoupper($this->getCard()->getCountry());
114 |
115 | return $data;
116 | }
117 |
118 | public function getTokenCardType()
119 | {
120 | return $this->getParameter('tokenCardType');
121 | }
122 |
123 | public function setTokenCardType($value)
124 | {
125 | return $this->setParameter('tokenCardType', $value);
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/Message/PayeezyRefundRequest.php:
--------------------------------------------------------------------------------
1 | validate('transactionReference', 'amount');
20 |
21 | $data['amount'] = $this->getAmount();
22 | $transaction_reference = $this->getTransactionReference();
23 | list($auth, $tag) = explode('::', $transaction_reference);
24 | $data['authorization_num'] = $auth;
25 | $data['transaction_tag'] = $tag;
26 |
27 | return $data;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Message/PayeezyResponse.php:
--------------------------------------------------------------------------------
1 | request = $request;
28 | $this->data = json_decode($data, true);
29 | }
30 |
31 | public function isSuccessful()
32 | {
33 | return ($this->data['transaction_approved'] == '1') ? true : false;
34 | }
35 |
36 | /**
37 | * Get an item from the internal data array
38 | *
39 | * This is a short cut function to ensure that we test that the item
40 | * exists in the data array before we try to retrieve it.
41 | *
42 | * @param $itemname
43 | * @return mixed|null
44 | */
45 | public function getDataItem($itemname)
46 | {
47 | if (isset($this->data[$itemname])) {
48 | return $this->data[$itemname];
49 | }
50 |
51 | return null;
52 | }
53 |
54 | /**
55 | * Get the authorization number
56 | *
57 | * This is the authorization number returned by the cardholder’s financial
58 | * institution when a transaction has been approved. This value overrides any
59 | * value sent for the Request Property of the same name.
60 | *
61 | * @return integer
62 | */
63 | public function getAuthorizationNumber()
64 | {
65 | return $this->getDataItem('authorization_num');
66 | }
67 |
68 | /**
69 | * Get the transaction tag.
70 | *
71 | * A unique identifier to associate with a tagged transaction. This value overrides
72 | * any value sent for the Request Property of the same name.
73 | *
74 | * @return string
75 | */
76 | public function getTransactionTag()
77 | {
78 | return $this->getDataItem('transaction_tag');
79 | }
80 |
81 | /**
82 | * Get the transaction reference
83 | *
84 | * Because refunding or voiding a transaction requires both the authorization number
85 | * and the transaction tag, we concatenate them together to make the transaction
86 | * reference.
87 | *
88 | * @return string
89 | */
90 | public function getTransactionReference()
91 | {
92 | return $this->getAuthorizationNumber() . '::' . $this->getTransactionTag();
93 | }
94 |
95 | /**
96 | * Get the transaction sequence number.
97 | *
98 | * A digit sequentially incremented number generated by Global Gateway e4 and passed
99 | * through to the financial institution. It is also passed back to the client in the
100 | * transaction response. This number can be used for tracking and audit purposes.
101 | *
102 | * @return string
103 | */
104 | public function getSequenceNo()
105 | {
106 | return $this->getDataItem('sequence_no');
107 | }
108 |
109 | /**
110 | * Get the credit card reference for a completed transaction.
111 | *
112 | * This is only provided if TransArmor processing is turned on for the gateway.
113 | *
114 | * @return string
115 | */
116 | public function getCardReference()
117 | {
118 | return $this->getDataItem('transarmor_token');
119 | }
120 |
121 | public function getMessage()
122 | {
123 | return $this->getDataItem('exact_message');
124 | }
125 |
126 | /**
127 | * Get the error code.
128 | *
129 | * This property indicates the processing status of the transaction. Please refer
130 | * to the section on Exception Handling for further information. The Transaction_Error
131 | * property will return True if this property is not “00”.
132 | *
133 | * @return string
134 | */
135 | public function getCode()
136 | {
137 | return $this->getDataItem('exact_resp_code');
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/src/Message/PayeezyVoidRequest.php:
--------------------------------------------------------------------------------
1 | setParameter('storeId', $value);
35 | }
36 |
37 | /**
38 | * Get Store ID
39 | *
40 | * Calls to the Connect Gateway API are secured with a store ID and
41 | * shared secret.
42 | *
43 | * @return string
44 | */
45 | public function getStoreId()
46 | {
47 | return $this->getParameter('storeId');
48 | }
49 |
50 | /**
51 | * Set Shared Secret
52 | *
53 | * Calls to the Connect Gateway API are secured with a store ID and
54 | * shared secret.
55 | *
56 | * @return PurchaseRequest provides a fluent interface
57 | */
58 | public function setSharedSecret($value)
59 | {
60 | return $this->setParameter('sharedSecret', $value);
61 | }
62 |
63 | /**
64 | * Get Shared Secret
65 | *
66 | * Calls to the Connect Gateway API are secured with a store ID and
67 | * shared secret.
68 | *
69 | * @return string
70 | */
71 | public function getSharedSecret()
72 | {
73 | return $this->getParameter('sharedSecret');
74 | }
75 |
76 | public function setHostedDataId($value)
77 | {
78 | return $this->setParameter('hostedDataId', $value);
79 | }
80 |
81 | public function getHostedDataId()
82 | {
83 | return $this->getParameter('hostedDataId');
84 | }
85 |
86 | public function setCustomerId($value)
87 | {
88 | return $this->setParameter('customerId', $value);
89 | }
90 |
91 | public function getCustomerId()
92 | {
93 | return $this->getParameter('customerId');
94 | }
95 |
96 | public function getData()
97 | {
98 | $this->validate('amount', 'card');
99 |
100 | $data = array();
101 | $data['storename'] = $this->getStoreId();
102 | $data['txntype'] = 'sale';
103 | $data['timezone'] = 'GMT';
104 | $data['chargetotal'] = $this->getAmount();
105 | $data['txndatetime'] = $this->getDateTime();
106 | $data['hash'] = $this->createHash($data['txndatetime'], $data['chargetotal']);
107 | $data['currency'] = $this->getCurrencyNumeric();
108 | $data['mode'] = 'payonly';
109 | $data['full_bypass'] = 'true';
110 | $data['oid'] = $this->getParameter('transactionId');
111 |
112 | // If no hosted data, or a number is passed, validate the whole card
113 | if (is_null($this->getHostedDataId()) || ! is_null($this->getCard()->getNumber())) {
114 | $this->getCard()->validate();
115 | } elseif (is_null($this->getCard()->getCvv())) {
116 | // Else we only require the cvv when using hosted data
117 | throw new InvalidCreditCardException("The CVV parameter is required when using hosteddataid");
118 | }
119 |
120 | $data['cardnumber'] = $this->getCard()->getNumber();
121 | $data['cvm'] = $this->getCard()->getCvv();
122 | $data['expmonth'] = $this->getCard()->getExpiryDate('m');
123 | $data['expyear'] = $this->getCard()->getExpiryDate('y');
124 |
125 | $data['bname'] = $this->getCard()->getBillingName();
126 | $data['baddr1'] = $this->getCard()->getBillingAddress1();
127 | $data['baddr2'] = $this->getCard()->getBillingAddress2();
128 | $data['bcity'] = $this->getCard()->getBillingCity();
129 | $data['bstate'] = $this->getCard()->getBillingState();
130 | $data['bcountry'] = $this->getCard()->getBillingCountry();
131 | $data['bzip'] = $this->getCard()->getBillingPostcode();
132 |
133 | $data['sname'] = $this->getCard()->getShippingName();
134 | $data['saddr1'] = $this->getCard()->getShippingAddress1();
135 | $data['saddr2'] = $this->getCard()->getShippingAddress2();
136 | $data['scity'] = $this->getCard()->getShippingCity();
137 | $data['sstate'] = $this->getCard()->getShippingState();
138 | $data['scountry'] = $this->getCard()->getShippingCountry();
139 | $data['szip'] = $this->getCard()->getShippingPostcode();
140 |
141 | $data['phone'] = $this->getCard()->getPhone();
142 | $data['email'] = $this->getCard()->getEmail();
143 |
144 | $data['responseSuccessURL'] = $this->getParameter('returnUrl');
145 | $data['responseFailURL'] = $this->getParameter('returnUrl');
146 |
147 | $data['customerid'] = $this->getCustomerId();
148 |
149 | $data['hosteddataid'] = $this->getHostedDataId();
150 |
151 | return $data;
152 | }
153 |
154 | /**
155 | * Returns a SHA-1 hash of the transaction data.
156 | *
157 | * @param $dateTime
158 | * @param $amount
159 | * @return string
160 | */
161 | public function createHash($dateTime, $amount)
162 | {
163 | $storeId = $this->getStoreId();
164 | $sharedSecret = $this->getSharedSecret();
165 | $currency = $this->getCurrencyNumeric();
166 | $stringToHash = $storeId . $dateTime . $amount . $currency . $sharedSecret;
167 | $ascii = bin2hex($stringToHash);
168 |
169 | return sha1($ascii);
170 | }
171 |
172 | public function sendData($data)
173 | {
174 | return $this->response = new PurchaseResponse($this, $data);
175 | }
176 |
177 | public function getEndpoint()
178 | {
179 | return $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint;
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/src/Message/PurchaseResponse.php:
--------------------------------------------------------------------------------
1 | getRequest()->getEndpoint();
31 | }
32 |
33 | public function getRedirectMethod()
34 | {
35 | return 'POST';
36 | }
37 |
38 | public function getRedirectData()
39 | {
40 | return $this->data;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Message/WebserviceAbstractRequest.php:
--------------------------------------------------------------------------------
1 |
33 |
34 |
35 | %xmlBody%
36 |
37 |
38 | ';
39 |
40 | /** @var string XML template for the purchase request */
41 | protected $xmlTemplate = '';
42 |
43 | /**
44 | * Get SSL Certificate file name
45 | *
46 | * You must establish a secure communication channel to send the HTTP request.
47 | * This ensures that the data sent between your client application and the First
48 | * Data Webservice Gateway Web Service API is encrypted and that both parties can
49 | * be sure they are communicating with each other and no one else.
50 | *
51 | * The Web Service API requires an SSL connection with client and server exchanging
52 | * certificates to guarantee this level of security. The client and server certificates
53 | * each uniquely identify the party.
54 | *
55 | * @return string
56 | */
57 | public function getSslCertificate()
58 | {
59 | return $this->getParameter('sslCertificate');
60 | }
61 |
62 | /**
63 | * Set SSL Certificate file name
64 | *
65 | * You must establish a secure communication channel to send the HTTP request.
66 | * This ensures that the data sent between your client application and the First
67 | * Data Webservice Gateway Web Service API is encrypted and that both parties can
68 | * be sure they are communicating with each other and no one else.
69 | *
70 | * The Web Service API requires an SSL connection with client and server exchanging
71 | * certificates to guarantee this level of security. The client and server certificates
72 | * each uniquely identify the party.
73 | *
74 | * @param string $value
75 | * @return WebserviceAbstractRequest provides a fluent interface.
76 | */
77 | public function setSslCertificate($value)
78 | {
79 | return $this->setParameter('sslCertificate', $value);
80 | }
81 |
82 | /**
83 | * Get SSL Key file name
84 | *
85 | * You must establish a secure communication channel to send the HTTP request.
86 | * This ensures that the data sent between your client application and the First
87 | * Data Webservice Gateway Web Service API is encrypted and that both parties can
88 | * be sure they are communicating with each other and no one else.
89 | *
90 | * The Web Service API requires an SSL connection with client and server exchanging
91 | * certificates to guarantee this level of security. The client and server certificates
92 | * each uniquely identify the party.
93 | *
94 | * @return string
95 | */
96 | public function getSslKey()
97 | {
98 | return $this->getParameter('sslKey');
99 | }
100 |
101 | /**
102 | * Set SSL Key file name
103 | *
104 | * You must establish a secure communication channel to send the HTTP request.
105 | * This ensures that the data sent between your client application and the First
106 | * Data Webservice Gateway Web Service API is encrypted and that both parties can
107 | * be sure they are communicating with each other and no one else.
108 | *
109 | * The Web Service API requires an SSL connection with client and server exchanging
110 | * certificates to guarantee this level of security. The client and server certificates
111 | * each uniquely identify the party.
112 | *
113 | * @param string $value
114 | * @return WebserviceAbstractRequest provides a fluent interface.
115 | */
116 | public function setSslKey($value)
117 | {
118 | return $this->setParameter('sslKey', $value);
119 | }
120 |
121 | /**
122 | * Get SSL Key password
123 | *
124 | * You must establish a secure communication channel to send the HTTP request.
125 | * This ensures that the data sent between your client application and the First
126 | * Data Webservice Gateway Web Service API is encrypted and that both parties can
127 | * be sure they are communicating with each other and no one else.
128 | *
129 | * The Web Service API requires an SSL connection with client and server exchanging
130 | * certificates to guarantee this level of security. The client and server certificates
131 | * each uniquely identify the party.
132 | *
133 | * @return string
134 | */
135 | public function getSslKeyPassword()
136 | {
137 | return $this->getParameter('sslKeyPassword');
138 | }
139 |
140 | /**
141 | * Set SSL Key password
142 | *
143 | * You must establish a secure communication channel to send the HTTP request.
144 | * This ensures that the data sent between your client application and the First
145 | * Data Webservice Gateway Web Service API is encrypted and that both parties can
146 | * be sure they are communicating with each other and no one else.
147 | *
148 | * The Web Service API requires an SSL connection with client and server exchanging
149 | * certificates to guarantee this level of security. The client and server certificates
150 | * each uniquely identify the party.
151 | *
152 | * @param string $value
153 | * @return WebserviceAbstractRequest provides a fluent interface.
154 | */
155 | public function setSslKeyPassword($value)
156 | {
157 | return $this->setParameter('sslKeyPassword', $value);
158 | }
159 |
160 | /**
161 | * Get Username
162 | *
163 | * Calls to the Webservice Gateway API are secured with a username and
164 | * password sent via HTTP Basic Authentication.
165 | *
166 | * @return string
167 | */
168 | public function getUserName()
169 | {
170 | return $this->getParameter('userName');
171 | }
172 |
173 | /**
174 | * Set Username
175 | *
176 | * Calls to the Webservice Gateway API are secured with a username and
177 | * password sent via HTTP Basic Authentication.
178 | *
179 | * @param string $value
180 | * @return WebserviceAbstractRequest provides a fluent interface.
181 | */
182 | public function setUserName($value)
183 | {
184 | return $this->setParameter('userName', $value);
185 | }
186 |
187 | /**
188 | * Get Password
189 | *
190 | * Calls to the Webservice Gateway API are secured with a username and
191 | * password sent via HTTP Basic Authentication.
192 | *
193 | * @return string
194 | */
195 | public function getPassword()
196 | {
197 | return $this->getParameter('password');
198 | }
199 |
200 | /**
201 | * Set Password
202 | *
203 | * Calls to the Webservice Gateway API are secured with a username and
204 | * password sent via HTTP Basic Authentication.
205 | *
206 | * @param string $value
207 | * @return WebserviceAbstractRequest provides a fluent interface.
208 | */
209 | public function setPassword($value)
210 | {
211 | return $this->setParameter('password', $value);
212 | }
213 |
214 | /**
215 | * Get the base transaction data.
216 | *
217 | * @return array
218 | */
219 | protected function getBaseData()
220 | {
221 | $data = array();
222 |
223 | return $data;
224 | }
225 |
226 | /**
227 | * Get the transaction headers.
228 | *
229 | * @return array
230 | */
231 | protected function getHeaders()
232 | {
233 | return array(
234 | 'Content-Type: text/xml'
235 | );
236 | }
237 |
238 | public function getData()
239 | {
240 | $data = $this->getBaseData();
241 | return $data;
242 | }
243 |
244 | /**
245 | * Build the cURL client.
246 | *
247 | * @return resource
248 | */
249 | public function buildCurlClient()
250 | {
251 | //
252 | // Use PHP Native cURL because the various Soap clients (BeSimple,
253 | // PHP native SoapClient) can't handle the WSDL file.
254 | //
255 | $this->curl = curl_init($this->getEndPoint());
256 |
257 | $sslCertificate = $this->getSslCertificate();
258 | $sslKey = $this->getSslKey();
259 | $sslKeyPassword = $this->getSslKeyPassword();
260 | $userName = $this->getUsername();
261 | $password = $this->getPassword();
262 | $headers = $this->getHeaders();
263 |
264 | // configuring cURL not to verify the server certificate
265 | curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, 0);
266 |
267 | // setting the path where cURL can find the client certificate
268 | curl_setopt($this->curl, CURLOPT_SSLCERT, $sslCertificate);
269 |
270 | // setting the path where cURL can find the client certificate’s
271 | // private key
272 | curl_setopt($this->curl, CURLOPT_SSLKEY, $sslKey);
273 |
274 | // setting the key password
275 | curl_setopt($this->curl, CURLOPT_SSLKEYPASSWD, $sslKeyPassword);
276 |
277 | // setting the request type to POST
278 | curl_setopt($this->curl, CURLOPT_POST, 1);
279 |
280 | // setting the content type
281 | curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers);
282 |
283 | // setting the authorization method to BASIC
284 | curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
285 |
286 | // supplying your credentials
287 | curl_setopt($this->curl, CURLOPT_USERPWD, $userName . ':' . $password);
288 |
289 | // telling cURL to return the HTTP response body as operation result
290 | // value when calling curl_exec
291 | curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1);
292 |
293 | return $this->curl;
294 | }
295 |
296 | public function sendData($data)
297 | {
298 | //
299 | // Do it with PHP Native Curl
300 | //
301 | $curl = $this->buildCurlClient();
302 |
303 | // Create the XML body
304 | $xmlBody = $this->xmlTemplate;
305 | foreach ($data as $key => $value) {
306 | $xmlBody = str_replace('%' . $key . '%', $value, $xmlBody);
307 | }
308 |
309 | // Substitute the XML body into the template
310 | $soapBody = str_replace('%xmlBody%', $xmlBody, $this->soapTemplate);
311 |
312 | // fill the request body with the SOAP message
313 | curl_setopt($curl, CURLOPT_POSTFIELDS, $soapBody);
314 |
315 | // echo "SOAP Body\n";
316 | // echo $soapBody;
317 | // echo "\nEND SOAP Body\n";
318 |
319 | // Send the request
320 | $result = curl_exec($curl);
321 |
322 | // close cURL
323 | curl_close($curl);
324 |
325 | // echo "SOAP Response\n";
326 | // echo $result;
327 | // echo "\nEND SOAP Response\n";
328 |
329 | // Create and return a response object
330 | return $this->createResponse($result);
331 | }
332 |
333 | /**
334 | * Get the endpoint URL for the request.
335 | *
336 | * @return string
337 | */
338 | public function getEndpoint()
339 | {
340 | return $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint;
341 | }
342 |
343 | /**
344 | * Create the response object.
345 | *
346 | * Create a structure by parsing the XML data and returning a simplified
347 | * array that our WebserviceResponse class can easily pull data from.
348 | *
349 | * @param string $data XML
350 | * @return WebserviceResponse
351 | */
352 | public function createResponse($data)
353 | {
354 | // echo "XML Data = $data\n";
355 |
356 | // Parse the XML
357 | $parser = xml_parser_create_ns();
358 | $intermediate_data = array();
359 | $parsed_data = array();
360 | xml_parse_into_struct($parser, $data, $intermediate_data);
361 |
362 | // echo "Intermediate data =\n";
363 | // print_r($intermediate_data);
364 | // echo "\nEnd intermediate data\n";
365 |
366 | // Invert the parsed array from this type of structure:
367 | /*
368 | [4] => Array
369 | (
370 | [tag] => HTTP://SECURE.LINKPT.NET/FDGGWSAPI/SCHEMAS_US/FDGGWSAPI:COMMERCIALSERVICEPROVIDER
371 | [type] => complete
372 | [level] => 4
373 | [value] => CSI
374 | )
375 | */
376 | // To this, which we want for our internal purposes
377 | // [COMMERCIALSERVICEPROVIDER] => CSI
378 | // We basically just strip out everything before the final ':' of the
379 | // tag and attach any value to that, ignoring any fields that come through
380 | // from the XML parser without any values.
381 |
382 | foreach ($intermediate_data as $item) {
383 | if (! empty($item['value'])) {
384 | $parsed_tag = explode(':', $item['tag']);
385 | $tag = array_pop($parsed_tag);
386 | $parsed_data[$tag] = $item['value'];
387 | }
388 | }
389 |
390 | return $this->response = new WebserviceResponse($this, $parsed_data);
391 | }
392 | }
393 |
--------------------------------------------------------------------------------
/src/Message/WebserviceAuthorizeRequest.php:
--------------------------------------------------------------------------------
1 |
13 | * // Create a gateway for the First Data Webservice Gateway
14 | * // (routes to GatewayFactory::create)
15 | * $gateway = Omnipay::create('FirstData_Webservice');
16 | *
17 | * // Initialise the gateway
18 | * $gateway->initialize(array(
19 | * 'sslCertificate' => 'WS9999999._.1.pem',
20 | * 'sslKey' => 'WS9999999._.1.key',
21 | * 'sslKeyPassword' => 'sslKEYpassWORD',
22 | * 'userName' => 'WS9999999._.1',
23 | * 'password' => 'passWORD',
24 | * 'testMode' => true,
25 | * ));
26 | *
27 | * // Create a credit card object
28 | * $card = new CreditCard(array(
29 | * 'firstName' => 'Example',
30 | * 'lastName' => 'Customer',
31 | * 'number' => '4222222222222222',
32 | * 'expiryMonth' => '01',
33 | * 'expiryYear' => '2020',
34 | * 'cvv' => '123',
35 | * 'email' => 'customer@example.com',
36 | * 'billingAddress1' => '1 Scrubby Creek Road',
37 | * 'billingCountry' => 'AU',
38 | * 'billingCity' => 'Scrubby Creek',
39 | * 'billingPostcode' => '4999',
40 | * 'billingState' => 'QLD',
41 | * ));
42 | *
43 | * // Do an authorize transaction on the gateway
44 | * $transaction = $gateway->authorize(array(
45 | * 'accountId' => '12345',
46 | * 'amount' => '10.00',
47 | * 'currency' => 'USD',
48 | * 'description' => 'Super Deluxe Excellent Discount Package',
49 | * 'transactionId' => 12345,
50 | * 'clientIp' => $_SERVER['REMOTE_ADDR'],
51 | * 'card' => $card,
52 | * ));
53 | * $response = $transaction->send();
54 | * if ($response->isSuccessful()) {
55 | * echo "Authorize transaction was successful!\n";
56 | * $sale_id = $response->getTransactionReference();
57 | * echo "Transaction reference = " . $sale_id . "\n";
58 | * }
59 | *
60 | */
61 | class WebserviceAuthorizeRequest extends WebservicePurchaseRequest
62 | {
63 | /** @var string Transaction type */
64 | protected $txn_type = 'preAuth';
65 | }
66 |
--------------------------------------------------------------------------------
/src/Message/WebserviceCaptureRequest.php:
--------------------------------------------------------------------------------
1 |
13 | * // Create a gateway for the First Data Webservice Gateway
14 | * // (routes to GatewayFactory::create)
15 | * $gateway = Omnipay::create('FirstData_Webservice');
16 | *
17 | * // Initialise the gateway
18 | * $gateway->initialize(array(
19 | * 'sslCertificate' => 'WS9999999._.1.pem',
20 | * 'sslKey' => 'WS9999999._.1.key',
21 | * 'sslKeyPassword' => 'sslKEYpassWORD',
22 | * 'userName' => 'WS9999999._.1',
23 | * 'password' => 'passWORD',
24 | * 'testMode' => true,
25 | * ));
26 | *
27 | * // Do a capture transaction on the gateway. This assumes that an authorize
28 | * // request has been successful, and that the transactionReference from the
29 | * // authorize request is stored in $sale_id.
30 | * $transaction = $gateway->capture(array(
31 | * 'transactionReference' => $sale_id,
32 | * ));
33 | * $response = $transaction->send();
34 | * if ($response->isSuccessful()) {
35 | * echo "Capture transaction was successful!\n";
36 | * $sale_id = $response->getTransactionReference();
37 | * echo "Transaction reference = " . $sale_id . "\n";
38 | * }
39 | *
40 | */
41 | class WebserviceCaptureRequest extends WebserviceAbstractRequest
42 | {
43 | /** @var string XML template for the capture request */
44 | protected $xmlTemplate = '
45 |
47 |
48 |
49 | %txn_type%
50 |
51 |
52 | %reference_no%
53 |
54 |
55 |
56 | ';
57 |
58 | /** @var string Transaction type */
59 | protected $txn_type = 'postAuth';
60 |
61 | public function getData()
62 | {
63 | $data = parent::getData();
64 |
65 | $data['txn_type'] = $this->txn_type;
66 |
67 | $this->validate('transactionReference');
68 |
69 | // Fetch the original transaction reference and tdate from the
70 | // concatenated transactionReference returned by the authorize()
71 | // request.
72 | $transaction_reference = $this->getTransactionReference();
73 | list($orderid, $tdate) = explode('::', $transaction_reference);
74 | $data['reference_no'] = $orderid;
75 |
76 | return $data;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/Message/WebservicePurchaseRequest.php:
--------------------------------------------------------------------------------
1 |
13 | * // Create a gateway for the First Data Webservice Gateway
14 | * // (routes to GatewayFactory::create)
15 | * $gateway = Omnipay::create('FirstData_Webservice');
16 | *
17 | * // Initialise the gateway
18 | * $gateway->initialize(array(
19 | * 'sslCertificate' => 'WS9999999._.1.pem',
20 | * 'sslKey' => 'WS9999999._.1.key',
21 | * 'sslKeyPassword' => 'sslKEYpassWORD',
22 | * 'userName' => 'WS9999999._.1',
23 | * 'password' => 'passWORD',
24 | * 'testMode' => true,
25 | * ));
26 | *
27 | * // Create a credit card object
28 | * $card = new CreditCard(array(
29 | * 'firstName' => 'Example',
30 | * 'lastName' => 'Customer',
31 | * 'number' => '4222222222222222',
32 | * 'expiryMonth' => '01',
33 | * 'expiryYear' => '2020',
34 | * 'cvv' => '123',
35 | * 'email' => 'customer@example.com',
36 | * 'billingAddress1' => '1 Scrubby Creek Road',
37 | * 'billingCountry' => 'AU',
38 | * 'billingCity' => 'Scrubby Creek',
39 | * 'billingPostcode' => '4999',
40 | * 'billingState' => 'QLD',
41 | * ));
42 | *
43 | * // Do a purchase transaction on the gateway
44 | * $transaction = $gateway->purchase(array(
45 | * 'accountId' => '12345',
46 | * 'amount' => '10.00',
47 | * 'transactionId' => 12345,
48 | * 'clientIp' => $_SERVER['REMOTE_ADDR'],
49 | * 'card' => $card,
50 | * ));
51 | * $response = $transaction->send();
52 | * if ($response->isSuccessful()) {
53 | * echo "Purchase transaction was successful!\n";
54 | * $sale_id = $response->getTransactionReference();
55 | * echo "Transaction reference = " . $sale_id . "\n";
56 | * }
57 | *
58 | */
59 | class WebservicePurchaseRequest extends WebserviceAbstractRequest
60 | {
61 | /** @var string XML template for the purchase request */
62 | protected $xmlTemplate = '
63 |
65 |
66 |
67 | %txn_type%
68 |
69 |
70 | %card_number%
71 | %card_expiry_month%
72 | %card_expiry_year%
73 |
74 |
75 | %amount%
76 |
77 |
78 | %reference_no%
79 | %ip%
80 | No
81 |
82 |
83 | %account_id%
84 | %card_name%
85 | %card_address1%
86 | %card_city%
87 | %card_state%
88 | %card_postcode%
89 | %card_country%
90 | %card_email%
91 |
92 |
93 |
94 | ';
95 |
96 | /** @var string Transaction type */
97 | protected $txn_type = 'sale';
98 |
99 | /**
100 | * Get the request accountId
101 | *
102 | * @return string
103 | */
104 | public function getAccountId()
105 | {
106 | return $this->getParameter('accountId');
107 | }
108 |
109 | /**
110 | * Set the request accountId
111 | *
112 | * @param string $value
113 | * @return WebserviceAbstractRequest provides a fluent interface.
114 | */
115 | public function setAccountId($value)
116 | {
117 | return $this->setParameter('accountId', $value);
118 | }
119 |
120 | public function getData()
121 | {
122 | $data = parent::getData();
123 |
124 | $data['txn_type'] = $this->txn_type;
125 |
126 | // We have to make the transactionId a required parameter because
127 | // it is returned as the transactionReference, and required for
128 | // voids, refunds, and captures. The accountId parameter is also
129 | // required by First Data.
130 | $this->validate('amount', 'card', 'transactionId', 'accountId');
131 |
132 | $data['amount'] = $this->getAmount();
133 | $data['reference_no'] = $this->getTransactionId();
134 | $data['ip'] = $this->getClientIp();
135 |
136 | // Add account details
137 | $data['account_id'] = $this->getAccountId();
138 |
139 | // add credit card details
140 | $data['card_number'] = $this->getCard()->getNumber();
141 | $data['card_name'] = $this->getCard()->getName();
142 | $data['card_expiry_month'] = $this->getCard()->getExpiryDate('m');
143 | $data['card_expiry_year'] = $this->getCard()->getExpiryDate('y');
144 | $data['card_address1'] = $this->getCard()->getBillingAddress1();
145 | $data['card_address2'] = $this->getCard()->getBillingAddress2();
146 | $data['card_city'] = $this->getCard()->getBillingCity();
147 | $data['card_state'] = $this->getCard()->getBillingState();
148 | $data['card_postcode'] = $this->getCard()->getBillingPostcode();
149 | $data['card_country'] = $this->getCard()->getBillingCountry();
150 | $data['card_email'] = $this->getCard()->getEmail();
151 | $data['cvd_code'] = $this->getCard()->getCvv();
152 |
153 | return $data;
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/src/Message/WebserviceRefundRequest.php:
--------------------------------------------------------------------------------
1 |
13 | * // Create a gateway for the First Data Webservice Gateway
14 | * // (routes to GatewayFactory::create)
15 | * $gateway = Omnipay::create('FirstData_Webservice');
16 | *
17 | * // Initialise the gateway
18 | * $gateway->initialize(array(
19 | * 'sslCertificate' => 'WS9999999._.1.pem',
20 | * 'sslKey' => 'WS9999999._.1.key',
21 | * 'sslKeyPassword' => 'sslKEYpassWORD',
22 | * 'userName' => 'WS9999999._.1',
23 | * 'password' => 'passWORD',
24 | * 'testMode' => true,
25 | * ));
26 | *
27 | * // Do a refund transaction on the gateway. This assumes that a purchase
28 | * // request has been successful, and that the transactionReference from the
29 | * // purchase request is stored in $sale_id.
30 | * $transaction = $gateway->refund(array(
31 | * 'transactionReference' => $sale_id,
32 | * 'amount' => 5.00,
33 | * ));
34 | * $response = $transaction->send();
35 | * if ($response->isSuccessful()) {
36 | * echo "Refund transaction was successful!\n";
37 | * $sale_id = $response->getTransactionReference();
38 | * echo "Transaction reference = " . $sale_id . "\n";
39 | * }
40 | *
41 | *
42 | * ### Quirks
43 | *
44 | * In the case of a captured authorization, the transaction reference passed
45 | * to refund() must be the transaction reference returned from the capture()
46 | * request and not the transaction reference from the original authorize()
47 | * request.
48 | */
49 | class WebserviceRefundRequest extends WebserviceAbstractRequest
50 | {
51 | /** @var string XML template for the refund request */
52 | protected $xmlTemplate = '
53 |
55 |
56 |
57 | %txn_type%
58 |
59 |
60 | %amount%
61 |
62 |
63 | %reference_no%
64 |
65 |
66 |
67 | ';
68 |
69 | /** @var string Transaction type */
70 | protected $txn_type = 'return';
71 |
72 | public function getData()
73 | {
74 | $data = parent::getData();
75 |
76 | $data['txn_type'] = $this->txn_type;
77 |
78 | $this->validate('amount', 'transactionReference');
79 |
80 | // Fetch the original transaction reference and tdate from the
81 | // concatenated transactionReference returned by the purchase()
82 | // request.
83 | $transaction_reference = $this->getTransactionReference();
84 | list($orderid, $tdate) = explode('::', $transaction_reference);
85 | $data['reference_no'] = $orderid;
86 | $data['tdate'] = $tdate;
87 |
88 | $data['amount'] = $this->getAmount();
89 |
90 | return $data;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/Message/WebserviceResponse.php:
--------------------------------------------------------------------------------
1 | data[$itemname])) {
32 | return $this->data[$itemname];
33 | }
34 |
35 | return null;
36 | }
37 |
38 | public function isSuccessful()
39 | {
40 | return ($this->getDataItem('TRANSACTIONRESULT') == 'APPROVED') ? true : false;
41 | }
42 |
43 | /**
44 | * Get the transaction reference
45 | *
46 | * Because refunding or voiding a transaction requires both the order ID
47 | * and the TDATE, we concatenate them together to make the transaction
48 | * reference.
49 | *
50 | * @return string
51 | */
52 | public function getTransactionReference()
53 | {
54 | return $this->getDataItem('ORDERID') . '::' . $this->getDataItem('TDATE');
55 | }
56 |
57 | public function getMessage()
58 | {
59 | return $this->getDataItem('ERRORMESSAGE');
60 | }
61 |
62 | public function getCode()
63 | {
64 | return $this->getDataItem('TRANSACTIONRESULT');
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/Message/WebserviceVoidRequest.php:
--------------------------------------------------------------------------------
1 |
13 | * // Create a gateway for the First Data Webservice Gateway
14 | * // (routes to GatewayFactory::create)
15 | * $gateway = Omnipay::create('FirstData_Webservice');
16 | *
17 | * // Initialise the gateway
18 | * $gateway->initialize(array(
19 | * 'sslCertificate' => 'WS9999999._.1.pem',
20 | * 'sslKey' => 'WS9999999._.1.key',
21 | * 'sslKeyPassword' => 'sslKEYpassWORD',
22 | * 'userName' => 'WS9999999._.1',
23 | * 'password' => 'passWORD',
24 | * 'testMode' => true,
25 | * ));
26 | *
27 | * // Do a void transaction on the gateway. This assumes that a purchase
28 | * // request has been successful, and that the transactionReference from the
29 | * // purchase request is stored in $sale_id.
30 | * $transaction = $gateway->void(array(
31 | * 'transactionReference' => $sale_id,
32 | * ));
33 | * $response = $transaction->send();
34 | * if ($response->isSuccessful()) {
35 | * echo "Void transaction was successful!\n";
36 | * $sale_id = $response->getTransactionReference();
37 | * echo "Transaction reference = " . $sale_id . "\n";
38 | * }
39 | *
40 | *
41 | * ### Quirks
42 | *
43 | * In the case of a captured authorization, the transaction reference passed
44 | * to void() must be the transaction reference returned from the capture()
45 | * request and not the transaction reference from the original authorize()
46 | * request.
47 | */
48 | class WebserviceVoidRequest extends WebserviceAbstractRequest
49 | {
50 | /** @var string XML template for the void request */
51 | protected $xmlTemplate = '
52 |
54 |
55 |
56 | %txn_type%
57 |
58 |
59 | %reference_no%
60 | %tdate%
61 |
62 |
63 |
64 | ';
65 |
66 | /** @var string Transaction type */
67 | protected $txn_type = 'void';
68 |
69 | public function getData()
70 | {
71 | $data = parent::getData();
72 |
73 | $data['txn_type'] = $this->txn_type;
74 |
75 | $this->validate('transactionReference');
76 |
77 | // Fetch the original transaction reference and tdate from the
78 | // concatenated transactionReference returned by the purchase()
79 | // request.
80 | $transaction_reference = $this->getTransactionReference();
81 | list($orderid, $tdate) = explode('::', $transaction_reference);
82 | $data['reference_no'] = $orderid;
83 | $data['tdate'] = $tdate;
84 |
85 | return $data;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/PayeezyGateway.php:
--------------------------------------------------------------------------------
1 |
22 | * // Create a gateway for the First Data Payeezy Gateway
23 | * // (routes to GatewayFactory::create)
24 | * $gateway = Omnipay::create('FirstData_Payeezy');
25 | *
26 | * // Initialise the gateway
27 | * $gateway->initialize(array(
28 | * 'gatewayId' => '12341234',
29 | * 'password' => 'thisISmyPASSWORD',
30 | * 'testMode' => true, // Or false when you are ready for live transactions
31 | * ));
32 | *
33 | * // Create a credit card object
34 | * $card = new CreditCard(array(
35 | * 'firstName' => 'Example',
36 | * 'lastName' => 'Customer',
37 | * 'number' => '4222222222222222',
38 | * 'expiryMonth' => '01',
39 | * 'expiryYear' => '2020',
40 | * 'cvv' => '123',
41 | * 'email' => 'customer@example.com',
42 | * 'billingAddress1' => '1 Scrubby Creek Road',
43 | * 'billingCountry' => 'AU',
44 | * 'billingCity' => 'Scrubby Creek',
45 | * 'billingPostcode' => '4999',
46 | * 'billingState' => 'QLD',
47 | * ));
48 | *
49 | * // Do a purchase transaction on the gateway
50 | * $transaction = $gateway->purchase(array(
51 | * 'description' => 'Your order for widgets',
52 | * 'amount' => '10.00',
53 | * 'transactionId' => 12345,
54 | * 'clientIp' => $_SERVER['REMOTE_ADDR'],
55 | * 'card' => $card,
56 | * ));
57 | * $response = $transaction->send();
58 | * if ($response->isSuccessful()) {
59 | * echo "Purchase transaction was successful!\n";
60 | * $sale_id = $response->getTransactionReference();
61 | * echo "Transaction reference = " . $sale_id . "\n";
62 | * }
63 | *
64 | *
65 | * ### Test Accounts
66 | *
67 | * Test accounts can be obtained here:
68 | * https://provisioning.demo.globalgatewaye4.firstdata.com/signup
69 | * Note that only USD transactions are supported for test accounts.
70 | *
71 | * Once you have created a test account, log in to the gateway here:
72 | * https://demo.globalgatewaye4.firstdata.com/main
73 | * Navigate to Administration -> Terminals and click on the terminal with TERM ECOMM name,
74 | * There will be a Gateway ID displayed there and you can also generate a password.
75 | *
76 | * Test credit card numbers can be found here:
77 | * https://support.payeezy.com/hc/en-us/articles/204504235-Using-test-credit-card-numbers
78 | *
79 | * ### Quirks
80 | *
81 | * This gateway requires both a transaction reference (aka an authorization number)
82 | * and a transaction tag to implement either voids or refunds. These are referred
83 | * to in the documentation as "tagged refund" and "tagged voids".
84 | *
85 | * Card token transactions are supported (these are referred to in the documentation as
86 | * "TransArmor Multi-Pay") but have to be enabled for each merchant account. There is no
87 | * createCard method, instead a card token is generated when a zero dollar authorization
88 | * is submitted.
89 | *
90 | * Void and Refund transactions require the amount parameter.
91 | *
92 | * @link https://support.payeezy.com/hc/en-us
93 | * @link https://provisioning.demo.globalgatewaye4.firstdata.com/signup
94 | * @link https://support.payeezy.com/hc/en-us/articles/204504235-Using-test-credit-card-numbers
95 | */
96 | class PayeezyGateway extends AbstractGateway
97 | {
98 | public function getName()
99 | {
100 | return 'First Data Payeezy';
101 | }
102 |
103 | public function getDefaultParameters()
104 | {
105 | return array(
106 | 'gatewayId' => '',
107 | 'password' => '',
108 | 'keyId' => '',
109 | 'hmac' => '',
110 | 'testMode' => false,
111 | );
112 | }
113 |
114 | /**
115 | * Get Gateway ID
116 | *
117 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
118 | * password.
119 | *
120 | * @return string
121 | */
122 | public function getGatewayId()
123 | {
124 | return $this->getParameter('gatewayId');
125 | }
126 |
127 | /**
128 | * Set Gateway ID
129 | *
130 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
131 | * password.
132 | *
133 | * @return PayeezyGateway provides a fluent interface.
134 | */
135 | public function setGatewayId($value)
136 | {
137 | return $this->setParameter('gatewayId', $value);
138 | }
139 |
140 | /**
141 | * Get Password
142 | *
143 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
144 | * password.
145 | *
146 | * @return string
147 | */
148 | public function getPassword()
149 | {
150 | return $this->getParameter('password');
151 | }
152 |
153 | /**
154 | * Set Password
155 | *
156 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
157 | * password.
158 | *
159 | * @return PayeezyGateway provides a fluent interface.
160 | */
161 | public function setPassword($value)
162 | {
163 | return $this->setParameter('password', $value);
164 | }
165 |
166 | /**
167 | * Get Key Id
168 | *
169 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
170 | * password.
171 | *
172 | * @return string
173 | */
174 | public function getKeyId()
175 | {
176 | return $this->getParameter('keyId');
177 | }
178 |
179 | /**
180 | * Set Key Id
181 | *
182 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
183 | * password.
184 | *
185 | * @return PayeezyGateway provides a fluent interface.
186 | */
187 | public function setKeyId($value)
188 | {
189 | return $this->setParameter('keyId', $value);
190 | }
191 |
192 | /**
193 | * Get Hmac
194 | *
195 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
196 | * password.
197 | *
198 | * @return string
199 | */
200 | public function getHmac()
201 | {
202 | return $this->getParameter('hmac');
203 | }
204 |
205 | /**
206 | * Set Hmac
207 | *
208 | * Calls to the Payeezy Gateway API are secured with a gateway ID and
209 | * password.
210 | *
211 | * @return PayeezyGateway provides a fluent interface.
212 | */
213 | public function setHmac($value)
214 | {
215 | return $this->setParameter('hmac', $value);
216 | }
217 |
218 | /**
219 | * Create a purchase request.
220 | *
221 | * @param array $parameters
222 | *
223 | * @return \Omnipay\FirstData\Message\PayeezyPurchaseRequest
224 | */
225 | public function purchase(array $parameters = array())
226 | {
227 | return $this->createRequest('\Omnipay\FirstData\Message\PayeezyPurchaseRequest', $parameters);
228 | }
229 |
230 | /**
231 | * Create an authorize request.
232 | *
233 | * @param array $parameters
234 | *
235 | * @return \Omnipay\FirstData\Message\PayeezyAuthorizeRequest
236 | */
237 | public function authorize(array $parameters = array())
238 | {
239 | return $this->createRequest('\Omnipay\FirstData\Message\PayeezyAuthorizeRequest', $parameters);
240 | }
241 |
242 | /**
243 | * Create a capture request.
244 | *
245 | * @param array $parameters
246 | *
247 | * @return \Omnipay\FirstData\Message\PayeezyCaptureRequest
248 | */
249 | public function capture(array $parameters = array())
250 | {
251 | return $this->createRequest('\Omnipay\FirstData\Message\PayeezyCaptureRequest', $parameters);
252 | }
253 |
254 | /**
255 | * Create a refund request.
256 | *
257 | * @param array $parameters
258 | *
259 | * @return \Omnipay\FirstData\Message\PayeezyRefundRequest
260 | */
261 | public function refund(array $parameters = array())
262 | {
263 | return $this->createRequest('\Omnipay\FirstData\Message\PayeezyRefundRequest', $parameters);
264 | }
265 |
266 | /**
267 | * Create a void request.
268 | *
269 | * @param array $parameters
270 | *
271 | * @return \Omnipay\FirstData\Message\PayeezyVoidRequest
272 | */
273 | public function void(array $parameters = array())
274 | {
275 | return $this->createRequest('\Omnipay\FirstData\Message\PayeezyVoidRequest', $parameters);
276 | }
277 | }
278 |
--------------------------------------------------------------------------------
/src/WebserviceGateway.php:
--------------------------------------------------------------------------------
1 | ) throws an error message. The XML header must be
42 | * omitted.
43 | *
44 | * To be honest I have better things to spend my time on than dealing with such
45 | * nonsense. If people can't drag themselves out of the 19th century and use
46 | * REST APIs instead of SOAP then they can at least have the good grace and
47 | * common courtesy to get their XML handling and formatting correct.
48 | *
49 | * #### Transaction ID
50 | *
51 | * A user supplied transaction ID (transactionId parameter) must be supplied for each
52 | * purchase() or authorize() request. This is known as "OrderId" in the Webservice Gateway.
53 | *
54 | * The First Data Webservice Gateway Web Service API only accepts ASCII characters. The Order
55 | * ID cannot contain the following characters: &, %, /, or exceed 100 characters in length.
56 | * The Order ID will be restricted in such a way so that it can only accepts alpha numeric
57 | * (a-z, A-Z, 0-9) and some special characters for merchants convenience.
58 | *
59 | * #### Voids and Refunds
60 | *
61 | * Voids and Refunds require both the transactionId and the TDATE parameter returned
62 | * from the purchase (or capture) call. To make things cleaner for calling applicatons,
63 | * the transactionReference returned by getTransactionReference() after the purhcase
64 | * or capture call is the transactionId and the TDATE concatenated together and
65 | * separated by '::'.
66 | *
67 | * Refunds require an amount parameter. The amount parameter is ignored by the void
68 | * call.
69 | *
70 | * ### Authentication
71 | *
72 | * Within the SSL connection (see below), authentication is done via HTTP Basic Auth.
73 | *
74 | * First Data should provide you, as part of the connection package, a username and a
75 | * password. The username will be of the form WS*******._.1 and the password will be
76 | * a string containing letters and numbers. Provide these as the userName and password
77 | * parameters when initializing the gateway.
78 | *
79 | * ### SSL Connection Security
80 | *
81 | * The Web Service API requires an SSL connection with client and server exchanging
82 | * certificates to guarantee this level of security. The client and server certificates
83 | * each uniquely identify the party.
84 | *
85 | * First Data should provide you, as part of the connection package, at least the
86 | * following files:
87 | *
88 | * * WS____.pem (certificate file)
89 | * * WS____.key (key file)
90 | * * WS____.key.pw.txt (text file containing the password for the key)
91 | *
92 | * ... where WS___ is your username also provided by First Data (see above).
93 | *
94 | * You need to store the certificate file and the key file on disk somewhere and
95 | * pass the following parameters when initializing the gateway:
96 | *
97 | * * sslCertificate -- on disk location of the .pem certificate file.
98 | * * sslKey -- on disk location of the .key file.
99 | * * sslKeyPassword -- the password for the key (not the file name)
100 | *
101 | * In case First Data provide you with a .p12 (PKCS-12) file for the certificate
102 | * instead of a PEM file, you will need to convert the .p12 file to a .pem file
103 | * using this command:
104 | *
105 | * ```
106 | * openssl pkcs12 -in WS____.p12 -out WS____.1.pem -clcerts -nokeys
107 | * ```
108 | *
109 | * ### Test Accounts
110 | *
111 | * To obtain a test account, use this form:
112 | * http://www.firstdata.com/gg/apply_test_account.htm
113 | *
114 | * ### Example
115 | *
116 | * This is an example of a purchase request.
117 | *
118 | *
119 | * // Create a gateway for the First Data Webservice Gateway
120 | * // (routes to GatewayFactory::create)
121 | * $gateway = Omnipay::create('FirstData_Webservice');
122 | *
123 | * // Initialise the gateway
124 | * $gateway->initialize(array(
125 | * 'sslCertificate' => 'WS9999999._.1.pem',
126 | * 'sslKey' => 'WS9999999._.1.key',
127 | * 'sslKeyPassword' => 'sslKEYpassWORD',
128 | * 'userName' => 'WS9999999._.1',
129 | * 'password' => 'passWORD',
130 | * 'testMode' => true,
131 | * ));
132 | *
133 | * // Create a credit card object
134 | * $card = new CreditCard(array(
135 | * 'firstName' => 'Example',
136 | * 'lastName' => 'Customer',
137 | * 'number' => '4222222222222222',
138 | * 'expiryMonth' => '01',
139 | * 'expiryYear' => '2020',
140 | * 'cvv' => '123',
141 | * 'email' => 'customer@example.com',
142 | * 'billingAddress1' => '1 Scrubby Creek Road',
143 | * 'billingCountry' => 'AU',
144 | * 'billingCity' => 'Scrubby Creek',
145 | * 'billingPostcode' => '4999',
146 | * 'billingState' => 'QLD',
147 | * ));
148 | *
149 | * // Do a purchase transaction on the gateway
150 | * $transaction = $gateway->purchase(array(
151 | * 'accountId' => '12345',
152 | * 'amount' => '10.00',
153 | * 'currency' => 'USD',
154 | * 'description' => 'Super Deluxe Excellent Discount Package',
155 | * 'transactionId' => 12345,
156 | * 'clientIp' => $_SERVER['REMOTE_ADDR'],
157 | * 'card' => $card,
158 | * ));
159 | * $response = $transaction->send();
160 | * if ($response->isSuccessful()) {
161 | * echo "Purchase transaction was successful!\n";
162 | * $sale_id = $response->getTransactionReference();
163 | * echo "Transaction reference = " . $sale_id . "\n";
164 | * }
165 | *
166 | *
167 | * @link https://www.firstdata.com/downloads/pdf/FDGG_Web_Service_API_v9.0.pdf
168 | */
169 | class WebserviceGateway extends AbstractGateway
170 | {
171 | public function getName()
172 | {
173 | return 'First Data Webservice';
174 | }
175 |
176 | public function getDefaultParameters()
177 | {
178 | return array(
179 | 'sslCertificate' => '',
180 | 'sslKey' => '',
181 | 'sslKeyPassword' => '',
182 | 'userName' => '',
183 | 'password' => '',
184 | 'testMode' => false,
185 | );
186 | }
187 |
188 | /**
189 | * Get SSL Certificate file name
190 | *
191 | * You must establish a secure communication channel to send the HTTP request.
192 | * This ensures that the data sent between your client application and the First
193 | * Data Webservice Gateway Web Service API is encrypted and that both parties can
194 | * be sure they are communicating with each other and no one else.
195 | *
196 | * The Web Service API requires an SSL connection with client and server exchanging
197 | * certificates to guarantee this level of security. The client and server certificates
198 | * each uniquely identify the party.
199 | *
200 | * @return string
201 | */
202 | public function getSslCertificate()
203 | {
204 | return $this->getParameter('sslCertificate');
205 | }
206 |
207 | /**
208 | * Set SSL Certificate file name
209 | *
210 | * You must establish a secure communication channel to send the HTTP request.
211 | * This ensures that the data sent between your client application and the First
212 | * Data Webservice Gateway Web Service API is encrypted and that both parties can
213 | * be sure they are communicating with each other and no one else.
214 | *
215 | * The Web Service API requires an SSL connection with client and server exchanging
216 | * certificates to guarantee this level of security. The client and server certificates
217 | * each uniquely identify the party.
218 | *
219 | * @param string $value
220 | * @return WebserviceGateway provides a fluent interface.
221 | */
222 | public function setSslCertificate($value)
223 | {
224 | return $this->setParameter('sslCertificate', $value);
225 | }
226 |
227 | /**
228 | * Get SSL Key file name
229 | *
230 | * You must establish a secure communication channel to send the HTTP request.
231 | * This ensures that the data sent between your client application and the First
232 | * Data Webservice Gateway Web Service API is encrypted and that both parties can
233 | * be sure they are communicating with each other and no one else.
234 | *
235 | * The Web Service API requires an SSL connection with client and server exchanging
236 | * certificates to guarantee this level of security. The client and server certificates
237 | * each uniquely identify the party.
238 | *
239 | * @return string
240 | */
241 | public function getSslKey()
242 | {
243 | return $this->getParameter('sslKey');
244 | }
245 |
246 | /**
247 | * Set SSL Key file name
248 | *
249 | * You must establish a secure communication channel to send the HTTP request.
250 | * This ensures that the data sent between your client application and the First
251 | * Data Webservice Gateway Web Service API is encrypted and that both parties can
252 | * be sure they are communicating with each other and no one else.
253 | *
254 | * The Web Service API requires an SSL connection with client and server exchanging
255 | * certificates to guarantee this level of security. The client and server certificates
256 | * each uniquely identify the party.
257 | *
258 | * @param string $value
259 | * @return WebserviceGateway provides a fluent interface.
260 | */
261 | public function setSslKey($value)
262 | {
263 | return $this->setParameter('sslKey', $value);
264 | }
265 |
266 | /**
267 | * Get SSL Key password
268 | *
269 | * You must establish a secure communication channel to send the HTTP request.
270 | * This ensures that the data sent between your client application and the First
271 | * Data Global Gateway Web Service API is encrypted and that both parties can
272 | * be sure they are communicating with each other and no one else.
273 | *
274 | * The Web Service API requires an SSL connection with client and server exchanging
275 | * certificates to guarantee this level of security. The client and server certificates
276 | * each uniquely identify the party.
277 | *
278 | * @return string
279 | */
280 | public function getSslKeyPassword()
281 | {
282 | return $this->getParameter('sslKeyPassword');
283 | }
284 |
285 | /**
286 | * Set SSL Key password
287 | *
288 | * You must establish a secure communication channel to send the HTTP request.
289 | * This ensures that the data sent between your client application and the First
290 | * Data Global Gateway Web Service API is encrypted and that both parties can
291 | * be sure they are communicating with each other and no one else.
292 | *
293 | * The Web Service API requires an SSL connection with client and server exchanging
294 | * certificates to guarantee this level of security. The client and server certificates
295 | * each uniquely identify the party.
296 | *
297 | * @param string $value
298 | * @return WebserviceGateway provides a fluent interface.
299 | */
300 | public function setSslKeyPassword($value)
301 | {
302 | return $this->setParameter('sslKeyPassword', $value);
303 | }
304 |
305 | /**
306 | * Get Username
307 | *
308 | * Calls to the Global Gateway API are secured with a username and
309 | * password sent via HTTP Basic Authentication.
310 | *
311 | * @return string
312 | */
313 | public function getUserName()
314 | {
315 | return $this->getParameter('userName');
316 | }
317 |
318 | /**
319 | * Set Username
320 | *
321 | * Calls to the Global Gateway API are secured with a username and
322 | * password sent via HTTP Basic Authentication.
323 | *
324 | * @param string $value
325 | * @return WebserviceGateway provides a fluent interface.
326 | */
327 | public function setUserName($value)
328 | {
329 | return $this->setParameter('userName', $value);
330 | }
331 |
332 | /**
333 | * Get Password
334 | *
335 | * Calls to the Global Gateway API are secured with a username and
336 | * password sent via HTTP Basic Authentication.
337 | *
338 | * @return string
339 | */
340 | public function getPassword()
341 | {
342 | return $this->getParameter('password');
343 | }
344 |
345 | /**
346 | * Set Password
347 | *
348 | * Calls to the Global Gateway API are secured with a username and
349 | * password sent via HTTP Basic Authentication.
350 | *
351 | * @param string $value
352 | * @return WebserviceGateway provides a fluent interface.
353 | */
354 | public function setPassword($value)
355 | {
356 | return $this->setParameter('password', $value);
357 | }
358 |
359 | /**
360 | * Create a purchase request.
361 | *
362 | * @param array $parameters
363 | * @return \Omnipay\FirstData\Message\WebservicePurchaseRequest
364 | */
365 | public function purchase(array $parameters = array())
366 | {
367 | return $this->createRequest('\Omnipay\FirstData\Message\WebservicePurchaseRequest', $parameters);
368 | }
369 |
370 | /**
371 | * Create an authorize request.
372 | *
373 | * @param array $parameters
374 | * @return \Omnipay\FirstData\Message\WebserviceAuthorizeRequest
375 | */
376 | public function authorize(array $parameters = array())
377 | {
378 | return $this->createRequest('\Omnipay\FirstData\Message\WebserviceAuthorizeRequest', $parameters);
379 | }
380 |
381 | /**
382 | * Create a capture request.
383 | *
384 | * @param array $parameters
385 | * @return \Omnipay\FirstData\Message\WebserviceCaptureRequest
386 | */
387 | public function capture(array $parameters = array())
388 | {
389 | return $this->createRequest('\Omnipay\FirstData\Message\WebserviceCaptureRequest', $parameters);
390 | }
391 |
392 | /**
393 | * Create a void request.
394 | *
395 | * @param array $parameters
396 | * @return \Omnipay\FirstData\Message\WebserviceVoidRequest
397 | */
398 | public function void(array $parameters = array())
399 | {
400 | return $this->createRequest('\Omnipay\FirstData\Message\WebserviceVoidRequest', $parameters);
401 | }
402 |
403 | /**
404 | * Create a refund request.
405 | *
406 | * @param array $parameters
407 | * @return \Omnipay\FirstData\Message\WebserviceRefundRequest
408 | */
409 | public function refund(array $parameters = array())
410 | {
411 | return $this->createRequest('\Omnipay\FirstData\Message\WebserviceRefundRequest', $parameters);
412 | }
413 | }
414 |
--------------------------------------------------------------------------------
/tests/GatewayTest.php:
--------------------------------------------------------------------------------
1 | gateway = new ConnectGateway($this->getHttpClient(), $this->getHttpRequest());
14 | $this->gateway->setSharedSecret('96MbdNvxTa');
15 | $this->gateway->setStoreId('1120540155');
16 |
17 | $this->options = array(
18 | 'amount' => '13.00',
19 | 'returnUrl' => 'https://www.example.com/return',
20 | 'card' => $this->getValidCard(),
21 | 'transactionId' => 'abc123',
22 | 'currency' => 'GBP',
23 | 'customerId' => 54321
24 | );
25 | }
26 |
27 | public function testPurchase()
28 | {
29 | $response = $this->gateway->purchase($this->options)->send();
30 |
31 | $this->assertFalse($response->isSuccessful());
32 | $this->assertTrue($response->isRedirect());
33 | $this->assertNull($response->getTransactionReference());
34 | $this->assertContains('ipg-online.com/connect/gateway/processing', $response->getRedirectUrl());
35 | }
36 |
37 | public function testCompletePurchaseSuccess()
38 | {
39 | $this->getHttpRequest()->request->replace(
40 | array(
41 | 'chargetotal' => '110.00',
42 | 'response_hash' => '796d7ca236576256236e92900dedfd55be08567a',
43 | 'status' => 'APPROVED',
44 | 'oid' => 'abc123456',
45 | 'txndatetime' => '2013:09:27-16:06:26',
46 | 'approval_code' => 'Y:136432:0013649958:PPXM:0015'
47 | )
48 | );
49 |
50 | $response = $this->gateway->completePurchase($this->options)->send();
51 |
52 | $this->assertTrue($response->isSuccessful());
53 | $this->assertFalse($response->isRedirect());
54 | $this->assertEquals('abc123456', $response->getTransactionId());
55 | $this->assertSame('APPROVED', $response->getMessage());
56 | $this->assertNull($response->getTransactionReference());
57 | }
58 |
59 | /**
60 | * @expectedException \Omnipay\Common\Exception\InvalidResponseException
61 | */
62 | public function testCompletePurchaseInvalidCallbackPassword()
63 | {
64 | $this->getHttpRequest()->request->replace(
65 | array(
66 | 'chargetotal' => '110.00',
67 | 'response_hash' => 'FAKE',
68 | 'status' => 'APPROVED',
69 | 'oid' => 'abc123456',
70 | 'txndatetime' => '2013:09:27-16:06:26',
71 | 'approval_code' => 'Y:136432:0013649958:PPXM:0015'
72 | )
73 | );
74 |
75 | $response = $this->gateway->completePurchase($this->options)->send();
76 | }
77 |
78 | public function testCompletePurchaseError()
79 | {
80 | $this->getHttpRequest()->request->replace(
81 | array(
82 | 'chargetotal' => '110.00',
83 | 'response_hash' => '0dfe9e4b3c6306343926207a8814a48f72087cc7',
84 | 'status' => 'DECLINED',
85 | 'oid' => 'abc1234',
86 | 'txndatetime' => '2013:09:27-16:00:19',
87 | 'approval_code' => 'N:05:DECLINED'
88 | )
89 | );
90 |
91 | $response = $this->gateway->completePurchase($this->options)->send();
92 |
93 | $this->assertFalse($response->isSuccessful());
94 | $this->assertFalse($response->isRedirect());
95 | $this->assertEquals('abc1234', $response->getTransactionId());
96 | $this->assertSame('DECLINED', $response->getMessage());
97 | }
98 |
99 | /**
100 | * testPurchaseWithHostedDataId.
101 | *
102 | * Simulates a purchase with "save this card" selected
103 | */
104 | public function testPurchaseWithHostedDataId()
105 | {
106 | $dataId = rand();
107 | $this->options['hostedDataId'] = $dataId;
108 |
109 | $response = $this->gateway->purchase($this->options)->send();
110 |
111 | $this->assertFalse($response->isSuccessful());
112 | $this->assertTrue($response->isRedirect());
113 | $requestData = $response->getRedirectData();
114 | $this->assertEquals($dataId, $requestData['hosteddataid']);
115 | }
116 |
117 | /**
118 | * testPurchaseWithHostedDataIdAndWithoutCardFailsWithoutCVV.
119 | *
120 | * Simulates paying using a saved card, rather than passing card data
121 | * This example is checking that an exception occurs if missing the CVV number
122 | *
123 | * @expectedException \Omnipay\Common\Exception\InvalidCreditCardException
124 | */
125 | public function testPurchaseWithHostedDataIdAndWithoutCardFailsWithoutCVV()
126 | {
127 | $dataId = rand();
128 | $this->options['hostedDataId'] = $dataId;
129 | // Remove number to simulate repeat purchase
130 | unset($this->options['card']['number']);
131 | // Also remove required cvv to check for error
132 | unset($this->options['card']['cvv']);
133 |
134 | $response = $this->gateway->purchase($this->options)->send();
135 |
136 | $this->assertFalse($response->isSuccessful());
137 | $this->assertTrue($response->isRedirect());
138 | $requestData = $response->getRedirectData();
139 | $this->assertEquals($dataId, $requestData['hosteddataid']);
140 | }
141 |
142 | /**
143 | * testPurchaseWithHostedDataIdAndWithoutCard.
144 | *
145 | * Simulates paying using a saved card, rather than passing card data
146 | */
147 | public function testPurchaseWithHostedDataIdAndWithoutCard()
148 | {
149 | $dataId = rand();
150 | $this->options['hostedDataId'] = $dataId;
151 | unset($this->options['card']);
152 | $this->options['card']['cvv'] = 123;
153 |
154 | $response = $this->gateway->purchase($this->options)->send();
155 |
156 | $this->assertFalse($response->isSuccessful());
157 | $this->assertTrue($response->isRedirect());
158 | $requestData = $response->getRedirectData();
159 | $this->assertEquals($dataId, $requestData['hosteddataid']);
160 | }
161 |
162 | /**
163 | * testPurchaseErrorWhenMissingHostedDataIdAndWithoutCardNumber.
164 | *
165 | * Simulates neither hosteddataid or card data being passed, should be caught in app.
166 | *
167 | * @expectedException \Omnipay\Common\Exception\InvalidCreditCardException
168 | */
169 | public function testPurchaseErrorWhenMissingHostedDataIdAndWithoutCardNumber()
170 | {
171 | unset($this->options['card']);
172 | $this->options['card']['cvv'] = 123;
173 |
174 | $response = $this->gateway->purchase($this->options)->send();
175 |
176 | $this->assertFalse($response->isSuccessful());
177 | $this->assertTrue($response->isRedirect());
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/tests/Message/CompletePurchaseResponseTest.php:
--------------------------------------------------------------------------------
1 | getMockRequest(),
13 | array(
14 | 'chargetotal' => '110.00',
15 | 'response_hash' => '796d7ca236576256236e92900dedfd55be08567a',
16 | 'status' => 'APPROVED',
17 | 'oid' => 'abc123456',
18 | 'txndatetime' => '2013:09:27-16:06:26',
19 | 'approval_code' => 'Y:136432:0013649958:PPXM:0015'
20 | )
21 | );
22 |
23 | $this->assertTrue($response->isSuccessful());
24 | $this->assertFalse($response->isRedirect());
25 | $this->assertSame('abc123456', $response->getTransactionId());
26 | $this->assertSame('APPROVED', $response->getMessage());
27 | }
28 |
29 | public function testCompletePurchaseFailure()
30 | {
31 | $response = new CompletePurchaseresponse(
32 | $this->getMockRequest(),
33 | array(
34 | 'chargetotal' => '110.00',
35 | 'response_hash' => '0dfe9e4b3c6306343926207a8814a48f72087cc7',
36 | 'status' => 'DECLINED',
37 | 'oid' => 'abc1234',
38 | 'txndatetime' => '2013:09:27-16:00:19',
39 | 'approval_code' => 'N:05:DECLINED'
40 | )
41 | );
42 |
43 | $this->assertFalse($response->isSuccessful());
44 | $this->assertFalse($response->isRedirect());
45 | $this->assertSame('abc1234', $response->getTransactionId());
46 | $this->assertSame('DECLINED', $response->getMessage());
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/Message/PayeezyAuthorizeRequestTest.php:
--------------------------------------------------------------------------------
1 | getHttpClient(), $this->getHttpRequest());
12 | $request->initialize(
13 | array(
14 | 'amount' => '12.00',
15 | 'card' => $this->getValidCard(),
16 | )
17 | );
18 |
19 | $data = $request->getData();
20 | $this->assertEquals('01', $data['transaction_type']);
21 | $this->assertEquals('4111111111111111', $data['cc_number']);
22 | $this->assertEquals('Visa', $data['credit_card_type']);
23 | $this->assertEquals('12.00', $data['amount']);
24 | $this->assertEquals('123 Billing St|12345|Billstown|CA|US', $data['cc_verification_str1']);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/Message/PayeezyPurchaseRequestTest.php:
--------------------------------------------------------------------------------
1 | getHttpClient(), $this->getHttpRequest());
13 | $request->initialize(
14 | array(
15 | 'amount' => '12.00',
16 | 'card' => $this->getValidCard(),
17 | )
18 | );
19 |
20 | $data = $request->getData();
21 | $this->assertEquals('00', $data['transaction_type']);
22 | $this->assertEquals('4111111111111111', $data['cc_number']);
23 | $this->assertEquals('Visa', $data['credit_card_type']);
24 | $this->assertEquals('12.00', $data['amount']);
25 | $this->assertEquals('123 Billing St|12345|Billstown|CA|US', $data['cc_verification_str1']);
26 | }
27 |
28 | public function testPurchaseSuccessMaestroType()
29 | {
30 | $options = array(
31 | 'amount' => '12.00',
32 | 'card' => $this->getValidCard(),
33 | );
34 |
35 | $options['card']['number'] = '6304000000000000';
36 |
37 | $request = new PayeezyPurchaseRequest($this->getHttpClient(), $this->getHttpRequest());
38 | $request->initialize($options);
39 |
40 | $data = $request->getData();
41 | $this->assertEquals('00', $data['transaction_type']);
42 | $this->assertEquals('maestro', $data['credit_card_type']);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/tests/Message/PayeezyPurchaseResponseTest.php:
--------------------------------------------------------------------------------
1 | getMockRequest(), json_encode(array(
13 | 'amount' => 1000,
14 | 'exact_resp_code' => 00,
15 | 'exact_message' => 'Transaction Normal',
16 | 'reference_no' => 'abc123',
17 | 'authorization_num' => 'auth1234',
18 | 'transaction_approved' => 1,
19 | )));
20 |
21 | $this->assertTrue($response->isSuccessful());
22 | $this->assertEquals('auth1234::', $response->getTransactionReference());
23 | $this->assertSame('Transaction Normal', $response->getMessage());
24 | $this->assertEquals('00', $response->getCode());
25 | }
26 |
27 | public function testPurchaseError()
28 | {
29 | $response = new PayeezyResponse($this->getMockRequest(), json_encode(array(
30 | 'amount' => 1000,
31 | 'exact_resp_code' => 22,
32 | 'exact_message' => 'Invalid Credit Card Number',
33 | 'reference_no' => 'abc123',
34 | 'authorization_num' => 'auth1234',
35 | 'transaction_approved' => 0,
36 | )));
37 |
38 | $this->assertFalse($response->isSuccessful());
39 | $this->assertEquals('auth1234::', $response->getTransactionReference());
40 | $this->assertSame('Invalid Credit Card Number', $response->getMessage());
41 | $this->assertEquals('22', $response->getCode());
42 | }
43 |
44 | public function testBankError()
45 | {
46 | $response = new PayeezyResponse($this->getMockRequest(), json_encode(array(
47 | 'amount' => 1000,
48 | 'exact_resp_code' => 00,
49 | 'reference_no' => 'abc123',
50 | 'authorization_num' => '',
51 | 'transaction_approved' => 0,
52 | )));
53 |
54 | $this->assertFalse($response->isSuccessful());
55 | $this->assertEquals('::', $response->getTransactionReference());
56 | $this->assertEquals('00', $response->getCode());
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/tests/Message/PayeezyRefundRequestTest.php:
--------------------------------------------------------------------------------
1 | getHttpClient(), $this->getHttpRequest());
12 | $request->initialize(
13 | array(
14 | 'amount' => '12.00',
15 | 'transactionReference' => '9999::DATADATADATA',
16 | )
17 | );
18 |
19 | $data = $request->getData();
20 | $this->assertEquals('9999', $data['authorization_num']);
21 | $this->assertEquals('DATADATADATA', $data['transaction_tag']);
22 | $this->assertEquals('12.00', $data['amount']);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/Message/PurchaseResponseTest.php:
--------------------------------------------------------------------------------
1 | getMockRequest(), array(
12 | 'amount' => 1000,
13 | 'returnUrl' => 'https://www.example.com/return',
14 | ));
15 |
16 | $this->assertFalse($response->isSuccessful());
17 | $this->assertTrue($response->isRedirect());
18 | $this->assertNull($response->getTransactionReference());
19 | $this->assertNull($response->getMessage());
20 | $this->assertSame('POST', $response->getRedirectMethod());
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/tests/Message/WebserviceCaptureRequestTest.php:
--------------------------------------------------------------------------------
1 | getHttpClient(), $this->getHttpRequest());
12 | $request->initialize(
13 | array(
14 | 'transactionReference' => '98765::ABCDEF',
15 | )
16 | );
17 |
18 | $data = $request->getData();
19 | $this->assertEquals('postAuth', $data['txn_type']);
20 | $this->assertEquals('98765', $data['reference_no']);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/tests/Message/WebservicePurchaseRequestTest.php:
--------------------------------------------------------------------------------
1 | getHttpClient(), $this->getHttpRequest());
12 | $request->initialize(
13 | array(
14 | 'amount' => '12.00',
15 | 'transactionId' => '98765',
16 | 'accountId' => '67890',
17 | 'card' => $this->getValidCard(),
18 | 'testMode' => true,
19 | )
20 | );
21 |
22 | $data = $request->getData();
23 | $this->assertEquals('sale', $data['txn_type']);
24 | $this->assertEquals('4111111111111111', $data['card_number']);
25 | $this->assertEquals('12.00', $data['amount']);
26 | $this->assertEquals('123 Billing St', $data['card_address1']);
27 | $this->assertEquals('Billstown', $data['card_city']);
28 | $this->assertEquals('12345', $data['card_postcode']);
29 | $this->assertEquals('CA', $data['card_state']);
30 | $this->assertEquals('US', $data['card_country']);
31 | $this->assertEquals('98765', $data['reference_no']);
32 |
33 | // Test request internals
34 | $curl = $request->buildCurlClient();
35 | $this->assertTrue(is_resource($curl));
36 |
37 | $endpoint = $request->getEndpoint();
38 | $this->assertEquals('https://ws.merchanttest.firstdataglobalgateway.com:443/fdggwsapi/services', $endpoint);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/tests/Message/WebserviceRefundRequestTest.php:
--------------------------------------------------------------------------------
1 | getHttpClient(), $this->getHttpRequest());
12 | $request->initialize(
13 | array(
14 | 'amount' => '12.00',
15 | 'transactionReference' => '98765::ABCDEF',
16 | )
17 | );
18 |
19 | $data = $request->getData();
20 | $this->assertEquals('return', $data['txn_type']);
21 | $this->assertEquals('12.00', $data['amount']);
22 | $this->assertEquals('98765', $data['reference_no']);
23 | $this->assertEquals('ABCDEF', $data['tdate']);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tests/Message/WebserviceVoidRequestTest.php:
--------------------------------------------------------------------------------
1 | getHttpClient(), $this->getHttpRequest());
12 | $request->initialize(
13 | array(
14 | 'transactionReference' => '98765::ABCDEF',
15 | )
16 | );
17 |
18 | $data = $request->getData();
19 | $this->assertEquals('void', $data['txn_type']);
20 | $this->assertEquals('98765', $data['reference_no']);
21 | $this->assertEquals('ABCDEF', $data['tdate']);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/Mock/PurchaseSuccess.txt:
--------------------------------------------------------------------------------
1 | HTTP/1.1 201 OK
2 | Date: Tue, 11 Feb 2014 02:34:58 GMT
3 | Content-type: text/html; charset=utf-8
4 |
5 | {"account_number":"","amount":"13.0","amount_requested":"","authorization":"","authorization_num":"ET181147","avs":"1","bank_id":"","bank_message":"Approved","bank_resp_code":"100","bank_resp_code_2":"","card_cost":"","cardholder_name":"Example User","cavv":"","cavv_algorithm":"","cavv_response":"","cc_expiry":"0318","cc_number":"############1111","cc_verification_str1":"123 Billing St|12345|Billstown|CA|US","cc_verification_str2":"208","check_number":"","check_type":"","clerk_id":"","client_email":"","client_ip":"104.36.244.246","correlation_id":"","credit_card_type":"Visa","ctr":"=========== TRANSACTION RECORD ==========\nPriceWaiter DEMO0243\n426 Market St\nChattenooga, TN 37402\nUnited States\nhttps:\/\/www.pricewaiter.com\/\n\nTYPE: Purchase\n\nACCT: Visa $ 13.00 USD\n\nCARDHOLDER NAME : Example User\nCARD NUMBER : ############1111\nDATE\/TIME : 11 Aug 14 14:09:06\nREFERENCE # : 000056 M\nAUTHOR. # : ET181147\nTRANS. REF. : order2\n\n Approved - Thank You 100\n\n\nPlease retain this copy for your records.\n\nCardholder will pay above amount to card\nissuer pursuant to cardholder agreement.\n=========================================","currency_code":"USD","current_balance":"","customer_id_number":"","customer_id_type":"","customer_name":"","customer_ref":"","cvd_presence_ind":"0","cvv2":"N","date_of_birth":"","device_id":"","ean":"","ecommerce_flag":"","error_description":"","error_number":"","exact_message":"Transaction Normal","exact_resp_code":"00","fraud_suspected":"","gateway_id":"AF8163-05","gift_card_amount":"","gross_amount_currency_id":"","language":"","logon_message":"","merchant_address":"426 Market St","merchant_city":"Chattenooga","merchant_country":"United States","merchant_name":"PriceWaiter DEMO0243","merchant_postal":"37402","merchant_province":"Tennessee","merchant_url":"https:\/\/www.pricewaiter.com\/","message":"","micr":"","pan":"","partial_redemption":"0","password":"","payer_id":"","previous_balance":"","reference_3":"","reference_no":"order2","registration_date":"","registration_no":"","release_type":"","retrieval_ref_no":"7775501","secure_auth_required":"","secure_auth_result":"","sequence_no":"000056","success":"","surcharge_amount":"","tax1_amount":"","tax1_number":"","tax2_amount":"","tax2_number":"","timestamp":"","track1":"","track2":"","transaction_approved":"1","transaction_error":"0","transaction_tag":"28513493","transaction_type":"00","transarmor_token":"","user_name":"","vip":"","virtual_card":"","xid":"","zip_code":""}
6 |
--------------------------------------------------------------------------------
/tests/Mock/RefundError.txt:
--------------------------------------------------------------------------------
1 | HTTP/1.1 201 OK
2 | Date: Tue, 11 Feb 2014 02:34:58 GMT
3 | Content-type: text/html; charset=utf-8
4 |
5 | account_number=&amount=13.0&amount_requested=&authorization=&authorization_num=&avs=&bank_id=&bank_message=&bank_resp_code=&bank_resp_code_2=&card_cost=&cardholder_name=&cavv=&cavv_algorithm=&cavv_response=&cc_expiry=9999&cc_number=&cc_verification_str1=&cc_verification_str2=&check_number=&check_type=&clerk_id=&client_email=&client_ip=&correlation_id=&credit_card_type=&ctr=¤cy_code=USD¤t_balance=&customer_id_number=&customer_id_type=&customer_name=&customer_ref=&cvd_presence_ind=0&cvv2=&date_of_birth=&device_id=&ean=&ecommerce_flag=&error_description=&error_number=&exact_message=Invalid+Refund&exact_resp_code=64&fraud_suspected=&gateway_id=AF8163-05&gift_card_amount=&gross_amount_currency_id=&language=&logon_message=&merchant_address=426+Market+St&merchant_city=Chattenooga&merchant_country=United+States&merchant_name=PriceWaiter+DEMO0243&merchant_postal=37402&merchant_province=Tennessee&merchant_url=https%3A%2F%2Fwww.pricewaiter.com%2F&message=&micr=&pan=&partial_redemption=0&password=&payer_id=&previous_balance=&reference_3=&reference_no=order2®istration_date=®istration_no=&release_type=&retrieval_ref_no=&secure_auth_required=&secure_auth_result=&sequence_no=000056&success=&surcharge_amount=&tax1_amount=&tax1_number=&tax2_amount=&tax2_number=×tamp=&track1=&track2=&transaction_approved=0&transaction_error=1&transaction_tag=28513493&transaction_type=34&transarmor_token=&user_name=&vip=&virtual_card=&xid=&zip_code=
6 |
--------------------------------------------------------------------------------
/tests/Mock/RefundSuccess.txt:
--------------------------------------------------------------------------------
1 | HTTP/1.1 201 OK
2 | Date: Tue, 11 Feb 2014 02:34:58 GMT
3 | Content-type: text/html; charset=utf-8
4 |
5 | account_number=&amount=13.0&amount_requested=&authorization=&authorization_num=ET181147&avs=&bank_id=&bank_message=Approved&bank_resp_code=100&bank_resp_code_2=&card_cost=&cardholder_name=Example+User&cavv=&cavv_algorithm=&cavv_response=&cc_expiry=0318&cc_number=%23%23%23%23%23%23%23%23%23%23%23%231111&cc_verification_str1=&cc_verification_str2=&check_number=&check_type=&clerk_id=&client_email=&client_ip=&correlation_id=&credit_card_type=Visa&ctr=¤cy_code=USD¤t_balance=&customer_id_number=&customer_id_type=&customer_name=&customer_ref=&cvd_presence_ind=0&cvv2=&date_of_birth=&device_id=&ean=&ecommerce_flag=&error_description=&error_number=&exact_message=Transaction+Normal&exact_resp_code=00&fraud_suspected=&gateway_id=AF8163-05&gift_card_amount=&gross_amount_currency_id=&language=&logon_message=&merchant_address=426+Market+St&merchant_city=Chattenooga&merchant_country=United+States&merchant_name=PriceWaiter+DEMO0243&merchant_postal=37402&merchant_province=Tennessee&merchant_url=https%3A%2F%2Fwww.pricewaiter.com%2F&message=&micr=&pan=&partial_redemption=0&password=&payer_id=&previous_balance=&reference_3=&reference_no=order2®istration_date=®istration_no=&release_type=&retrieval_ref_no=7775501&secure_auth_required=&secure_auth_result=&sequence_no=000056&success=&surcharge_amount=&tax1_amount=&tax1_number=&tax2_amount=&tax2_number=×tamp=&track1=&track2=&transaction_approved=1&transaction_error=0&transaction_tag=28513493&transaction_type=34&transarmor_token=&user_name=&vip=&virtual_card=&xid=&zip_code=
6 |
--------------------------------------------------------------------------------
/tests/Mock/WebservicePurchaseSuccess.txt:
--------------------------------------------------------------------------------
1 | CSISun Jan 10 23:34:04 201621840362OK242CAPPROVED259611OK242C0021840362:XXRnull:XXRnull1452486844APPROVEDAERRORConfiguration Error.
2 |
--------------------------------------------------------------------------------
/tests/PayeezyGatewayTest.php:
--------------------------------------------------------------------------------
1 | gateway = new PayeezyGateway($this->getHttpClient(), $this->getHttpRequest());
20 | $this->gateway->setGatewayId('1234');
21 | $this->gateway->setPassword('abcde');
22 |
23 | $this->options = array(
24 | 'amount' => '13.00',
25 | 'card' => $this->getValidCard(),
26 | 'transactionId' => 'order2',
27 | 'currency' => 'USD',
28 | 'testMode' => true,
29 | );
30 | }
31 |
32 | public function testProperties()
33 | {
34 | $this->assertEquals('1234', $this->gateway->getGatewayId());
35 | $this->assertEquals('abcde', $this->gateway->getPassword());
36 | }
37 |
38 | public function testPurchaseSuccess()
39 | {
40 | $this->setMockHttpResponse('PurchaseSuccess.txt');
41 |
42 | $response = $this->gateway->purchase($this->options)->send();
43 |
44 | $this->assertTrue($response->isSuccessful());
45 | $this->assertFalse($response->isRedirect());
46 | $this->assertEquals('ET181147::28513493', $response->getTransactionReference());
47 | $this->assertEquals('000056', $response->getSequenceNo());
48 | $this->assertEmpty($response->getCardReference());
49 | }
50 |
51 | public function testAuthorizeSuccess()
52 | {
53 | $this->setMockHttpResponse('PurchaseSuccess.txt');
54 |
55 | $response = $this->gateway->authorize($this->options)->send();
56 |
57 | $this->assertTrue($response->isSuccessful());
58 | $this->assertFalse($response->isRedirect());
59 | $this->assertEquals('ET181147::28513493', $response->getTransactionReference());
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/tests/WebserviceGatewayTest.php:
--------------------------------------------------------------------------------
1 | gateway = new WebserviceGateway($this->getHttpClient(), $this->getHttpRequest());
20 | $this->gateway->setSslCertificate('my.pem');
21 | $this->gateway->setSslKey('my.key');
22 | $this->gateway->setSslKeyPassword('thisISaPASSWORD');
23 | $this->gateway->setUserName('1234');
24 | $this->gateway->setPassword('abcde');
25 |
26 | $this->options = array(
27 | 'accountId' => '12345',
28 | 'transactionId' => '259611',
29 | 'amount' => '10.00',
30 | 'currency' => 'USD',
31 | 'clientIp' => '127.0.0.1',
32 | 'card' => $this->getValidCard(),
33 | 'testMode' => true,
34 | );
35 | }
36 |
37 | public function testProperties()
38 | {
39 | $this->assertEquals('my.pem', $this->gateway->getSslCertificate());
40 | $this->assertEquals('my.key', $this->gateway->getSslKey());
41 | $this->assertEquals('thisISaPASSWORD', $this->gateway->getSslKeyPassword());
42 | $this->assertEquals('1234', $this->gateway->getUserName());
43 | $this->assertEquals('abcde', $this->gateway->getPassword());
44 | }
45 |
46 | public function testPurchaseSuccess()
47 | {
48 | // Mocks don't work on this gateway because it has to call cURL directly.
49 | // $this->setMockHttpResponse('WebservicePurchaseSuccess.txt');
50 | $data = file_get_contents(__DIR__ . '/Mock/WebservicePurchaseSuccess.txt');
51 |
52 | $purchase = $this->gateway->purchase($this->options);
53 | $response = $purchase->createResponse($data);
54 |
55 | // echo "Response data =\n";
56 | // print_r($response->getData());
57 | // echo "\nEnd Response data\n";
58 |
59 | $this->assertTrue($response->isSuccessful());
60 | $this->assertFalse($response->isRedirect());
61 | $this->assertEquals('259611::1452486844', $response->getTransactionReference());
62 | $this->assertNull($response->getMessage());
63 | $this->assertEquals('APPROVED', $response->getCode());
64 | }
65 | }
66 |
--------------------------------------------------------------------------------