评论

多端应用如何接入第三方支付

分享基于小程序多端框架开发的App如何接入支付宝支付

最近在使用小程序多端框架做一个 APP,业务上除了要接入微信支付,还需要接入支付宝支付。通过研究了解到多端框架支持原生插件,也就是说支付宝接入的部分可以用原生来实现,都到这了,收拾收拾开搞了。

考虑到要同时在 iOS 和 Android 两个平台接,这就需要写两个原生插件,一个个的来。

一、  iOS 接入过程

参考多端应用插件使用指引,先创建一个空白的多端插件项目

这个项目是个自带的插件开发模板

按照模拟器中的步骤操作,第 1 是安全设置要打开「多端插件服务端口」

自己的mac 电脑要安装 xcode(必须的,要不然你怎么原生开发?),在工具栏顶部选择「iOS-运行」,应该会拉起 Xcode打开项目

什么也不用管,直接点击播放按钮

会拉起一个iphone 模拟器

点按钮「点击加载多端插件」,然后点击「点击调用多端插件」,可以正常互动,这个示例模板运行很正常。

研究一下这里的代码,在 Xcode 里,MyPlugin 目录中会写一些开放的方法,比如mySyncFunc

然后在开发者工具里,可以看到在调用这个声明的函数

这就完成了一个调用,而声明的 myAsyncFuncwithCallback 则是一个异步的方法,基本的情况都考虑到了。

简单的示例能够跑通,接下来开始做支付宝接入,支付宝这个 SDK 依赖我们用 CocoaPods 来管理,在开发者工具里 iOS 目录搞一个新文件,名字叫「Podfile」

然后粘贴一下代码:

platform :ios, '11.0'

target 'wx换成插件id' do

pod "MyPlugin", :path => "."

pod 'WechatOpenSDK'

end

插件 id 需要自己替换,这个插件申请可以在「微信开发者平台」自己小程序的多端应用中申请,获得插件 ID 后就可以拿来用了。

然后再新建一个「MyPlugin.podspec」文件,粘贴下面的代码

Pod::Spec.new do |spec|
  spec.name         = 'MyPlugin'
  spec.version      = '1.0.0'
  spec.summary      = 'Summary of MyPlugin'
  spec.homepage     = 'https://your-framework-website.com'
  spec.author       = { 'Your Name' => 'your@email.com' }
  spec.source       = { :git => 'https://github.com/your/repo.git', :tag => "#{spec.version}" }

  # Set your deployment target
  spec.ios.deployment_target = '11.0'
  
  # 引入 Open SDK
  spec.dependency 'WechatOpenSDK-XCFramework'
  # 引入 支付宝 SDK
  spec.dependency 'AlipaySDK-iOS', '~> 15.8.16'

end

在 iOS 目录右键打开终端,运行命令「pod install」,发现有很多告警,基本都是配置被覆盖了

关闭 Xcode,点击 NativePlugin.xcworkspace 来打开项目

可按照使用 CocoaPods 开发 iOS 插件 | 微信开放文档这个文档来操作消掉告警

消掉之后就这样子了

支付宝 SDK 依赖引入进来了,接下来就开始写支付宝插件的代码,在 Xcode 的「MyPlugin.mm」文件中写就可以。

这里我把代码示例写了一下,大家可以自己取用

#import 
#import 
#import "WeAppNativePlugin.framework/WeAppNativePlugin.h"
#import "MyPlugin.h"
# import 

__attribute__((constructor))
static void initPlugin() {
    [MyPlugin registerPluginAndInit:[[MyPlugin alloc] init]];
};

@implementation MyPlugin

// 声明插件ID
WEAPP_DEFINE_PLUGIN_ID(wx9a790b5a7ff816c6)

// 声明插件同步方法
WEAPP_EXPORT_PLUGIN_METHOD_SYNC(mySyncFunc, @selector(mySyncFunc:))

// 声明插件异步方法
WEAPP_EXPORT_PLUGIN_METHOD_ASYNC(myAsyncFuncwithCallback, @selector(myAsyncFunc:withCallback:))

// 声明插件异步方法
WEAPP_EXPORT_PLUGIN_METHOD_ASYNC(doAliPayOrderwithCallback, @selector(doAliPayOrder:withCallback:))

- (id)mySyncFunc:(NSDictionary *)param {
    NSLog(@"mySyncFunc %@", param);
    return @"mySyncFunc";
}

- (void)myAsyncFunc:(NSDictionary *)param withCallback:(WeAppNativePluginCallback)callback {
    NSLog(@"myAsyncFunc %@", param);
    callback(@{ @"a": @"1", @"b": @[@1, @2], @"c": @3 });
}

- (void)doAliPayOrder:(NSDictionary *)param withCallback:(WeAppNativePluginCallback)callback {
    // 获取支付相关参数
    NSLog(@"doAliPayOrder %@", param);
    NSString *orderString = [param objectForKey:@"orderString"];
    NSString *appScheme = [param objectForKey:@"appScheme"];
    NSString *universalLink = [param objectForKey:@"universalLink"];
    [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme 
       fromUniversalLink:universalLink callback:^(NSDictionary *resultDic) {
        NSLog(@"reslut = %@", resultDic);
    }];
}

