JAVA-JSAPI微信公众号-微信支付(非常详细)

因为之前有开发微信的经验,所以少走很多弯路,但是不得不提,微信有很多坑,我现在一个一个帮你们填上,让你们不用走弯路,一路畅通无阻,有任何问题,可以 邮箱我:[email protected]

1.开通微信支付功能

JAVA-JSAPI微信公众号-微信支付(非常详细)_第1张图片

2.安装证书、设置微信支付秘钥

2.1.此秘钥是自己生成,密码随机生成器,选择32位:链接地址:
https://suijimimashengcheng.51240.com/
JAVA-JSAPI微信公众号-微信支付(非常详细)_第2张图片

3.添加支付配置

3.1 一定要注意,支付授权目录,一定是详细一点,
如:支付页面是,http://baidu.com/pay/wxpay/wxpay.aspx
支付授权目录应该设置成:http://baidu.com/pay/wxpay/ 最后以"/"结尾
JAVA-JSAPI微信公众号-微信支付(非常详细)_第3张图片

4.设置js安全域名,授权域名

4.1 应该设置已经备案过得域名,并把 txt 文件放在根目录 即可
JAVA-JSAPI微信公众号-微信支付(非常详细)_第4张图片

5.获取用户授权码:code

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
JAVA-JSAPI微信公众号-微信支付(非常详细)_第5张图片
5.4JAVA-JSAPI微信公众号-微信支付(非常详细)_第6张图片

5.5 JAVA-JSAPI微信公众号-微信支付(非常详细)_第7张图片

6.通过code,获取用户唯一码:openid

6.1
JAVA-JSAPI微信公众号-微信支付(非常详细)_第8张图片
6.2.设置当前域名所在的Ip地址在微信白名单中

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.微信支付,前面的都是为了打基础,真正的好戏,现在才开始

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原生的代码,我们需要改造一番,适合自己的才最好,因为你的所有的配置,不可能写在代码中,所以最好是在数据库,或者配置文件中配置JAVA-JSAPI微信公众号-微信支付(非常详细)_第9张图片
JAVA-JSAPI微信公众号-微信支付(非常详细)_第10张图片

7.4.上面所有的准备,代码,已经完毕,现在开始,前台的调用

8.前台 jsapi调用微信支付

8.1 我使用 java 写接口,c# 写调用api,然后呈现
rlskOpenWechatData
rlskWechatPayResponse
rlskWechatUserInfo

这三个,在后台的方法中,已经拿到具体数据了,现在呈现即可

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="WxTest._default" %>





    
    
    
    
    


    
用户基本信息:
1.唯一标识:<%=rlskWechatUserInfo.openid %>
2.昵称:<%=rlskWechatUserInfo.nickname %>
3.头像:
4.性别:<%=rlskWechatUserInfo.sex %>
6.国家:<%=rlskWechatUserInfo.country %>
6.省份:<%=rlskWechatUserInfo.province %>
7.城市:<%=rlskWechatUserInfo.city %>
8.用户特权信息:<%=rlskWechatUserInfo.privilege %>
9.unionid:<%=rlskWechatUserInfo.unionid %>
10.ip:<%=ip %>
1.开启扫一扫


2.微信支付
3.微信支付


备注:微信中遇到的坑不少,但是你不要怀疑微信有问题,因为不只你一人调用过,别人怎么不说有问题,就你有问题?所以,文档看详细点,不要一目十行。如有问题,随时邮件沟通 ! [email protected]

你可能感兴趣的:(微信/钉钉)