NAV Navbar

Introduction

Welcome to the Xeepa Integration Guide! Xeepa provides a simple and powerful integration to accept Card, Mobile Money and, or Bank Transfer payments, into your business or application.

Pay.js

Integration

The first step in the integration process is to include https://js.xeepa.com script in the head section of your site.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" />
    <title>My Site</title>
    <script src="https://js.xeepa.com"></script>
  </head>
  <body></body>
</html>

This script exposes a global function, xeepa, that can be used to initiate the payment flow (via a popup). It is recommended that you call this function after a user initiated action e.g. after the click of a button, as illustrated in the below example:

<body>
  <button id="payment-button">Pay</button>

  <script>
    const button = document.getElementById("payment-button");
    button.onclick = function() {
      xeepa({

      });
    };
  </script>
</body>

The function takes a single options object that can contain the following parameters:

Required:

Parameter Type Description
key String Retrieve this in the developer section of your Xeepa dashboard
amount Double Amount in cents
currency String USD or KES
methods Array of Strings Can be card, mobile_money or bank
onCharge Function Function that gets called when a payment succeeds
onError Function Function that gets called when a fatal error occurs during the payment flow
onCancel Function Function that gets called when the user cancels the payment flow

Optional:

Parameter Type Description
reference String Merchant unique payment identifier
accountId Double Wallet Account ID
webhook String URL endpoint to receive payment status updates
phone String Default mobile money phone number
email String Default credit card payment email
restrictMobileMoneyToKenyanIPs boolean Show mobile money option only if the user is checking out from Kenya.

Here's a complete example of the whole integration:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" />
    <title>My Site</title>
    <script src="https://js.xeepa.com"></script>
  </head>
  <body>
    <button class="payment-button" type="submit">Pay</button>

    <script>
      const button = document.getElementById("payment-button");
      button.onclick = function() {
        const close = xeepa({
          key: "my account developer key",
          amount: 100 * 100, // $100 USD
          currency: "USD",
          methods: ["card", "mobile_money"],
          // reference: '1234567890',
          // accountId: 0,
          // phone: '254700111000',
          // email: 'test@example.com',
          // restrictMobileMoneyToKenyanIPs: true,
          webhook: "https://my-site.com/webhook",
          onCharge(transactionId) {
            // one can send the transactionId to the backend for verification
            // via the verify api, but its strongly recommended
            // to perform transaction verifications
            // via the webhook API
            console.log("charged", transactionId);

            // post transaction ops
            close(); // close the modal
          },
          onError(e) {
            // charge error
            console.error("charge error", e);
          },
          onCancel() {
            // user cancelled transaction
          }
        });
      };
    </script>

  </body>
</html>

Closing the Payment Popup

Note that you'll need to manually close the payment modal after a successful payment has been made (in the onCharge function), via a close function that is returned after invoking the xeepa global function.

Webhook

If you like, Xeepa can send you a notification every time a status change has happened on one of your transactions following which you can query for the status. Once an event or status has changed on your transaction, xeepa serializes the transaction data and sends it to an Url you provide.

How does this Work? To do this:

{
    "message": "success",
    "requestId": "transaction's requestId",
    "txnId": "transaction's Id",
    "amount": "amount paid",
    "displayAmount": "A string you can present to you client containing amount paid",
    "charge": "transaction cost",
    "exciseDuty": "exciseDuty",
    "total": "transaction's total amount",
    "mpesaTrace": "mpesa transaction code if paying by mpesa",
    "completionTime": "Thu Nov 14 2019 11:26:00 GMT+0300",
    "meta": {
      "phone": "phone Number if paying with mobile money",
      "last4": "if paying by card - last 4 digits ",
      "serviceProvider": "card provider or mobile money provider",
      "conversionRate": "currency conversionRate used, if not paying by KES"
    }
}

Authenticate the hmac header from xeepa : X-xeepa-sig: 'provided header': This is generated using your apiSecret and the response body in the given transaction.

In JavaScript:

import crypto from 'crypto';
const digest = crypto
  .createHmac("sha256", "secret-shared-key-goes-here")
  .update(JSON.stringify(payload))
  .digest("hex"); // payload is the response body.

In Python,

import base64
import hmac
import hashlib
digest = hmac.new('secret-shared-key-goes-here', payload, hashlib.sha256).digest()

Here's an example:

{
  "message": "success",
  "requestId": "5dc1e5db3769985eefb1bc59",
  "txnId": "5dc1e5de89c2f45ee07bd420",
  "displayAmount": "USD 1",
  "amount": "95.4",
  "reference": "137396",
  "charge": "4",
  "exciseDuty": "0.6",
  "total": "100",
  "event": {
    "event": "PAYMENT_RECEIVED",
    "code": "00PR",
    "success": true
  },
  "meta": {
    "name": "email@gmail.com",
    "email": "email@gmail.com",
    "serviceProvider": "MASTERCARD",
    "last4": "5154",
    "conversionRate": " 1 USD = 104 KES"
  }
}