Git Product home page Git Product logo

omnipay's Introduction

Omnipay

An easy to use, consistent payment processing library for PHP

Unit Tests Latest Stable Version Total Downloads

Omnipay is a payment processing library for PHP. It has been designed based on ideas from Active Merchant, plus experience implementing 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?

  • Because you can learn one API and use it in multiple projects using different payment gateways
  • Because if you need to change payment gateways you won't need to rewrite your code
  • Because most official PHP payment gateway libraries are a mess
  • Because most payment gateways have exceptionally poor documentation
  • Because you are writing a shopping cart and need to support multiple gateways

TL;DR

Just want to see some code?

use Omnipay\Omnipay;

$gateway = Omnipay::create('Stripe');
$gateway->setApiKey('abc123');

$formData = array('number' => '4242424242424242', 'expiryMonth' => '6', 'expiryYear' => '2030', 'cvv' => '123');
$response = $gateway->purchase(array('amount' => '10.00', 'currency' => 'USD', 'card' => $formData))->send();

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();
}

As you can see, Omnipay has a consistent, well thought out API. We try to abstract as much as possible the differences between the various payments gateways.

Package Layout

Omnipay is a collection of packages which all depend on the 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 PHP-HTTP library to make HTTP requests. A Guzzle 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 it is officially supported. You should use your own username as the vendor prefix, and prepend omnipay- to the package name to make it clear that your package works with Omnipay. 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.

Installation

Omnipay is installed via Composer. For most uses, you will need to require league/omnipay and an individual gateway:

composer require league/omnipay:^3 omnipay/paypal

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)

composer require league/common:^3 omnipay/paypal php-http/buzz-adapter

Upgrade from v2 to v3

If your gateway is supported for v3, you can require that version. Make sure you require league/omnipay or a separate Http Adapter.

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

Note: The package name has been changed from omnipay/omnipay to league/omnipay for v3

Payment Gateways

All payment gateways must implement GatewayInterface, and will usually extend AbstractGateway for basic functionality.

The following gateways are available:

