4. Mobile App Setup

This section describes the setup process for plugging the VPay Javascript Payment Dropin into a mobile app (Flutter, ReactNative, etc). All examples are made with reference to the SANDBOX environment.
A. Open a webview and point to https://dropinbutton-sandbox.vpay.africa/service/pay while passing your payment options payload as a query string. This will load the SANDBOX dropin payment interface inside the webview and guide the customer to payment completion.
& transactionref=a4b2-1345- 78da
&[email protected], +2348191000800
NOTE: The key parameter above is the public key from your sandbox Settings page.
Each transactionref that you generate should be alphanumeric and unique (different from previously used ones). You may generate a ref using any scheme of your preference.
Remember, when switching to live payment mode, set query string domain = live, set key = live public key from your Settings => API page and then use the live URL as your webview address, i.e: https://dropinbutton.vpay.africa/service/pay
B. Setup a socket stream listener against https://zander.vpay.africa (SANDBOX) or https://kola.vpay.africa (LIVE).
  • Emit a payload against the key NEW_TRANSACTION_REF and pass the same transactionref value used above as a stringified JSON payload.
  • Implement a socket listener against the key TRANSACTION_STATUS. Once the transaction is successful OR when the transaction Time-To-Live (TTL) has elapsed, the server will push a notification to your socket listener and then you may close the webview opened in #4A above.
See sample snippets below:
<script src="https://zander.vpay.africa/socket.io/socket.io.js"></script>
<!-- For LIVE setup, change script point to kola.vpay.africa -->
<!--<script src="https://zander.vpay.africa/socket.io/socket.io.js"></script>-->
let socket_payload = JSON.stringify({
transactionref: "xxx-xxxx"
let sandbox_socket_url = "https://zander.vpay.africa/";
//let live_socket_url = "https://kola.vpay.africa/";
let socket = io(sandbox_socket_url, { transports: ["websocket"], forceNew: true });
socket.on("connect", () => {
socket.emit("NEW_TRANSACTION_REF", socket_payload);
socket.on("TRANSACTION_STATUS", (data) => {
//You may use the data['code'] to take next action
//******* In order to use this snippet, first install *******//
//******* the "socket_io_client" from "pub.dev" *******//
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:socket_io_client/socket_io_client.dart' as IO;
import 'package:socket_io_client/socket_io_client.dart';
class SocketStream {
IO.Socket? _socket;
void connectAndListenForEvent({
required String transactionref,
}) async {
String sandbox_socket_url = "https://zander.vpay.africa";
//String live_socket_url = "https://kola.vpay.africa";
String socket_payload = jsonEncode({"transactionref": transactionref});
_socket = IO.io(
_socket?.onConnect((data) {
_socket!.emit("NEW_TRANSACTION_REF", socket_payload);
_socket?.onConnectError((data) => debugPrint("Socket connection error"));
_socket?.onConnectTimeout((data) => debugPrint("Socket connection time out"));
_socket?.on("TRANSACTION_STATUS", (data) {
//You may use the data['code'] to direct the user to another page
void disconnectSocket() {
import socketIOClient from "socket.io-client";
export const useMobileSocket = () => {
// NOTE: your_ref should be same value used above for the webview.
useEffect(() => {
const init = async () => {
const sandbox_socket_url = "https://zander.vpay.africa";
//const live_socket_url = "https://kola.vpay.africa";
const socket = socketIOClient(sandbox_socket_url, { transports: ["websocket"], forceNew: true });
socket.on("connect", () => {
if (your_ref) {
socket.emit("NEW_TRANSACTION_REF", JSON.stringify({ transactionref: your_ref }));
socket.on("TRANSACTION_STATUS", (data) => {
// do something important here 💪
// data contains the transaction status information
return () => {};
}, [your_ref]);
import org.json.*;
JSONObject obj = { transactionref: "xxx-xxxx" };
String jsonString = obj.toString(4);