diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..0d77ee1a --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [barryvdh] diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 00000000..9683b370 --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,43 @@ +name: Unit Tests + +on: + push: + branches: + - master + pull_request: + branches: + - "*" + schedule: + - cron: '0 0 * * *' + +jobs: + php-tests: + runs-on: ubuntu-latest + timeout-minutes: 15 + env: + COMPOSER_NO_INTERACTION: 1 + + strategy: + matrix: + php: [8.3, 8.2, 8.1, 8.0, 7.4, 7.3] + dependency-version: [prefer-lowest, prefer-stable] + + name: P${{ matrix.php }} - ${{ matrix.dependency-version }} + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + tools: composer:v2 + + - name: Install dependencies + run: | + composer update --${{ matrix.dependency-version }} --prefer-dist --no-progress + + - name: Execute Unit Tests + run: composer test diff --git a/.gitignore b/.gitignore index 8a282a56..daea6b43 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ composer.lock composer.phar phpunit.xml +.idea/* diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c527189d..00000000 --- a/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -language: php - -php: - - 5.3 - - 5.4 - - 5.5 - -env: - - SYMFONY_VERSION="2.1" GUZZLE_VERSION="3.1" - - SYMFONY_VERSION="2.*" GUZZLE_VERSION="3.1" - - SYMFONY_VERSION="2.1" GUZZLE_VERSION="3.*" - - SYMFONY_VERSION="2.*" GUZZLE_VERSION="3.*" - -before_script: - - composer self-update - - composer --version - - composer require symfony/http-foundation:${SYMFONY_VERSION} --no-update - - composer require guzzle/http:${GUZZLE_VERSION} --no-update - -script: composer install -n --dev --prefer-source diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..951c346f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,170 @@ +Changelog +========= + +## v3.2 - 2021-06-01 + +Omnipay 3.2 is compatible with PHP8. This is done by upgrading the test suite to PHPUnit 8/9, with the release of omnipay/tests v4 and omnipay/common v3.1. This change is primarily for gateway developers, to make it possible to actually test PHP8, but they will need to upgrade their tests to use PHPUnit 9 (the currently supported PHPUnit version). +## v3.1 - 2020-10-29 + +Omnipay 3.1 uses Guzzle 7 by default (using the Guzzle 7 adapter). This doesn't change omnipay-common because they will work with any compatible Http Client. +The minimum PHP versions is bumped to 7.2 because of this. + +## v3.0 - 2018-05-14 + +Omnipay 3.0 focuses on separation of the HTTP Client, to be independent of Guzzle. +This release brings compatibility with the latest Symfony 3+4 and Laravel 5. +The breaking changes for applications using Omnipay are kept to a minimum. + +The `omnipay/omnipay` package name has been changed to `league/omnipay` + +### Upgrading applications from Omnipay 2.x to 3.x + +#### Breaking changes + - The `redirect()` method no calls `exit()` after sending the content. This is up to the developer now. + - An HTTP Client is required. Guzzle will be installed when using `league/omnipay`, + but otherwise you need to required your own implementation (see [PHP HTTP Clients](http://docs.php-http.org/en/latest/clients.html)) +- The `omnipay/omnipay` package name has been changed to `league/omnipay` and no longers installs all the gateways directly. + +#### Added + - It is now possible to use `setAmountInteger(integer $value)` to set the amount in the base units of the currency. + - Support for [Money for PHP](http://moneyphp.org/) objects are added, by using `setMoney(Money $money)` the Amount and Currency are set. + +### Upgrading Gateways from 2.x to 3.x + +The primary difference is the HTTP Client. We are now using HTTPlug (http://httplug.io/) but rely on our own interface. + +### Breaking changes +- Change typehint from Guzzle ClientInterface to `Omnipay\Common\Http\ClientInterface` +- `$client->get('..')`/`$client->post('..')` etc are removed, you can call `$client->request('GET', '')`. +- No need to call `$request->send()`, requests are sent directly. +- Instead of `$client->createRequest(..)` you can create+send the request directly with `$client->request(..)`. +- When sending a JSON body, convert the body to a string with `json_encode()` and set the correct Content-Type. +- The response is a PSR-7 Response object. You can call `$response->getBody()->getContents()` to get the body as string. +- `$response->json()` and `$response->xml()` are gone, but you can implement the logic directly. +- An HTTP Client is no longer added by default by `omnipay/common`, but `league/omnipay` will add Guzzle. +Gateways should not rely on Guzzle or other clients directly. +- `$body` should be a string (eg. `http_build_query($data)` or `json_encode($data)` instead of just `$data`). +- The `$headers` parameters should be an `array` (not `null`, but can be empty) + +Examples: +```php +// V2 XML: + $response = $this->httpClient->post($this->endpoint, null, $data)->send(); + $result = $httpResponse->xml(); + +// V3 XML: + $response = $this->httpClient->request('POST', $this->endpoint, [], http_build_query($data)); + $result = simplexml_load_string($httpResponse->getBody()->getContents()); +``` + +```php +// Example JSON request: + + $response = $this->httpClient->request('POST', $this->endpoint, [ + 'Accept' => 'application/json', + 'Content-Type' => 'application/json', + ], json_encode($data)); + + $result = json_decode($response->getBody()->getContents(), true); +``` + +#### Testing changes + +PHPUnit is upgraded to PHPUnit 6. Common issues: + +- `setExpectedException()` is removed + +```php +// PHPUnit 5: +$this->setExpectedException($class, $message); + +// PHPUnit 6: +$this->expectException($class); +$this->expectExceptionMessage($message); +``` + +- Tests that do not perform any assertions, will be marked as risky. This can be avoided by annotating them with ` @doesNotPerformAssertions` + +- You should remove the `Mockery\Adapter\Phpunit\TestListener` in phpunit.xml.dist + + +## v2.0.0 - 2013-11-17 + +### Package Separation + +As of 2.0, Omnipay has been split into separate packages. Core functionality is contained within the [omnipay/common](https://github.com/omnipay/common) repository, and all gateways have their own repositories. This means that if your project only requires on a single gateway, you can load it without installing all of the other gateways. All officially supported gateways can be found under the [Omnipay GitHub organization](//github.com/omnipay). + +If you want to install all gateways, you can still use the `omnipay/omnipay` metapackage in `composer.json`: + +~~~ javascript +{ + "require": { + "omnipay/omnipay": "~2.0" + } +} +~~~ + +Alternatively, if you want to migrate to an individual gateway, simply change your `composer.json` file to reference the specific gateway (`omnipay/common` will be included for you automatically): + +~~~ javascript +{ + "require": { + "omnipay/paypal": "~2.0" + } +} +~~~ + +### Breaking Changes + +The `GatewayFactory` class can no longer be called in a static fashion. To help those who want to use dependency injection, you can now create an instance of GatewayFactory: + +~~~ php +$factory = new GatewayFactory(); +$gateway = $factory->create('PayPal_Express'); +~~~ + +The following code is invalid and will no longer work: + +~~~ php +$gateway = GatewayFactory::create('PayPal_Express'); // will cause PHP error! +~~~ + +If you want to continue to use static methods for simplicity, you can use the new Omnipay class: + +~~~ php +// at the top of your PHP file +use Omnipay\Omnipay; + +// further down when you need to create the gateway +$gateway = Omnipay::create('PayPal_Express'); +~~~ + +Behind the scenes, this will create a GatewayFactory instance for you and call the appropriate method on it. + +### Additions + +**Omnipay now supports sending line-item data to gateways.** Currently this is only supported by the PayPal gateway. Line item details can be added to a request like so: + +~~~ php +$request->setItems(array( + array('name' => 'Food', 'quantity' => 1, 'price' => '40.00'), + array('name' => 'Drinks', 'quantity' => 2, 'price' => '6.00'), +)); +~~~ + +For more details, see the [pull request](https://github.com/omnipay/omnipay/pull/154). + +**Omnipay now also supports modifying request data before it is sent to the gateway.**. This allows you to send arbitrary custom data with a request, even if Omnipay doesn't support a parameter directly. To modify the request data, instead of calling `send()` directly on the request, you may use the new `sendData()` method: + +~~~ php +// standard method - send default data +$response = $request->send(); + +// new method - get and send custom data +$data = $request->getData(); +$data['customParameter'] = true; + +$response = $request->sendData($data); +~~~ + +For more details, see the [pull request](https://github.com/omnipay/omnipay/pull/162). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d67ed30d..6ad2b7f9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,5 +6,6 @@ * Commit just the modifications, do not mess with the composer.json or CHANGELOG.md files. * 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) style and that all tests pass. +* Don't forget to check all versionnumbers and tag it correctly in GIT ;) * Send the pull request. * Check that the Travis CI build passed. If not, rinse and repeat. diff --git a/LICENSE b/LICENSE index d49d0a9d..55cf185f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2012-2013 Adrian Macneil +Copyright (c) 2012-2018 Adrian Macneil Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/README.md b/README.md index edb0ce5b..3b1f96a5 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ # Omnipay -**An easy to use, consistent payment processing library for PHP 5.3+** +**An easy to use, consistent payment processing library for PHP** -[![Build Status](https://travis-ci.org/thephpleague/omnipay-common.png?branch=master)](https://travis-ci.org/thephpleague/omnipay-common) -[![Latest Stable Version](https://poser.pugx.org/omnipay/omnipay/version.png)](https://packagist.org/packages/omnipay/omnipay) -[![Total Downloads](https://poser.pugx.org/omnipay/omnipay/d/total.png)](https://packagist.org/packages/omnipay/omnipay) +[![Unit Tests](https://github.com/thephpleague/omnipay/actions/workflows/run-tests.yml/badge.svg)](https://github.com/thephpleague/omnipay/actions/workflows/run-tests.yml) +[![Latest Stable Version](https://poser.pugx.org/omnipay/common/version)](https://packagist.org/packages/omnipay/common) +[![Total Downloads](https://poser.pugx.org/omnipay/common/d/total)](https://packagist.org/packages/omnipay/common) Omnipay is a payment processing library for PHP. It has been designed based on ideas from [Active Merchant](http://activemerchant.org/), plus experience implementing -dozens of gateways for [CI Merchant](http://ci-merchant.org/). It has a clear and consistent API, +dozens of gateways for [CI Merchant]. It has a clear and consistent API, is fully unit tested, and even comes with an example application to get you started. **Why use Omnipay instead of a gateway's official PHP package/example code?** @@ -19,14 +19,6 @@ is fully unit tested, and even comes with an example application to get you star * Because most payment gateways have exceptionally poor documentation * Because you are writing a shopping cart and need to support multiple gateways -**Important Note: Upgrading from < 2.0** - -If you are upgrading from a pre-2.0 version of Omnipay, please note that the -project has now been split into multiple packages. There have also been some -changes to how gateway instances are created. See the -[full release notes](https://github.com/thephpleague/omnipay/releases/tag/v2.0.0) -for more details. - ## TL;DR Just want to see some code? @@ -37,15 +29,15 @@ use Omnipay\Omnipay; $gateway = Omnipay::create('Stripe'); $gateway->setApiKey('abc123'); -$formData = ['number' => '4242424242424242', 'expiryMonth' => '6', 'expiryYear' => '2016', 'cvv' => '123']; -$response = $gateway->purchase(['amount' => '10.00', 'currency' => 'USD', 'card' => $formData])->send(); +$formData = array('number' => '4242424242424242', 'expiryMonth' => '6', 'expiryYear' => '2030', 'cvv' => '123'); +$response = $gateway->purchase(array('amount' => '10.00', 'currency' => 'USD', 'card' => $formData))->send(); -if ($response->isSuccessful()) { - // payment was successful: update database - print_r($response); -} elseif ($response->isRedirect()) { +if ($response->isRedirect()) { // redirect to offsite payment gateway $response->redirect(); +} elseif ($response->isSuccessful()) { + // payment was successful: update database + print_r($response); } else { // payment failed: display message to customer echo $response->getMessage(); @@ -61,7 +53,8 @@ Omnipay is a collection of packages which all depend on the [omnipay/common](https://github.com/thephpleague/omnipay-common) package to provide a consistent interface. There are no dependencies on official payment gateway PHP packages - we prefer to work with the HTTP API directly. Under the hood, we use the popular and powerful -[Guzzle](http://guzzlephp.org/) library to make HTTP requests. +[PHP-HTTP](http://docs.php-http.org/en/latest/index.html) library to make HTTP requests. +A [Guzzle](http://guzzlephp.org/) adapter is required by default, when using `league/omnipay`. New gateways can be created by cloning the layout of an existing package. When choosing a name for your package, please don't use the `omnipay` vendor prefix, as this implies that @@ -70,83 +63,235 @@ it is officially supported. You should use your own username as the vendor prefi For example, if your GitHub username was `santa`, and you were implementing the `giftpay` payment library, a good name for your composer package would be `santa/omnipay-giftpay`. -If you want to transfer your gateway to the `omnipay` GitHub organization and add it -to the list of officially supported gateways, please open a pull request on the -[omnipay/common](https://github.com/thephpleague/omnipay-common) package. Before new gateways will -be accepted, they must have 100% unit test code coverage, and follow the conventions -and code style used in other Omnipay gateways. - ## Installation -Omnipay is installed via [Composer](http://getcomposer.org/). To install all officially -supported gateways, simply add the following to your `composer.json` file: +Omnipay is installed via [Composer](https://getcomposer.org/). +For most uses, you will need to require `league/omnipay` and an individual gateway: -```json -{ - "require": { - "omnipay/omnipay": "~2.0" - } -} +``` +composer require league/omnipay:^3 omnipay/paypal ``` -Alternatively, you can require individual gateways: +If you want to use your own HTTP Client instead of Guzzle (which is the default for `league/omnipay`), +you can require `omnipay/common` and any `php-http/client-implementation` (see [PHP Http](http://docs.php-http.org/en/latest/clients.html)) -```json -{ - "require": { - "omnipay/paypal": "~2.0" - } -} ``` +composer require league/common:^3 omnipay/paypal php-http/buzz-adapter +``` + +## Upgrade from v2 to v3 -Next, run composer to update your dependencies: +If your gateway is supported for v3, you can require that version. Make sure you require `league/omnipay` or a separate Http Adapter. - $ curl -s http://getcomposer.org/installer | php - $ php composer.phar update +If there is no version for v3 yet, please raise an issue or upgrade the gateways yourself and create a PR. +See the [Upgrade guide for omnipay/common](https://github.com/thephpleague/omnipay-common/blob/master/UPGRADE.md) + +> Note: The package name has been changed from `omnipay/omnipay` to `league/omnipay` for v3 ## Payment Gateways -All payment gateways must implement [GatewayInterface](https://github.com/thephpleague/omnipay-common/blob/master/src/Omnipay/Common/GatewayInterface.php), and will usually -extend [AbstractGateway](https://github.com/thephpleague/omnipay-common/blob/master/src/Omnipay/Common/AbstractGateway.php) for basic functionality. +All payment gateways must implement [GatewayInterface](https://github.com/thephpleague/omnipay-common/blob/master/src/Common/GatewayInterface.php), and will usually +extend [AbstractGateway](https://github.com/thephpleague/omnipay-common/blob/master/src/Common/AbstractGateway.php) for basic functionality. The following gateways are available: -Gateway | Composer Package | Maintainer ---- | --- | --- -[2Checkout](https://github.com/thephpleague/omnipay-2checkout) | omnipay/twocheckout | [Adrian Macneil](https://github.com/adrianmacneil) -[Alipay](https://github.com/lokielse/omnipay-alipay) | lokielse/omnipay-alipay | [Loki Else](https://github.com/lokielse) -[Authorize.Net](https://github.com/thephpleague/omnipay-authorizenet) | omnipay/authorizenet | [Adrian Macneil](https://github.com/adrianmacneil) -[Buckaroo](https://github.com/thephpleague/omnipay-buckaroo) | omnipay/buckaroo | [Adrian Macneil](https://github.com/adrianmacneil) -[CardSave](https://github.com/thephpleague/omnipay-cardsave) | omnipay/cardsave | [Adrian Macneil](https://github.com/adrianmacneil) -[Coinbase](https://github.com/thephpleague/omnipay-coinbase) | omnipay/coinbase | [Adrian Macneil](https://github.com/adrianmacneil) -[DataCash](https://github.com/coatesap/omnipay-datacash) | coatesap/omnipay-datacash | [Andrew Coates](https://github.com/coatesap) -[Dummy](https://github.com/thephpleague/omnipay-dummy) | omnipay/dummy | [Adrian Macneil](https://github.com/adrianmacneil) -[eWAY](https://github.com/thephpleague/omnipay-eway) | omnipay/eway | [Adrian Macneil](https://github.com/adrianmacneil) -[First Data](https://github.com/thephpleague/omnipay-firstdata) | omnipay/firstdata | [Andrew Coates](https://github.com/coatesap) -[GoCardless](https://github.com/thephpleague/omnipay-gocardless) | omnipay/gocardless | [Adrian Macneil](https://github.com/adrianmacneil) -[Manual](https://github.com/thephpleague/omnipay-manual) | omnipay/manual | [Adrian Macneil](https://github.com/adrianmacneil) -[Migs](https://github.com/thephpleague/omnipay-migs) | omnipay/migs | [Adrian Macneil](https://github.com/adrianmacneil) -[Mollie](https://github.com/thephpleague/omnipay-mollie) | omnipay/mollie | [Adrian Macneil](https://github.com/adrianmacneil) -[MultiSafepay](https://github.com/thephpleague/omnipay-multisafepay) | omnipay/multisafepay | [Alexander Deruwe](https://github.com/aderuwe) -[Netaxept (BBS)](https://github.com/thephpleague/omnipay-netaxept) | omnipay/netaxept | [Adrian Macneil](https://github.com/adrianmacneil) -[Netbanx](https://github.com/thephpleague/omnipay-netbanx) | omnipay/netbanx | [Maks Rafalko](https://github.com/borNfreee) -[Neteller](https://github.com/alfaproject/omnipay-neteller) | alfaproject/omnipay-neteller | [João Dias](https://github.com/alfaproject) -[Pacnet](https://github.com/mfauveau/omnipay-pacnet) | mfauveau/omnipay-pacnet | [Matthieu Fauveau](https://github.com/mfauveau) -[PayFast](https://github.com/thephpleague/omnipay-payfast) | omnipay/payfast | [Adrian Macneil](https://github.com/adrianmacneil) -[Payflow](https://github.com/thephpleague/omnipay-payflow) | omnipay/payflow | [Adrian Macneil](https://github.com/adrianmacneil) -[PaymentExpress (DPS)](https://github.com/thephpleague/omnipay-paymentexpress) | omnipay/paymentexpress | [Adrian Macneil](https://github.com/adrianmacneil) -[PaymentSense](https://github.com/coatesap/omnipay-paymentsense) | coatesap/omnipay-paymentsense | [Andrew Coates](https://github.com/coatesap) -[PayPal](https://github.com/thephpleague/omnipay-paypal) | omnipay/paypal | [Adrian Macneil](https://github.com/adrianmacneil) -[Pin Payments](https://github.com/thephpleague/omnipay-pin) | omnipay/pin | [Adrian Macneil](https://github.com/adrianmacneil) -[Realex](https://github.com/coatesap/omnipay-realex) | coatesap/omnipay-realex | [Andrew Coates](https://github.com/coatesap) -[Sage Pay](https://github.com/thephpleague/omnipay-sagepay) | omnipay/sagepay | [Adrian Macneil](https://github.com/adrianmacneil) -[SecurePay](https://github.com/thephpleague/omnipay-securepay) | omnipay/securepay | [Adrian Macneil](https://github.com/adrianmacneil) -[SecPay](https://github.com/justinbusschau/omnipay-secpay) | justinbusschau/omnipay-secpay | [Justin Busschau](https://github.com/justinbusschau) -[Sisow](https://github.com/nettob/omnipay-sisow) | nettob/omnipay-sisow | [Niek](https://github.com/nettob) -[Skrill](https://github.com/alfaproject/omnipay-skrill) | alfaproject/omnipay-skrill | [João Dias](https://github.com/alfaproject) -[Stripe](https://github.com/thephpleague/omnipay-stripe) | omnipay/stripe | [Adrian Macneil](https://github.com/adrianmacneil) -[TargetPay](https://github.com/thephpleague/omnipay-targetpay) | omnipay/targetpay | [Alexander Deruwe](https://github.com/aderuwe) -[WorldPay](https://github.com/thephpleague/omnipay-worldpay) | omnipay/worldpay | [Adrian Macneil](https://github.com/adrianmacneil) +Gateway | 2.x | 3.x | Composer Package | Maintainer +--- | --- | --- | --- | --- +[2c2p](https://github.com/dilab/omnipay-2c2p) | ✓ | ✓ | dilab/omnipay-2c2p | [Xu Ding](https://github.com/dilab) +[2Checkout](https://github.com/thephpleague/omnipay-2checkout) | ✓ | - | omnipay/2checkout | [Omnipay](https://github.com/thephpleague/omnipay) +[2Checkout Improved](https://github.com/collizo4sky/omnipay-2checkout) | ✓ | - | collizo4sky/omnipay-2checkout | [Agbonghama Collins](https://github.com/collizo4sky) +[99Bill](https://github.com/laraveler/omnipay-99bill) | - | ✓ | x-class/omnipay-99bill | [Laraveler](https://github.com/laraveler) +[Acapture (PayVision)](https://github.com/queueup-dev/omnipay-acapture) | ✓ | - | qup/omnipay-acapture | [Niels de Vries](https://github.com/niels-qup) +[Adyen](https://github.com/academe/omnipay-adyen) | - | ✓ | academe/omnipay-adyen | [Jason Judge](https://github.com/judgej) +[Affirm](https://github.com/eduardlleshi/omnipay-affirm) | ✓ | ✓ | eduardlleshi/omnipay-affirm | [Eduard Lleshi](https://github.com/eduardlleshi) +[Agms](https://github.com/agmscode/omnipay-agms) | ✓ | - | agmscode/omnipay-agms | [Maanas Royy](https://github.com/maanas) +[Alipay(Global)](https://github.com/lokielse/omnipay-global-alipay) | ✓ | ✓ | lokielse/omnipay-global-alipay | [Loki Else](https://github.com/lokielse) +[Alipay](https://github.com/lokielse/omnipay-alipay) | ✓ | ✓ | lokielse/omnipay-alipay | [Loki Else](https://github.com/lokielse) +[Allied Wallet](https://github.com/delatbabel/omnipay-alliedwallet) | ✓ | - | delatbabel/omnipay-alliedwallet | [Del](https://github.com/delatbabel) +[Arca](https://github.com/k3rnel/omnipay-arca) | - | ✓ | k3rnel/omnipay-arca | [Poghos Boyajyan](https://github.com/k3rnel) +[Authorize.Net](https://github.com/thephpleague/omnipay-authorizenet) | ✓ | ✓ | omnipay/authorizenet | [Jason Judge](https://github.com/judgej) +[Authorize.Net API](https://github.com/academe/omnipay-authorizenetapi) | - | ✓ | academe/omnipay-authorizenetapi | [Jason Judge](https://github.com/judgej) +[Authorize.Net Recurring Billing](https://github.com/cimpleo/omnipay-authorizenetrecurring) | - | ✓ | cimpleo/omnipay-authorizenetrecurring | [CimpleO](https://github.com/cimpleo) +[Bankart](https://github.com/ampeco/omnipay-bankart) | ✓ | ✓ | ampeco/omnipay-bankart | [Ampeco](https://github.com/ampeco) +[Barclays ePDQ](https://github.com/digitickets/omnipay-barclays-epdq) | ✓ | - | digitickets/omnipay-barclays-epdq | [DigiTickets](https://github.com/digitickets) +[BlueOrange bank](https://github.com/DeH4eG/omnipay-blueorange) | - | ✓ | deh4eg/omnipay-blueorange | [Denis Smolakov](https://github.com/DeH4eG) +[Beanstream](https://github.com/lemonstand/omnipay-beanstream) | ✓ | - | lemonstand/omnipay-beanstream | [LemonStand](https://github.com/lemonstand) +[BitPay](https://github.com/hiqdev/omnipay-bitpay) | ✓ | ✓ | hiqdev/omnipay-bitpay | [HiQDev](https://github.com/hiqdev) +[BKM Express](https://github.com/yasinkuyu/omnipay-bkm) | ✓ | - | yasinkuyu/omnipay-bkm | [Yasin Kuyu](https://github.com/yasinkuyu) +[BlueSnap](https://github.com/vimeo/omnipay-bluesnap) | ✓ | - | vimeo/omnipay-bluesnap | [Vimeo](https://github.com/vimeo) +[Braintree](https://github.com/thephpleague/omnipay-braintree) | ✓ | ✓ | omnipay/braintree | [Omnipay](https://github.com/thephpleague/omnipay) +[Buckaroo](https://github.com/thephpleague/omnipay-buckaroo) | ✓ | - | omnipay/buckaroo | [Omnipay](https://github.com/thephpleague/omnipay) +[CardGate](https://github.com/cardgate/omnipay-cardgate) | ✓ | - | cardgate/omnipay-cardgate | [CardGate](https://github.com/cardgate) +[CardSave](https://github.com/thephpleague/omnipay-cardsave) | ✓ | - | omnipay/cardsave | [Omnipay](https://github.com/thephpleague/omnipay) +[CashBaBa](https://github.com/tapos007/omnipay-cashbaba) | ✓ | ✓ | omnipay/cashbaba | [Recursion Technologies Ltd](https://github.com/tapos007) +[Checkout.com](https://github.com/fotografde/omnipay-checkoutcom) | ✓ | - | fotografde/checkoutcom | [fotograf.de](https://github.com/fotografde) +[CloudBanking](https://github.com/spsingh/omnipay-cloudbanking) | ✓ | - | cloudbanking/omnipay-cloudbanking | [Cloudbanking](http://cloudbanking.com.au/) +[Coinbase](https://github.com/thephpleague/omnipay-coinbase) | ✓ | - | omnipay/coinbase | [Omnipay](https://github.com/thephpleague/omnipay) +[CoinGate](https://github.com/coingate/omnipay-coingate) | ✓ | - | coingate/omnipay-coingate | [CoinGate](https://github.com/coingate) +[CoinPayments](https://github.com/InkedCurtis/omnipay-coinpayments) | ✓ | ✓ | InkedCurtis/omnipay-coinpayments | [InkedCurtis](https://github.com/InkedCurtis) +[Creditcall](https://github.com/meebio/omnipay-creditcall) | ✓ | - | meebio/omnipay-creditcall | [John Jablonski](https://github.com/jan-j) +[CSOB](https://github.com/bileto/omnipay-csob) (GP WebPay) | ✓ | - | bileto/omnipay-csob | +[Cybersource](https://github.com/dioscouri/omnipay-cybersource) | ✓ | ✓ | dioscouri/omnipay-cybersource | [Dioscouri Design](https://github.com/dioscouri) +[Cybersource SOAP](https://github.com/Klinche/omnipay-cybersource-soap) | ✓ | - | dabsquared/omnipay-cybersource-soap | [DABSquared](https://github.com/DABSquared) +[DataCash](https://github.com/digitickets/omnipay-datacash) | ✓ | - | digitickets/omnipay-datacash | [DigiTickets](https://github.com/digitickets) +[Datatrans](https://github.com/w-vision/omnipay-datatrans) | ✓ | - | w-vision/datatrans | [Dominik Pfaffenbauer](https://github.com/dpfaffenbauer) +[Datatrans](https://github.com/academe/omnipay-datatrans) | ✓ | ✓ | academe/omnipay-datatrans | [Jason Judge](https://github.com/judgej) +[Docdata Payments](https://github.com/Uskur/omnipay-docdata-payments) | ✓ | ✓ | uskur/omnipay-docdata-payments | [Uskur](https://github.com/Uskur) +[Dummy](https://github.com/thephpleague/omnipay-dummy) | ✓ | ✓ | omnipay/dummy | [Del](https://github.com/delatbabel) +[Ebanx](https://github.com/descubraomundo/omnipay-ebanx) | - | ✓ | descubraomundo/omnipay-ebanx | [Descubra o Mundo](https://github.com/descubraomundo/) +[eGHL](https://bitbucket.org/eghl/eghl-omnipay/src/master/) | - | ✓ | e-ghl/omnipay | [Jawad Humayun](https://bitbucket.org/jawad242/) +[eGHL](https://github.com/dilab/omnipay-eghl) | ✓ | ✓ | dilab/omnipay-eghl | [Xu Ding](https://github.com/dilab) +[eCoin](https://github.com/hiqdev/omnipay-ecoin) | ✓ | ✓ | hiqdev/omnipay-ecoin | [HiQDev](https://github.com/hiqdev) +[ecoPayz](https://github.com/dercoder/omnipay-ecopayz) | ✓ | - | dercoder/omnipay-ecopayz | [Alexander Fedra](https://github.com/dercoder) +[eSewa](https://github.com/sudiptpa/esewa) | - | ✓ | sudiptpa/omnipay-esewa | [Sujip Thapa](https://github.com/sudiptpa) +[EgopayRu](https://github.com/pinguinjkeke/omnipay-egopaymentru) | ✓ | - | pinguinjkeke/omnipay-egopaymentru | [Alexander Avakov](https://github.com/pinguinjkeke) +[Elavon](https://github.com/lxrco/omnipay-elavon) | ✓ | ✓ | lxrco/omnipay-elavon | [Korri](https://github.com/Korri) +[ePayments](https://github.com/hiqdev/omnipay-epayments) | ✓ | ✓ | hiqdev/omnipay-epayments | [HiQDev](https://github.com/hiqdev) +[ePayService](https://github.com/hiqdev/omnipay-epayservice) | ✓ | ✓ | hiqdev/omnipay-epayservice | [HiQDev](https://github.com/hiqdev) +[eWAY](https://github.com/thephpleague/omnipay-eway) | ✓ | ✓ | omnipay/eway | [Del](https://github.com/delatbabel) +[Fasapay](https://github.com/andreas22/omnipay-fasapay) | ✓ | - | andreas22/omnipay-fasapay | [Andreas Christodoulou](https://github.com/andreas22) +[Faspay](https://github.com/David-Kurniawan/omnipay-faspay) | ✓ | ✓ | David-Kurniawan/omnipay-faspay | [David](https://github.com/David-Kurniawan) +[Fat Zebra](https://github.com/delatbabel/omnipay-fatzebra) | ✓ | - | delatbabel/omnipay-fatzebra | [Del](https://github.com/delatbabel) +[FreeKassa](https://github.com/hiqdev/omnipay-freekassa) | ✓ | ✓ | hiqdev/omnipay-freekassa | [HiQDev](https://github.com/hiqdev) +[Fibank](https://github.com/ampeco/omnipay-fibank) | - | ✓ | ampeco/omnipay-fibank | [Ampeco](https://github.com/ampeco) +[First Data](https://github.com/thephpleague/omnipay-firstdata) | ✓ | - | omnipay/firstdata | [OmniPay](https://github.com/thephpleague/omnipay) +[Flo2cash](https://github.com/guisea/omnipay-flo2cash) | ✓ | - | guisea/omnipay-flo2cash | [Aaron Guise](https://github.com/guisea) +[Free / Zero Amount](https://github.com/colinodell/omnipay-zero) | ✓ | - | colinodell/omnipay-zero | [Colin O'Dell](https://github.com/colinodell) +[GiroCheckout](https://github.com/academe/Omnipay-GiroCheckout) | ✓ | ✓ | academe/omnipay-girocheckout | [Jason Judge](https://github.com/judgej) +[Globalcloudpay](https://github.com/dercoder/omnipay-globalcloudpay) | ✓ | - | dercoder/omnipay-globalcloudpay | [Alexander Fedra](https://github.com/dercoder) +[GoCardless](https://github.com/thephpleague/omnipay-gocardless) | ✓ | - | omnipay/gocardless | [Del](https://github.com/delatbabel) +[GoPay](https://github.com/bileto/omnipay-gopay) | ✓ | - | bileto/omnipay-gopay | +[GovPayNet](https://github.com/flexcoders/omnipay-govpaynet) | ✓ | - | omnipay/omnipay-govpaynet | [FlexCoders](https://github.com/flexcoders) +[GVP (Garanti)](https://github.com/yasinkuyu/omnipay-gvp) | ✓ | - | yasinkuyu/omnipay-gvp | [Yasin Kuyu](https://github.com/yasinkuyu) +[GVP (Garanti)](https://github.com/emr/omnipay-gvp) | - | ✓ | emr/omnipay-gvp | [Emre Akinci](https://github.com/emr) +[Helcim](https://github.com/academe/omnipay-helcim) | ✓ | - | academe/omnipay-helcim | [Jason Judge](https://github.com/judgej) +[Icepay Payments](https://github.com/superbrave/omnipay-icepay-payments) | - | ✓ | superbrave/omnipay-icepay-payments | [SuperBrave](https://github.com/superbrave) +[iDram](https://github.com/ptuchik/omnipay-idram) | - | ✓ | ptuchik/omnipay-idram | [Avik Aghajanyan](https://github.com/ptuchik) +[iDeal](https://github.com/deniztezcan/omnipay-ideal) | - | ✓ | deniztezcan/omnipay-ideal | [Deniz Tezcan](https://github.com/deniztezcan) +[Ingenico ePayments](https://github.com/deniztezcan/omnipay-ingenico-epayments) | - | ✓ | deniztezcan/omnipay-ingenico-epayments | [Deniz Tezcan](https://github.com/deniztezcan) +[iPay88](https://github.com/dilab/omnipay-ipay88) | ✓ | ✓ | dilab/omnipay-ipay88 | [Xu Ding](https://github.com/dilab) +[IfthenPay](https://github.com/ifthenpay/omnipay-ifthenpay) | ✓ | - | ifthenpay/omnipay-ifthenpay | [Rafael Almeida](https://github.com/rafaelcpalmeida) +[Ikajo](https://github.com/hiqdev/omnipay-ikajo) | ✓ | ✓ | hiqdev/omnipay-ikajo | [HiQDev](https://github.com/hiqdev) +[InterKassa](https://github.com/hiqdev/omnipay-interkassa) | ✓ | ✓ | hiqdev/omnipay-interkassa | [HiQDev](https://github.com/hiqdev) +[InovioPay](https://github.com/mvestil/omnipay-inoviopay) | ✓ | ✓ | mvestil/omnipay-inoviopay | [Mark Vestil](https://github.com/mvestil) +[Iyzico](https://github.com/yasinkuyu/omnipay-iyzico) | ✓ | - | yasinkuyu/omnipay-iyzico | [Yasin Kuyu](https://github.com/yasinkuyu) +[Judo Pay](https://github.com/Transportersio/omnipay-judopay) | ✓ | - | transportersio/omnipay-judopay | [Transporters.io](https://github.com/Transportersio) +[Klarna Checkout](https://github.com/MyOnlineStore/omnipay-klarna-checkout) | ✓ | ✓ | myonlinestore/omnipay-klarna-checkout | [MyOnlineStore](https://github.com/MyOnlineStore) +[Laybuy](https://github.com/mediabeastnz/omnipay-laybuy) | ✓ | - | mediabeastnz/omnipay-laybuy | [Myles Derham](https://github.com/mediabeastnz) +[Luminor Gateway](https://github.com/DeH4eG/omnipay-luminor) | - | ✓ | deh4eg/omnipay-luminor | [Denis Smolakov](https://github.com/DeH4eG) +[Komerci (Rede, former RedeCard)](https://github.com/byjg/omnipay-komerci) | ✓ | - | byjg/omnipay-komerci | [João Gilberto Magalhães](https://github.com/byjg) +[Komoju](https://github.com/dannyvink/omnipay-komoju) | ✓ | - | vink/omnipay-komoju | [Danny Vink](https://github.com/dannyvink) +[Midtrans](https://github.com/dilab/omnipay-midtrans) | ✓ | ✓ | dilab/omnipay-midtrans | [Xu Ding](https://github.com/dilab) +[MercadoPago](https://github.com/lucassmacedo/omnipay-mercadopago) | - | ✓ | lucassmacedo/omnipay-mercadopago | [Lucas Macedo](https://github.com/lucassmacedo) +[Magnius](https://github.com/fruitcake/omnipay-magnius) | - | ✓ | fruitcake/omnipay-magnius | [Fruitcake](https://github.com/fruitcake) +[Manual](https://github.com/thephpleague/omnipay-manual) | ✓ | - | omnipay/manual | [Del](https://github.com/delatbabel) +[Migs](https://github.com/thephpleague/omnipay-migs) | ✓ | - | omnipay/migs | [Omnipay](https://github.com/thephpleague/omnipay) +[Mpesa](https://github.com/wasksofts/omnipay-mpesa) | ✓ | - | wasksofts/omnipay-mpesa | [wasksofts](https://github.com/wasksofts/omnipay-mpesa) +[MTNCAM Mobile Money](https://github.com/larrytech7/omnipay-momocm) | ✓ | ✓ | larrytech7/omnipay-momocm | [Akah Harvey](https://github.com/larrytech7) +[Mollie](https://github.com/thephpleague/omnipay-mollie) | ✓ | ✓ | omnipay/mollie | [Barry vd. Heuvel](https://github.com/barryvdh) +[MOLPay](https://github.com/leesiongchan/omnipay-molpay) | ✓ | - | leesiongchan/molpay | [Lee Siong Chan](https://github.com/leesiongchan) +[MoMo](https://github.com/phpviet/omnipay-momo) | - | ✓ | phpviet/omnipay-momo | [PHPViet](https://github.com/phpviet) +[Moneris](https://github.com/unoapp-dev/omnipay-moneris) | - | ✓ | unoapp-dev/omnipay-moneris | [UNOapp Dev](https://github.com/unoapp-dev) +[MultiCards](https://github.com/incube8/omnipay-multicards) | ✓ | - | incube8/omnipay-multicards | [Del](https://github.com/delatbabel) +[MultiSafepay](https://github.com/thephpleague/omnipay-multisafepay) | ✓ | - | omnipay/multisafepay | [Alexander Deruwe](https://github.com/aderuwe) +[MyCard](https://github.com/xxtime/omnipay-mycard) | ✓ | - | xxtime/omnipay-mycard | [Joe Chu](https://github.com/xxtime) +[MyFatoorah](https://github.com/my-fatoorah/omnipay-myfatoorah) | - | ✓ | myfatoorah/omnipay | [MyFatoorah Plugins Team](https://github.com/my-fatoorah) +[National Australia Bank (NAB) Transact](https://github.com/sudiptpa/omnipay-nabtransact) | ✓ | ✓ | sudiptpa/omnipay-nabtransact | [Sujip Thapa](https://github.com/sudiptpa) +[NestPay (EST)](https://github.com/yasinkuyu/omnipay-nestpay) | ✓ | - | yasinkuyu/omnipay-nestpay | [Yasin Kuyu](https://github.com/yasinkuyu) +[NestPay (EST)](https://github.com/uskur/omnipay-nestpay) | - | ✓ | uskur/omnipay-nestpay | [Uskur](https://github.com/uskur) +[Netaxept (BBS)](https://github.com/thephpleague/omnipay-netaxept) | ✓ | - | omnipay/netaxept | [Omnipay](https://github.com/thephpleague/omnipay) +[Netbanx](https://github.com/thephpleague/omnipay-netbanx) | ✓ | - | omnipay/netbanx | [Maks Rafalko](https://github.com/borNfreee) +[Neteller](https://github.com/dercoder/omnipay-neteller) | ✓ | - | dercoder/omnipay-neteller | [Alexander Fedra](https://github.com/dercoder) +[NetPay](https://github.com/netpay/omnipay-netpay) | ✓ | - | netpay/omnipay-netpay | [NetPay](https://github.com/netpay) +[Network Merchants Inc. (NMI)](https://github.com/mfauveau/omnipay-nmi) | ✓ | - | mfauveau/omnipay-nmi | [Matthieu Fauveau](https://github.com/mfauveau) +[Nocks](https://github.com/nocksapp/checkout-omnipay) | ✓ | ✓ | nocksapp/omnipay-nocks | [Nocks](https://github.com/nocksapp) +[Nuvei](https://github.com/diversifiedtech/omnipay-nuvei) | - | ✓ | nmc9/omnipay-nuvei | [DiversifiedTech](https://github.com/diversifiedtech) +[OkPay](https://github.com/hiqdev/omnipay-okpay) | ✓ | ✓ | hiqdev/omnipay-okpay | [HiQDev](https://github.com/hiqdev) +[OnePay](https://github.com/dilab/omnipay-onepay) | ✓ | ✓ | dilab/omnipay-onepay | [Xu Ding](https://github.com/dilab) +[Openpay Australia](https://github.com/sudiptpa/openpay) | ✓ | ✓ | sudiptpa/omnipay-openpay | [Sujip Thapa](https://github.com/sudiptpa) +[Oppwa](https://github.com/vdbelt/omnipay-oppwa) | ✓ | ✓ | vdbelt/omnipay-oppwa | [Martin van de Belt](https://github.com/vdbelt) +[PAY. (Pay.nl & Pay.be)](https://github.com/paynl/omnipay-paynl) | ✓ | ✓ | paynl/omnipay-paynl | [Andy Pieters](https://github.com/andypieters) +[PayMongo](https://github.com/oozman/omnipay-paymongo) | - | ✓ | oozman/omnipay-paymongo | [Oozman](https://github.com/oozman) +[Payoo](https://github.com/dilab/omnipay-payoo) | ✓ | ✓ | dilab/omnipay-payoo | [Xu Ding](https://github.com/dilab) +[Pacnet](https://github.com/mfauveau/omnipay-pacnet) | ✓ | - | mfauveau/omnipay-pacnet | [Matthieu Fauveau](https://github.com/mfauveau) +[Pagar.me](https://github.com/descubraomundo/omnipay-pagarme) | ✓ | - | descubraomundo/omnipay-pagarme | [Descubra o Mundo](https://github.com/descubraomundo) +[Paratika (Asseco)](https://github.com/yasinkuyu/omnipay-paratika) | ✓ | - | yasinkuyu/omnipay-paratika | [Yasin Kuyu](https://github.com/yasinkuyu) +[PayFast](https://github.com/thephpleague/omnipay-payfast) | ✓ | - | omnipay/payfast | [Omnipay](https://github.com/thephpleague/omnipay) +[PayGate](https://github.com/mvnrsa/omnipay-paygate) | - | ✓ | mvnrsa/paygate | [Marnus van Niekerk](https://github.com/mvnrsa) +[Payflow](https://github.com/thephpleague/omnipay-payflow) | ✓ | - | omnipay/payflow | [Del](https://github.com/delatbabel) +[PaymentExpress (DPS)](https://github.com/thephpleague/omnipay-paymentexpress) | ✓ | ✓ | omnipay/paymentexpress | [Del](https://github.com/delatbabel) +[PaymentExpress / DPS (A2A)](https://github.com/onlinesid/omnipay-paymentexpress-a2a) | ✓ | - | onlinesid/omnipay-paymentexpress-a2a | [Sid](https://github.com/onlinesid) +[PaymentgateRu](https://github.com/pinguinjkeke/omnipay-paymentgateru) | ✓ | ✓ | pinguinjkeke/omnipay-paymentgateru | [Alexander Avakov](https://github.com/pinguinjkeke) +[PaymentSense](https://github.com/digitickets/omnipay-paymentsense) | ✓ | - | digitickets/omnipay-paymentsense | [DigiTickets](https://github.com/digitickets) +[PaymentWall](https://github.com/incube8/omnipay-paymentwall) | ✓ | - | incube8/omnipay-paymentwall | [Del](https://github.com/delatbabel) +[Paynow](https://github.com/pay-now/omnipay-paynow) | - | ✓ | pay-now/omnipay-paynow | [Paynow](https://github.com/pay-now) +[PayPal](https://github.com/thephpleague/omnipay-paypal) | ✓ | ✓ | omnipay/paypal | [Del](https://github.com/delatbabel) +[PayPro](https://github.com/payproNL/omnipay-paypro) | ✓ | - | paypronl/omnipay-paypro | [Fruitcake](https://github.com/fruitcake) +[PAYONE](https://github.com/academe/omnipay-payone) | ✓ | ✓ | academe/omnipay-payone | [Jason Judge](https://github.com/judgej) +[Paysafecard](https://github.com/dercoder/omnipay-paysafecard) | ✓ | - | dercoder/omnipay-paysafecard | [Alexander Fedra](https://github.com/dercoder) +[Paysafecard](https://github.com/worldstream-labs/omnipay-paysafecard) | - | ✓ | worldstream-labs/omnipay-paysafecard | [Worldstream](https://github.com/worldstream-labs) +[Paysafe Payment Hub (Neteller)](https://github.com/worldstream-labs/omnipay-paysafe-payment-hub) | - | ✓ | worldstream-labs/omnipay-paysafe-payment-hub | [Worldstream](https://github.com/worldstream-labs) +[Paysera](https://github.com/povils/omnipay-paysera) | ✓ | - | povils/omnipay-paysera | [Povils](https://github.com/povils) +[Paysera](https://github.com/semyonchetvertnyh/omnipay-paysera) | - | ✓ | semyonchetvertnyh/omnipay-paysera | [Semyon Chetvertnyh](https://github.com/semyonchetvertnyh) +[PaySimple](https://github.com/dranes/omnipay-paysimple) | ✓ | - | dranes/omnipay-paysimple | [Dranes](https://github.com/dranes) +[PaySsion](https://github.com/InkedCurtis/omnipay-payssion) | ✓ | - | inkedcurtis/omnipay-payssion | [Curtis](https://github.com/inkedcurtis) +[PayTrace](https://github.com/iddqdidkfa/omnipay-paytrace) | ✓ | - | softcommerce/omnipay-paytrace | [Oleg Ilyushyn](https://github.com/iddqdidkfa) +[PayU](https://github.com/bileto/omnipay-payu) | ✓ | - | bileto/omnipay-payu | +[PayZen](https://github.com/ubitransports/omnipay-payzen) | ✓ | - | ubitransports/omnipay-payzen | [Ubitransport](https://github.com/ubitransports) +[Paxum](https://github.com/hiqdev/omnipay-paxum) | ✓ | ✓ | hiqdev/omnipay-paxum | [HiQDev](https://github.com/hiqdev) +[Pelecard](https://github.com/Uskur/omnipay-pelecard) | ✓ | ✓ | uskur/omnipay-pelecard | [Uskur](https://github.com/Uskur) +[Pin Payments](https://github.com/thephpleague/omnipay-pin) | ✓ | - | omnipay/pin | [Del](https://github.com/delatbabel) +[Ping++](https://github.com/phoenixg/omnipay-pingpp) | ✓ | - | phoenixg/omnipay-pingpp | [Huang Feng](https://github.com/phoenixg) +[POLi](https://github.com/burnbright/omnipay-poli) | ✓ | - | burnbright/omnipay-poli | [Sid](https://github.com/onlinesid) +[Portmanat](https://github.com/dercoder/omnipay-portmanat) | ✓ | - | dercoder/omnipay-portmanat | [Alexander Fedra](https://github.com/dercoder) +[Posnet](https://github.com/yasinkuyu/omnipay-posnet) | ✓ | - | yasinkuyu/omnipay-posnet | [Yasin Kuyu](https://github.com/yasinkuyu) +[Postfinance](https://github.com/bummzack/omnipay-postfinance) | ✓ | - | bummzack/omnipay-postfinance | [Roman Schmid](https://github.com/bummzack) +[Qiwi](https://github.com/hiqdev/omnipay-qiwi) | ✓ | ✓ | hiqdev/omnipay-qiwi | [HiQDev](https://github.com/hiqdev) +[QQ Wallet(QPay)](https://github.com/kuangjy2/omnipay-qpay) | - | ✓ | kuangjy/omnipay-qpay | [Kuang Jiaye](https://github.com/kuangjy2) +[Quickpay](https://github.com/NobrainerWeb/omnipay-quickpay) | ✓ | - | nobrainerweb/omnipay-quickpay | [Nobrainer Web](https://github.com/NobrainerWeb) +[Rabobank](https://github.com/thephpleague/omnipay-rabobank) | ✓ | - | omnipay/rabobank | [Barry vd. Heuvel](https://github.com/barryvdh) +[Razorpay](https://github.com/razorpay/omnipay-razorpay) | ✓ | - | razorpay/omnipay-razorpay | [razorpay](https://github.com/razorpay) +[Realex](https://github.com/digitickets/omnipay-realex) | ✓ | - | digitickets/omnipay-realex | [DigiTickets](https://github.com/digitickets) +[RedSys](https://github.com/jsampedro77/sermepa-omnipay) | ✓ | - | nazka/sermepa-omnipay | [Javier Sampedro](https://github.com/jsampedro77) +[RentMoola](https://github.com/rentmoola/omnipay-rentmoola) | ✓ | - | rentmoola/omnipay-rentmoola | [Geoff Shaw](https://github.com/Shawg) +[RoboKassa](https://github.com/hiqdev/omnipay-robokassa) | ✓ | ✓ | hiqdev/omnipay-robokassa | [HiQDev](https://github.com/hiqdev) +[RocketGate](https://github.com/mvestil/omnipay-rocketgate) | ✓ | ✓ | mvestil/omnipay-rocketgate | [Mark Vestil](https://github.com/mvestil) +[Sage Pay](https://github.com/thephpleague/omnipay-sagepay) | ✓ | ✓ | omnipay/sagepay | [Jason Judge](https://github.com/judgej) +[Sberbank](https://github.com/AndrewNovikof/omnipay-sberbank) | - | ✓ | andrewnovikof/omnipay-sberbank | [Andrew Novikov](https://github.com/AndrewNovikof) +[SecPay](https://github.com/justinbusschau/omnipay-secpay) | ✓ | - | justinbusschau/omnipay-secpay | [Justin Busschau](https://github.com/justinbusschau) +[SecurePay](https://github.com/thephpleague/omnipay-securepay) | ✓ | ✓ | omnipay/securepay | [Omnipay](https://github.com/thephpleague/omnipay) +[Secure Trading](https://github.com/meebio/omnipay-secure-trading) | ✓ | - | meebio/omnipay-secure-trading | [John Jablonski](https://github.com/jan-j) +[Sisow](https://github.com/fruitcake/omnipay-sisow) | ✓ | ✓ | fruitcakestudio/omnipay-sisow | [Fruitcake](https://github.com/fruitcake) +[Skrill](https://github.com/alfaproject/omnipay-skrill) | ✓ | - | alfaproject/omnipay-skrill | [João Dias](https://github.com/alfaproject) +[Sofort](https://github.com/aimeoscom/omnipay-sofort) | ✓ | - | aimeoscom/omnipay-sofort | [Aimeos GmbH](https://github.com/aimeoscom) +[Spreedly](https://github.com/gregoriohc/omnipay-spreedly) | ✓ | - | gregoriohc/omnipay-spreedly | [Gregorio Hernández Caso](https://github.com/gregoriohc) +[Square](https://github.com/Transportersio/omnipay-square) | ✓ | ✓ | transportersio/omnipay-square | [Transporters.io](https://github.com/Transportersio) +[Starkpay](https://github.com/starkpay/omnipay) | ✓ | ✓ | starkpay/omnipay | [Starkpay](https://github.com/starkpay) +[Stripe](https://github.com/thephpleague/omnipay-stripe) | ✓ | ✓ | omnipay/stripe | [Del](https://github.com/delatbabel) +[TargetPay](https://github.com/thephpleague/omnipay-targetpay) | ✓ | - | omnipay/targetpay | [Alexander Deruwe](https://github.com/aderuwe) +[TatraBank](https://github.com/bileto/omnipay-tatrabank) | ✓ | - | omnipay-tatrabank | +[ToyyibPay](https://github.com/sitehandy/omnipay-toyyibpay) | - | ✓ | sitehandy/omnipay-toyyibpay | [Amirol Zolkifli](https://github.com/sitehandy) +[Tpay](https://github.com/tpay-com/omnipay-tpay) | ✓ | - | omnipay/tpay | [Tpay.com](https://github.com/tpay-com) +[UnionPay](https://github.com/lokielse/omnipay-unionpay) | ✓ | ✓ | lokielse/omnipay-unionpay | [Loki Else](https://github.com/lokielse) +[Vantiv](https://github.com/lemonstand/omnipay-vantiv) | ✓ | - | lemonstand/omnipay-vantiv | [LemonStand](https://github.com/lemonstand) +[Veritrans](https://github.com/andylibrian/omnipay-veritrans) | ✓ | - | andylibrian/omnipay-veritrans | [Andy Librian](https://github.com/andylibrian) +[Vindicia](https://github.com/vimeo/omnipay-vindicia) | ✓ | - | vimeo/omnipay-vindicia | [Vimeo](https://github.com/vimeo) +[VivaPayments](https://github.com/delatbabel/omnipay-vivapayments) | ✓ | - | delatbabel/omnipay-vivapayments | [Del](https://github.com/delatbabel) +[VR Payment](https://github.com/antibodies-online/omnipay-vr-payment) | - | ✓ | antibodies-online/omnipay-vr-payment | [antibodies-online](https://github.com/antibodies-online) +[WebMoney](https://github.com/dercoder/omnipay-webmoney) | ✓ | ✓ | dercoder/omnipay-webmoney | [Alexander Fedra](https://github.com/dercoder) +[WeChat](https://github.com/labs7in0/omnipay-wechat) | ✓ | - | labs7in0/omnipay-wechat | [7IN0's Labs](https://github.com/labs7in0) +[WechatPay](https://github.com/lokielse/omnipay-wechatpay) | ✓ | ✓ | lokielse/omnipay-wechatpay | [Loki Else](https://github.com/lokielse) +[WePay](https://github.com/collizo4sky/omnipay-wepay) | ✓ | - | collizo4sky/omnipay-wepay | [Agbonghama Collins](https://github.com/collizo4sky) +[Wirecard](https://github.com/igaponov/omnipay-wirecard) | ✓ | ✓ | igaponov/omnipay-wirecard | [Igor Gaponov](https://github.com/igaponov) +[Wirecard](https://github.com/academe/omnipay-wirecard) | ✓ | - | academe/omnipay-wirecard | [Jason Judge](https://github.com/judgej) +[Worldpay XML Direct Corporate Gateway](https://github.com/teaandcode/omnipay-worldpay-xml) | ✓ | - | teaandcode/omnipay-worldpay-xml | [Dave Nash](https://github.com/teaandcode) +[Worldpay XML Hosted Corporate Gateway](https://github.com/catharsisjelly/omnipay-worldpay-cg-hosted) | ✓ | ✓ | catharsisjelly/omnipay-worldpay-cg-hosted | [Chris Lock](https://github.com/catharsisjelly) +[Worldpay Business Gateway](https://github.com/thephpleague/omnipay-worldpay) | ✓ | ✓ | omnipay/worldpay | [Omnipay](https://github.com/thephpleague/omnipay) +[Yandex.Kassa](https://github.com/hiqdev/omnipay-yandex-kassa) | ✓ | ✓ | hiqdev/omnipay-yandex-kassa | [HiQDev](https://github.com/hiqdev) +[Yandex.Money](https://github.com/yandex-money/yandex-money-cms-omnipay) | ✓ | - | yandexmoney/omnipay | [Roman Ananyev](https://github.com/aTastyCookie/) +[Yandex.Money for P2P payments](https://github.com/hiqdev/omnipay-yandexmoney) | ✓ | ✓ | hiqdev/omnipay-yandexmoney | [HiQDev](https://github.com/hiqdev) +[Yekpay](https://github.com/nekofar/omnipay-yekpay) | - | ✓ | nekofar/omnipay-yekpay | [Milad Nekofar](https://github.com/nekofar) +[ZarinPal](https://github.com/nekofar/omnipay-zarinpal) | - | ✓ | nekofar/omnipay-zarinpal | [Milad Nekofar](https://github.com/nekofar) Gateways are created and initialized like so: @@ -182,7 +327,7 @@ gateway (other than by the methods they support). ## Credit Card / Payment Form Input -User form input is directed to an [CreditCard](https://github.com/thephpleague/omnipay-common/blob/master/src/Omnipay/Common/CreditCard.php) +User form input is directed to an [CreditCard](https://github.com/thephpleague/omnipay-common/blob/master/src/Common/CreditCard.php) object. This provides a safe way to accept user input. The `CreditCard` object has the following fields: @@ -244,7 +389,7 @@ which fails the Luhn check), [InvalidCreditCardException](https://github.com/the will be thrown. You should validate the card details using your framework's validation library before submitting the details to your gateway, to avoid unnecessary API calls. -For on-site payment gateways, the following card fields are always required: +For on-site payment gateways, the following card fields are generally required: * firstName * lastName @@ -266,13 +411,18 @@ The main methods implemented by gateways are: * `completePurchase($options)` - handle return from off-site gateways after purchase * `refund($options)` - refund an already processed transaction * `void($options)` - generally can only be called up to 24 hours after submitting a transaction +* `acceptNotification()` - convert an incoming request from an off-site gateway to a generic notification object + for further processing +* `createCard` - get a cardReference that can be used for future payments. This might be used in a monthly billing scenario, for example. -On-site gateways do not need to implement the `completeAuthorize` and `completePurchase` methods. If any gateway does not support -certain features (such as refunds), it will throw `BadMethodCallException`. +On-site gateways do not need to implement the `completeAuthorize` and `completePurchase` methods. Gateways that don't +receive payment notifications don't need to implement `acceptNotification`. If any gateway does not support certain +features (such as refunds), it will throw `BadMethodCallException`. -All gateway methods take an `$options` array as an argument. Each gateway differs in which -parameters are required, and the gateway will throw `InvalidRequestException` if you -omit any required parameters. All gateways will accept a subset of these options: +All gateway methods except `acceptNotification` take an `$options` array as an argument. The `acceptNotification` method +does not take any parameters and will access the HTTP URL variables or POST data implicitly. Each gateway differs in +which parameters are required, and the gateway will throw `InvalidRequestException` if you omit any required parameters. +All gateways will accept a subset of these options: * card * token @@ -288,11 +438,11 @@ Pass the options through to the method like so: ```php $card = new CreditCard($formData); -$request = $gateway->authorize([ +$request = $gateway->authorize(array( 'amount' => '10.00', // this represents $10.00 'card' => $card, 'returnUrl' => 'https://www.example.com/return', -]); +)); ``` When calling the `completeAuthorize` or `completePurchase` methods, the exact same arguments should be provided as @@ -318,15 +468,18 @@ For a successful responses, a reference will normally be generated, which can be at a later date. The following methods are always available: ```php -$response = $gateway->purchase(['amount' => '10.00', 'card' => $card])->send(); +$response = $gateway->purchase(array('amount' => '10.00', 'card' => $card))->send(); $response->isSuccessful(); // is the response successful? $response->isRedirect(); // is the response a redirect? $response->getTransactionReference(); // a reference generated by the payment gateway +$response->getTransactionId(); // the reference set by the originating website if available. $response->getMessage(); // a message generated by the payment gateway ``` In addition, most gateways will override the response object, and provide access to any extra fields returned by the gateway. +If the payment authorization is re-usable the gateway will implement ```$response->getCardReference();```. This +method is always available (but may return NULL) from 3.1.1 ### Redirect Response @@ -336,7 +489,7 @@ POST (FormRedirectResponse). These could potentially be combined into a single r After processing a payment, the cart should check whether the response requires a redirect, and if so, redirect accordingly: ```php -$response = $gateway->purchase(['amount' => '10.00', 'card' => $card])->send(); +$response = $gateway->purchase(array('amount' => '10.00', 'card' => $card))->send(); if ($response->isSuccessful()) { // payment is complete } elseif ($response->isRedirect()) { @@ -369,7 +522,7 @@ You can handle both scenarios by wrapping the entire request in a try-catch bloc ```php try { - $response = $gateway->purchase(['amount' => '10.00', 'card' => $card])->send(); + $response = $gateway->purchase(array('amount' => '10.00', 'card' => $card))->send(); if ($response->isSuccessful()) { // mark order as complete } elseif ($response->isRedirect()) { @@ -384,6 +537,25 @@ try { } ``` +## Test mode and developer mode + Most gateways allow you to set up a sandbox or developer account which uses a different url + and credentials. Some also allow you to do test transactions against the live site, which does + not result in a live transaction. + + Gateways that implement only the developer account (most of them) call it testMode. Authorize.net, + however, implements both and refers to this mode as developerMode. + + When implementing with multiple gateways you should use a construct along the lines of the following: +```php +if ($is_developer_mode) { + if (method_exists($gateway, 'setDeveloperMode')) { + $gateway->setDeveloperMode(TRUE); + } else { + $gateway->setTestMode(TRUE); + } +} +``` + ## Token Billing Token billing allows you to store a credit card with your gateway, and charge it at a later date. @@ -394,9 +566,14 @@ are available: * `updateCard($options)` - update a stored card, not all gateways support this method * `deleteCard($options)` - remove a stored card, not all gateways support this method -Once you have a `cardReference`, you can use it instead of the `card` parameter when creating a charge: +Once you have a `cardReference`, (which should be available from the response object +using getCardReference) you can use it instead of the `card` parameter when creating a charge: - $gateway->purchase(['amount' => '10.00', 'cardReference' => 'abc']); + $gateway->purchase(array('amount' => '10.00', 'cardReference' => 'abc')); + +In many cases the createCard action will also process the initial payment at the same time. +In these cases you should pass in the 'action' ('authorize' or 'purchase') in the createCard +options. ## Recurring Billing @@ -406,6 +583,28 @@ recurring billing profiles. Also in most cases token billing will cover your nee store a credit card then charge it on whatever schedule you like. Feel free to get in touch if you really think this should be a core feature and worth the effort. +## Incoming Notifications + +Some gateways (e.g. Cybersource, GoPay) offer HTTP notifications to inform the merchant about the completion (or, in +general, status) of the payment. To assist with handling such notifications, the `acceptNotification()` method will +extract the transaction reference and payment status from the HTTP request and return a generic `NotificationInterface`. + +```php +$notification = $gateway->acceptNotification(); + +$notification->getTransactionReference(); // A reference provided by the gateway to represent this transaction +$notification->getTransactionStatus(); // Current status of the transaction, one of NotificationInterface::STATUS_* +$notification->getMessage(); // Additional message, if any, provided by the gateway + +// update the status of the corresponding transaction in your database +``` + +**Note:** some earlier gateways used the `completeAuthorize` and `completePurchase` messages to handle the incoming +notifications. These are being converted and the `complete*` messages deprecated. +They won't be removed in OmniPay 2.x, but it is advisable to switch to the `acceptNotification` message when convenient. +An example is Sage Pay Server [completeAuthorize](https://github.com/thephpleague/omnipay-sagepay/blob/master/src/ServerGateway.php#L81) +which is now handled by [acceptNotification](https://github.com/thephpleague/omnipay-sagepay/blob/master/src/ServerGateway.php#L40). + ## Example Application An example application is provided in the [omnipay/example](https://github.com/thephpleague/omnipay-example) repo. @@ -429,6 +628,10 @@ you can subscribe to. If you believe you have found a bug, please report it using the GitHub issue tracker for the appropriate package, or better yet, fork the library and submit a pull request. +## Security +If you discover any security related issues, please email barryvdh@gmail.com instead of using the issue tracker. + + ## Feedback **Please provide feedback!** We want to make this library useful in as many projects as possible. diff --git a/composer.json b/composer.json index f4a53ff6..9bbc6db9 100644 --- a/composer.json +++ b/composer.json @@ -1,51 +1,14 @@ { - "name": "omnipay/omnipay", + "name": "league/omnipay", "type": "metapackage", - "description": "Includes Omnipay payment processing library and all officially supported gateways", + "description": "Omnipay payment processing library", "keywords": [ - "2checkout", - "2co", - "auth.net", - "authorize", - "authorize.net", - "buckaroo", - "cardsave", - "coinbase", - "commweb", - "dps", - "egate", - "eway", - "express", - "first data", - "firstdata", - "gateway", - "gocardless", - "ideal", - "merchant", - "migs", - "mollie", - "multisafepay", - "netaxept", - "netbanx", - "pay", - "payfast", - "payflow", - "payment", - "paymentexpress", - "paypal", - "pin", - "purchase", - "rapid", - "sagepay", - "securepay", - "stripe", - "tala", - "tala-payments", - "targetpay", - "twocheckout", - "worldpay" + "omnipay", + "checkout", + "creditcard", + "payment" ], - "homepage": "https://github.com/thephpleague/omnipay", + "homepage": "https://omnipay.thephpleague.com/", "license": "MIT", "authors": [ { @@ -53,44 +16,30 @@ "email": "adrian@adrianmacneil.com" }, { - "name": "Omnipay Community", - "homepage": "https://github.com/thephpleague/omnipay/graphs/contributors" + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" } ], "require": { - "omnipay/2checkout": "~2.0", - "omnipay/authorizenet": "~2.0", - "omnipay/buckaroo": "~2.0", - "omnipay/cardsave": "~2.0", - "omnipay/coinbase": "~2.0", - "omnipay/common": "~2.3.0", - "omnipay/dummy": "~2.0", - "omnipay/eway": "~2.0", - "omnipay/firstdata": "~2.0", - "omnipay/gocardless": "~2.0", - "omnipay/manual": "~2.0", - "omnipay/migs": "~2.0", - "omnipay/mollie": "~2.0", - "omnipay/multisafepay": "~2.0", - "omnipay/netaxept": "~2.0", - "omnipay/netbanx": "~2.0", - "omnipay/payfast": "~2.0", - "omnipay/payflow": "~2.0", - "omnipay/paymentexpress": "~2.0", - "omnipay/paypal": "~2.0", - "omnipay/pin": "~2.0", - "omnipay/sagepay": "~2.0", - "omnipay/securepay": "~2.0", - "omnipay/stripe": "~2.0", - "omnipay/targetpay": "~2.0", - "omnipay/worldpay": "~2.0" + "php": "^7.2|^8.0", + "omnipay/common": "^3.1", + "php-http/discovery": "^1.14", + "php-http/guzzle7-adapter": "^1" }, "require-dev": { - "omnipay/tests": "~2.0" + "omnipay/tests": "^3|^4" + }, + "autoload-dev": { + "psr-4": { "Omnipay\\Tests\\" : "tests" } }, "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.2.x-dev" } - } + }, + "scripts": { + "test": "phpunit" + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 00000000..1347f357 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,23 @@ + + + + + ./src + + + + + ./tests/ + + + diff --git a/tests/OmnipayTest.php b/tests/OmnipayTest.php new file mode 100644 index 00000000..766ce5d1 --- /dev/null +++ b/tests/OmnipayTest.php @@ -0,0 +1,35 @@ +assertInstanceOf('Omnipay\Common\GatewayFactory', $factory); + } + + + /** + * Verify a new Client instance can be instantiated + */ + public function testNewClient() + { + $client = new Client(); + + $this->assertInstanceOf('Omnipay\Common\Http\Client', $client); + } +} \ No newline at end of file