Gateway 2.x 3.x Composer Package Maintainer
2c2p dilab/omnipay-2c2p Xu Ding
2Checkout - omnipay/2checkout Omnipay
2Checkout Improved - collizo4sky/omnipay-2checkout Agbonghama Collins
99Bill - x-class/omnipay-99bill Laraveler
Acapture (PayVision) - qup/omnipay-acapture Niels de Vries
Adyen - academe/omnipay-adyen Jason Judge
Affirm eduardlleshi/omnipay-affirm Eduard Lleshi
Agms - agmscode/omnipay-agms Maanas Royy
Alipay(Global) lokielse/omnipay-global-alipay Loki Else
Alipay lokielse/omnipay-alipay Loki Else
Allied Wallet - delatbabel/omnipay-alliedwallet Del
Arca - k3rnel/omnipay-arca Poghos Boyajyan
Authorize.Net omnipay/authorizenet Jason Judge
Authorize.Net API - academe/omnipay-authorizenetapi Jason Judge
Authorize.Net Recurring Billing - cimpleo/omnipay-authorizenetrecurring CimpleO
Bankart ampeco/omnipay-bankart Ampeco
Barclays ePDQ - digitickets/omnipay-barclays-epdq DigiTickets
BlueOrange bank - deh4eg/omnipay-blueorange Denis Smolakov
Beanstream - lemonstand/omnipay-beanstream LemonStand
BitPay hiqdev/omnipay-bitpay HiQDev
BKM Express - yasinkuyu/omnipay-bkm Yasin Kuyu
BlueSnap - vimeo/omnipay-bluesnap Vimeo
Braintree omnipay/braintree Omnipay
Buckaroo - omnipay/buckaroo Omnipay
CardGate - cardgate/omnipay-cardgate CardGate
CardSave - omnipay/cardsave Omnipay
CashBaBa omnipay/cashbaba Recursion Technologies Ltd
Checkout.com - fotografde/checkoutcom fotograf.de
CloudBanking - cloudbanking/omnipay-cloudbanking Cloudbanking
Coinbase - omnipay/coinbase Omnipay
CoinGate - coingate/omnipay-coingate CoinGate
CoinPayments InkedCurtis/omnipay-coinpayments InkedCurtis
Creditcall - meebio/omnipay-creditcall John Jablonski
CSOB (GP WebPay) - bileto/omnipay-csob
Cybersource dioscouri/omnipay-cybersource Dioscouri Design
Cybersource SOAP - dabsquared/omnipay-cybersource-soap DABSquared
DataCash - digitickets/omnipay-datacash DigiTickets
Datatrans - w-vision/datatrans Dominik Pfaffenbauer
Datatrans academe/omnipay-datatrans Jason Judge
Docdata Payments uskur/omnipay-docdata-payments Uskur
Dummy omnipay/dummy Del
Ebanx - descubraomundo/omnipay-ebanx Descubra o Mundo
eGHL - e-ghl/omnipay Jawad Humayun
eGHL dilab/omnipay-eghl Xu Ding
eCoin hiqdev/omnipay-ecoin HiQDev
ecoPayz - dercoder/omnipay-ecopayz Alexander Fedra
eSewa - sudiptpa/omnipay-esewa Sujip Thapa
EgopayRu - pinguinjkeke/omnipay-egopaymentru Alexander Avakov
Elavon lxrco/omnipay-elavon Korri
ePayments hiqdev/omnipay-epayments HiQDev
ePayService hiqdev/omnipay-epayservice HiQDev
eWAY omnipay/eway Del
Fasapay - andreas22/omnipay-fasapay Andreas Christodoulou
Faspay David-Kurniawan/omnipay-faspay David
Fat Zebra - delatbabel/omnipay-fatzebra Del
FreeKassa hiqdev/omnipay-freekassa HiQDev
Fibank - ampeco/omnipay-fibank Ampeco
First Data - omnipay/firstdata OmniPay
Flo2cash - guisea/omnipay-flo2cash Aaron Guise
Free / Zero Amount - colinodell/omnipay-zero Colin O'Dell
GiroCheckout academe/omnipay-girocheckout Jason Judge
Globalcloudpay - dercoder/omnipay-globalcloudpay Alexander Fedra
GoCardless - omnipay/gocardless Del
GoPay - bileto/omnipay-gopay
GovPayNet - omnipay/omnipay-govpaynet FlexCoders
GVP (Garanti) - yasinkuyu/omnipay-gvp Yasin Kuyu
GVP (Garanti) - emr/omnipay-gvp Emre Akinci
Helcim - academe/omnipay-helcim Jason Judge
Icepay Payments - superbrave/omnipay-icepay-payments SuperBrave
iDram - ptuchik/omnipay-idram Avik Aghajanyan
iDeal - deniztezcan/omnipay-ideal Deniz Tezcan
Ingenico ePayments - deniztezcan/omnipay-ingenico-epayments Deniz Tezcan
iPay88 dilab/omnipay-ipay88 Xu Ding
IfthenPay - ifthenpay/omnipay-ifthenpay Rafael Almeida
Ikajo hiqdev/omnipay-ikajo HiQDev
InterKassa hiqdev/omnipay-interkassa HiQDev
InovioPay mvestil/omnipay-inoviopay Mark Vestil
Iyzico - yasinkuyu/omnipay-iyzico Yasin Kuyu
Judo Pay - transportersio/omnipay-judopay Transporters.io
Klarna Checkout myonlinestore/omnipay-klarna-checkout MyOnlineStore
Laybuy - mediabeastnz/omnipay-laybuy Myles Derham
Luminor Gateway - deh4eg/omnipay-luminor Denis Smolakov
Komerci (Rede, former RedeCard) - byjg/omnipay-komerci João Gilberto Magalhães
Komoju - vink/omnipay-komoju Danny Vink
Midtrans dilab/omnipay-midtrans Xu Ding
MercadoPago - lucassmacedo/omnipay-mercadopago Lucas Macedo
Magnius - fruitcake/omnipay-magnius Fruitcake
Manual - omnipay/manual Del
Migs - omnipay/migs Omnipay
Mpesa - wasksofts/omnipay-mpesa wasksofts
MTNCAM Mobile Money larrytech7/omnipay-momocm Akah Harvey
Mollie omnipay/mollie Barry vd. Heuvel
MOLPay - leesiongchan/molpay Lee Siong Chan
MoMo - phpviet/omnipay-momo PHPViet
Moneris - unoapp-dev/omnipay-moneris UNOapp Dev
MultiCards - incube8/omnipay-multicards Del
MultiSafepay - omnipay/multisafepay Alexander Deruwe
MyCard - xxtime/omnipay-mycard Joe Chu
MyFatoorah - myfatoorah/omnipay MyFatoorah Plugins Team
National Australia Bank (NAB) Transact sudiptpa/omnipay-nabtransact Sujip Thapa
NestPay (EST) - yasinkuyu/omnipay-nestpay Yasin Kuyu
NestPay (EST) - uskur/omnipay-nestpay Uskur
Netaxept (BBS) - omnipay/netaxept Omnipay
Netbanx - omnipay/netbanx Maks Rafalko
Neteller - dercoder/omnipay-neteller Alexander Fedra
NetPay - netpay/omnipay-netpay NetPay
Network Merchants Inc. (NMI) - mfauveau/omnipay-nmi Matthieu Fauveau
Nocks nocksapp/omnipay-nocks Nocks
Nuvei - nmc9/omnipay-nuvei DiversifiedTech
OkPay hiqdev/omnipay-okpay HiQDev
OnePay dilab/omnipay-onepay Xu Ding
Openpay Australia sudiptpa/omnipay-openpay Sujip Thapa
Oppwa vdbelt/omnipay-oppwa Martin van de Belt
PAY. (Pay.nl & Pay.be) paynl/omnipay-paynl Andy Pieters
PayMongo - oozman/omnipay-paymongo Oozman
Payoo dilab/omnipay-payoo Xu Ding
Pacnet - mfauveau/omnipay-pacnet Matthieu Fauveau
Pagar.me - descubraomundo/omnipay-pagarme Descubra o Mundo
Paratika (Asseco) - yasinkuyu/omnipay-paratika Yasin Kuyu
PayFast - omnipay/payfast Omnipay
PayGate - mvnrsa/paygate Marnus van Niekerk
Payflow - omnipay/payflow Del
PaymentExpress (DPS) omnipay/paymentexpress Del
PaymentExpress / DPS (A2A) - onlinesid/omnipay-paymentexpress-a2a Sid
PaymentgateRu pinguinjkeke/omnipay-paymentgateru Alexander Avakov
PaymentSense - digitickets/omnipay-paymentsense DigiTickets
PaymentWall - incube8/omnipay-paymentwall Del
Paynow - pay-now/omnipay-paynow Paynow
PayPal omnipay/paypal Del
PayPro - paypronl/omnipay-paypro Fruitcake
PAYONE academe/omnipay-payone Jason Judge
Paysafecard - dercoder/omnipay-paysafecard Alexander Fedra
Paysafecard - worldstream-labs/omnipay-paysafecard Worldstream
Paysafe Payment Hub (Neteller) - worldstream-labs/omnipay-paysafe-payment-hub Worldstream
Paysera - povils/omnipay-paysera Povils
Paysera - semyonchetvertnyh/omnipay-paysera Semyon Chetvertnyh
PaySimple - dranes/omnipay-paysimple Dranes
PaySsion - inkedcurtis/omnipay-payssion Curtis
PayTrace - softcommerce/omnipay-paytrace Oleg Ilyushyn
PayU - bileto/omnipay-payu
PayZen - ubitransports/omnipay-payzen Ubitransport
Paxum hiqdev/omnipay-paxum HiQDev
Pelecard uskur/omnipay-pelecard Uskur
Pin Payments - omnipay/pin Del
Ping++ - phoenixg/omnipay-pingpp Huang Feng
POLi - burnbright/omnipay-poli Sid
Portmanat - dercoder/omnipay-portmanat Alexander Fedra
Posnet - yasinkuyu/omnipay-posnet Yasin Kuyu
Postfinance - bummzack/omnipay-postfinance Roman Schmid
Qiwi hiqdev/omnipay-qiwi HiQDev
QQ Wallet(QPay) - kuangjy/omnipay-qpay Kuang Jiaye
Quickpay - nobrainerweb/omnipay-quickpay Nobrainer Web
Rabobank - omnipay/rabobank Barry vd. Heuvel
Razorpay - razorpay/omnipay-razorpay razorpay
Realex - digitickets/omnipay-realex DigiTickets
RedSys - nazka/sermepa-omnipay Javier Sampedro
RentMoola - rentmoola/omnipay-rentmoola Geoff Shaw
RoboKassa hiqdev/omnipay-robokassa HiQDev
RocketGate mvestil/omnipay-rocketgate Mark Vestil
Sage Pay omnipay/sagepay Jason Judge
Sberbank - andrewnovikof/omnipay-sberbank Andrew Novikov
SecPay - justinbusschau/omnipay-secpay Justin Busschau
SecurePay omnipay/securepay Omnipay
Secure Trading - meebio/omnipay-secure-trading John Jablonski
Sisow fruitcakestudio/omnipay-sisow Fruitcake
Skrill - alfaproject/omnipay-skrill João Dias
Sofort - aimeoscom/omnipay-sofort Aimeos GmbH
Spreedly - gregoriohc/omnipay-spreedly Gregorio Hernández Caso
Square transportersio/omnipay-square Transporters.io
Starkpay starkpay/omnipay Starkpay
Stripe omnipay/stripe Del
TargetPay - omnipay/targetpay Alexander Deruwe
TatraBank - omnipay-tatrabank
ToyyibPay - sitehandy/omnipay-toyyibpay Amirol Zolkifli
Tpay - omnipay/tpay Tpay.com
UnionPay lokielse/omnipay-unionpay Loki Else
Vantiv - lemonstand/omnipay-vantiv LemonStand
Veritrans - andylibrian/omnipay-veritrans Andy Librian
Vindicia - vimeo/omnipay-vindicia Vimeo
VivaPayments - delatbabel/omnipay-vivapayments Del
VR Payment - antibodies-online/omnipay-vr-payment antibodies-online
WebMoney dercoder/omnipay-webmoney Alexander Fedra
WeChat - labs7in0/omnipay-wechat 7IN0's Labs
WechatPay lokielse/omnipay-wechatpay Loki Else
WePay - collizo4sky/omnipay-wepay Agbonghama Collins
Wirecard igaponov/omnipay-wirecard Igor Gaponov
Wirecard - academe/omnipay-wirecard Jason Judge
Worldpay XML Direct Corporate Gateway - teaandcode/omnipay-worldpay-xml Dave Nash
Worldpay XML Hosted Corporate Gateway catharsisjelly/omnipay-worldpay-cg-hosted Chris Lock
Worldpay Business Gateway omnipay/worldpay Omnipay
Yandex.Kassa hiqdev/omnipay-yandex-kassa HiQDev
Yandex.Money - yandexmoney/omnipay Roman Ananyev
Yandex.Money for P2P payments hiqdev/omnipay-yandexmoney HiQDev
Yekpay - nekofar/omnipay-yekpay Milad Nekofar
ZarinPal - nekofar/omnipay-zarinpal Milad Nekofar

