MFS Auto-Pay Studio

bKash • Nagad • Rocket • uPay SMS Auto-Gateway Simulator

Gateway Online Get Code
AP

MFS Broadcaster

Listening SMS...

ID: companion_031A V1.2-STABLE

Receiver Settings Auto-configured

Active MFS Listeners Checks Broadcast Action

Broadcast Stream Logs
// Broadcaster initialized...
// Awaiting android.provider.Telephony.SMS_RECEIVED

Trigger Simulated Payment SMS Acts as SMS sender

Live Server Endpoint Monitor

Incoming JSON Request
Awaiting webhook callback...
Simulated DB Table
TrxID Amount MFS Status
No transactions registered yet.

Store Checkout Simulator Order ID: #ORD-99827

Item Summary
1x premium subscription Tk 500.00
Processing Fees Tk 0.00
Total Payable: Tk 500.00
Send money manually to recipient number, then insert transaction ID below to test the instant auto-verification check.

Implementation Blueprint & Developer Code Hub

Deploy this automated system inside your production environment with absolute confidence.

This Android BroadcastReceiver triggers on incoming SMS. It evaluates Regex matches to extract critical transaction details and initiates an HTTP POST command dispatch to your central merchant servers.

SMSReceiver.kt
package com.mfs.autoverify

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.telephony.SmsMessage
import android.util.Log
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.io.IOException
import java.util.regex.Pattern

class SMSReceiver : BroadcastReceiver() {
    private val client = OkHttpClient()

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == "android.provider.Telephony.SMS_RECEIVED") {
            val bundle = intent.extras
            if (bundle != null) {
                val pdus = bundle["pdus"] as Array<*>?
                if (pdus != null) {
                    for (pdu in pdus) {
                        val message = SmsMessage.createFromPdu(pdu as ByteArray)
                        val sender = message.originatingAddress ?: ""
                        val body = message.messageBody ?: ""
                        
                        // Parse matching messages from bKash, Nagad, Rocket, uPay
                        if (isMFSMessage(sender, body)) {
                            parseAndSendPayload(body, sender)
                        }
                    }
                }
            }
        }
    }

    private fun isMFSMessage(sender: String, body: String): Boolean {
        val upperSender = sender.uppercase()
        return upperSender.contains("BKASH") || upperSender.contains("NAGAD") || 
               upperSender.contains("ROCKET") || upperSender.contains("UPAY") || 
               body.contains("TrxID") || body.contains("TxnID")
    }

    private fun parseAndSendPayload(body: String, mfsGateway: String) {
        var amount = "0.0"
        var trxId = ""
        var senderPhone = ""
        var balance = "0.0"
        var method = "UNKNOWN"

        if (body.contains("bkash", ignoreCase = true) || mfsGateway.uppercase().contains("BKASH")) {
            method = "bKash"
            val amtPattern = Pattern.compile("received Tk ([\\d,.]+)")
            val trxPattern = Pattern.compile("TrxID ([A-Z0-9]+)")
            val senderPattern = Pattern.compile("from ([\\d]+)")
            val balPattern = Pattern.compile("Balance Tk ([\\d,.]+)")

            val amtMatcher = amtPattern.matcher(body)
            val trxMatcher = trxPattern.matcher(body)
            val senderMatcher = senderPattern.matcher(body)
            val balMatcher = balPattern.matcher(body)

            if (amtMatcher.find()) amount = amtMatcher.group(1) ?: "0.0"
            if (trxMatcher.find()) trxId = trxMatcher.group(1) ?: ""
            if (senderMatcher.find()) senderPhone = senderMatcher.group(1) ?: ""
            if (balMatcher.find()) balance = balMatcher.group(1) ?: "0.0"
        } else if (body.contains("nagad", ignoreCase = true) || mfsGateway.uppercase().contains("NAGAD")) {
            method = "Nagad"
            val amtPattern = Pattern.compile("(?:Received Tk\\.|Received Tk|Tk\\.)\\s*([\\d,.]+)")
            val trxPattern = Pattern.compile("(?:TxnID|TxID|Txn ID):\\s*([A-Z0-9]+)")
            val senderPattern = Pattern.compile("from\\s*([\\d]+)")
            val balPattern = Pattern.compile("Balance:\\s*Tk\\.\\s*([\\d,.]+)")

            val amtMatcher = amtPattern.matcher(body)
            val trxMatcher = trxPattern.matcher(body)
            val senderMatcher = senderPattern.matcher(body)
            val balMatcher = balPattern.matcher(body)

            if (amtMatcher.find()) amount = amtMatcher.group(1) ?: "0.0"
            if (trxMatcher.find()) trxId = trxMatcher.group(1) ?: ""
            if (senderMatcher.find()) senderPhone = senderMatcher.group(1) ?: ""
            if (balMatcher.find()) balance = balMatcher.group(1) ?: "0.0"
        }

        if (trxId.isNotEmpty()) {
            sendWebhook(method, amount, trxId, senderPhone, balance, body)
        }
    }

    private fun sendWebhook(method: String, amount: String, trxId: String, sender: String, balance: String, rawBody: String) {
        val url = "https://api.yourserver.com/v1/payment-webhook"
        val passphrase = "mfs_secure_hash_8891"

        val json = JSONObject()
        json.put("method", method)
        json.put("amount", amount.replace(",", "").toDoubleOrNull() ?: 0.0)
        json.put("trxID", trxId)
        json.put("sender", sender)
        json.put("balance", balance.replace(",", "").toDoubleOrNull() ?: 0.0)
        json.put("raw_sms", rawBody)
        json.put("timestamp", System.currentTimeMillis())

        val mediaType = "application/json; charset=utf-8".toMediaType()
        val requestBody = json.toString().toRequestBody(mediaType)

        val request = Request.Builder()
            .url(url)
            .post(requestBody)
            .addHeader("Content-Type", "application/json")
            .addHeader("X-Passphrase-Signature", passphrase)
            .build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                Log.e("MFS_RECEIVER", "Webhook transmission failed", e)
            }

            override fun onResponse(call: Call, response: Response) {
                Log.i("MFS_RECEIVER", "Webhook sent successfully. Code: ${response.code}")
                response.close()
            }
        })
    }
}