简介:面向Unity开发者的微信与支付宝SDK集成资料包,覆盖微信登录、微信分享、微信支付及支付宝支付四大核心功能,适用于需要为iOS/Android游戏快速接入第三方能力的中高级Unity开发者。资源包共包含7322个文件,以C#脚本、二进制库和动态链接库为主体,同时提供aar、jar、Java源码等Android工程依赖,以及配置文件、图片、文档和少量示例场景,压缩包大小约464.91MB,目录结构完整,便于按模块查阅。内容基于真实项目整理,不仅列出了SDK导入、IL2CPP配置、登录与支付接口调用等操作流程,还给出了回调解析、订单校验、平台差异处理等关键细节和排错思路,配合3000余个脚本文件可直接对照工程实践。已有2245人学习下载,对于希望少走弯路、快速完成微信/支付宝接入的开发者有切实帮助。
1. 把 Unity 工程接入微信登录、微信分享、微信支付和支付宝SDK,到底要做什么
把 Unity 工程同时接入微信登录、微信分享、微信支付和支付宝SDK,是国内双端发行绕不开的标配:玩家用微信一键进游戏,顺手分享给好友,商城下单时又能用微信或支付宝完成支付。技术本身不复杂,但这类 SDK 全部是原生侧(Android 的 aar / iOS 的 framework),Unity 侧要自己搭桥、配回调页面、管生命周期,任何一环断了,表现就是“微信没反应”“分享后没动静”“收银台不弹”或者“支付成功但游戏里没到账”。这篇文章面向双端打包、发行到中国大陆的 Unity 团队,尤其是没有专职客户端平台组的项目,把从账号申请、代码桥接、支付链路到上线验证的完整路径拆开,每一步都给能直接抄的方案。
2. 接入前先把地基打好:AppID、包名、签名和 Unity 工程准备
2.1 微信与支付宝开放平台:AppID、AppSecret、商户号、RSA2 私钥谁用在哪
微信开放平台创建“移动应用”并通过审核后,会得到两个核心参数:AppID 和 AppSecret。AppID 是客户端用来识别应用的标识,可以出现在 Unity 工程和 APK 里;AppSecret 必须只存在服务端,绝对不能写进 Unity 代码或打包进安装包。否则别人反编译拿到 AppSecret,就可以用你的身份去换 access_token,后果基本等于把账号体系拱手送人。
支付宝开放平台那边对应的是一组密钥:应用公钥、应用私钥、支付宝公钥。应用私钥留在服务端给下单请求签名用,应用公钥填回支付宝开放平台,支付宝公钥用来验证支付宝异步通知。很多项目在支付宝文档里看到“应用私钥”就直接往客户端塞,这是翻车的高发点——私钥一旦被客户端拿到,任何人都能伪装你的应用向支付宝发起下单。
这里还容易混的一个概念是微信支付商户号。微信支付的统一下单接口需要 mch_id(商户号),它和 AppID 是两个字段;微信开放平台里还有一个开发者账号编号,看起来像数字,但不是 AppID 也不是商户号。建议在项目配置表里把 AppID、AppSecret、商户号、应用私钥、支付宝公钥分开存,别放在同一行,免得接支付时传错参数。
要注意的是,应用创建和审核在排期上得提前留时间。微信移动应用审核一般要 1~7 天,且个人开发者拿不到微信支付权限。如果公司主体还没有企业资质,先把这块启动,否则后面只能拿测试号开发,提审时会集中爆雷。
2.2 把微信与支付宝 SDK 装进 Unity 工程:Plugins 目录规划
微信 SDK 分 Android 和 iOS 两份。Android 端一般是一个 aar(新版本)或者 jar + so(老版本),iOS 是静态库加头文件。支付宝 Android 是一个 aar,iOS 是 framework 外加 AlipaySDK.bundle 资源包。
我习惯按下面这个结构放,简单直观:
Assets/Plugins/Android/ ├─ libs/ │ ├─ wechat-sdk-android-xx.aar │ └─ alipaysdk-android-xx.aar Assets/Plugins/iOS/ ├─ libWeChatSDK.a ├─ AlipaySDK.framework/ └─ AlipaySDK.bundle/Unity 打包时,Assets/Plugins/Android 下的文件会进入 APK,Assets/Plugins/iOS 下的会整体复制到导出的 Xcode 工程。注意 aar 本身可能自带 AndroidManifest,它会在打包时参与 manifest merge,如果工程里已经有重复的权限声明或 Activity 注册,要留意打包日志中的 merge 报错。
关于版本号,不必过分纠结。去官网下载当前稳定版即可。微信 Android SDK 的核心包路径是 com.tencent.mm.opensdk,支付宝是 com.alipay.sdk,后面所有 C# 桥接代码都依赖这两个包名。需要注意的是,支付宝 SDK 依赖 AndroidX 和相关网络库,Unity 工程开 AndroidX 后不要重复引入旧版 support 库,否则后面会遇到 duplicate class。
2.3 AndroidManifest 和 wxapi 回调 Activity:绕不开的固定动作
微信要求接收登录、分享、支付结果的 Activity 必须放在“包名.wxapi”目录下,也就是最终类名是com.你的包名.wxapi.WXEntryActivity和com.你的包名.wxapi.WXPayEntryActivity。Unity 默认不带这两个类,必须在 Assets/Plugins/Android 下提供 Java 源码,再由打包过程编译进去。
下面是一个最简的 WXEntryActivity,处理微信回传的 Intent 和回调结果:
package com.example.game.wxapi; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import com.tencent.mm.opensdk.modelbase.BaseReq; import com.tencent.mm.opensdk.modelbase.BaseResp; import com.tencent.mm.opensdk.modelmsg.SendAuth; import com.tencent.mm.opensdk.openapi.IWXAPI; import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler; import com.tencent.mm.opensdk.openapi.WXAPIFactory; import com.unity3d.player.UnityPlayer; public class WXEntryActivity extends Activity implements IWXAPIEventHandler { private IWXAPI api; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); api = WXAPIFactory.createWXAPI(this, "wxd1234567890abcdef", true); api.handleIntent(getIntent(), this); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); api.handleIntent(intent, this); } @Override public void onResp(BaseResp resp) { if (resp instanceof SendAuth.Resp) { SendAuth.Resp authResp = (SendAuth.Resp) resp; String code = resp.errCode == 0 ? authResp.code : ""; UnityPlayer.UnitySendMessage("SDKManager", "OnWxAuthResult", resp.errCode + "|" + code); } finish(); } @Override public void onReq(BaseReq req) { } }这段代码有几个点必须说清楚:onCreate 里用 WXAPIFactory.createWXAPI 创建实例,然后立刻把 Intent 交给 handleIntent 分发。onNewIntent 对应微信用 singleTask 模式把回调页从后台拉到前台的场景,如果不重新 setIntent 再分发,第二次及之后的回调全会丢。onResp 是真正收结果的地方,授权成功时 errCode 为 0,SendAuth.Resp.code 是短期有效的授权码,需要发给服务端换 access_token;errCode 为 -2 是用户取消。
AndroidManifest 里要注册这两个 Activity:
<application> <activity android:name="${applicationId}.wxapi.WXEntryActivity" android:exported="true" android:launchMode="singleTask" /> <activity android:name="${applicationId}.wxapi.WXPayEntryActivity" android:exported="true" android:launchMode="singleTask" /> </application>三个关键点:exported="true" 是让微信能拉起来这个 Activity;launchMode 必须是 singleTask,否则每次回调都会新建页面,微信回到游戏时栈关系混乱;路径里的 ${applicationId} 是 Android 的 manifest 占位符,打包时会自动替换成你在 Player Settings 里填的包名,比手写死包名安全得多。
2.4 applicationId、签名和打包出口:三件事一起确认
微信登录、分享、支付都会校验收到的包名和签名。支付宝也一样。所以打包前把下面三件事核对清楚,基本能避免一半的回调问题:
- Player Settings 里的 applicationId 必须和开放平台后台填写的包名完全一致。
- 最终签名证书的 MD5 必须和开放平台后台上传的签名信息一致。
- Unity 导出的 APK 不要做二次签名后再提交测试;如果渠道方一定要重新签名,要同步更新开放平台的签名信息。
一个常见的误操作是:在 Unity 编辑器里直接 Run 到手机,Unity 默认使用 debug keystore。调试包微信授权没问题,但用发布证书重新打一遍,微信提示“签名校验失败”,于是开始怀疑自己代码写错。这通常不是代码问题,是签名不一致。
3. 微信登录与微信分享的 Unity 落地:从发起授权到回调回游戏
3.1 初始化注册:在 Unity 主线程里把 AppID 交给微信 SDK
微信 SDK 使用前必须调用 registerApp。这个调用会建立一个进程内的 IWXAPI 实例,后面登录、分享、支付都复用它。我把初始化放在一个常驻 GameObject 的 Awake 里,通过 C# 调用 Java 桥接类完成。
Java 桥接类 WxApiBridge 负责注册和发起授权:
package com.example.game.bridge; import android.content.Context; import com.tencent.mm.opensdk.modelmsg.SendAuth; import com.tencent.mm.opensdk.openapi.IWXAPI; import com.tencent.mm.opensdk.openapi.WXAPIFactory; public class WxApiBridge { private static IWXAPI api; private static String appId; public static void register(Context context, String id) { appId = id; api = WXAPIFactory.createWXAPI(context, id, true); api.registerApp(id); } public static void sendAuth() { SendAuth.Req req = new SendAuth.Req(); req.scope = "snsapi_userinfo"; req.state = "unity_" + System.currentTimeMillis(); api.sendReq(req); } }配合的 C# 侧调用:
public class SdkBridge : MonoBehaviour { void Awake() { #if UNITY_ANDROID && !UNITY_EDITOR using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) using (var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity")) using (var bridge = new AndroidJavaClass("com.example.game.bridge.WxApiBridge")) { bridge.CallStatic("register", activity, "wxd1234567890abcdef"); } #elif UNITY_IOS WxApiIOS.Register("wxd1234567890abcdef"); #endif } }这里有一个容易踩的细节:C# 里不能随便 new 一个 AndroidJavaObject 当 Context 传过去。微信 SDK 的 IWXAPI 是进程内单例,如果拿到的是不同的 context 包装对象,会出现在“注册成功但拉起微信没反应”这种玄学问题。正确做法是通过 UnityPlayer.currentActivity 拿真实的 Activity,这也是所有原生桥接的统一姿势。
3.2 发起登录与处理授权回调:把 code 交给服务端换 token
在登录界面调用 WxApiBridge.sendAuth(),手机上装了微信客户端才能拉起授权页。如果玩家没装微信,常见做法是提供手机号登录作为备选,不建议把所有登录入口压到微信一个渠道上。微信授权返回后,WXEntryActivity 已经把结果发给了 Unity 里名为 SDKManager 的 GameObject。
Unity 侧接收并解析:
public class SDKManager : MonoBehaviour { public void OnWxAuthResult(string msg) { string[] parts = msg.Split('|'); int errCode = int.Parse(parts[0]); if (errCode == 0) { string code = parts[1]; StartCoroutine(ServerLogin(code)); } else if (errCode == -2) { // 用户主动取消,重置登录 UI } else { // 其他错误,提示用户稍后再试 } } }拿到 code 之后不要自己直接请求微信接口,应该把它发给游戏服务端。服务端拿 code + AppSecret 去微信的 sns/oauth2/access_token 接口换 access_token 和 openid,然后再取用户信息。这样的原因是 AppSecret 不能暴露给客户端,同时服务端可以做账号绑定、风控和登录日志;如果客户端直接请求微信接口,一旦 AppSecret 泄露,账号安全风险会立刻放大。
3.3 分享的三种内容:网页、图片、文本和两个目标场景
微信分享的核心是 SendMessageToWX.Req,里面放一个 WXMediaMessage。根据分享载体不同,消息类型字段也分三种:WXWebpageObject 分享网页链接,WXImageObject 分享图片,WXTextObject 分享纯文本。
public static void shareWeb(Context context, String appId, String url, String title, String desc, Bitmap thumb) { IWXAPI api = WXAPIFactory.createWXAPI(context, appId, true); WXWebpageObject webPage = new WXWebpageObject(); webPage.webpageUrl = url; WXMediaMessage msg = new WXMediaMessage(webPage); msg.title = title; msg.description = desc; msg.setThumbImage(thumb); SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = "web_" + System.currentTimeMillis(); req.message = msg; req.scene = SendMessageToWX.Req.WXSceneSession; api.sendReq(req); }这里三个参数要重点说:url 不能为空,且必须是 http/https 开头,如果域名被微信标记恶意,分享出去后打开是拦截页,比分享失败还伤体验;缩略图 thumb 压缩后必须小于 32KB,超过这个值微信会直接返回错误码,表现是转圈后没反应,很多团队直接把原图塞进去;scene 决定分享到哪,WXSceneSession 是好友会话,WXSceneTimeline 是朋友圈,同一份内容想两个场景都发,就得构造两次 Request。
分享的结果也会回到 WXEntryActivity.onResp,类型是 SendMessageToWX.Resp。这个回调一般只用来关闭分享面板和埋点,不需要关心玩家分享后有没有人真正打开链接。
3.4 iOS 端不能漏掉的转发口:AppDelegate 的 openURL
iOS 和 Android 最大的区别在于,所有从微信返回 App 的 URL 必须显式转给微信 SDK。Unity 导出的 Xcode 工程里,主 Controller 继承自 UnityAppController,需要在 application:openURL 分支里调用 [WXApi handleOpenURL:url delegate:self];。没有这一步,典型症状是 Android 一切正常,iOS 上登录完一直停在微信界面回不来。
常见做法是直接改导出工程里的 AppDelegate.mm,或者用一个 Unity iOS 插件在导出时自动注入。我一般选择后者,因为每次重新导出 Xcode 工程都会覆盖 AppDelegate,手动改一次就忘一次。关键是 openURL 入口必须在每次回调时都执行,不能只在冷启动处理。
4. 微信支付与支付宝支付:客户端只负责调起收银台,服务端锁定金额和订单
4.1 统一下单放在服务端,Unity 客户端不碰金额
客户端永远不能自己传金额给支付 SDK。微信支付的标准流程是:游戏服务端调用统一下单接口,把商品 ID、金额、玩家 ID 传给微信/支付宝,拿到一个带签名的支付凭证(微信的 prepayId、支付宝的 orderString),再返给客户端。客户端拿这个凭证调起收银台,微信和支付宝会按凭证里锁定的金额收款。
为什么必须这样?因为任何客户端本地参数都能被改。只要金额由客户端传给原生 SDK,玩家用抓包工具把 100 元改成 0.01 元就能完成支付。服务端下单还有个好处:游戏服务器能先做库存扣减、活动校验、订单号生成,从流程上保证一个订单不会被客户端重复发起支付。在模块划分上,Unity 侧不要出现任何价格计算逻辑,只暴露“发起支付(orderInfo)”这个动作。
4.2 微信支付落地:把服务端字段组装成 PayReq 调起收银台
服务端统一下单完成后,返回给客户端一般包含 appId、partnerId、prepayId、nonceStr、timeStamp、sign。Unity 拿到后交给原生桥接:
public static void pay(Context context, String appId, String partnerId, String prepayId, String nonceStr, String timestamp, String sign) { IWXAPI api = WXAPIFactory.createWXAPI(context, appId, true); PayReq req = new PayReq(); req.appId = appId; req.partnerId = partnerId; req.prepayId = prepayId; req.packageValue = "Sign=WXPay"; req.nonceStr = nonceStr; req.timeStamp = timestamp; req.sign = sign; api.sendReq(req); }PayReq 里所有字段都必须来自服务端,Unity 侧不要自己拼任何参数。packageValue 固定是字符串 “Sign=WXPay”,它只是协议规定的包体标识,真正参与验签的不是它;nonceStr 和 timeStamp 都是由服务端生成并参与签名,客户端替换成本地时间戳会导致微信验签失败。还有一个容易忽略的细节:req.appId 必须和服务端统一下单时用的 AppID 一致。如果开放平台下有多个应用,服务端用 A 应用下单,客户端注册 B 应用,结果就是调不起微信支付,或者回调永远进不来。
4.3 支付回调与到账依据:客户端刷新 UI,服务端异步通知发货
微信支付结果回到 WXPayEntryActivity,它同样要放在包名.wxapi 路径下。支付类回调和登录类似:
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler { @Override public void onResp(BaseResp resp) { if (resp instanceof PayResp) { PayResp payResp = (PayResp) resp; UnityPlayer.UnitySendMessage("SDKManager", "OnWxPayResult", resp.errCode + "|" + payResp.prepayId); } finish(); } }注意最后那个 finish(),不写会导致支付页在任务栈里残留,下一次拉起支付时页面栈混乱。errCode 的语义是:0 表示支付成功,-1 表示支付失败,-2 表示用户取消。
但这里要反复强调:客户端的“成功”只是拿到了微信返回的支付成功事件,绝不代表游戏服务端已经确认到账。真正决定发货的是微信和支付宝的服务端异步通知。异步通知由微信服务器直接发到游戏服务器的回调地址,携带金额、订单号、签名,服务端要验签后按通知发货。客户端回调只用来刷新 UI,比如提示“支付已成功,到账请稍候”。如果客户端 errCode=0 就直接发道具,遇到异步通知延迟或丢失,就会出现扣了款没发货,玩家重试又导致发货两次的血泪经验。
4.4 支付宝 App 支付:orderString、PayTask 与 resultStatus 的正确用法
支付宝 Android 侧不像微信那样走回调 Activity,而是用 PayTask 类拉起收银台。Unity 接支付宝时,C# 调用原生 Java:
public static void payWithAlipay(Activity activity, String orderString) { PayTask payTask = new PayTask(activity); Map<String, String> result = payTask.payV2(orderString, true); String resultStatus = result.get("resultStatus"); UnityPlayer.UnitySendMessage("SDKManager", "OnAlipayResult", resultStatus); }PayTask 构造参数必须是 Activity,不能传 Application context,否则部分机型上拉起收银台会闪退。payV2 的第二个参数 true 表示拉起收银台时显示加载进度框,一般保持 true。resultStatus 中 9000 代表支付成功,8000 代表正在处理中。8000 这个状态经常出现在网络抖动或风控场景,游戏端不能把 8000 当成失败让玩家重复支付,正确做法是提示“等待确认”,然后让服务端去支付宝查询订单状态。
支付宝的 orderString 是服务端调用 alipay.trade.app.pay 接口后返回的签名串,它是客户端调起收银台的全部依据。out_trade_no(商户订单号)由服务端生成,建议包含业务标识和随机码,比如 wxpay_20250101_xxxx,这样客户端和服务端排查订单时能一眼看出来源。客户端回调里只拿 resultStatus 更新 UI,授权服务器以支付宝异步通知为唯一发货依据。
5. Unity 接入微信支付宝的高频坑:回调进不来、签名不匹配、材质紫红色、依赖冲突
5.1 微信没反应的经典原因:WXEntryActivity 没注册或包名对不上
现象:调用 sendAuth 或 sendReq 后,微信界面一闪而过,甚至完全没有反应,Logcat 里出现 ActivityNotFoundException,或者提示找不到 com.xxx.wxapi.WXEntryActivity。
原因:AndroidManifest 里没有注册回调 Activity,或者注册的类名路径和当前 applicationId 不一致。Unity 玩家在 Player Settings 里改包名后,manifest 里还引用旧包名,是最常见的翻车姿势。
解决:先确认最终 applicationId,再验证 Assets/Plugins/Android 下的 AndroidManifest.xml。在 Player Settings 中勾选 Custom Main Manifest 后,Unity 会生成一个可编辑的 manifest 文件,把 Activity 的 android:name 改成${applicationId}.wxapi.WXEntryActivity这种占位符写法,这样以后改包名也不用回头改这里。改完必须重新打包验证,光改编辑器配置不生效。
5.2 签名校验失败:为什么编辑器里正常、真机上不行,以及核对的姿势
现象:同一套代码,Unity 直接 Run 到手机微信授权正常;打包后再用 Android Studio 签名或渠道商签名,微信弹出“签名校验失败,请确认签名信息”。
原因:开放平台填的签名 MD5 与最终安装包的签名不一致。直接 Run 时 Unity 默认用 debug keystore,开放平台校验的是 release 签名的 MD5;渠道包经过二次签名后,签名信息也会变化。
解决:始终拿“最终要给玩家用的那个包”去核对签名。用 keytool 命令把 APK 的签名信息打出来,再和微信开放平台后台“应用签名”字段逐字对比。核对方法见下一章的命令,这里只提醒排查顺序:凡是“三台手机两台能调起、一台不能”的怪问题,先查包名、签名、AppID 三件套,不要只盯代码。
5.3 支付成功但游戏不出货:异步通知幂等和服务端发货原则
现象:玩家支付成功,钱包扣款了,游戏内道具没到账;杀掉 App 重进又到账了;或者同一个订单被发货两次。
原因:客户端 errCode=0 时直接发货,而服务端异步通知还没到;或者服务端处理通知时没有做幂等控制,同一条通知被多次消费。玩家在支付成功后立刻杀进程,客户端的回调会直接消失,只有服务端通知能兜底。
解决:服务端只认异步通知。收到通知后先按 out_trade_no 查本地订单状态,如果已经发货,直接响应成功并忽略;如果未处理,验签通过后核对金额、订单号,都一致才进入发货逻辑。客户端回调只刷新 UI。这样就算客户端重复创建订单,服务端也只会成功写一次。另外,在支付订单表加一个唯一索引(order_no),防止并发通知下重复插入,这是最实用的一层后悔药。
5.4 材质紫红、类被裁剪、混淆改名:IL2CPP 面数翻车现场
现象:编辑器里材质颜色正常,Android/iOS 真机上出现大片紫红色;同时可能伴随微信回调时灵时不灵。
原因:紫红色是 Unity 打包时把 shader 从资源里剥离了。常见于运行时加载的材质、AssetBundle 里的 shader、或者资源没有被 Always Included Shaders 收集。微信回调失效的另一个原因是 Android 混淆:当 Unity 开启 Minify 后,如果 Proguard 规则没有保留 SDK 类,WXEntryActivity 的类名可能被改名,微信按包名.wxapi 找不到入口。
解决:在 Edit > Project Settings > Graphics 的 Always Included Shaders 中,把项目用到的 Shader 都加进去,尤其是 AssetBundle 动态加载的材质。同时在混淆规则中保留微信、支付宝 SDK 和 wxapi 包名。常见做法是在 Assets/Plugins/Android/proguard-user.txt 里加:
-keep class com.tencent.mm.opensdk.** { *; } -keep class com.yourpackage.wxapi.** { *; } -keep class com.alipay.sdk.** { *; }还有一点要专门提醒:你如果搜的是“unity 微信小游戏打包”,那是另一条路线。微信小游戏用的是小游戏平台的登录和支付接口,AppID、初始化方式、回调域名都和原生 App 不同,不要拿这里的方法去套,两个方向混用会卡审核。
5.5 AndroidX 与依赖冲突:微信支付宝一起进包时的版本债
现象:打包时 Java 编译报 “Duplicate class com.alipay.sdk...”,或者 manifest merge 报冲突,再或者编译通过但运行时 ClassNotFoundException。
原因:Unity 工程里不止一份支付宝/微信 SDK。比如旧版广告插件内置了一份老支付宝 SDK,你又按文档放进了一个新版本;或者支付宝 SDK 依赖 AndroidX,而工程同时引入了一个旧版 support 库,编译期就炸。
解决:优先清理 Assets/Plugins/Android 下的重复 aar/jar。把明显重复的旧版本删除,保留一个即可。如果工程本身特别复杂,用 Unity 的 External Dependency Manager 统一管理依赖版本,让 Gradle 去解析传递依赖。注意一点:不要同时“本地 aar + Gradle 远程依赖”双轨制,那是在制造新坑。
6. 上线验证:一条命令核对签名,一个真机清单跑完整链路
四件套接完后,真正影响上线的是签名、回调、服务端通知这几条链路。我习惯在提审前做三层验证,可以直接抄。
第一层是静态检查。用 keytool 核对最终包的签名信息:
keytool -printcert -jarfile game-release.apk | grep -E "MD5|SHA1"把输出的 MD5 和微信开放平台后台的“应用签名”字段比对。再用 aapt 确认回调 Activity 被打进了包:
aapt dump xmltree game-release.apk AndroidManifest.xml | grep -i "wxapi"第二层是真机闭环。准备两台不同品牌的 Android 手机,跑“微信登录、切后台再回来、微信分享、微信支付、支付宝支付”五个动作。重点关注微信支付后回到游戏的那一瞬间,有没有卡死或白屏;支付宝回跳到游戏时,Unity 主线程是否报异常。这类问题多半是回调被放到了子线程处理,需要放到主线程。
第三层是流量侧验证。用抓包工具看客户端到游戏服务端的请求,确认客户端只在支付时把 prepayId 或 orderString 发给游戏服,请求里没有金额字段,更没有 AppSecret 或应用私钥。服务端日志里对比下单时间和异步通知到达时间,超过 5 分钟计入告警。
上线之前我会把 Debug.Log 全部关掉,日志里也不要带 prepayId 和大串签名值,方便出问题时截图定位但又不至于被玩家拿去分析。我自己的习惯是接完这四个 SDK 后,先把支付查询接口的管理后台入口做好,因为“支付状态停在支付中”的咨询量比想象中大得多。提前把对账接口配好,线上出问题时你能自己查,不用等玩家反馈。希望这条验证路径能帮你少踩几次支付和登录的坑,让玩家少等几秒到账。
本文还有配套的精品资源,点击获取