Gateways are created and initialized like so:

use Omnipay\Omnipay;

$gateway = Omnipay::create('PayPal_Express');
$gateway->setUsername('adrian');
$gateway->setPassword('12345');

Most settings are gateway specific. If you need to query a gateway to get a list of available settings, you can call getDefaultParameters():

$settings = $gateway->getDefaultParameters();
// default settings array format:
array(
    'username' => '', // string variable
    'testMode' => false, // boolean variable
    'landingPage' => array('billing', 'login'), // enum variable, first item should be treated as default
);

Generally most payment gateways can be classified as one of two types:

  • Off-site gateways such as PayPal Express, where the customer is redirected to a third party site to enter payment details
  • On-site (merchant-hosted) gateways such as PayPal Pro, where the customer enters their credit card details on your site

However, there are some gateways such as Sage Pay Direct, where you take credit card details on site, then optionally redirect if the customer's card supports 3D Secure authentication. Therefore, there is no point differentiating between the two types of gateway (other than by the methods they support).

Credit Card / Payment Form Input

User form input is directed to an CreditCard object. This provides a safe way to accept user input.

The CreditCard object has the following fields:

  • firstName
  • lastName
  • number
  • expiryMonth
  • expiryYear
  • startMonth
  • startYear
  • cvv
  • issueNumber
  • type
  • billingAddress1
  • billingAddress2
  • billingCity
  • billingPostcode
  • billingState
  • billingCountry
  • billingPhone
  • shippingAddress1
  • shippingAddress2
  • shippingCity
  • shippingPostcode
  • shippingState
  • shippingCountry
  • shippingPhone
  • company
  • email

Even off-site gateways make use of the CreditCard object, because often you need to pass customer billing or shipping details through to the gateway.

The CreditCard object can be initialized with untrusted user input via the constructor. Any fields passed to the constructor which are not recognized will be ignored.

$formInputData = array(
    'firstName' => 'Bobby',
    'lastName' => 'Tables',
    'number' => '4111111111111111',
);
$card = new CreditCard($formInputData);

You can also just pass the form data array directly to the gateway, and a CreditCard object will be created for you.

CreditCard fields can be accessed using getters and setters:

$number = $card->getNumber();
$card->setFirstName('Adrian');

If you submit credit card details which are obviously invalid (missing required fields, or a number which fails the Luhn check), InvalidCreditCardException 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 generally required:

  • firstName
  • lastName
  • number
  • expiryMonth
  • expiryYear
  • cvv

You can also verify the card number using the Luhn algorithm by calling Helper::validateLuhn($number).

Gateway Methods

