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



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

0 0


OmniPay-PHPNE-talk

Slides for my PHPNE OmniPay presentation

On Github academe / OmniPay-PHPNE-talk

OmniPay

The PHP Library for Payment Gateways

Presentation for @PHPNE by Jason Judge / @JasonDJudge

(Speaker notes are in this slideshow for more background - press 'S' to see them)

The Problems to Solve

  • To abstract the gateway
  • To switch gateways more easily
  • To avoid supplied SDKs - they are awful
  • To provide the common services(authorize/void/capture/payment)
  • 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.
  • To avoid needing to use the SDKs that gateway providers supply, because most of them are awful.
  • Scope: authorize/void/capture/payment – simple shop stuff.

Basic Architecture

  • Composer-based
  • Core omnipay/common package
  • Official omnipay/{gateway-name} drivers
  • Unofficial third party drivers
  • All drivers built from low-level 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; not composer package omnipay/omnipay, which pulls in everything it knows about.

Some 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

Official Gateways (1)

  • omnipay/2checkout
  • omnipay/authorizenet
  • omnipay/buckaroo
  • omnipay/cardsave
  • omnipay/coinbase
  • omnipay/common
  • omnipay/dummy
  • omnipay/eway
  • omnipay/firstdata
  • omnipay/gocardless

Official Gateways (2)

  • omnipay/manual
  • omnipay/migs
  • omnipay/mollie
  • omnipay/multisafepay
  • omnipay/netaxept
  • omnipay/netbanx
  • omnipay/payfast
  • omnipay/payflow
  • omnipay/paymentexpress
  • omnipay/paypal

Official Gateways (3)

  • omnipay/pin
  • omnipay/sagepay
  • 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

Refresh the page if you don't see the logos in their animated glory!

Gateway Architectures

  • Direct
    • Server to Server
    • High PCI responsibility
  • Hosted
    • User leaves the site (can use iframe)
    • Result sent back by notify channel
  • Shared
    • JavaScript or direct POST from browser
    • Back channel used to check the results

Direct

  • 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.

    Hosted

  • 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.

How to Use OmniPay

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

General 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')

General 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',
    // ...
]);

General 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',
]);

General Use

4. Send the request message:

$responseMessage = $requestMessage->send();

Get a Response message in return.

Handle any exceptions.

General 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.

General 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

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

Example Application

  • github: thephpleague/omnipay-example

Gateway Trends

  • More going for "shared" option, using JavaScript or direct POSTing.
  • Token-based payments are becoming more popular as the 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).

OmniPay Version 3.0

  • Planned for end 2015
  • Improved Documentation
  • Namespace change to League\Omnipay\{gateway-name}
  • Remove dependencies: Guzzle and Symfony
  • PSR-7 HTTP models will be used instead
  • Splitting the credid card and the payee details
  • 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

Thank You

 

 

 

 

 

 

Feedback most welcome

OmniPay The PHP Library for Payment Gateways Presentation for @PHPNE by Jason Judge / @JasonDJudge (Speaker notes are in this slideshow for more background - press 'S' to see them)