POS Integration (APP)

This integration allows businesses with custom-developed apps to integrate their applications into the OPay POS system seamlessly. This enables streamlined operations for both business management and payment processing on a single device. The streamlined payment collection process minimises human errors and ensures a seamless reconciliation experience with real-time synchronization of payment results.

Banner

Preparation

1

2

3

4
5

Configuration

In the AndroidManifest.xml file, add <intent-Filter> to the configuration of the Activity, set exported to true, and then set your own callback deep link (host/pathPrefix/scheme). As you see from the sample below, the callback is: myAppName://business/createOrder

Demo
XML
<activity
  android:name=".XXActivity"
  android:exported="true">
  <intent-filter>
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data
          android:host="business"
          android:pathPrefix="/createOrder"
          android:scheme="myAppName" />
  </intent-filter>
  <intent-filter>
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data
          android:host="business"
          android:pathPrefix="/qureyOrder"
          android:scheme="myAppName" />
  </intent-filter>
</activity>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

Create Payment Order

URL: opay://business/merchant/cashier?amount=%s&orderNo=%s&callback=%s&sceneCode=ExtAppPay&verifyPin=%s&showResultPage =%s&autoPrint=%s

Request

ParameterDescriptionRequiredValue
amountThe amount to collect from customers.Yes-
orderNoYour business order number, maximum 32 characters.Yes-
callbackThe URL where the app will jump to after payment is completed.Yes-
sceneCodeTo get a list of payment methods.YesExtAppPay
verifyPinWhether to enter payment pin.Notrue or false; true by default
showResultPageWhether to display the result page.Notrue or false; true by default
autoPrintWhether to auto-print receipts.Notrue or false; false by default

Demo
Kotlin
findViewById<View>(R.id.btnCreateOrder).setOnClickListener {
    val amount = amountEv.text.toString()  //Receipt amount
    val orderNo = orderNoEv.text.toString() //External order number
    val callback = "myAppName://business/createOrder"
    val sceneCode = "thread://business/merchant"
    val verifyPin = false
    val showResultPage = true
    val autoPrint = false
    val scheme = String.format("opay://business/merchant/cashier?amount=%s&orderNo=%s&callback=%s&sceneCode=%s&verifyPin=%s&showResultPage=%s&autoPrint=%s", amount, orderNo, callback, sceneCode, verifyPin, showResultPage, autoPrint)
    val intent = Intent()
    intent.data = Uri.parse(scheme)
    startActivity(intent)
}
1
2
3
4
5
6
7
8
9
10
11
12
13

Query Order Status

URL: opay://business/merchant/cashier/query?orderNo=%s&callback=%s

Request

ParameterDescriptionRequiredValue
orderNoYour business order number, maximum 32 characters.Yes-
callbackThe URL where the app will jump to after payment is completed.Yes-

Demo
Kotlin
findViewById<View>(R.id.btnQueryOrder).setOnClickListener {
    val orderNo = orderNoEv.text.toString() //External order number
    val callback = "myAppName://business/queryOrder" //
    val queryScheme = String.format("opay://business/merchant/cashier/query?            orderNo=%s&callback=%s", orderNo, callback)
    val intent = Intent()
    intent.data = Uri.parse(queryScheme)
    startActivity(intent)
}
1
2
3
4
5
6
7
8

Callback (on Activity by onNewIntent)

Make sure you add your own callback URL to the "Create payment order" and "Query order status" interface.

OPay will return the parameters below:

ParameterDescriptionSample Value
resultPayment result
201: CANCEL
202: SUCCESS
203: PENDING
205: FAIL
orderNoYour Business order number
tsTransactionDate/timestamp
didDevice ID of the POS terminalF9C1B83A672979341A8ABA730C7340E0
SNSerial number of the POS terminal
amountPayment amount, in naira.10000
cashierMethodPayment method
cardTypeCard type
cardNumberMasked card number621700*********0812

Demo
Kotlin
override fun onNewIntent(intent: Intent?) = super.onNewIntent(intent).also {
    val uri = intent?.data
    val scheme = uri?.toString()?.split("?")?.firstOrNull()
    if (scheme == "myAppName://business/createOrder") { // which you set in AndroidManifest.xml
        val result = uri.getQueryParameter("result") ?: ""
        val orderNo = uri.getQueryParameter("orderNo") ?: ""
        val amount = uri.getQueryParameter("amount") ?: ""
        val ts = uri.getQueryParameter("ts") ?: ""
        val did = uri.getQueryParameter("did") ?: ""
        val cashierMethod = uri.getQueryParameter("cashierMethod") ?: ""
        val cardType = uri.getQueryParameter("cardType")
            ?: "" // Card Type, card payment will return this parameter
        val cardNumber = uri.getQueryParameter("cardNumber")
            ?: "" // Masked card number, card payment will return this parameter
        val SN = uri.getQueryParameter("SN")?:""
        when (result) {
            OrderStatus.PENDING -> {
                // do your thing
            }
            OrderStatus.SUCCESS -> {
                // do your thing
            }
            OrderStatus.FAIL -> {
                // do your thing
            }
            OrderStatus.CANCEL -> {
                // do your thing
            }
            else -> {}
        }
    } else if (scheme == "myAppName://business/queryOrder") {
        val result = uri.getQueryParameter("result") ?: ""
        val orderNo = uri.getQueryParameter("orderNo") ?: ""
        val amount = uri.getQueryParameter("amount") ?: ""
        val ts = uri.getQueryParameter("ts") ?: ""
        val did = uri.getQueryParameter("did") ?: ""
        val cashierMethod = uri.getQueryParameter("cashierMethod") ?: ""
        val cardType = uri.getQueryParameter("cardType")
            ?: "" // Card Type, card payment will return this parameter
        val cardNumber = uri.getQueryParameter("cardNumber")
            ?: "" // Masked card number, card payment will return this parameter
        val SN = uri.getQueryParameter("SN")?:""
        when (result) {
            OrderStatus.PENDING -> {
                // do your thing
            }
            OrderStatus.SUCCESS -> {
                // do your thing
            }
            OrderStatus.FAIL -> {
                // do your thing
            }
            OrderStatus.CANCEL -> {
                // do your thing
            }
            else -> {}
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
Last Updated: 11/7/2024, 2:29:28 AM