因为之前有开发微信的经验,所以少走很多弯路,但是不得不提,微信有很多坑,我现在一个一个帮你们填上,让你们不用走弯路,一路畅通无阻,有任何问题,可以 邮箱我:[email protected]
2.1.此秘钥是自己生成,密码随机生成器,选择32位:链接地址:
https://suijimimashengcheng.51240.com/
3.1 一定要注意,支付授权目录,一定是详细一点,
如:支付页面是,http://baidu.com/pay/wxpay/wxpay.aspx
支付授权目录应该设置成:http://baidu.com/pay/wxpay/ 最后以"/"结尾
4.1 应该设置已经备案过得域名,并把 txt 文件放在根目录 即可
5.1 获取用户授权,得到 code
在微信公众号测试菜单中,添加地址:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd59849ba4991d63b&redirect_uri=xxxxxx&response_type=code&scope=snsapi_userinfo&state=STATE%23wechat_redirect&connect_redirect=1#wechat_redirect
5.2 上面的链接地址中的:xxxxxx 改为,微信调试地址,并经过urlencode编码一次,如:
编码前:http://wx.baidu.com
编码后:http%3a%2f%2fwx.baidu.com 传入编码后的地址即可
5.3 此链接是用户授权认证,有了此链接,可以获取到用户的:oauth_code
5.4
6.3 代码块
6.3.1 准备类:CodeResponse,6.3.2 会用到
/**
* 网页授权接口调用凭证
*/
private String accessToken;
/**
* 接口调用凭证超时时间,单位(秒)
*/
private String expiresIn;
/**
* 用户刷新access_token
*/
private String refreshToken;
/**
* 用户唯一标识
*/
private String openid;
/**
* 用户授权的作用域
*/
private String scope;
/**
* 错误码
*/
private String errcode;
/**
* 错误信息
*/
private String errmsg;
6.3.2 CodeResponse 中的 openid 已经拿到了想得到的 用户唯一码:openid
String appId = "微信公众号的appId";
String secret = "微信公众号的秘钥";
String code = "前台传的code,不懂的可以看 5.5 的那张图";
Map map = new HashMap();
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?";
map.put("appid", appId);
map.put("secret", secret);
map.put("code", code);
map.put("grant_type", "authorization_code");
try {
//不要纠结这个doQueryString方法,就是一个get请求,网上搜索 java get请求,一大推
String tokenStr = WebUtils.doQueryString(url, map);
CodeResponse codeResponse = JSON.parseObject(tokenStr, CodeResponse.class);
if (StringUtils.isEmpty(codeResponse.getErrcode())) {//判断返回的json中有没有 errcode,如果没有说明获取成功,否则查看原因
return codeResponse ;//最上面用 CodeResponse 接收即可
} else {
//这里是随意写的,你们直接用肯定会报错,意思是,返回错误码和错误信息,好查找错误原因
return codeResponse.getErrmsg(), codeResponse.getErrcode()
}
} catch (Exception ext) {
return null;
}
6.3.3 用户基本信息类 UserInfoResponse
/**
* 用户的唯一标识
*/
private String openid;
/**
* 用户昵称
*/
private String nickname;
/**
* 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
*/
private String sex;
/**
* 省份
*/
private String province;
/**
* 城市
*/
private String city;
/**
* 国家
*/
private String country;
/**
* 用户头像
*/
private String headimgurl;
/**
* 用户特权信息
*/
private String privilege;
/**
* 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段
*/
private String unionid;
/**
* 错误码
*/
private String errcode;
/**
* 错误信息
*/
private String errmsg;
6.3.4 附加:通过 openid获取用户基本信息
Map infoMap = new HashMap();
String infoUrl = "https://api.weixin.qq.com/sns/userinfo?";
infoMap.put("access_token", codeResponse.getData().getAccessToken());
infoMap.put("openid", codeResponse.getData().getOpenid());
infoMap.put("lang", "zh_CN");
String infoStr = WebUtils.doQueryString(infoUrl, infoMap);
UserInfoResponse userInfoResponse = JSON.parseObject(infoStr, UserInfoResponse.class);
if (StringUtils.isEmpty(userInfoResponse.getErrcode())) {
return userInfoResponse;
} else {
return null;
}
7.1. 帮助类
/**
* 用户输入的是 元,需要 分,不能填写 点 , 提供精确的乘法运算。
*
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static String Mul2(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return getDoubleStr2(b1.multiply(b2).doubleValue());
}
public static String replaceBlank(String str) {
String dest = "";
if (str!=null) {
dest = str.replace("\\n","").replace("\n","").replace("\\r","").replace("\r","").replace(" ","").trim();
}
return dest;
}
public static String MapToJson(Map map) {
String json = StringUtils.replaceBlank(JSONObject.toJSONString(map));
return json;
}
public static T MapToObjcet(Map map, Class zclass) {
String json = MapToJson(map);
return JSONObject.parseObject(json, zclass);
}
7.2 下面缺少的方法,sdk中有,我就不写了
String mch_id = "商户号";
String key = "商户密钥";//key是商户密钥.本文章 2.1 中已经提到
String appId = "微信appid";
String fee = "0.01";
String ip = "当前请求微信支付的服务器ip地址";
Map params = MapToJsonUtils.objectToMap(payRequest);
String key = setting.getPayKey();
String nonceStr = WXPayUtil.generateNonceStr();
String openid = "用户的openid";
params.put("nonce_str", nonceStr);
params.put("openid", openid);
params.put("body", "商品123");
params.put("mch_id", mch_id);
params.put("appid", appId);
params.put("sign_type", WXPayConstants.MD5);
Double feeDouble = Double.valueOf(fee);
String feeStr = DoubleUtil.Mul2(feeDouble, 100);//用户输入的是 元,需要 分,不能填写 点
params.put("total_fee", feeStr);
params.put("trade_type", "JSAPI");
params.put("spbill_create_ip", ip);
//下面这个方法可能需要改造一下,最好是把 key也 传进去 计算 7.3的图片中会有
String signature = WXPayUtil.generateSignature(params, key, WXPayConstants.MD5); //TODO key是商户密钥
params.put("sign", signature);
WxPayConfigImpl instance = WxPayConfigImpl.getInstance();
WXPay wxPay = new WXPay(instance);
//下面这个方法可能需要改造一下,最好是把 key也 传进去 计算 7.3的图片中会有
Map returnMap = wxPay.unifiedOrder(params, key);
PayResponse payResponse = MapToJsonUtils.MapToObjcet(returnMap, PayResponse.class);
if (payResponse.getReturnCode().equals("SUCCESS") && payResponse.getResultCode().equals("SUCCESS")) {
//第二次验签、这一步非常重要,在很多别的博客中都没有这句话,造成了 前台返回签名错误
//这里是一个大坑,必须要签名两次的
Map chooseWXPayMap = new HashMap<>();
chooseWXPayMap.put("appId", payResponse.getAppid());
chooseWXPayMap.put("timeStamp", WXPayUtil.getCurrentTimestamp();
chooseWXPayMap.put("nonceStr", payResponse.getNonceStr());
chooseWXPayMap.put("package", "prepay_id=" + payResponse.getPrepayId());//这个很关键,需要
chooseWXPayMap.put("signType", WXPayConstants.MD5);
WXPayUtil.getLogger().info("wxPay.chooseWXPayMap:" + chooseWXPayMap.toString());
// 生成支付签名
String paySign = WXPayUtil.generateSignature(chooseWXPayMap, key, WXPayConstants.MD5);
chooseWXPayMap.put("paySign", paySign);
payResponse.setPaySign(paySign);
return payResponse;
} else {
return null;
}
7.3 这些都是 微信支付提供的sdk原生的代码,我们需要改造一番,适合自己的才最好,因为你的所有的配置,不可能写在代码中,所以最好是在数据库,或者配置文件中配置
7.4.上面所有的准备,代码,已经完毕,现在开始,前台的调用
8.1 我使用 java 写接口,c# 写调用api,然后呈现
rlskOpenWechatData
rlskWechatPayResponse
rlskWechatUserInfo
这三个,在后台的方法中,已经拿到具体数据了,现在呈现即可
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="WxTest._default" %>
备注:微信中遇到的坑不少,但是你不要怀疑微信有问题,因为不只你一人调用过,别人怎么不说有问题,就你有问题?所以,文档看详细点,不要一目十行。如有问题,随时邮件沟通 ! [email protected]