Android微信支付接入教程 接口调用工具技巧实战

阿木 发布于 7 小时前 3 次阅读


凌晨一点,坐在电脑前,咖啡凉透了。

这次微信支付又宣告报错了,报错内容为:appid和mch_id不匹配。究竟是第几次出现这种情况呢?实在难以清晰记确切清楚。大致不是证书到了过期的状态,就是进行签名时遭遇了失败。官方所提供的文档都已经被翻弄得残破损坏了,社区里面充斥着全部写着“已解决”字样可是却找不见任何解决方案的帖子。

突然想摔键盘。

但想想,骂完还是得擦。这大概是每个接支付的开发者的宿命。

我们为什么还在用微信支付?

废话,因为用户在用。

但你问我是不是有想换的想法?是有的。每一次当看到“平台私钥解密失败”那一行字的时候,我就会产生一种想要把服务器从窗户扔出去的冲动。

可用户不管这些。他们只关心:点没点开,付没付成。

所以我们得伺候着。像伺候一台随时会闹脾气的精密仪器。

微信支付V3,真的是救世主吗?

官方说V2要退了,V3更安全、更规范、响应快56%。

我信。但你知道升级意味着什么吗?

表明你小心翼翼留存了五年之久的旧代码,某一天忽然全部失效。表明你从RSA1转变为RSA2,从静态密钥变换到动态令牌,从XML更改至JSON。

表示着你终究学会了JWT签名,接着发觉——呀,为何依旧报错呢?

证书序列号填错了。

那一刻你想抽自己。

dependencies {
    implementation 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:5.4.0'
}

为什么总在“签名失败”?

说实话,我到现在都不能100%背出微信支付的签名规则。

是先进行拼接而后再加密,还是先加密之后再进行拼接,参数需不需要进行排序,排序是不是按照ASCII升序来进行,时间戳到底是10位还是13位?

每次调通,都像蒙对了一道选择题。

进行过一次持续了整整两天的操作,最终发觉原来是服务器的时间比正常慢了5分钟,微信支付由此认定我是来自过去的人,进而拒绝了交易。

那一刻,我真想给那个调NTP服务的同事磕个头。

还有那些要命的“回调”

最怕什么?不是支付失败,是支付成功了,服务器没收到通知

用户付了钱,订单还是“待支付”。他骂你诈骗,你说网络波动。

谁信?

之后,掌握了这样的做法:自行发起定时任务,积极主动地去查询支付状态。要是官方没有给你打电话,那么你就拨打过去进行询问。

这叫“补偿机制”。说白了,是不信任机制的信任机制。




挺讽刺的。

对了,你知道Native支付不能长按识别二维码吗?

我也是被用户骂了才知道。

用户说:“你们二维码有问题,扫不了!”

我说:“您是用微信扫的吗?”

用户说:“是啊,从相册选的。”

就在那一个时刻,我当时陷入了沉默,微信支付基于安全方面的考虑决定禁止从相册识别二维码,这算得上是一种相当不错的设计,却又是一种极其愚蠢的体验。

然而你又能怎样呢?你唯有将所说的这话制作成弹窗,于每一个下单的页面进行循环播放。

public class Constant {
    public static final String APP_ID = "你的应用ID";
    public static final String APP_SECRET = "你的应用密钥";
    public static final String PARTNER_ID = "你的商户号";
}

没人看。下次照旧。

其实,集成文档从不说这些

官方教程永远是:

第一步,申请商户号。

第二步,下载SDK。

第三步,配置参数。

第四步,调用接口。

第五步,完成。

干净,漂亮,无懈可击。

PayReq req = new PayReq();
req.appId = Constant.APP_ID;
req.partnerId = Constant.PARTNER_ID;
req.prepayId = "生成的预支付交易会话标识";
req.nonceStr = "随机字符串";
req.timeStamp = "时间戳";
req.packageValue = "Sign=WXPay";
req.sign = "签名";

像一份不需要呼吸的人生规划。

但实际的真实情况是,商户号申请已经过了三天,然而却依旧处在审核的状态当中,所下载的SDK在版本方面并不正确 , 在配置各种参数时,其中存在了一个空格,依靠肉眼竟然无法察觉出来,当调用一种接口之后,返回的结果显示是200 , 不过其body部分却是空的。

你问客服,客服说“请参考文档”。

你参考文档,文档说“请确保参数正确”。

妈的。

怎么做才能少挨骂?

我没标准答案。但吃过这么多亏,总要长点记性:

第一,永远不要让用户替你背锅。

那个单子,被两个不同的微信号给扫了,然后出现报错,显示“商家订单信息有误”,用户呢,根本看不明白,就只会认为是你那个系统出问题坏掉了。

if (api == null) {
    api = WXAPIFactory.createWXAPI(this, Constant.APP_ID, true);
    api.registerApp(Constant.APP_ID);
}
api.sendReq(req);

错误的翻译需要转化为通俗易懂的表述:“那次的订单是由别的账号开启支付操作的,要运用相同的微信账号达成支付。”。

虽然字数多了,但用户不会骂你。

第二,幂等,幂等,还是幂等。

支付回调,退款通知,订单查询,这些事物随时有可能重复发送。倘若你的系统没有进行去重,一旦用户支付了一回款项,你却给他发送十次发货操作。

别笑,真发生过。

第三,给自己留条后路。

证书会过期,接口会变更,商户平台偶尔抽风。

别把全部逻辑都置于try - catch之中,寄望于永远不会出现报错情况。留出一个可供手动补单的入口,哪怕仅仅是后台的一个按钮而已。

关键时刻,那是救命稻草。

凌晨一点四十了

屏幕还亮着。代码还没跑通。

微信支付的错误提示依然冷漠,像一块拒绝融化的冰。

但我知道,再过几个小时,或者几天,它总会通的。

@Override
public void onResp(BaseResp resp) {
    if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
        PayResp payResp = (PayResp) resp;
        if (payResp.errCode == 0) {
            // 支付成功
        } else {
            // 支付失败
        }
    }
}

不是因为文档写得有多好,也不是因为我有多厉害。

只是因为,用户需要付钱。

而我的工作,就是让这件事,尽可能不要被他们察觉。

让支付像呼吸一样自然,像空气一样隐形。

这才是集成微信支付最难的接口。

不是技术接口。

是人和人之间的那个接口。