1.创建应用的过程
https://pay.weixin.qq.com/guide/inapp_payment.shtml
2.Android Studio添加依赖
在build.gradle文件中,添加如下依赖即可:
1)带统计功能(我们公司用的是友盟,所以采用的是下面一种)
dependencies {
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
}
2)不带统计功能
dependencies {
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}
3.依赖完成后,在清单文件中配置
这两个avtivity说白了就是继承了IWXAPIEventHandler微信回调监听的页面,方便微信调起和进入微信支付。
先看WXEntryActivity 这个页面:
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
protected void onCreate(Bundle savedInstanceState) {
IWXAPI iwxapi = WXAPIFactory.createWXAPI(this, Constants.WX_APP_ID);
iwxapi.handleIntent(getIntent(), this);
super.onCreate(savedInstanceState);
finish();
}
public void onReq(BaseReq arg0) {
}
public void onResp(BaseResp resp) {
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
//发送成功
EventBus.getDefault().post(new EventBusBean(Constants.APP_SHARE_SUCCESS));
} else if (resp.errCode == BaseResp.ErrCode.ERR_USER_CANCEL) {
//发送取消
EventBus.getDefault().post(new EventBusBean(Constants.APP_SHARE_CANCEL));
} else {
//发送失败
EventBus.getDefault().post(new EventBusBean(Constants.APP_SHARE_FAILURE));
}
}
}
和官方给的demo差不多,只不过在onResp时做了不同返回值的处理,可以更改为广播或者别的刷新方式。
再来看WXPayEntryActivity这个页面:
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
private IWXAPI iwxapi;// IWXAPI 是第三方app和微信通信的openapi接口
@Override
public void onCreate(Bundle savedInstanceState) {
iwxapi = WXAPIFactory.createWXAPI(this, Constants.WX_APP_ID);
iwxapi.handleIntent(getIntent(), this);
super.onCreate(savedInstanceState);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
iwxapi.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq req) {
}
@Override
public void onResp(BaseResp resp) {
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
//支付成功
EventBus.getDefault().post(new EventBusBean(Constants.APP_PAY_SUCCESS));
} else if (resp.errCode == BaseResp.ErrCode.ERR_USER_CANCEL) {
//支付取消
EventBus.getDefault().post(new EventBusBean(Constants.APP_PAY_CANCEL));
} else {
//支付失败
EventBus.getDefault().post(new EventBusBean(Constants.APP_PAY_FAILURE));
}
finish();
}
}
由于这个页面我没有在oncreate中就finish掉,在有些手机上退出支付会有闪屏(比如我们老大的小米手机…)所以自写一个style样式,去除这个问题
4.调起微信支付
1)需要调取支付的页面也需要配置一个style样式(同上)否则也会造成闪屏。
2)应用需要打正式包,因为微信要检验签名文件,当然你也可以改官方申请渠道上的校验码,但是万一到时候上架没改回来。。。那就很操蛋了。
3)后台返回的参数需要手机端进行再次签名,否则调不起来(有些后台可能在返回的时候就做了一次签名,可以直接调起)
可以自己写一个工具类,支付的时候传入服务器返回的值
public class WeChatPayUtil {
private Context context;
private IWXAPI wxApi;// IWXAPI 是第三方app和微信通信的openapi接口
public WeChatPayUtil(Context context) {
this.context = context;
//通过WXAPIFactory工厂,获取IWXAPI的实例
wxApi = WXAPIFactory.createWXAPI(context, Constants.WX_APP_ID, true);
//将应用的appId注册到微信
wxApi.registerApp(Constants.WX_APP_ID);
}
// 支付
public void toPay(PayReq req) {
if (!wxApi.isWXAppInstalled()) {
ToastUtil.mackToastSHORT("您尚未安装微信"), context);
payErr();
return;
}
if (!wxApi.isWXAppSupportAPI()) {
ToastUtil.mackToastSHORT("当前版本不支持支付功能"), context);
payErr();
return;
}
//对参数重新拼接签名
ArrayMap paramsMap = new ArrayMap<>();
paramsMap.put("appid", req.appId);
paramsMap.put("noncestr", req.nonceStr);
paramsMap.put("package", req.packageValue);
paramsMap.put("partnerid", req.partnerId);
paramsMap.put("prepayid", req.prepayId);
paramsMap.put("timestamp", req.timeStamp);
req.sign = getAppSign(paramsMap);
boolean sendResult = wxApi.sendReq(req);
LogUtil.e("支付状态:" + sendResult);
if (!sendResult) {
ToastUtil.mackToastSHORT("支付失败,请重试", context);
payErr();
}
}
//重新对后台返回的sign签名
private String getAppSign(ArrayMap paramsMap) {
StringBuilder stringBuilder = new StringBuilder();
for (Map.Entry entry : paramsMap.entrySet()) {
stringBuilder.append(entry.getKey());
stringBuilder.append('=');
stringBuilder.append(entry.getValue());
stringBuilder.append('&');
}
String appSign = MD5Util.byteArrayToHex(stringBuilder.toString().getBytes()).toUpperCase();
LogUtil.e(appSign);
return appSign;
}
private void payErr() {
EventBus.getDefault().post(new EventBusBean(Constants.APP_PAY_NO_TOAST));
}
}
重新签名方法:
public static String byteArrayToHex(byte[] byteArray) {
// 首先初始化一个字符数组,用来存放每个16进制字符
char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
// new一个字符数组,这个就是用来组成结果字符串的(解释一下:一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方))
char[] resultCharArray = new char[byteArray.length * 2];
// 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去
int index = 0;
for (byte b : byteArray) {
resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
resultCharArray[index++] = hexDigits[b & 0xf];
}
// 字符数组组合成字符串返回
return new String(resultCharArray);
}
服务器返回值:
PayReq req = new PayReq();
req.appId = Constants.WX_APP_ID;
req.partnerId = credentialBean.getMerchantId();
req.prepayId = credentialBean.getPrepayId();
req.packageValue = "Sign=WXPay";
req.nonceStr = credentialBean.getNonceStr();
req.timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
req.sign = credentialBean.getSign();
weChatPayUtil.toPay(req);
以上就是关于集成微信支付的总结,官方文档是真的坑,也是折腾了好久,希望能够让遇到同样问题的同志们能有一定的参考价值。。。