# 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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.vpay.africa/vpay-js-inline-dropin-integration-guide/4.-mobile-app-setup.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