The main methods implemented by gateways are:

  • authorize($options) - authorize an amount on the customer's card
  • completeAuthorize($options) - handle return from off-site gateways after authorization
  • capture($options) - capture an amount you have previously authorized
  • purchase($options) - authorize and immediately capture an amount on the customer's card
  • 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. 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 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
  • amount
  • currency
  • description
  • transactionId
  • clientIp
  • returnUrl
  • cancelUrl

Pass the options through to the method like so:

$card = new CreditCard($formData);
$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 when you made the initial authorize or purchase call (some gateways will need to verify for example the actual amount paid equals the amount requested). The only parameter you can omit is card.

To summarize the various parameters you have available to you:

  • Gateway settings (e.g. username and password) are set directly on the gateway. These settings apply to all payments, and generally you will store these in a configuration file or in the database.
  • Method options are used for any payment-specific options, which are not set by the customer. For example, the payment amount, currency, transactionId and returnUrl.
  • CreditCard parameters are data which the user supplies. For example, you want the user to specify their firstName and billingCountry, but you don't want a user to specify the payment currency or returnUrl.

The Payment Response

The payment response must implement ResponseInterface. There are two main types of response:

  • Payment was successful (standard response)
  • Website requires redirect to off-site payment form (redirect response)

Successful Response

For a successful responses, a reference will normally be generated, which can be used to capture or refund the transaction at a later date. The following methods are always available:

$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

The redirect response is further broken down by whether the customer's browser must redirect using GET (RedirectResponse object), or POST (FormRedirectResponse). These could potentially be combined into a single response class, with a getRedirectMethod().

After processing a payment, the cart should check whether the response requires a redirect, and if so, redirect accordingly:

$response = $gateway->purchase(array('amount' => '10.00', 'card' => $card))->send();
if ($response->isSuccessful()) {
    // payment is complete
} elseif ($response->isRedirect()) {
    $response->redirect(); // this will automatically forward the customer
} else {
    // not successful
}

The customer isn't automatically forwarded on, because often the cart or developer will want to customize the redirect method (or if payment processing is happening inside an AJAX call they will want to return JS to the browser instead).

To display your own redirect page, simply call getRedirectUrl() on the response, then display it accordingly:

$url = $response->getRedirectUrl();
// for a form redirect, you can also call the following method:
$data = $response->getRedirectData(); // associative array of fields which must be posted to the redirectUrl

Error Handling

You can test for a successful response by calling isSuccessful() on the response object. If there was an error communicating with the gateway, or your request was obviously invalid, an exception will be thrown. In general, if the gateway does not throw an exception, but returns an unsuccessful response, it is a message you should display to the customer. If an exception is thrown, it is either a bug in your code (missing required fields), or a communication error with the gateway.

You can handle both scenarios by wrapping the entire request in a try-catch block:

