微信扫码支付方式二

**

近期要做支付,查了很多资料,所以把一些东西分享给大家

首先要去申请一个公众号,是服务类型的,完成企业认证。

如图所示,申请支付,通过后会把商户号相关信息发送到预留的邮箱
如图所示,申请支付,通过后会把商户号相关信息发送到预留的邮箱

这里查看公众号的AppId,设置开发者密码。

在这里插入图片描述

我们用申请支付通过后,发给我们的商户号登陆商户平台> 设置API密钥

API密钥用于接口调用时候,必填参数签名sign的生成,签名算法

在这里插入图片描述

准备工作差不多已经完成,接下来准备开始开发

官方开发文档地址
由于近期工作时间比较紧张,这里只说一个下单的接口使用方法,其余的类似。
大概就是利用HTTP方式请求接口,然后拿到响应的内容。请求参数,响应参数文档都有写,照着填就行。需要注意的是,请求接口的参数必须是xml格式的,不是json!
首先得写一个http请求的工具类,网上一大堆,我这里帖出一个:


    public class HttpUtils extends WXPayConfig {
	    public enum RequestMethod {
	        POST, GET
	    }

	    /**
	     * 发送https请求
	     * @param requestUrl 请求地址
	     * @param requestMethod 请求方式(GET、POST)
	     * @param outputStr 提交的数据
	     * @return 返回微信服务器响应的信息
	     */
	    public static String httpsRequest(String requestUrl, RequestMethod requestMethod, String outputStr) {
	        try {
	            // 创建SSLContext对象,并使用我们指定的信任管理器初始化
	            X509TrustManager[] tm = { new MyX509TrustManager() };
	            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
	            sslContext.init(null, tm, new java.security.SecureRandom());
	            // 从上述SSLContext对象中得到SSLSocketFactory对象
	            SSLSocketFactory ssf = sslContext.getSocketFactory();
	            URL url = new URL(requestUrl);
	            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
	            conn.setSSLSocketFactory(ssf);
	            conn.setDoOutput(true);
	            conn.setDoInput(true);
	            conn.setUseCaches(false);
	            // 设置请求方式(GET/POST)
	            conn.setRequestMethod(requestMethod.toString());
	            conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
	            // 当outputStr不为null时向输出流写数据
	            if (null != outputStr) {
	                OutputStream outputStream = conn.getOutputStream();
	                // 注意编码格式
	                outputStream.write(outputStr.getBytes("UTF-8"));
	                outputStream.close();
	            }
	            // 从输入流读取返回内容
	            InputStream inputStream = conn.getInputStream();
	            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
	            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
	            String str = null;
	            StringBuffer buffer = new StringBuffer();
	            while ((str = bufferedReader.readLine()) != null) {
	                buffer.append(str);
	            }
	            // 释放资源
	            bufferedReader.close();
	            inputStreamReader.close();
	            inputStream.close();
	            inputStream = null;
	            conn.disconnect();
	            return buffer.toString();
	        } catch (ConnectException ce) {
	            log.error("连接超时:{}", ce);
	        } catch (Exception e) {
	            log.error("https请求异常:{}", e);
	        }
	        return null;
	    }
}

下面是生成sign的方法,data就是请求的参数,放进一个Map中,键就是官方文档里给的参数名

 /**
     * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
     *
     * @param data 待签名数据
     * @param key API密钥
     * @param signType 签名方式
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data, String key, SignType signType) throws Exception {
        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 (k.equals(WXPayConstants.FIELD_SIGN)) {
                continue;
            }
            if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
                sb.append(k).append("=").append(data.get(k).trim()).append("&");
        }
        sb.append("key=").append(key);
        if (SignType.MD5.equals(signType)) {
            return MD5(sb.toString()).toUpperCase();
        }
        else if (SignType.HMACSHA256.equals(signType)) {
            return HMACSHA256(sb.toString(), key);
        }
        else {
            throw new Exception(String.format("Invalid sign_type: %s", signType));
        }
    }

下来我们用main方法测试(当然你也可以用postman等工具)

 public static void main(String[] args) throws Exception {
        Map map = new HashMap();
        map.put("appid", WXPayConfig.pcAppId);//公众号APPId
        map.put("mch_id",WXPayConfig.mch_id);//商户号ID
        map.put("nonce_str", WXPayUtil.generateNonceStr());//随机数,方式有很多种。
        map.put("body","测试");//商品描述
        map.put("notify_url","https://www.baidu.com");//通知地址,我这里乱填的
        map.put("out_trade_no","11111111111");//商品订单号,根据实际情况自己生成
        map.put("spbill_create_ip","127.0.0.1");//客户端IP
        map.put("total_fee","1");//订单金额,注意单位是分
        map.put("trade_type",WXPayConfig.NATIVE);//交易类型,这里填NATIVE
        //生成签名sign
        String sign = WXPayUtil.generateSignature(map,WXPayConfig.key,SignType.MD5);
        //把签名继续装进map
        map.put("sign",sign);
        //把map类型的参数转换成xml
        String xmlParam = WXPayUtil.mapToXml(map);
        //下单接口地址(参考官方接口文档)
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        String result =HttpUtils.httpsRequest(url, HttpUtils.RequestMethod.POST,xmlParam);
        log.info(result);
    }

这里返回的也是xml格式,具体看官方。其中有一个标签是code_url,里面就存着我们需要的二维码链接,把这个链接发给前端,用插件生成二维码图片,或者直接在后端生成图片存到某一路径下,让前端直接显示。
在这里插入图片描述

我们需要做的就是把这个xml格式的字符串给他转换出我们想要的类型,map也好,对象也行,总之这里xml之间的转换,网上也有一大堆,这里就不贴出代码了,因为每个人的方式不同。

最后感谢看完这篇我都看不下去的大佬们 ,这也只是我小小的记录而已,并没有多少实质上的技术含量,还望大牛们海涵,哪里有不对的地方,请大佬们指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT界的奇葩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值