You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用中如何集成已安装UPI支付应用并获取支付结果?

实现Android UPI支付流程(适配印度主流应用)

一、筛选设备内已安装的目标UPI应用

首先要精准识别GPay、PhonePe、Paytm、Amazon Pay这几款应用,通过包名匹配+Scheme校验来获取有效列表:

  1. 先定义目标应用的包名与对应显示名称:
val targetUpiApps = mapOf(
    "com.google.android.apps.nbu.paisa.user" to "Google Pay",
    "com.phonepe.app" to "PhonePe",
    "net.one97.paytm" to "Paytm",
    "in.amazon.mShop.android.shopping" to "Amazon Pay"
)
  1. 通过PackageManager查询支持upi://pay Scheme的应用,并过滤出目标列表:
fun getInstalledUpiApps(context: Context): List<Pair<String, String>> {
    val upiIntent = Intent(Intent.ACTION_VIEW).apply {
        data = Uri.parse("upi://pay")
    }
    val resolveInfos = context.packageManager.queryIntentActivities(upiIntent, 0)
    
    return resolveInfos.mapNotNull { info ->
        val pkgName = info.activityInfo.packageName
        targetUpiApps[pkgName]?.let { appName ->
            Pair(appName, pkgName)
        }
    }
}

将返回的列表展示为弹窗或下拉菜单,供用户选择支付应用。

二、发起UPI支付请求

用户选定应用后,构造包含支付参数的Intent并唤起对应应用:

private const val UPI_PAYMENT_REQUEST_CODE = 1001

fun launchUpiPayment(context: Context, pkgName: String, rentAmount: String, merchantVpa: String) {
    val payUri = Uri.Builder()
        .scheme("upi")
        .authority("pay")
        .appendQueryParameter("pa", merchantVpa) // 收款方VPA地址
        .appendQueryParameter("pn", "你的应用名称") // 收款方名称
        .appendQueryParameter("am", rentAmount) // 支付金额(例:"1500.00")
        .appendQueryParameter("cu", "INR") // 货币类型,固定为INR
        .appendQueryParameter("tn", "月租支付:${Calendar.getInstance().getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.ENGLISH)}") // 支付备注
        .build()

    val payIntent = Intent(Intent.ACTION_VIEW).apply {
        data = payUri
        setPackage(pkgName)
        flags = Intent.FLAG_ACTIVITY_NEW_TASK
    }

    (context as Activity).startActivityForResult(payIntent, UPI_PAYMENT_REQUEST_CODE)
}

三、接收并解析支付结果

在Activity/Fragment中通过onActivityResult(或Activity Result API)获取支付状态:

方式1:传统onActivityResult

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == UPI_PAYMENT_REQUEST_CODE) {
        data?.getStringExtra("response")?.let { responseStr ->
            // 解析UPI返回的键值对字符串
            val responseMap = responseStr.split("&").associate { param ->
                val parts = param.split("=")
                parts[0] to parts.getOrNull(1)
            }

            val payStatus = responseMap["status"]?.uppercase()
            val responseCode = responseMap["responseCode"]

            when {
                payStatus == "SUCCESS" && responseCode == "00" -> {
                    // 支付成功,更新账单状态
                }
                payStatus == "FAILURE" -> {
                    // 支付失败,提示用户重试
                }
                payStatus == "SUBMITTED" -> {
                    // 支付已提交,需后端异步校验(UPI存在延迟确认情况)
                }
                else -> {
                    // 用户取消支付或其他异常
                }
            }
        } ?: run {
            // 用户未完成支付直接返回
        }
    }
}

方式2:Jetpack Activity Result API(推荐)

private val upiResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    result.data?.getStringExtra("response")?.let { responseStr ->
        // 解析逻辑与上述一致
    }
}

// 发起支付时替换为:
upiResultLauncher.launch(payIntent)

四、核心注意事项

  • 异步校验必须做:前端返回的成功状态可能存在延迟或不准确,务必通过后端调用NPCI官方UPI校验接口,二次确认支付状态。
  • 包名维护:目标应用的包名可能随版本更新变化,需定期验证最新包名。
  • 无额外权限:仅需调用系统Intent,无需申请特殊权限。
  • 真机测试:务必在印度地区的Android设备上测试,确保所有目标应用均可正常唤起并返回结果。

内容的提问来源于stack exchange,提问作者KIRAN K J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 22:17:13