OmniPay – The PHP Library for Payment Gateways – Official Gateways (1)



OmniPay – The PHP Library for Payment Gateways – Official Gateways (1)

0 0


OmniPay-DrupalCampNorth-talk


On Github academe / OmniPay-DrupalCampNorth-talk

OmniPay

The PHP Library for Payment Gateways

Presentation for DrupalCamp North / @DrupalCampNE by Jason Judge / @JasonDJudge

(Background notes are in these slides - press 'S' to see them)

What Are Payment Gateways?

  • The means to collect payment from a user
  • The means to authorise payment from a user
  • The means to collect against authorisation
  • All through web services

Drupal Payment Gateways

  • Gateway modules built for projects
    • Other commerce projects
  • Much duplication
  • Inconsistent support of gateways
  • Each of these projects have their own payments framework, modules, and way of working.
  • Inconsistent support: each e-commerce product supports a different set of payment gateways, whatever happened to scratch people's itch at the time.

The Problems to Solve

  • The gateways are all so different; can we abstract them?
  • Difficult to switch between gateways
  • Gateway supplied SDKs are awful
  • To provide the common services easily(authorize/void/capture/payment)
  • There are many gateways out there, all operating differently, and with their own quirks. Which you use will depend largely on business needs, so you need to be able to plug in whatever gateway at a technical level.
  • To provide a simple way to add payment gateways to your system, without having to understand too much about the specific gateways.
  • To be able to switch between gateways easily through a consistent interface, especially when your gateway does not yet exist for your particular application.
  • To avoid needing to use the SDKs that gateway providers supply, because most of them suck.
  • Scope: authorize/void/capture/payment – simple shop stuff.

The Drupal Payment Module

  • Plugable platform for processing payments
  • Solves the duplication problem:
  • The gateway modules still need to be written
  • The Drupal Payment module provides some helper functions, GUIs, forms, admin pages etc.
  • Crutially, it knows how to interface to the projects, so the gateway modules do not need to.
  • These payment gateway modules can now be shared between lots of projects.
  • But still these gateway modules need to be written by someone.

Introducing...

OmniPay

Not to be confused with a company with fancy logos in Ireland

OmniPay Basic Architecture

  • Installed using composer
  • Core omnipay/common package
  • Official omnipay/{gateway-name} drivers
  • Unofficial third party drivers
  • All drivers built from message specs; no SDKs
  • Unofficial drivers don't sit in the OmniPay namespace.
  • Unofficial drivers are still listed on the OmniPay website.
  • Only pull the drivers you want.
  • composer package omnipay/omnipay will pull in all drivers it knows about.

Some Current Figures

  • Version: 2.3.x
  • PHP: 5.3+
  • Official gateways: 27
  • Unofficial gateways: 25
  • Dependencies: Guzzle, Symfony
  • Author: Adrian Macneil, now The PHP League with many contributors
  • Activity: high

Official Gateways (1)

  • omnipay/2checkout
  • omnipay/authorizenet
  • omnipay/buckaroo
  • omnipay/cardsave
  • omnipay/coinbase
  • omnipay/eway
  • omnipay/firstdata
  • omnipay/gocardless
  • omnipay/manual
  • omnipay/migs

Official Gateways (2)

  • omnipay/mollie
  • omnipay/multisafepay
  • omnipay/netaxept
  • omnipay/netbanx
  • omnipay/payfast
  • omnipay/payflow
  • omnipay/paymentexpress
  • omnipay/paypal
  • omnipay/pin
  • omnipay/sagepay

Official Gateways (3)

  • omnipay/securepay
  • omnipay/stripe
  • omnipay/targetpay
  • omnipay/worldpay

Unofficial Gateways (1)

  • academe/omnipay-helcim
  • agmscode/omnipay-agms
  • alfaproject/omnipay-neteller
  • alfaproject/omnipay-skrill
  • andreas22/omnipay-fasapay
  • andylibrian/omnipay-veritrans
  • cardgate/omnipay-cardgate
  • coatesap/omnipay-datacash
  • coatesap/omnipay-paymentsense
  • coatesap/omnipay-realex

Unofficial Gateways (2)

  • dabsquared/omnipay-cybersource-soap
  • delatbabel/omnipay-fatzebra
  • dercoder/omnipay-ecopayz
  • dercoder/omnipay-globalcloudpay
  • dioscouri/omnipay-cybersource
  • fruitcakestudio/omnipay-sisow
  • igaponov/omnipay-wirecard
  • justinbusschau/omnipay-secpay
  • lokielse/omnipay-alipay
  • mfauveau/omnipay-nmi

