Direct integration

Introduction to STOMP

Overview

The section shows you how to integrate with the IPC payment service API from your Point of Sale application directly through IPC’s STOMP API.

Click below to jump straight in to our Payment API documentation:

Protocol

IPC’s payment service API uses JSON (JavaScript Object Notation) messages over STOMP (Simple, or Streaming, Text Orientated Messaging Protocol) WebSocket connections. These allow bi-directional messaging to complete payment operations.

Some of the advantages of using STOMP are:

  • Support real-time interaction with IPC during the payment flow
  • Build on web sockets, which are natively supported on many platforms and in many languages (e.g. JavaScript, Java, .NET)
  • Provide a standardised and formal structure to web socket messages, making the messages easier to work with
  • You can implement STOMP with many off-the-shelf STOMP client libraries available in many languages and platforms

If you're not familiar with the STOMP protocol, you should learn about it before you continue with this guide. For more information, see theSTOMP Specificationweb page.

Processes

SDK flow

The flow chart above shows the standard process for each operation. The operations are summarised below:

  1. Connect to IPC’s STOMP endpoint
    1. Open a web socket connection to the STOMP URL
    2. Send a STOMP CONNECT frame
    3. Wait for a STOMP CONNECTED frame
  2. Subscribe to each STOMP destination required for the operation
    1. Send a STOMP SUBSCRIBE frame
  3. Send and receive messages on the STOMP destinations relevant to the operation (operations may support many messages back-and-forth to complete)
    1. Send STOMP SEND frames
    2. Receive STOMP MESSAGE frames
  4. When all messages have been exchanged, disconnect from IPC’s STOMP endpoint
    1. Send a STOMP DISCONNECT frame
    2. Close the web socket connection

Each of these STOMP actions (CONNECT, CONNECTED, SEND, MESSAGE and DISCONNECT) should be supported by your chosen STOMP library. See theSTOMP Specificationweb page for details on these actions and available STOMP clients.

The payload and headers of each SEND frame sent to, and MESSAGE frame received from, IPC are described in theAPI Reference.

Errors

This API has three types of errors:

Business errors

The request was in progress but failed. The error is returned in the process's normal reply destination. If this occurs during a payment, you must still give a receipt to the customer and record the payment.

Technical errors

The request could not be processed and the error is returned in the reply/v1/error STOMP destination. An example is the request message was invalid, or part of the system is unavailable. In this scenario, you don't have to give a receipt and you can re-try the payment after you fix the error.

Protocol errors

The server sends a STOMP ERROR frame, and the web socket connection is terminated. This may occur if there is a fatal error in the connection between client and server which cannot be rectified. Another example is an when IPC receives invalid STOMP frames from the client. You must re-establish a new web socket connection after you fix the error.

API Security

Before your POS (Point Of Sale) application can establish a connection to IPC, each application must have a unique point of sale license key.

To get a point of sale license key for a new POS device, use the v1/pos/registration endpoint to register the POS device.

Once registered, you must provide the point of sale license key in an x-wp-authorization header. This header is in the CONNECT message to make the STOMP connection for any other operation.

Example: x-wp-authorization: <Point of Sale License Key>

Any authorization error causes the server to send a STOMP ERROR and the web socket connection is terminated.

Process Flows

JavaScript example - Registering a POS

Note: This example uses stomp.js as the STOMP client function.

Define the STOMP endpoint

Copied!
// The location of IPC's STOMP endpoint
var stompClient = Stomp.client("wss://localhost:8080/ipc-app/payment/PAYPOINT1")

Define how to handle replies from IPC throughout the registration process

Copied!
// Function to handle the connection errors with IPC
var handle_connection_error = function(error) {
  // Correct the error and retry
  ...
}

// Function to handle a successful registration reply
var handle_registration_reply = function(stompMessage) {
  var payload = JSON.parse(stompMessage.body)
  var headers = stompMessage.headers

  // Store the POS License Key in the paypload, to be used in the x-wp-authorisation header of future connections to IPC
  ...

  // Disconnect from IPC
  stompClient.disconnect(null, handle_connection_error)
}

// Function to handle errors from an unsuccesful registration
var handle_error_reply = function(stompMessage) {
  var payload = JSON.parse(stompMessage.body)
  var headers = stompMessage.headers

  // Correct the error
  ...

  // Disconnect from IPC
  stompClient.disconnect(null, handle_connection_error)

  // Retry if necessary
  ...
}

Define how to start the registration process

