- 作者:彭老师
- 日期:2020-07-03
- 类型:Android
- 说明:本文源于彭老师手写摘要,如需转载请带上链接或注明出处!
上次做微信支付模糊记得是2015年,虽然阔别这么久至少心里有底。但没想到这么坑!
无论你看与不看这篇文章,相信你都见过下面4个页面。并且逐字阅读很多遍了
1、https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1
2、https://developers.weixin.qq.com/doc/oplatform/Downloads/Android_Resource.html
3、https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5
4、https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2
然并卵,根本无从下手!
- 总结下:
- WeChatOpenSdkSample这个项目所谓的Demo根本没有支付模块
- wechat_sdk_sample_android这个项目还是Eclipse的
请注意:以上两个项目都有用!!!后面会说到
介绍下思路:能不能弄到一个Jar
包,然后调用Api不就得了
1、参考WeChatOpenSdkSample
项目中的build.gradle
,在自己项目对应加入:
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:5.3.1'
|
- 可能会编译不通过,亲猜发现是集成了友盟Umeng。所以改下:
compileOnly 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:5.3.1'
|
2、参考wechat_sdk_sample_android
项目中的WXPayEntryActivity
,复制到自己项目对应目录(切记:项目包名.wxapi.WXPayEntryActivity)
package com.xyz.xyz.wxapi;
import android.app.Activity; import android.app.AlertDialog; import android.content.Intent; import android.os.Bundle;
import com.cmonbaby.utils.show.LogUtils; import com.cmonbaby.utils.show.ToastUtils; import com.xyz.xyz.R; import com.xyz.xyz.common.utils.Constance; import com.tencent.mm.opensdk.constants.ConstantsAPI; import com.tencent.mm.opensdk.modelbase.BaseReq; import com.tencent.mm.opensdk.modelbase.BaseResp; import com.tencent.mm.opensdk.openapi.IWXAPI; import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler; import com.tencent.mm.opensdk.openapi.WXAPIFactory;
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
private IWXAPI api;
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.pay_result);
api = WXAPIFactory.createWXAPI(this, Constance.APP_ID); api.handleIntent(getIntent(), this); }
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); api.handleIntent(intent, this); }
@Override public void onReq(BaseReq req) { }
@Override public void onResp(BaseResp resp) { LogUtils.e(TAG, "onPayFinish, errCode = " + resp.errCode);
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("提示"); builder.setMessage(getString(R.string.pay_result_callback_msg, String.valueOf(resp.errCode))); builder.show();
if (resp.errCode == 0) { ToastUtils.show(this, "支付成功"); } else if (resp.errCode == -1) { ToastUtils.show(this, "支付失败"); } else if (resp.errCode == -2) { ToastUtils.show(this, "取消支付"); } else { ToastUtils.show(this, "支付错误"); } } } }
|
然后很天真,后面的代码简直不要太简单,分分钟打爆它!!!
看到微信有那么一段介绍:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5
- 调起支付
- 商户服务器生成支付订单,先调用统一下单API(详见第7节)生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付。以下是调起微信支付的关键代码:
IWXAPI api; PayReq request = new PayReq(); request.appId = "wxd930ea5d5a258f4f"; request.partnerId = "1900000109"; request.prepayId= "1101000000140415649af9fc314aa427",; request.packageValue = "Sign=WXPay"; request.nonceStr= "1101000000140429eb40476f8896f4c9"; request.timeStamp= "1398746574"; request.sign= "7FFECB600D7157C5AA49810D2D8F28BC2811827B"; api.sendReq(request);
|
怎么办,看文档呗。这里我给大家走下捷径:
1、确认你是debug还是release环境,跑在真机上的。怎么验证呢?
点击:https://developers.weixin.qq.com/doc/oplatform/Downloads/Android_Resource.html
该页面最底部有一个:签名生成工具
用于获取安装到手机的第三方应用签名的apk包。点击下载 签名生成工具
安装APK
到真机上 - 打开app
- 输入项目包名 - 得到签名结果
微信开放平台 - 登录 - 管理中心 - 开发信息(匹配两值是否一致)
点击:https://open.weixin.qq.com/
后台给出接口,安卓传参:totalFee
付款金额,userId
识别某用户ID。得到返回结果,赋值给上述appId
、partnerId
、prepayId
等7个属性
结果发现还是返回 -1(支付失败)
这个阶段是最难熬的,给点提示:
1、如果持续返回 -1(支付失败)可以断言后台签名有误!
2、如果提示:支付验证签名失败。则说明后台签名正确!接近答案了!
改动上述代码:
private void pay(WechatPayEntity pay) { IWXAPI api = WXAPIFactory.createWXAPI(this, Constance.APP_ID); String temp = String.valueOf(System.currentTimeMillis() / 1000);
PayReq request = new PayReq(); request.appId = pay.getAppid(); request.partnerId = pay.getPartnerid(); request.prepayId= pay.getPrepayid(); request.packageValue = "Sign=WXPay"; request.nonceStr= pay.getNoncestr(); request.timeStamp= temp;
Map<String, String> map = new HashMap<>(); map.put("appid", pay.getAppid()); map.put("partnerid", pay.getPartnerid()); map.put("prepayid", pay.getPrepayid()); map.put("package", "Sign=WXPay"); map.put("noncestr", pay.getNoncestr()); map.put("timestamp", temp);
request.sign= getSign(map);
api.sendReq(request); }
private String getSign(Map<String, String> data) { Set<String> keySet = data.keySet(); String[] keyArray = keySet.toArray(new String[keySet.size()]); Arrays.sort(keyArray); StringBuilder sb = new StringBuilder(); for (String k : keyArray) { if (data.get(k).trim().length() > 0) sb.append(k).append("=").append(data.get(k).trim()).append("&"); } sb.append("key=").append("11hKHB6OIJG4I32J038JH34IG234548I"); MessageDigest md = null; try { md = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } byte[] array = new byte[0]; try { array = md.digest(sb.toString().getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } StringBuilder sb2 = new StringBuilder(); for (byte item : array) { sb2.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); } return sb2.toString().toUpperCase(); }
|