// 插件初始化方法,在注册插件后会被自动调用
- (void)initPlugin {
    NSLog(@"initPlugin");
    [self registerAppDelegateMethod:@selector(application:openURL:options:)];
    [self registerAppDelegateMethod:@selector(application:continueUserActivity:restorationHandler:)];
}

// 处理支付宝 URL Scheme 回调
- (void)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options {
    if ([url.host isEqualToString:@"safepay"]) {
        //跳转支付宝客户端进行支付,处理支付结果
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@", resultDic);
        }];
    }
}

// 处理支付宝 Universal Link 回调
- (void)application:(UIApplication *)application continueUserActivity:
      (NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray> *__nullable restorableObjects))restorationHandler {
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        [[AlipaySDK defaultService] handleOpenUniversalLink:userActivity standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@", resultDic);
        }];
    }
}

@end

还是点击 Xcode 的播放按钮,顺利的话还是会 build success

在 iPhone 的模拟器里再试一下加载和使用,还是可以运行(我保留了示例的代码)

下面我们可以在开发者工具里,ios 的 page 页面尝试调用一下我们写的支付宝方法

这个使用还是看自己实现,

涉及到的 Universal Links 文档可参考:

插件项目: 小程序文档 - 支付宝文档中心

多端项目:Universal Link 配置 | 微信开放文档

appScheme 的设置路径:

插件项目: xcode -> 项目名称 -> info -> URL Types。

多端项目:默认已配置「移动应用id」,自定义要在「project.miniapp.json -> ios -> 应用配置(info.plist 相关)-> URL Types -> URL Schemes」中

原生到多端的通信差不多就搞定了,接下来就需要融入自己的业务了,这个就不继续分享了,大家继续!


二、  Android 接入过程

Android 插件的过程,可参考Android 原生插件开发指引 | 微信开放文档用示例项目先跑一遍,跑通了之后再替换支付宝支付

这里粘贴 PluginManager.kt 文件的关键代码(插件ID的获取方式看 iOS 的步骤)

package com.donut.wx替换你自己的插件ID

import android.app.Activity
import com.alipay.sdk.app.PayTask
import com.tencent.luggage.wxa.SaaA.plugin.AsyncJsApi
import com.tencent.luggage.wxa.SaaA.plugin.NativePluginBase
import com.tencent.luggage.wxa.SaaA.plugin.NativePluginInterface
import com.tencent.luggage.wxa.SaaA.plugin.SyncJsApi
import org.json.JSONObject


class TestNativePlugin: NativePluginBase(), NativePluginInterface {
    private val TAG = "TestNativePlugin"

    override fun getPluginID(): String {
        android.util.Log.e(TAG, "getPluginID")
        return BuildConfig.PLUGIN_ID
    }

    @SyncJsApi(methodName = "mySyncFunc")
    fun test(data: JSONObject?, activity: Activity): String {
        android.util.Log.i(TAG, data.toString())

        // 从 data 中获取 orderInfo
        val orderInfo = data?.getString("orderInfo")


        // 创建一个 Runnable 来处理支付
        val payRunnable = Runnable {
            val alipay = PayTask(activity)
            val result = alipay.payV2(orderInfo, true)
            // 处理支付结果
            handlePayResult(result.toString())
        }

        val payThread = Thread(payRunnable)
        payThread.start()
        return "Payment initiated"
    }

    @AsyncJsApi(methodName = "myAsyncFuncwithCallback")
    fun testAsync(data: JSONObject?, callback: (data: Any) -> Unit, activity: Activity) {
        android.util.Log.i(TAG, data.toString())

        // 从 data 中获取 orderInfo
        val orderInfo = data?.getString("orderInfo")

        // 创建一个 Runnable 来处理支付
        val payRunnable = Runnable {
            val alipay = PayTask(activity)
            val result = alipay.payV2(orderInfo, true)

            // 发送状态消息到 JS
            val values1 = HashMap()
            values1["status"] = "testAsync start"
            this.sendMiniPluginEvent(values1)

            // 处理支付结果并通过回调返回
            val resultMessage = handlePayResult(result.toString())
            callback(resultMessage)
        }

        // 启动支付线程
        val payThread = Thread(payRunnable)
        payThread.start()
    }

    private fun handlePayResult(result: String): String {
        // 处理支付结果
        android.util.Log.i(TAG, "支付结果: $result")
        // 这里可以解析 result 字符串并根据支付结果进行相应的处理
        // 返回处理后的结果
        return result // 或者根据需要返回更具体的信息
    }

}

另外在 plugin 目录的build.gradle中,需要导入支付宝 sdk,然后build和asyc

dependencies {
    implementation "androidx.exifinterface:exifinterface:1.1.0"
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

    api "androidx.constraintlayout:constraintlayout:1.1.3"

    api 'com.google.android.material:material:1.0.0'
    api 'com.alipay.sdk:alipaysdk-android:+@aar'
    compileOnly("com.tencent.luggage:wxa-standalone-open-runtime-SaaA-plugin-sdk:$saaaSDKVersionDepend") {}
}


开发者工具里的插件加载和方法调用和 iOS 的差不多,不展示了


Android的插件重点就是:先跑通官方给的示例插件项目,然后自己再换支付宝的代码,因为 CPU 类型和系统类型大家都不太一致,所以没有分享的很详细,只是给个大概。所以如果遇到报错或与文档描述不一致,就专注于解决报错就可以了。

最后一次编辑于  02-10  
点赞 1
收藏
评论
登录 后发表内容