Copied!
// Function to start the registration process once connected to IPC
var start_registration = function() {
  // Subscribe to destinations you expect to receive replies on, assigning functions to each reply
  stompClient.subscribe('/reply/v1/pos/registration', handle_registration_reply)
  stompClient.subscribe('/reply/v1/error', handle_error_reply)

  // Define the payload for registration
  var payload = JSON.stringify({
    pointOfSaleReference: 'POS_123',      // The Point of Sale Reference you entered into the IPS Control Center
    pointOfSaleId: 'uydVea',              // Point of Sale ID from the IPS Control Center
    pointOfSaleActivationCode: 'jYecVUTB' // Point of Sale Activation Code from the IPS Control Center
  })

  // Define the headers for registration
  var headers = {
    'x-wp-publisher-id': ...,   // Unique ID per POS instance
    'x-wp-correlation-id': ..., // UUID, unique per operation
    'x-wp-message-id': ...      // UUID, unique per message
  }

  // Start the registration
  stompClient.send('/v1/pos/registration', headers, payload)
}

Connect to IPC to start the registration process

Copied!
var headers = {
  // No headers required for connection
}

// Connect to IPC, and start the registration when connected
stompClient.connect(headers, start_registration, handle_connection_error)

JavaScript example - Making a sale

Note: This example uses stomp.js as the STOMP client function.

Define the STOMP endpoint

Copied!
// The location of IPC's STOMP endpoint
var stompClient = Stomp.client("wss://localhost:8080/ipc-app/payment/PAYPOINT1")

Define how to handle replies from IPC throughout the payment process

Copied!
// Function to handle the connection errors with IPC
var handle_connection_error = function(error) {
  // Correct the error and retry
}

// Function to handle payment notifications
var handle_notification_reply = function(stompMessage) {
  var payload = JSON.parse(stompMessage.body)
  var headers = stompMessage.headers

  // Display the notification text to the POS operator
  ...
}

// Function to handle payment receipts
var handle_receipt_reply = function(stompMessage) {
  var payload = JSON.parse(stompMessage.body)
  var headers = stompMessage.headers

  // Print the receipt
  ...
}

// Function to handle payment results
var handle_result_reply = function(stompMessage) {
  var payload = JSON.parse(stompMessage.body)
  var headers = stompMessage.headers

  // Handle the result of the payment, e.g. display on screen, or store the payment data
  ...
}

// Function to handle payment actions
var handle_action_reply = function(stompMessage) {
  var payload = JSON.parse(stompMessage.body)
  var headers = stompMessage.headers

  // Perform the action
  ...

  // Respond to the action by sending a message to /v1/payment/action
  ...
}

// Function to handle confirmation from IPC that the payment process is complete
var handle_complete_reply = function(stompMessage) {
  var payload = JSON.parse(stompMessage.body)
  var headers = stompMessage.headers

  // The payment flow has completed, ready to start the next payment

  // Disconnect from IPC
  stompClient.disconnect(null, handle_connection_error)
}

// Function to handle errors from the payment process
var handle_error_reply = function(stompMessage) {
  var payload = JSON.parse(stompMessage.body)
  var headers = stompMessage.headers

  // Correct the error
  ...

  // Disconnect from IPC
  stompClient.disconnect(null, handle_connection_error)

  // Retry if necessary
  ...
}

Define how to start the payment

Copied!
// Function to start the payment process once connected to IPC
var start_payment = function() {
  // Subscribe to destinations you expect to receive replies on, assigning functions to each reply
  stompClient.subscribe('/reply/v1/payment/notification', handle_notification_reply)
  stompClient.subscribe('/reply/v1/payment/receipt', handle_receipt_reply)
  stompClient.subscribe('/reply/v1/payment/result', handle_result_reply)
  stompClient.subscribe('/reply/v1/payment/action', handle_action_reply)
  stompClient.subscribe('/reply/v1/payment/complete', handle_complete_reply)
  stompClient.subscribe('/reply/v1/error', handle_error_reply)

  // Define the payload for starting a payment
  var payload = JSON.stringify({
    paymentType: 'sale',
    merchantTransactionReference: "12345678AB",
    instruction: {
      value: {
        amount: 1099
      },
      paymentInstrument: {
        type: "card/present"
      }
    }
  })

  // Define the headers for starting a payment
  var headers = {
    'x-wp-publisher-id': ...,   // Unique ID per POS instance
    'x-wp-correlation-id': ..., // UUID, unique per operation
    'x-wp-message-id': ...      // UUID, unique per message
  }

  // Start the payment
  stompClient.send('/v1/payment', headers, payload)
}

Connect to IPC to start the payment

Copied!
var headers = {
  // The POS License Key header
  'x-wp-authorization': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ4Z3CseLRkkmLxat9JI2RYWjHwFSulJQiy8dmiNvdCW4'
}

// Connect to IPC, and start the payment when connected
stompClient.connect(headers, start_payment, handle_connection_error)

API Reference

The API reference describes the payload and headers of each message that can be sent between your POS application and IPC's payment service API.

Recommendations

We recommend that you use a STOMP client library if one is available for your language. The library clients enable the efficient connection and disconnection from the STOMP API, and send and receive STOMP frames.

FAQs

See theFAQstopic for frequently asked questions.