try {
    $response = $gateway->purchase(array('amount' => '10.00', 'card' => $card))->send();
    if ($response->isSuccessful()) {
        // mark order as complete
    } elseif ($response->isRedirect()) {
        $response->redirect();
    } else {
        // display error to customer
        exit($response->getMessage());
    }
} catch (\Exception $e) {
    // internal error, log exception and display a generic message to the customer
    exit('Sorry, there was an error processing your payment. Please try again later.');
}

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:

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. Token billing is not supported by all gateways. For supported gateways, the following methods are available:

  • createCard($options) - returns a response object which includes a cardReference, which can be used for future transactions
  • 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, (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(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

At this stage, automatic recurring payments functionality is out of scope for this library. This is because there is likely far too many differences between how each gateway handles recurring billing profiles. Also in most cases token billing will cover your needs, as you can 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.

$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 which is now handled by acceptNotification.

Example Application

An example application is provided in the omnipay/example repo. You can run it using PHP's built in web server (PHP 5.4+):

$ php composer.phar update --dev
$ php -S localhost:8000

For more information, see the Omnipay example application.

Support

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

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

If you believe you have found a bug, please report it using the GitHub issue tracker 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 [email protected] instead of using the issue tracker.

Feedback

Please provide feedback! We want to make this library useful in as many projects as possible. Please head on over to the mailing list and point out what you do and don't like, or fork the project and make suggestions. No issue is too small.

omnipay's People

Contributors

aderuwe avatar amacneil avatar aperdomo avatar barryvdh avatar busgurlu avatar colinodell avatar delatbabel avatar dercoder avatar dilab avatar eileenmcnaughton avatar greydnls avatar judgej avatar lokielse avatar nickyr avatar niels-qup avatar onlinesid avatar pborreli avatar pilot avatar pinguinjkeke avatar rlerdorf avatar roryy avatar sash avatar sergiy-petrov avatar silverfire avatar steveneaston avatar stevenkamanu avatar sudiptpa avatar theokouzelis avatar tomaskit avatar yasinkuyu avatar

Stargazers

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

Watchers

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

omnipay's Issues

Question about token billing

I'm currently implementing Icepay in #94 which supports token billing.
In the docs (https://github.com/adrianmacneil/omnipay#token-billing) I see that a method createCard() is responsible for storing the token with the provider.

The way I read the Icepay docs, the token is stored with them as part of the initial payment - I think so, at least. The request I am to send them has to include a bunch of payment information.

How would this work with the createCard() thing?

[MASS PAY]

I'd like to ask if possible to implement mass payment with PayPal Payments Pro. It will be very useful to send mass payment from company paypal account to clients paypal accounts via CLI. I found this resource: https://www.x.com/paypal-apis-masspay-php-5.3/nvp
If yes I can fork the library and try to implement it.

SagePay: Server Authorize Response is always unsuccessful

Hi guys,

I think there may be a bug on line 21 of Omnipay / SagePay / Message / ServerAuthorizeResponse.php. The isSuccessful() method always returns FALSE – it doesn't seem like this method needs to be implemented because the parent method has it covered.

Is this a bug or am I wrong?

Support for ticket/voucher code payment providers

I was just looking at Omnipay, which looks awesome would like to start using it. Is there any plan to support payment providers such as Ukash/Ticketsurf that issue voucher codes rather than having to enter card details?

If you don't have any plans to support these sort of providers I guess it's just a case of creating another interface to support these like: VoucherProviderInterface

Exceptions vs Failure Response

As discussed in the README, there are two ways we could handle gateway errors:

If there is an error with the payment, an Exception will be thrown. Standard exceptions will be provided, or gateways can define their own exceptions. All payments should be wrapped in a try-catch block:

try {
    $response = $gateway->purchase(1000, $card);
    // mark order as complete
} catch (\Tala\Payments\Exception $e) {
    // display error to the user
}

An alternative to this would be having a response object which indicates the success state. For example:

$response = $gateway->purchase(1000, $card);
if ($response->isSuccessful()) {
    // mark order as complete
} else {
    // display error to the user
}

This method is (arguably) nicer for the end developer, but means we end up writing more boilerplate code in each gateway, because we can not easily do things such as throw an exception inside a nested function if there is a network error, or if the supplied credit card is invalid. Exceptions would also allow each gateway to be more specific about what is causing a particular error, and users could catch specific exceptions and do different things with them.

SagePay_Server completePurchase()

Hi

I'm running the example app using the SagePay_Server gateway and I seem to have a problem when Sage Pay tries to call the /gateways/{name}/completePurchase route. The Simulator gateway is receiving an exception from Symfony because the transactionId parameter is missing.

I think it's because the paramaters are loaded from the session on line 192 of index.php in the example application and I suspect that as the request is coming from the Sage Pay server (and therefore a different session to the one the paramaters were stored in earlier) it's simply getting an empty array.

If you have any suggestions that would be great, otherwise I'll dig into this further over the weekend.

Thanks!

Tom

Beanstream support

I know I can probably learn the lib, add a driver and submit a pull request ... but there is another library (PHP-Payments) that comes baked with Beanstream, so I will likely use that.

decimal amount

@adrianmacneil what made you decide to change from passing int's as this is what most gateways seem to prefer anyway?

WorldPay extra parameters

How would I inject extra parameters into the defaults?

For example, I need to be able to send MC_Order, or MC_Customer etc.

Is that possible? Is there a way to dynamically set defaults and then use them in request?

Thank you,

Message enumeration

A lot of gateways (maybe all?) provide an error code as well as a message. Have you considered a way of standardising these error codes as much as possible so that rather than having to interpret a message each time one can use a number?

I ask this because I'm receiving an error message back from various gateways and then I can't translate them. What I'm having to do is create a slug from the entire message and use that as an array key in various language files within the framework- obviously this isn't ideal!

Whilst cumbersome, perhaps mapping them to the standard on a per driver basis would suffice?

UnitTest help on few methods

I'm working on adding CyberSource as payment provider (https://github.com/cvele/omnipay/tree/CyberSource) and would appriciate a bit of help on building unit tests for few methods: Refund, DeleteCard, UpdateCard.

Main problem I have there is that those methods require id to be passed to them and I don't have it.

Would like to avoid mocking responses.

Also, how do you handle api key situations for tests ?

how can i use omnipay with laravel 4

i want to use omnipay in my laravel 4 app

i need to create new Gateway also...

  • how can i do that ... should i have to create a new folder in vendor folder or is there any config file which can load some class with a namespace..
  • for making it work with laravel 4 should i have to create ServiceProvider.php..??

Authorize.net AIM doesn't work

I always get the error:
"Invalid response from payment gateway"

Even if I use your test example application, I get the same error.

Is it a major bug?

StackTrace:

in D:\work\example\vendor\omnipay\omnipay\src\Omnipay\AuthorizeNet\Message\AIMResponse.php line 29
at AIMResponse->__construct(object(AIMAuthorizeRequest), object(EntityBody)) in D:\work\example\vendor\omnipay\omnipay\src\Omnipay\AuthorizeNet\Message\AbstractRequest.php line 94
at AbstractRequest->send() in D:\work\example\htdocs\index.php line 103
at {closure}('AuthorizeNet_AIM')
at call_user_func_array(object(Closure), array('AuthorizeNet_AIM')) in D:\work\example\vendor\symfony\http-kernel\Symfony\Component\HttpKernel\HttpKernel.php line 129
at HttpKernel->handleRaw(object(Request), '1') in D:\work\example\vendor\symfony\http-kernel\Symfony\Component\HttpKernel\HttpKernel.php line 73
at HttpKernel->handle(object(Request), '1', true) in D:\work\example\vendor\silex\silex\src\Silex\Application.php line 504
at Application->handle(object(Request)) in D:\work\example\vendor\silex\silex\src\Silex\Application.php line 481
at Application->run() in D:\work\example\htdocs\index.php line 284

UPD:

I installed 0.7.1 version and there is no bug. So Authorize.net AIM is broken in 0.8.*.

How to implement ccavenue gateway

i have this function for redirecting customers to ccavenue how can i implement that via omnipay

<? 
function ccavenue_gateway($gateway_type, $redirect_url, $order_details)
{

            $WorkingKey = ""  ;
        require("world_libfuncs.php3");
    }
    $Checksum = getCheckSum($Merchant_Id,$order_details['amount'],$order_details['order_id'] ,$Redirect_Url,$WorkingKey);

    ?>

    <!-- Redirect user to cc avenue to make payment -->
<form  name= "ccavenue_redirect" >
    <input type="hidden" name="Merchant_Id" value="<?php echo $Merchant_Id; ?>">
    <input type="hidden" name="Amount" value="<?php echo $order_details['amount']; ?>">
    <input type="hidden" name="Order_Id" value="<?php echo $order_details['order_id']; ?>">
    <input type="hidden" name="Redirect_Url" value="<?php echo $Redirect_Url; ?>">
    <input type="hidden" name="Checksum" value="<?php echo $Checksum; ?>">
    <input type="hidden" name="billing_cust_name" value="<?php echo $order_details['BA']['fname']; ?>">
    <input type="hidden" name="billing_cust_address" value="<?php echo $order_details['BA']['address']; ?>">
    <input type="hidden" name="billing_cust_city" value="<?php echo $order_details['BA']['city']; ?>">
    <input type="hidden" name="billing_cust_state" value="<?php echo $order_details['BA']['state']; ?>">
    <input type="hidden" name="billing_cust_country" value="<?php echo $order_details['BA']['country']; ?>">
    <input type="hidden" name="billing_cust_tel" value="<?php echo $order_details['BA']['mobile1']; ?>">
    <input type="hidden" name="billing_zip_code" value="<?php echo $order_details['BA']['pincode']; ?>">
    <input type="hidden" name="billing_cust_email" value="<?php echo $order_details['BA']['email']; ?>">
    <input type="hidden" name="delivery_cust_name" value="<?php echo $order_details['SA']['fname']; ?>">
    <input type="hidden" name="delivery_cust_address" value="<?php echo $order_details['SA']['address']; ?>">
    <input type="hidden" name="delivery_cust_city" value="<?php echo $order_details['SA']['city']; ?>">
    <input type="hidden" name="delivery_cust_state" value="<?php echo  $order_details['SA']['state'];  ?>">
    <input type="hidden" name="delivery_cust_country" value="<?php echo $order_details['SA']['country']; ?>">
    <input type="hidden" name="delivery_cust_tel" value="<?php echo $order_details['SA']['mobile1'];; ?>">
    <input type="hidden" name="delivery_zip_code" value="<?php echo $order_details['SA']['pincode']; ?>">
<!--    <input type="hidden" name="delivery_cust_notes" value="--><?php //echo $delivery_cust_notes; ?><!--">-->
<!--    <input type="hidden" name="Merchant_Param" value="--><?php //echo $Merchant_Param; ?><!--">-->

</form>

<script language="javascript">
    document.ccavenue_redirect.action="https://www.ccavenue.com/shopzone/cc_details.jsp";
    document.ccavenue_redirect.method="post";
    document.ccavenue_redirect.submit();
</script>

<?
} ?>

PHP5.3 or PHP5.4?

The package requires PHP5.3.3 or higher.

The td;dr example code uses PHP 5.4 array constructs.

So which is it? Does this mean PHP5.4 has crept into other parts of the package?

FYI - SagePay Tokens & WordPress Plugin Wrapper

I'm currently working on (and have almost finished) getting SagePay Tokens to work, and also working on a WordPress plugin that wraps the omnipay library and provides a standard way for other plugins to check it's installed and register handlers for notification callbacks.

If anyone has any requirements / thoughts around these areas, pop them in a reply to this message and I'll try to factor them into what I'm doing.

Note: the WordPress plugin is something I'm delivering to a client and so I will be providing commercial support for it, and so I'll be maintaining it to a "professional" standard, so the emphasis with be on stability rather than cutting edge funky :)

RFC: Using Symfony OptionsResolver component

Hey,

Just very raw idea, you could use Symfony OptionsResolver component to handle the options definition in gateways.

It's very simple but powerful component. It would allow to define default, required options, check their types, automatically set the defaults if missing and other very cool things.

It also works nicely for gateways which would eventually extend other gateways.

Long story short, it can be used to handle the gateway options in elegant and flexible way.

What do you think?

Local validation for address parts

This is just experience from SagePay Server.

Each address field has valid permitted lengths (min and max) and also sets of characters that are accepted. Being able to access those validation rules from the application to ensure the address and other details are valid, would be useful.

For example, postal codes for SagePay have a maximum length of 10 characters and only accept letters (case-insensitive), digits, spaces and a hyphen. It is also a mandatory field. Anything outside of that will result in a failure when submitted. Catching that before it is sent to SagePay helps in error reporting - the user can be told what is wrong and where, while the error messages that come back from SagePay are not so helpful.

So, are there any thoughts on how this would be implemented? We have solved this in our implementations using a model for the addresses, and then putting validation rules into those. Quite often we find that users need to amend their address, just for the transaction, in order to meet the SagePay validation rules. A good example that comes up a lot in one project is Irish clients who put "N/A" into the postcode field, since the Republic of Ireland does not have postal codes yet. SagePay raises a fatal "invalid character" which means nothing to anyone. In this case it is the "/" that is causing that errror. For other payment gateways that "N/A" may be perfectly acceptable.

I can provide some further examples of what we do practically, if that helps understand where I am coming from. I realise validation cannot all be done before sending to the payment gateway, but if valid acceptable data from these gateways varies a lot, then some of the more obvious validation issues can be caught early.

Braintree Gateway and Symfony2 integration

Hey!

I'm in progress of implementing Braintree gateway.
So if anything should stop me (you have it in works too), please let me know! 😄

As you probably know from @stloyd, we have started some work on Symfony2 integration, I hope to have initial working version by the end of the weekend, but this is just a rough estimation - I'll do my best. You can track the progress here.

I'll probably split this into 2 bundles, one for just Omnipay integration.
And second with more Sylius-specific features.

Thanks for your work!

Bests,
Pawel

Recurring billing

Hey guys,
recurring billing is quite important, how come you are not interested in supporting that?

Why is this library so good?

I love you man 👍 This task, especially abstracting away that darn authorize.net library, this does a lot of stuff that I wanted to do myself before.

Credit Card Storage / Customer Information Management

This is more a question for the project -- has thought been put into the Auth.net CIM gateway? This allows customers to store their credit cards in the Authorize.net system, but unlike what I am seeing for some of the gateways Auth.net requires you to have a customer profile which contains many payment profiles and in order to save/use a saved card you must have both the payment profile and the customer profile id which requires extra parameters to be sent to the gateway.

Another case I am dealing with is being able to enter credit card details, charge a given amount and then also save the credit card in the payment gateway if successful.

I can explain this more and it might be an advanced use case outside the scope of this project but I'm wondering if anyone else has input on Auth.net CIM with Omnipay.

CardSave - CrossReferenceTransaction

Firstly, Omnipay is awesome! Thanks.

Is there a way built into Omnipay for doing "CrossReferenceTransaction" with CardSave? It is CardSave's way of doing token billing.

Existing Transaction Details

I'm implementing a method for Stripe to allow for the retrieval of an existing transaction's details (Docs) and I was wondering what the preferred naming for the new method might be. I'm currently calling it 'retrieve' but am open for suggestions.

SagePay Gateway integration

I saw in another ticket you're aiming to implement all of the gateways in CI Merchant before taking on board any other gateway requests so I was wondering if you had a roadmap or an estimated timeline for implementation of any of the remaining ones.

I'm keen to use Sagepay with Omnipay and was wondering if you had a plan for when it might be implemented.

Thanks for your time.

Helper::normalizeYear() should it operate in a window around the current date?

This helper method adds 2000 to any two-digit year. So '00' becomes '2000' and '10' becomes '2010'.

Also '99' becomes '2099'. If a card has a start date of "99' (and I know not all cards need a start date, but some do) then it makes more sense that the date is to be interpreted as '1999'.

Of course, all card dates may already be outside this range; I have no idea if there are still current cards issued before 2000, but just raising this in case it has not been considered.

Personally I would add 2000 to the range 0 to 90, and add 1900 to the range 91 to 99, just to widen the window of the lower range of valid years a little.

Class naming conventions

We have many places where we need an abstract base class, which will be implemented by subclasses. E.g.

Currently we have a standard of GatewayInterface, which is implemented by AbstractGateway, and extended in sub classes named PayPalExpressGateway.

While this is quite verbose (PayPalExpressGateway is already in the Gateway namespace), I basically followed naming conventions I found in Symfony, e.g. Iterator and SessionHandler.

Looking at FuelPHP 2.0, I see the convention is generally to have classes laid out like Session Storage, with a Base class, and no suffix on the subclasses. To me it looks a little weird having hundreds of classes simply called Base in different namespaces, I know this is part of what namespaces are for, and I guess it's more down to personal preference.

Illuminate (PSR-compliant Laravel) tends to follow the Symfony convention, e.g. Grammars.

Also this naming is consistent with things like our Response objects. I'm keen to read any recommendations for class naming conventions - I guess the main thing is we pick one convention and stick to it throughout our codebase.

I found this interesting Drupal thread, where they are standardising on ThingBase for classes not intended to be instantiated directly (whether they are abstract or not), and SpecificThing for sub classes. I like this standard (rather than AbstractThing), it's nice because ThingBase sits next to ThingInterface in the file browser, and also because it doesn't matter if later down the line the class is no longer abstract.

I propose to rename AbstractGateway to GatewayBase, and keep our existing GatewayInterface and PayPalExpressGateway naming convention.

Thoughts?

PaymentRequest object vs an $options argument

The payment methods will take an amount (supplied as an integer in the lowest unit, e.g. cents, to avoid floating point
precision issues), a payment source, and an array of extra options, and return a response object:

$card = new CreditCard();
$options = array('returnUrl' => 'https://example.com/payment/complete');
$response = $gateway->authorize(1000, $card, $options); // authorize $10

Alternatively, we could introduce some form of payment request object:

$card = new CreditCard();
$request = new PaymentRequest();
$request->setAmount(1000);
$request->setSource($card);
$request->setReturnUrl('https://example.com/payment/complete');
$response = $gateway->authorize($request);

This provides a cleaner way to set the payment parameters, rather than just passing through an associative array (which some people are seriously against, and parameter arrays doesn't seem to be a very common pattern in PHP, but it's certainly nicer than $obj->method(null, null, null, 'something')).

Perhaps a payment request object is a little overkill though?

To give you an idea, standard parameters which need to be passed through to the payment request are (not including user supplied data, which is stored in the CreditCard object):

  • transactionId
  • description
  • returnUrl
  • cancelUrl
  • Paypal needs fancy details about tax rates etc
  • some form of items array for certain gateways - with a PaymentRequest object we could have a nice addItem() method, rather than an items array inside the $options array

Feedback Wanted: Let me know which option you think provides a nicer API or greater flexibility.

Possible typo

$data['card']['cvc'] = $card->getCvv();

omnipay / src / Omnipay / Billing / Stripe / Gateway.php : 81

I was wondering if that was a typo or expected. I've just started reading the code.

New tag

Hi,

if it's possible, could you please create a new tag for using changes from #53

Thank you.

Handling of basket or transaction detail data?

This is as much a question as anything: does this package handle basket/cart data for the gateways? I expect each one will need the data formatted into different structures, and data escaped in different ways, so it makes sense to be able to handle the transactions in a standard structure/object, and perform the relevant formatting in each gateway as required.

Unit Suite

This might be a silly question, I've recently started learning about unit tests and phpunit, I can run individual tests from the omnipay directory by using phpunit tests/Omnipay/PayPal/ProGatewayTest.php. These complete just fine but if I try running the whole suite using phpunit from the omnipay directory it seems to get about 26% of the way through (fails on different tests each time, between 195 and 207) then gives:
Fatal error: Cannot redeclare class Mockery_516ff2bd97853 in {...}\omnipay\vendor\mockery\mockery\library\Mockery\Generator.php(129) : eval()'d code on line 1
Any suggestions?

Add support of custom parameters.

For example in PayPal Express

'PAYMENTREQUEST_0_INVNUM'=>$this->getInvoiceNumber(),
'PAYMENTREQUEST_0_CUSTOM'=>$this->getCustomInfo(),

Cannot test declined workflow with DummyGateway.

The comment in DummyGateway says:

 * This gateway is useful for testing. It simply authorizes any payment made using a valid
 * credit card number and expiry.
 *
 * Any card number which passes the Luhn algorithm and ends in 0 is authorized
 * Any card number which passes the Luhn algorithm and ends in 1 is declined

I've tried with valid card 5555557730105001, but it was not failed. Also I cannot find the code related to this logic in the gateway.

Stripe Capture Support

I'm curious why Stripe/Gateway.php doesn't include a capture method? I recognize the difference between Omnipay method naming and Stripe method naming described in the docs (https://stripe.com/docs/api#charge_capture). In Stripe, you create a charge, then capture that charge; in Omnipay, you authorize the charge, then capture it.

But it does seem limiting to the end developer and UX functionality to only support purchase in Stripe, especially since the capture method does not have any direct couple to the authorize method. Maybe a create method could be added to the AbstractGateway?

SagePay not recognizing Mastercard

... or more precisely SagePay Direct, simulator and test servers rejecting the card type values Omnipay is sending for Mastercard and Diners Club.

The constants provided for these brands in the Omnipay CreditCard class are "mastercard" and "diners_club", but SagePay appears to accept only "mc" and "diners" (case insensitive).

I can work around this easily by defining my own, very short, CreditCard class

<?php namespace Kuroi\Orders\Models;

/**
 * Reset card types to Sage-acceptable values
 */
class SagePayCreditCard extends \Omnipay\Common\CreditCard
{
    const BRAND_MASTERCARD = 'mc';
    const BRAND_DINERS_CLUB = 'diners';
}

and "using" that instead of the default Omnipay version, but I'm struggling to see an elegant way to override them within the Omnipay Sagepay classes, in such a way as to ensure that they don't get bypassed by apps blindly using the parent CreditCard class.

I'm also wondering why other people aren't going nuts about this. MasterCard and SagePay isn't an uncommon combination on my side of the globe.

OmniPay + SagePay\Server and no card data

I'm hoping to use OmniPay with SagePay\Server and letting SagePay collect the card data.

Right now I'm getting "The card parameter is required" from Omnipay\Common\Message\AbstractRequest.php on line 125.

Am I right in assuming what I'm attempting just isn't possible in OmniPay as it stands? I'm likely to embark on trying to add it if that's the case - but as I'm very new to OmniPay just wanted to check I've not missed something obvious ;)

Cracking library - thanks for sharing

Curl Issue?

Hi there!
I have a problem when I try calling omnipay like this: http://pastebin.com/V6LMucMb
I get this error: 'RuntimeException [ 60 ]: SSL certificate problem, verify that the CA cert is OK Details: error:14090086:SSL'
Researching a bit about this error, found this solution: http://ademar.name/blog/2006/04/curl-ssl-certificate-problem-v.html, which basically consists on adding 2 lines of code.
This solution worked for me, adding these two lines:

curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);

