# 4. Mobile App Setup

*Sandbox:* [*https://dropinbutton-sandbox.vpay.africa/service/pay*](https://dropinbutton-sandbox.vpay.africa/service/pay)

*Live:* [*https://dropinbutton.vpay.africa/service/pay*](https://dropinbutton.vpay.africa/service/pay)

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

```url
https://dropinbutton-sandbox.vpay.africa/service/pay?
    amount=1890
    &email=yourbuyersemail@abc.com
    &customer_logo=https://yourdomain.com/yourbusinesslogo
    &domain=sandbox
    &key=fdcdb195-6553-4890-844cee576b7ea715
    &transactionref=a4b2-1345-78da
    &customer_service_channel=support@vpay.africa,+2348191000800
    &txn_charge_type=percentage
    &txn_charge=1.5
    &currency=NGN
```

{% hint style="danger" %}
NOTE: The **key** parameter above is the public key from your sandbox Settings page.&#x20;
{% endhint %}

{% hint style="warning" %}
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.
{% endhint %}

{% hint style="warning" %}
Remember, when switching to live payment mode, set query string **domain** = live, set **key** = live public key from the **Settings => API** page of your VPay Dashboard and then use the live URL as your webview address, i.e: <https://dropinbutton.vpay.africa/service/pay>
{% endhint %}

**B.** Setup a socket stream listener against <https://zander.vpay.africa> (SANDBOX) or  <https://kola.vpay.africa> (LIVE).&#x20;

* Emit a payload against the key **NEW\_TRANSACTION\_REF** and pass the same **transactionref** value used above as a <mark style="color:red;">**stringified**</mark> 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:

{% tabs %}
{% tab title="Javascript" %}

```html
<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>-->

<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", () => {
    console.log("Connected");
    socket.emit("NEW_TRANSACTION_REF", socket_payload);

    socket.on("TRANSACTION_STATUS", (data) => {
      //You may use the data['code'] to take next action

      // sample response data payload
      /*{
          reference: "efc2-g2dd-fvvb",            // the system generated ref
          transactionref: "ref-3458-72343085Hs",  //your generated ref
          code: "00",
          message: "Transaction successful",
          timestamp: "2023-12-09T12:38:49.505Z"
      }*/
    });
  });
</script>
```

{% endtab %}

{% tab title="Dart" %}

```dart
//******* 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(
        sandbox_socket_url,
        OptionBuilder()
            .setTransports(['websocket']).enableForceNew()
            .build());

    _socket?.connect();
    _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() {
    _socket?.dispose();
  }
}
```

{% endtab %}

{% tab title="ReactNative" %}

<pre class="language-tsx"><code class="lang-tsx">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 }));
                }
            });
        
<strong>            socket.on("TRANSACTION_STATUS", (data) => {
</strong><strong>                // do something important here 💪
</strong>                // data contains the transaction status information
            });
        };
        
        init();
        return () => {};
    }, [your_ref]);
};
</code></pre>

{% endtab %}

{% tab title="Java" %}

```java
import org.json.*;

JSONObject obj = { transactionref: "xxx-xxxx" };
String jsonString = obj.toString(4);
```

{% endtab %}
{% endtabs %}