Unofficial Gateways (3)

  • mfauveau/omnipay-pacnet
  • omnipay/payu
  • paypronl/omnipay-paypro
  • samvaughton/omnipay-barclays-epdq
  • teaandcode/omnipay-worldpay-xml

That's a Lot of Payment Gateways

  • Having these gateways available does not mean there is not some work involved to integrate it, but it does make the life of the developer easier.
  • Remember, the choice of gateway is often going to be a business decision and not one based on technical reasons.

Composer - a slight diversion

  • PHP dependency manager.
  • Installs from a number of sources.
  • Used in many frameworks and projects.
  • Shared code; shared effort. DRY!
  • More central to Drupal 8.
  • The sources include packagist, other composer repositories (one for WordPress, one for Drupal, private respos, git, svn, etc.)
  • There is plenty of work going on to bring composer into Drupal 8.
  • The "island" mentality is hard to discard, but it seems to be shifting.
  • Once you base work around composer, you will find it hard to leave it.

Gateway Architectures

Traditionally:

  • On-site
    • User never leaves the site
    • Server to Serverc comms
    • High PCI responsibility
  • Off-site
    • User leaves the site (maybe only in an iframe)
    • May use back-end notify channel

Onsite

  • These gateway APIs just handle server talking to server. There is no user interaction at all, so any user input must pass through your server before it is passed to the gateway to get a result. Only do this if you have a big budget to cater for the intense PCI scrutiny to get compliance.
  • Note that with 3D Secure and suchlike, the user may still have to be sent to a third-party site to fill out some security details.

    Offsite

  • The user is taken to the payment gateway to complete their details. On return, the transaction is completed according to the authorisation result. There are variations on this:
    • The remote site can be in an iframe, so the user appears not to have left the main site.
    • The result can be sent back via the user’s browser, with an encrypted GET parameter.
    • The result can be sent back via a notification URL. The consequences of this, are that you need to keep the transaction in non-volatile storage that can be shared between the user’s session, and the session-less notification handler.

      Shared

  • In this type of gateway, the payment form is on your site, but the credit card details are never submitted directly to your site. There are two ways this works:
    • JavaScript API, where the form submission is caught by JavaScript and POSTed direct to the gateway site. The response is either an error message indicating what needs to be corrected on the form, or the result is added to the form and it is then allowed to post direct back to you site (without the credit card details). The user never leaves your site.
    • The form is POSTed direct to the gateway site. The details are verified and the result is POSTed direct to your site (usually via a back-channel) and the user is then returned back to your site. The user is taken away from your site, but only for a moment, and with no interaction.

Onsite/Offsite is not Helpful

  • Same thing to application.
  • Want heavy PCI compliance? Take CC details.
  • The meanings are blurred - Stripe, Authorize.Net DPM.
  • OmniPay can handle all these.
  • The application should not care where the user goes - it only needs to know whether the payment has been authorised.
  • If you let credit card details pass through your server, then you are putting yourself and your customers at risk.
  • Even offsite you are not risk free.
  • The hybrid gateways offer forms on your site, but CC details are posted direct to the gateway site.
  • Direct posting does not mean your site is totally safe from PCI - some malicious javascript on your site could still capture CC details from your front-end form and send it off to a third party, so not a panacea.

How to Use OmniPay

  • OmniPay handles the messaging
  • You handle the routing and data

Some Code Now Follows

Common Use

1. Create the Gateway Object:

$gateway = OmniPay::create('SagePay\Direct')
    ->setVendor('academe')
    ->setTestMode(true);

All credentials are set at this stage:

    ->setAccount('myAccount')
    ->setKey('myKey')
    ->setSecret('mySecret')

Common Use

2. Create the Credit Card/Customer Object:

$card = new CreditCard([
    'firstName' => 'Jason',
    'lastName' => 'Judge',

    'number' => '4929000000006',
    'expiryMonth' => '12',
    'expiryYear' => '2016',
    'CVV' => '123',

    'billingAddress1' => 'Campus North',
    'billingCity' => 'Newcastle Upon Tyne',
    // ...

    'shippingAddress1' => 'Campus North',
    // ...
]);

Common Use

3. Create the Request Message:

// Purchase Request
$requestMessage = $gateway->purchase([
    'amount' => '99.99',
    'currency' => 'GBP',
    'card' => $card,
    'transactionId' => $transactionId,
    'description' => 'Pizzas for everyone',

    'returnUrl' => 'http://example.com/complete',
    'cancelUrl' => 'http://example.com/complete',
    'errorUrl' => 'http://example.com/complete',
]);

Common Use

4. Send the request message:

$responseMessage = $requestMessage->send();

Get a Response message in return.

Handle any exceptions.

Common Use

5. Take next action based on response:

if ($responseMessage->isSuccessful()) {
    // All finished and all successful.
    // ...
} elseif ($responseMessage->isRedirect()) {
    // Do the redirect.
    $responseMessage->redirect();
} else {
    // Some kind of error: 
    // Log $responseMessage->getMessage();
    // ...
}

Some gateways may have other required actions.

Common Use

6. If returning from a redirect:

Repeat steps 1-5 with the "complete" version of the service.

// Use completePurchase() to complete the Purchase.
$requestMessage = $gateway->completePurchase([
    'transactionId' => $transactionId,
    'transactionReference' => $transactionReference,
]);

$responseMessage = $requestMessage->send();

// Then check the result as before.

Some notes:

  • The messages are active messages; they “send” themselves.
  • Sending a message may or may not involve the remote gateway. For direct gateway APIs it will, for others, often not (but it may).
  • The messages honour a standard interface, so details provided and results received will be done through a common set of methods. Gateway drivers will often extend those interfaces to support features only that gateway has.
  • The messages translate the fields for you, between OmniPay field names and gateway field names.
  • The messages use the appropriate HTTP service of Guzzle to send and receive data in the right format. You don’t need to worry about the HTTP body formats.

Integration

  • drupal 8: Omnipay - Bart Feenstra
  • So far all integration has one thing in common: they integrate at a low level, and you have to build all the machinery around that (forms, storage, routing, etc.)

Integration

  • composer: ignited/laravel-omnipay - Alex Whiteside
  • composer: barryvdh/laravel-omnipay - Barry vd. Heuvel

The Ideal Situation

  • The Omnipay module interfaces Drupal Payment, the gateway modules and the composer OmniPay gateway packages.
  • The gateway modules should be simple and quick to implement; most of the common handling code is in the Drupal OmniPay and the Drupal Payment modules.

Some Gateway Trends

  • More "hybrid" options; JavaScript and direct POSTing.
  • Token-based payments taking off; increasing number of subscription services grow.
  • Stripe popularised the idea that payment gateways can rely on JavaScript to perform the communications, and that can mean the customer not ever having to leave your site. All the major gateways are leaping into this approach. I hear a rumour that even SagePay is going to launch one of these very soon. JavaScript posting makes PCI compliance a little lighter.
  • Token-based APIs are becoming more popular, allowing a site to get authorization to take a payment, or multiple payments, at a later date using a token that does not require the storage of credit card numbers (which we hope no-one is doing anyway).

Coming Up Version 3.0

  • Planned for end 2015
  • Improved Documentation; more consistency
  • Namespace change vendor to League
  • Remove dependencies: Guzzle and Symfony
  • PSR-7 HTTP models instead
  • More classes to handle the data
  • More metadata to automate plumbing better
  • Maybe more metadata to help automate the plumbing, e.g. defining capabilities in more detail and listing what fields are mandatory or optional, and what validation needs to be applied to them.

Demo Time

Demo: SagePay Direct

Demo: SagePay Direct

  • One script:
    • authorise.php
  • User stays on one site
  • Authorisation in one step

The full demo scripts are available athttps://github.com/academe/OmniPay-SagePay-Demo

Demo: Switch to SagePay Server

Demo: Switch to SagePay Server

  • Three scripts (for the three steps):
    • authorise.php
    • sagepay-confirm.php
    • final.php
  • User redirected to SagePay site

Summary

  • Fragmented Payment Modules are painful
  • OmniPay pulls in skills from many sources
  • composer is fab
  • The core of 50 gateways in our hands
  • Needs more work to join the pieces

Thank You

 

 

 

 

 

 

Feedback most welcome

OmniPay The PHP Library for Payment Gateways Presentation for DrupalCamp North / @DrupalCampNE by Jason Judge / @JasonDJudge (Background notes are in these slides - press 'S' to see them)