Adding your own payment gateway 2

In the previous article we covered how to register our gateway with Event Organiser, and how to create our own settings section, abd save and retrieve the data. Hopefully you’ve now got a working settings section, in which the user can enter any details required for your gateway ( e-mail, merchant key, etc).

In this part we’re going to cover how to actually get Event Organiser to use your payment gateway. Fortunately, Event Organiser handles the booking submission for you – all you’re left to do is two things:

  • Redirect the user, or otherwise handle the checkout for payment
  • Set up a ‘payment listener’ – which listens for confirmation of payment.

Step 4: Processing a booking form submission

When we registered our payment gateway back in Step 1, we did the following:

function eventorganiser_gc_add_google_checkout( $gateways ){
    $gateways['google'] = __( 'Google Checkout', 'eventorganiserp' );
    return $gateways;
}
add_filter( 'eventorganiser_gateways', 'eventorganiser_gc_add_google_checkout' );

The key of the $gateways array acts as a string identifier for our gateway and when a booking is made, Event Organiser will trigger the following action:

 eventorganiser_pre_gateway_booking_{$gateway}

This is our queue to take the user to our checkout. With most gateways this will involve redirecting the user to an url which encodes all the checkout information (total cost, items, necessary ‘merchant data’ to identify the transaction – in this case our booking ID).

In our example we would need to do something like:

add_action( 'eventorganiser_pre_gateway_booking_google', 'eventorganiser_gc_handle_booking_submission', 10, 2 );
function eventorganiser_gc_handle_booking_submission( $booking_id, $booking ){

      //Send to checkout... 

}

Quite how you send your user to the checkout will depend on the gateway you are using. But often you’ll want to include information such as the name and date of the event, and to populate the ‘checkout cart’ with the names, quantities, and prices of the tickets. Here are a few snippets that can help you do that

It is vital that you include the booking ID in what you send to your gateway. Your payment gateway should allow you to send ‘custom’ or ‘merchant’ information – this is data which the gateway will send back to you when payment is complete. You must include the booking ID so that when payment is confirmed, you will know which booking it was for.

To redirect the users to an url it’s recommended that you use wp_redirect() followed by a call to exit. See the Codex.

Getting the tickets & calculating total cost

//Getting the tickets for in the booking event
$tickets = eo_get_booking_tickets( $booking_id );
/**
 * An array of the tickets objects, each ticket is of the form
 *
 * $ticket->ticket_name - the name of the ticket
 * $ticket->ticket_quantity - the number bought as part of the booking
 * $ticket->ticket_price - the price of the ticket
 */

//Calculate the total cost and quantity
$ticket_quantity = 0;
$price = 0;
foreach ( $tickets as $ticket ) {

    $ticket_quantity += (int) $ticket->ticket_quantity;
    $price += floatval( $ticket->ticket_price ) * intval( $ticket->ticket_quantity );

}

Getting the site’s currency

$currency = eventorganiser_pro_get_option('currency');

This function will return the site’s currency (e.g. USD, GBP, EUR etc).

Getting the event title and date

//Getting the event title
$event = get_the_title( $booking['event_id'] );

//Getting the event date
$event_date = eo_get_the_start( 'Y-m-d H:i:s', $booking['event_id'], null, $booking['occurrence_id'] );

Getting the bookee’s name and email

//Getting the bookee's name
$bookee_name = eo_get_booking_meta( $booking_id, 'bookee_display_name' );
$bookee_email = eo_get_booking_meta( $booking_id, 'bookee_email' );

Telling your Gateway where to send their ‘payment notification’

You payment gateway will require an url to which they should send payment notifications (sometimes known as an IPN). They will probably have one of the following three set-ups:

  • Specify the url as part of the data sent with the cart
  • Merchants (the admin user) should specify the url their via the payment gateway’s website (usually in their profile or merchant section)
  • Uses the above, unless an url is specified with the cart.