on the file /buzz/lib/Buzz/Client/Curl.php, just before curl_exec method is getting called.

I'm not sure if this is a Buzz issue, or an Omnipay issue, just wanted to let you know to find out if I'm doing something wrong (and that's why I have to do this to make it work) or it's just like this.

Thanks a lot for this great package!

Question about completePurchase

The README states:

When calling the completeAuthorize or completePurchase methods, the exact same arguments should be provided as when you made the initial authorize or purchase call (some gateways will need to verify for example the actual amount paid equals the amount requested).

I am implementing a gateway (that I'll be contributing) that uses an off-site redirect. When the user is done on the gateway, he's redirected to a URL of my choice.
Now this API wants me to do a status request to check on the status of the purchase.
So far this all fits in with my mental picture of Omnipay: $gateway->purchase($options) initially and the status request is done within $gateway->completePurchase($options) when the user is redirected back to my URL.

Now this gateway also has out-of-band notification (they connect to a general URL on my site) when a purchase status changes. There of course, I do not have the original $options because the session is not that of the user who made the purchase.
I don't see how I have to fit this in. Should my gateway just have a method updatePurchase that only takes the provided transaction reference, does a status request and go from there?

(Btw, great work being done on this library since I last was involved, sorry I couldn't spare more time for it!)

Authorize.net AIM doesn't use shipping info

Hi,

why don't Omnipay send shipping info?
There are many setters and getters for shipping info but when request is send only billing info is used:

    $this->card = new CreditCard();

    $this->card->setAddress1($objShippingAddress->address1);
    $this->card->setAddress2($objShippingAddress->address2);
    $this->card->setFirstName($objBillingAddress->first_name);
    $this->card->setLastName($objBillingAddress->last_name);

    $this->card->setNumber($objOrder->cc);
    $this->card->setExpiryMonth($objOrder->cc_exp_month);
    $this->card->setExpiryYear($objOrder->cc_exp_year);
    $this->card->setCvv($objOrder->cc_code);

    $this->card->setBillingAddress1($objBillingAddress->address1);
    $this->card->setBillingAddress2($objBillingAddress->address2);
    $this->card->setBillingCity($objBillingAddress->city);
    $this->card->setBillingCountry($objBillingAddress->country);
    $this->card->setBillingPostcode($objBillingAddress->zip);
    $this->card->setBillingPhone($objBillingAddress->phone_number);
    $this->card->setBillingState($objBillingAddress->state);

    $this->card->setShippingAddress1($objShippingAddress->address1);
    $this->card->setShippingAddress2($objShippingAddress->address2);
    $this->card->setShippingCity($objShippingAddress->city);
    $this->card->setShippingCountry($objShippingAddress->country);
    $this->card->setShippingPostcode($objShippingAddress->zip);
    $this->card->setShippingPhone($objShippingAddress->phone_number);
    $this->card->setShippingState($objShippingAddress->state);

    $this->card->setCompany($objBillingAddress->business_name);
    $this->card->setEmail($objUser->email);

And the result is:

omi

I believe this is because of code in AIMAuthorizeRequest::getData():

...
return array_merge($data, $this->getBillingData());
...

The second questions about customer ID and customer type fields.

May be it would be nice to implement some basic logic to set fields to $data array, e.g.:

$this->card->setField('x_cust_id', $customerID);

and then use these fields when request is sent.

Current version is not customizable.

What do you think?

Credit card data

I'm working on an e-commerce site and my idea would be to support different types of gateways by using this wonderful library.

Is there a way to know if the selected gateway by the client requires credit card data?
If he chooses to pay with a merchant-hosted gateway, does the gateway implementation expose such information?

Add Support for App55 gateway

Hi just came across this library a few months ago and was wondering could you add support for App55. I use it a lot in some of my projects and would appreciate its inclusion.

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

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

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.