feat: 新增拼团
This commit is contained in:
@@ -1,20 +1,61 @@
|
||||
package uts.sdk.modules.tbDouyinPay
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.ss.android.dypay.api.DyPay
|
||||
import com.ss.android.dypay.api.IDyPayResultCallback
|
||||
import io.dcloud.uts.UTSAndroid
|
||||
import org.json.JSONObject
|
||||
import java.lang.reflect.Proxy
|
||||
|
||||
object TbDouyinPayNative {
|
||||
private val main = Handler(Looper.getMainLooper())
|
||||
private const val DYPAY_CLASS_NAME = "com.ss.android.dypay.api.DyPay"
|
||||
private const val CALLBACK_CLASS_NAME = "com.ss.android.dypay.api.IDyPayResultCallback"
|
||||
|
||||
fun initialize(appId: String) { DyPay.setAppId(appId) }
|
||||
private fun getDyPayClass(): Class<*>? {
|
||||
return try {
|
||||
Class.forName(DYPAY_CLASS_NAME)
|
||||
} catch (_: Throwable) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun initialize(appId: String) {
|
||||
try {
|
||||
val clazz = getDyPayClass() ?: return
|
||||
val method = clazz.methods.firstOrNull { it.name == "setAppId" && it.parameterTypes.size == 1 }
|
||||
method?.invoke(null, appId)
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
|
||||
fun available(): Boolean {
|
||||
val activity = UTSAndroid.getUniActivity() ?: return false
|
||||
return DyPay.isDypayAppUsable(activity)
|
||||
try {
|
||||
val clazz = getDyPayClass()
|
||||
if (clazz != null) {
|
||||
val method = clazz.methods.firstOrNull { it.name == "isDypayAppUsable" && it.parameterTypes.size == 1 }
|
||||
if (method != null) {
|
||||
val res = method.invoke(null, activity)
|
||||
if (res is Boolean) return res
|
||||
}
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
|
||||
return try {
|
||||
val pm = activity.packageManager
|
||||
pm.getPackageInfo("com.ss.android.ugc.aweme", 0)
|
||||
true
|
||||
} catch (_: Throwable) {
|
||||
try {
|
||||
val pm = activity.packageManager
|
||||
pm.getPackageInfo("com.ss.android.ugc.aweme.lite", 0)
|
||||
true
|
||||
} catch (_: Throwable) {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun pay(payload: String, loading: Boolean, done: (String) -> Unit) {
|
||||
@@ -25,26 +66,81 @@ object TbDouyinPayNative {
|
||||
return@post
|
||||
}
|
||||
try {
|
||||
if (!DyPay.isDypayAppUsable(activity)) {
|
||||
val dyPayClass = getDyPayClass()
|
||||
if (dyPayClass == null) {
|
||||
done("""{"resultCode":"2","errorMsg":"支付 SDK 调用异常,请查询订单"}""")
|
||||
return@post
|
||||
}
|
||||
|
||||
val isUsableMethod = dyPayClass.methods.firstOrNull { it.name == "isDypayAppUsable" && it.parameterTypes.size == 1 }
|
||||
val isUsable = (isUsableMethod?.invoke(null, activity) as? Boolean) ?: false
|
||||
if (!isUsable) {
|
||||
done("""{"resultCode":"100","errorMsg":"请安装或升级抖音客户端"}""")
|
||||
return@post
|
||||
}
|
||||
|
||||
val json = JSONObject(payload)
|
||||
val data = HashMap<String, String>()
|
||||
for (key in listOf("appid", "partnerid", "prepayid", "package", "noncestr", "timestamp", "sign")) {
|
||||
data[key] = json.getString(key)
|
||||
if (json.has(key)) {
|
||||
data[key] = json.getString(key)
|
||||
}
|
||||
}
|
||||
DyPay(activity).pay(data, object : IDyPayResultCallback {
|
||||
override fun onResult(result: Map<String, String>) {
|
||||
|
||||
val callbackClass = try {
|
||||
Class.forName(CALLBACK_CLASS_NAME)
|
||||
} catch (_: Throwable) {
|
||||
null
|
||||
}
|
||||
|
||||
if (callbackClass == null) {
|
||||
done("""{"resultCode":"2","errorMsg":"支付 SDK 调用异常,请查询订单"}""")
|
||||
return@post
|
||||
}
|
||||
|
||||
val callbackProxy = Proxy.newProxyInstance(
|
||||
callbackClass.classLoader ?: activity.classLoader,
|
||||
arrayOf(callbackClass)
|
||||
) { _, method, args ->
|
||||
if (method.name == "onResult" && args != null && args.isNotEmpty()) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val result = args[0] as? Map<String, Any?>
|
||||
val resultCode = result?.get("resultCode")?.toString() ?: "3"
|
||||
val errorMsg = result?.get("errorMsg")?.toString() ?: ""
|
||||
val response = JSONObject()
|
||||
.put("resultCode", result["resultCode"] ?: "3")
|
||||
.put("errorMsg", result["errorMsg"] ?: "")
|
||||
.put("resultCode", resultCode)
|
||||
.put("errorMsg", errorMsg)
|
||||
main.post { done(response.toString()) }
|
||||
}
|
||||
}, loading)
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
val constructor = dyPayClass.constructors.firstOrNull {
|
||||
it.parameterTypes.size == 1 && Activity::class.java.isAssignableFrom(it.parameterTypes[0])
|
||||
} ?: dyPayClass.getConstructor(Activity::class.java)
|
||||
|
||||
val dyPayInstance = constructor.newInstance(activity)
|
||||
|
||||
val payMethod = dyPayClass.methods.firstOrNull {
|
||||
it.name == "pay" && it.parameterTypes.size == 3
|
||||
} ?: dyPayClass.methods.firstOrNull {
|
||||
it.name == "pay" && it.parameterTypes.size == 2
|
||||
}
|
||||
|
||||
if (payMethod == null) {
|
||||
done("""{"resultCode":"2","errorMsg":"支付 SDK 调用异常,请查询订单"}""")
|
||||
return@post
|
||||
}
|
||||
|
||||
if (payMethod.parameterTypes.size == 3) {
|
||||
payMethod.invoke(dyPayInstance, data, callbackProxy, loading)
|
||||
} else {
|
||||
payMethod.invoke(dyPayInstance, data, callbackProxy)
|
||||
}
|
||||
} catch (_: Throwable) {
|
||||
done("""{"resultCode":"2","errorMsg":"支付 SDK 调用异常,请查询订单"}""")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
package uts.sdk.modules.uniRequestMerchantTransfer
|
||||
|
||||
import android.content.Context
|
||||
import io.dcloud.uts.UTSAndroid
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
object RequestMerchantTransferNative {
|
||||
private const val OPEN_BUSINESS_VIEW_SDK_INT = 0x25020500
|
||||
|
||||
fun send(
|
||||
appId: String?,
|
||||
mchId: String,
|
||||
packageValue: String,
|
||||
openId: String?,
|
||||
subAppId: String?,
|
||||
subMchId: String?,
|
||||
done: (Boolean, String) -> Unit
|
||||
) {
|
||||
val context = UTSAndroid.getAppContext()
|
||||
if (context == null) {
|
||||
done(false, "当前应用上下文不可用")
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
val factoryClass = try {
|
||||
Class.forName("com.tencent.mm.opensdk.openapi.WXAPIFactory")
|
||||
} catch (_: Throwable) {
|
||||
null
|
||||
}
|
||||
|
||||
if (factoryClass == null) {
|
||||
done(false, "未集成微信 OpenSDK,请使用自定义基座或打包运行")
|
||||
return
|
||||
}
|
||||
|
||||
val createMethod = factoryClass.getMethod(
|
||||
"createWXAPI",
|
||||
Context::class.java,
|
||||
String::class.java,
|
||||
Boolean::class.javaPrimitiveType
|
||||
)
|
||||
val api = createMethod.invoke(null, context, appId, false)
|
||||
if (api == null) {
|
||||
done(false, "微信 API 初始化失败")
|
||||
return
|
||||
}
|
||||
|
||||
val apiClass = api.javaClass
|
||||
val getApiVersionMethod = apiClass.methods.firstOrNull {
|
||||
it.name == "getWxAppSupportAPI" || it.name == "getWXAppSupportAPI"
|
||||
}
|
||||
val wxSdkVersion = (getApiVersionMethod?.invoke(api) as? Number)?.toInt() ?: 0
|
||||
|
||||
var requiredSdkVersion = OPEN_BUSINESS_VIEW_SDK_INT
|
||||
try {
|
||||
val buildClass = Class.forName("com.tencent.mm.opensdk.constants.Build")
|
||||
val field = buildClass.getField("OPEN_BUSINESS_VIEW_SDK_INT")
|
||||
requiredSdkVersion = field.getInt(null)
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
|
||||
if (wxSdkVersion < requiredSdkVersion) {
|
||||
done(false, "当前微信版本过低,请升级微信以使用该功能")
|
||||
return
|
||||
}
|
||||
|
||||
fun encode(v: String?): String {
|
||||
return if (v != null) URLEncoder.encode(v, StandardCharsets.UTF_8.name()) else ""
|
||||
}
|
||||
|
||||
val queryBuilder = StringBuilder()
|
||||
queryBuilder.append("mchId=").append(encode(mchId)).append("&")
|
||||
queryBuilder.append("package=").append(encode(packageValue)).append("&")
|
||||
if (appId != null) {
|
||||
queryBuilder.append("appId=").append(encode(appId)).append("&")
|
||||
}
|
||||
if (openId != null) {
|
||||
queryBuilder.append("openId=").append(encode(openId)).append("&")
|
||||
}
|
||||
if (subAppId != null) {
|
||||
queryBuilder.append("subAppId=").append(encode(subAppId)).append("&")
|
||||
}
|
||||
if (subMchId != null) {
|
||||
queryBuilder.append("subMchId=").append(encode(subMchId)).append("&")
|
||||
}
|
||||
val queryString = if (queryBuilder.isNotEmpty() && queryBuilder.endsWith("&")) {
|
||||
queryBuilder.substring(0, queryBuilder.length - 1)
|
||||
} else {
|
||||
queryBuilder.toString()
|
||||
}
|
||||
|
||||
val reqClass = Class.forName("com.tencent.mm.opensdk.modelbiz.WXOpenBusinessView\$Req")
|
||||
val reqInstance = reqClass.getDeclaredConstructor().newInstance()
|
||||
|
||||
reqClass.getField("businessType").set(reqInstance, "requestMerchantTransfer")
|
||||
reqClass.getField("query").set(reqInstance, queryString)
|
||||
|
||||
val sendReqMethod = apiClass.methods.firstOrNull {
|
||||
it.name == "sendReq" && it.parameterTypes.size == 1
|
||||
}
|
||||
|
||||
val ret = (sendReqMethod?.invoke(api, reqInstance) as? Boolean) ?: false
|
||||
if (ret) {
|
||||
done(true, "ok")
|
||||
} else {
|
||||
done(false, "fail")
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
done(false, "调用微信转账接口异常: " + (e.message ?: ""))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +1,23 @@
|
||||
|
||||
import { RequestMerchantTransfer, RequestMerchantTransferOptions, RequestMerchantTransferGeneralCallbackResult } from '../interface.uts';
|
||||
import WXAPIFactory from 'com.tencent.mm.opensdk.openapi.WXAPIFactory'
|
||||
import URLEncoder from 'java.net.URLEncoder'
|
||||
import StandardCharsets from 'java.nio.charset.StandardCharsets'
|
||||
import WXOpenBusinessView from 'com.tencent.mm.opensdk.modelbiz.WXOpenBusinessView'
|
||||
import Build from 'com.tencent.mm.opensdk.constants.Build'
|
||||
export const requestMerchantTransfer : RequestMerchantTransfer = function (options : RequestMerchantTransferOptions) {
|
||||
var appId = options.appId
|
||||
var api = WXAPIFactory.createWXAPI(UTSAndroid.getAppContext(), appId, false)
|
||||
var wxSdkVersion = api.wxAppSupportAPI
|
||||
if (wxSdkVersion >= Build.OPEN_BUSINESS_VIEW_SDK_INT) {
|
||||
var req = WXOpenBusinessView.Req()
|
||||
req.businessType = "requestMerchantTransfer"
|
||||
|
||||
// 通过 URL 编码处理参数,确保特殊字符不会影响请求
|
||||
var query = ""
|
||||
query += 'mchId=' + encodeParams(options.mchId) + '&'
|
||||
query += 'package=' + encodeParams(options.package) + '&'
|
||||
if (appId != null) {
|
||||
query += 'appId=' + encodeParams(options.appId) + '&'
|
||||
}
|
||||
if (options.openId != null) {
|
||||
query += 'openId=' + encodeParams(options.openId) + '&'
|
||||
}
|
||||
if (options.subAppId != null) {
|
||||
query += 'subAppId=' + encodeParams(options.subAppId) + '&'
|
||||
}
|
||||
if (options.subMchId != null) {
|
||||
query += 'subMchId=' + encodeParams(options.subMchId) + '&'
|
||||
}
|
||||
query = query.substring(0, query.length - 1)
|
||||
req.query = query
|
||||
// 发送请求并检查返回值
|
||||
var ret = api.sendReq(req)
|
||||
if (ret) {
|
||||
var result : RequestMerchantTransferGeneralCallbackResult = {
|
||||
errMsg: 'ok'
|
||||
export const requestMerchantTransfer : RequestMerchantTransfer = function (options : RequestMerchantTransferOptions) {
|
||||
RequestMerchantTransferNative.send(
|
||||
options.appId,
|
||||
options.mchId,
|
||||
options.package,
|
||||
options.openId,
|
||||
options.subAppId,
|
||||
options.subMchId,
|
||||
(success : boolean, errMsg : string) => {
|
||||
const result : RequestMerchantTransferGeneralCallbackResult = {
|
||||
errMsg: errMsg
|
||||
}
|
||||
options.success?.(result)
|
||||
options.complete?.(result)
|
||||
}else{
|
||||
var result : RequestMerchantTransferGeneralCallbackResult = {
|
||||
errMsg: 'fail'
|
||||
if (success) {
|
||||
options.success?.(result)
|
||||
} else {
|
||||
options.fail?.(result)
|
||||
}
|
||||
options.fail?.(result)
|
||||
options.complete?.(result)
|
||||
}
|
||||
} else {
|
||||
var result : RequestMerchantTransferGeneralCallbackResult = {
|
||||
errMsg: '当前微信版本过低,请升级微信以使用该功能'
|
||||
}
|
||||
options.fail?.(result)
|
||||
options.complete?.(result)
|
||||
}
|
||||
}
|
||||
function encodeParams(params : string | null) : string | null {
|
||||
return URLEncoder.encode(params, StandardCharsets.UTF_8.toString())
|
||||
}
|
||||
)
|
||||
}␍
|
||||
Reference in New Issue
Block a user