If your gateway gives you the option to, you should favour specifying the url along with the checkout cart as this means the (admin) user doesn’t have to log into their payment gateway account and set the url themselves. In any case the url should be of the form:

    http://www.yoursite.com?eo-listener=ipn&eo-gateway={gateway}

In our example,

    http://www.yoursite.com?eo-listener=ipn&eo-gateway=google

You can easily do this via:

    $url = add_query_arg( 
              array( 'eo-listener' => 'ipn', 'eo-gateway' => 'google' ), 
              home_url() 
           );

In our example you would need to manually set the IPN url in Google’s Merchant Settings. Since this requires an action on the part of the admin user, we should display a notice on the setting page in the Google checkout section.

Once you’ve built the ‘cart’ for your payment gateway, you should pass it through the following filter: eventorganiser_pre_gateway_checkout_{$gateway} as this will enable other plug-ins to change the checkout (for instance to add a discount). You should pass the `$booking` array (see `eventorganiser_gc_handle_booking_submission` callback above ) as the second argument.

 $cart = '...';//Cart object/array - depends on the gateway
 //Example for 'google' checkout. Replace 'google' with your gateway identifier.
 $cart = apply_filters( 'eventorganiser_pre_gateway_checkout_google', $cart, $booking ); 

Step 5: Responding to payment

Hopefully, with the help of the above you were able to construct your payment gateways checkout cart, include all necessary data (e.g. booking ID!) and redirect the bookee to your gateway. Once they’ve made the payment, your gateway should send a confirmation to the url you specified above.

If you’ve set it up correctly you can hook into the following action which is triggered when a notification is received:

  eventorganiser_gateway_listener_{$gateway}_ipn

In our example

  eventorganiser_gateway_listener_google_ipn

This is triggered whenever the notification url in the previous step receives something. This could be a payment notification, it could be a ‘payment requires action’ notice. Or it could be an error, or even someone visiting the url in their browser. Therefore you should verify it’s a genuine payment notification from your gateway. Your gateway should provide with information on what steps you need to do this.

function eventorganiser_gc_ipn_listener(){

    //Verify it's a genuine payment notification. Exit if it's not. 

    //Handle message from gateway

    //Get the booking ID
    $booking_id = //Get booking ID from the payment notification

    //Create an array with as much data about the transaction as you can.
    $log = array(); 

    //Determine what the notification is. 

    //If it's confirmation of payment,
    do_action( 'eventorganiser_gateway_notification_transaction', $booking_id, $log );

    //If the payment is not yet confirmed / needs admin action 
    do_action( 'eventorganiser_gateway_notification_pending', $booking_id, $log );
}
add_action( 'eventorganiser_gateway_listener_google_ipn', 'eventorganiser_gc_ipn_listener' );

Creating a log

In the code snippet about you needed to define a $log array. This is helpful for debugging, and easily checking the payment gateway details of the payment. It’s recommended to include as much information as you can.

This log should contain:

  $log = array(
     'transaction_id' => //A transaction ID that the payment gateway has for this booking
     'gateway' => $gateway //The string identifier for your gateway
      ...
      //Any other data
  );

Confirming payment

To confirm payment, simply call the following action:

 do_action( 'eventorganiser_gateway_notification_transaction', $booking_id, $log );

Payment requires action

If the payment has not been confirmed, and/or requires admin intervention

 do_action( 'eventorganiser_gateway_notification_pending', $booking_id, $log );

You should include information on what the user should do to confirm payment.

Note: There is no standard yet as to what the $log should contain, or how it should keep the data – but later versions of Event Organiser Pro will involve greater integration with payment gateways, and admin notifications. For this a more structured log will be required. More information will be released nearer the time, and this post will be updated.

And that’s all!

Event Organiser will then handle confirming the booking, e-mailing bookees, emailing the website admin user, etc. I hope that this two-part article has made it much easier for you to add your own payment gateway. If do create your own gateway add-on and you’d like to share (or sell) the fruits of your labour, then please get it touch.