微信支付之二维码支付(native)

您所在的位置:网站首页 链接怎么生成微信二维码 微信支付之二维码支付(native)

微信支付之二维码支付(native)

2024-03-28 05:59| 来源: 网络整理| 查看: 265

HoJe男孩子你要加油阿

准备材料微信支付需要的参数统一下单二维码回调接口用到的工具类

. 准备材料

首先肯定是要有微信的开发文档开发文档地址再然后就是一些必须的参数

注意:回调地址异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。

再然后就是微信的SDK

. 微信支付需要的参数

上面的开发文档你肯定看熟了吧,流程肯定会了吧,代码怎么写呢?先来看看需要哪些参数吧.

好了知道流程了知道需要哪些参数了那咱们动手吧!

. 统一下单

首页你得有统一下单的url:https://api.mch.weixin.qq.com/pay/unifiedorder

1@Controller 2@RequestMapping("/wxpay") 3public class WXpayController { 4    @Autowired 5    private PayOrderService payOrderService; 6 7    /** 8     * 微信二维码支付 9     */10    @RequestMapping(value = "/nativePay")11    public Map createQRCode(HttpServletRequest request, HttpServletResponse response, String orderid) {12        PayOrderDO payOrderDO = this.payOrderService.getOder(orderid);//订单信息13        //生成订单对象14        Map request_data = new HashMap();15        try {16            Map data = new HashMap();17            data.put("appid", WxConstants.APP_ID);//公众账号ID18            data.put("mch_id",WxConstants.PARTNER);//商户号19            data.put("body", "测试");//商品详情20            data.put("out_trade_no",orderid);//订单号21            data.put("nonce_str", UuidUtil.get32UUID());//32位字符串22            //转换微信中存在最小计算单位是分的问题23            BigDecimal payMoney = payOrderDO.getPayMoney();24            BigDecimal bigDecimal = new BigDecimal(100);25            BigDecimal amount = payMoney.multiply(bigDecimal).setScale(0, BigDecimal.ROUND_DOWN);26            data.put("total_fee", String.valueOf(amount));//总金额27            data.put("spbill_create_ip", IPUtils.getIpAddr(request));//用户终端IP28            data.put("trade_type", "NATIVE");  // H5支付的交易类型为MWEB29            data.put("notify_url", WxConstants.NOTIFY_URL);//通知地址30            data.put("product_id",orderid ); 31            String sign = createSign(data, WxConstants.PARTNER_KEY, WxConstants.CHARSET);32            //调用生成签名的方法,用以Map集合中的相关参数生成签名 需要签名密钥33            data.put("sign", sign);//签名34            String xml = WXPayUtil.generateSignedXml(data, WxConstants.PARTNER_KEY);//转Xml格式 微信SDK自带的3536            System.out.println("request - XML:" + xml);3738            String resultXML = HttpsClientUtil.doPost(WxConstants.BAUSE_URL, xml);//发送post请求   返回的是微信给我们的xml格式的数据3940            System.out.println("result - XML:" + resultXML);4142                Map result_map = xmlToMap(resultXML);43                //xml转map 微信SDK自带的44                String return_msg = result_map.get("return_msg");//返回信息45                String return_code = result_map.get("return_code");//状态码46                String result_code = result_map.get("result_code");//业务结果47                if (null != result_map && "SUCCESS".equals(return_code) && "SUCCESS".equals(result_code)) {48                    request_data.put("url", result_map.get("code_url"));49                }else{50                request_data.put("url", "");51            }5253        }catch (Exception e){54            request_data.put("url", "");55        }56        return request_data;57    }

本人自己写的也可能不是很完美欢迎你们指出 送上更完美的demo 谢谢!!!

. 二维码

QR码是一种矩阵码,或二维空间的条码,1994年由日本Denso-Wave公司发明。QR是英文Quick Response的缩写,即快速反应的意思,源自发明者希望QR码可让其内容快速被解码。QR码常见於日本,并为目前日本最流行的二维空间条码。QR码比普通条码可储存更多资料,亦无需像普通条码般在扫描时需直线对准扫描器。QR码呈正方形,只有黑白两色。在4个角落的其中3个,印有较小,像「回」字的的正方图案。这3个是供解码软体作定位用的图案,使用者无需对准,无论以任何角度扫描,资料仍可正确被读取。QR Code条码的特点1.高密度编码,信息容量大:   可容纳多达1850个大写字母或2710个数字或1108个字节,或500多个汉字,比普通条码信息容量约高几十倍。   2.编码范围广:   该条码可以把图片、声音、文字、签字、指纹等可以数字化的信息进行编码,用条码表示出来;可以表示多种语言文字;可表示图像数据。   3.容错能力强,具有纠错功能:   这使得二维条码因穿孔、污损等引起局部损坏时,照样可以正确得到识读,损毁面积达50%仍可恢复信息。   4.译码可靠性高:   它比普通条码译码错误率百万分之二要低得多,误码率不超过千万分之一。   5.可引入加密措施:   保密性、防伪性好。   6.成本低,易制作,持久耐用。 本人百度粘贴的阿!!!废话不多说了微信二维码支付关键不就是个二维码嘛!

当统一下单成功了返回的结果"code_url"就是我们要的二维码的链接有很多种生成二位码的方法我知道的就两种1丶第一种是前端的js插件QRious下载链接没有找到更好的抱歉了各位这是一个在线的地址使用该二维码生成插件需要在页面中引入qrious.js文件。使用一个img元素来作为二维码图片的容器。可以通过QRious()方法来实例化一个对象实例。

1(function() {2  const qr = new QRious({3    element: document.getElementById('qr'),4    value: 'http://www.baidu.com/'5  })6})()

效果如图

好了前端代码怎么写看你怎么做了2丶Zxing是Google提供的关于条码(一维码、二维码)的解析工具,提供了二维码的生成与解析的方法,Java利用Zxing生成与解析二维码这种方法得写一个工具类百度网上有的我是用的QRious就不多说了

. 回调接口 我踩的坑阿!注意:1丶回调url必须得填写正确要不然微信访问不到会一直调用,就是支付成功后微信异步通知我们的服务器地址加项目加路径.2丶一定要验证签名,要不然微信不知道是那个商户的会觉得不合法.3丶给微信的数据一定是xml格式的,要不然微信解析不到就会一直调用(这就是微信比支付宝坑的地方)话不多说上代码

1/** 2     * 微信支付回调函数 3     * 支付成功后微信服务器会调用此方法,修改数据库订单状态 4     */ 5    @RequestMapping(value = "/notify") 6    public void wxPayCallBack(HttpServletRequest request, HttpServletResponse response) { 7        try { 8            InputStream inStream = request.getInputStream(); 9            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();10            byte[] buffer = new byte[1024];11            int len = 0;12            while ((len = inStream.read(buffer)) != -1) {13                outSteam.write(buffer, 0, len);14            }15            outSteam.close();16            inStream.close();17            String result = new String(outSteam.toByteArray(), WxConstants.CHARSET);18            Map map = xmlToMap(result);19            // 判断签名是否正确 微信SDK自带的方法20            if (WXPayUtil.isSignatureValid(map, WxConstants.PARTNER_KEY)) {21                 logger.info("微信支付成功回调");22                // ------------------------------23                // 处理业务开始24                // ------------------------------25                String resXml = "";26                if ("SUCCESS".equals((String) map.get("result_code"))) {27                    // 这里是支付成功28                    String orderNo = (String) map.get("out_trade_no");29                    logger.info("微信订单号{}付款成功",orderNo);30                    //这里 根据实际业务场景 做相应的操作 我们这里是更改数据库订单状态31                    // 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.32                    resXml = "" + "" + "" + " ";33                } else {34                    logger.info("支付失败,错误信息:{}",packageParams.get("err_code"));35                    resXml = "" + "" + "" + " ";36                }37                // ------------------------------38                // 处理业务完毕39                // ------------------------------40                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());41                out.write(resXml.getBytes());42                out.flush();43                out.close();44            } else {45                System.out.println("通知签名验证失败");46            }474849        } catch (Exception e) {50           e.printStackTrace();51           logger.info("通知签名验证失败");52        }5354    } . 用到的工具类

1丶32位字符串

1public class UuidUtil {23    public static String get32UUID() {4        String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");5        return uuid;6    }7}

2丶获取用户的终端ip

1/** 2 * IP地址 3 * 4 * @author HoJe 5 */ 6public class IPUtils { 7    private static Logger logger = LoggerFactory.getLogger(IPUtils.class); 8 9    /**10     * 获取IP地址11     *12     * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址13     * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址14     */15    public static String getIpAddr(HttpServletRequest request) {16        String ip = null;17        try {18            ip = request.getHeader("x-forwarded-for");19            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {20                ip = request.getHeader("Proxy-Client-IP");21            }22            if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {23                ip = request.getHeader("WL-Proxy-Client-IP");24            }25            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {26                ip = request.getHeader("HTTP_CLIENT_IP");27            }28            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {29                ip = request.getHeader("HTTP_X_FORWARDED_FOR");30            }31            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {32                ip = request.getRemoteAddr();33            }34        } catch (Exception e) {35            logger.error("IPUtils ERROR ", e);36        }3738        //使用代理,则获取第一个IP地址39        if(StringUtils.isEmpty(ip) && ip.length() > 15) {40            if(ip.indexOf(",") > 0) {41                ip = ip.substring(0, ip.indexOf(","));42            }43        }4445        return ip;46    }4748}

3丶生成签名

1/** 2     * 生成签名 3     * 这个方法是从微信sdk里copy过来的,自己也可以写,要注意生成签名后UTF-8的转换,要不然容易报签名Body UTF-8错误 4     * 5     * @param data 待签名数据 6     * @param key  API密钥 7     * @param charset UTF-8 8     */ 9    public static String createSign(final Map data, String key, String charset) throws Exception {10        return createSign(data, key, WXPayConstants.SignType.MD5, charset);11    }1213    /**14     * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。15     *16     * @param data     待签名数据17     * @param key      API密钥18     * @param signType 签名方式19     * @param charset UTF-820     * @return 签名21     */22    private static String createSign(final Map data, String key, WXPayConstants.SignType signType, String charset) throws Exception {23        //根据规则创建可排序的map集合24        Set keySet = data.keySet();25        String[] keyArray = keySet.toArray(new String[keySet.size()]);26        Arrays.sort(keyArray);27        StringBuilder sb = new StringBuilder();28        for (String k : keyArray) {29            if (k.equals(WXPayConstants.FIELD_SIGN)) {30                continue;31            }32            if (data.get(k).trim().length() > 0){33                sb.append(k).append("=").append(data.get(k).trim()).append("&");34            } // 参数值为空,则不参与签名35        }36        sb.append("key=").append(key);37        //转换UTF-838        String str = new String(sb.toString().getBytes(charset));39        if (WXPayConstants.SignType.MD5.equals(signType)) {40            return MD5(sb.toString()).toUpperCase();41        } else if (WXPayConstants.SignType.HMACSHA256.equals(signType)) {42            return HMACSHA256(sb.toString(), key);43        } else {44            throw new Exception(String.format("Invalid sign_type: %s", signType));45        }46    }47}

4丶http请求的工具 实际没有用到很多方法有的是退款需要用到的

1/** 2 * http请求工具 3 * 4 * 5 * 6 * 7 */ 8public class HttpsClientUtil { 9    private static PoolingHttpClientConnectionManager connMgr; 10    private static RequestConfig requestConfig; 11    private static final int MAX_TIMEOUT = 7000; 12 13    static { 14        // 设置连接池 15        connMgr = new PoolingHttpClientConnectionManager(); 16        // 设置连接池大小 17        connMgr.setMaxTotal(100); 18        connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal()); 19 20        RequestConfig.Builder configBuilder = RequestConfig.custom(); 21        // 设置连接超时 22        configBuilder.setConnectTimeout(MAX_TIMEOUT); 23        // 设置读取超时 24        configBuilder.setSocketTimeout(MAX_TIMEOUT); 25        // 设置从连接池获取连接实例的超时 26        configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT); 27        // 在提交请求之前 测试连接是否可用 28        configBuilder.setStaleConnectionCheckEnabled(true); 29        requestConfig = configBuilder.build(); 30    } 31 32    /** 33     * 发送 GET 请求(HTTP),不带输入数据 34     * 35     * @param url 36     * @return 37     */ 38    public static String doGet(String url) { 39        return doGet(url, new HashMap()); 40    } 41 42    /** 43     * 发送 GET 请求(HTTP),K-V形式 44     * 45     * @param url 46     * @param params 47     * @return 48     */ 49    public static String doGet(String url, Map params) { 50        String apiUrl = url; 51        StringBuffer param = new StringBuffer(); 52        int i = 0; 53        for (String key : params.keySet()) { 54            if (i == 0) 55                param.append("?"); 56            else 57                param.append("&"); 58            param.append(key).append("=").append(params.get(key)); 59            i++; 60        } 61        apiUrl += param; 62        String result = null; 63        HttpClient httpclient = new DefaultHttpClient(); 64        try { 65            HttpGet httpPost = new HttpGet(apiUrl); 66            HttpResponse response = httpclient.execute(httpPost); 67            int statusCode = response.getStatusLine().getStatusCode(); 68 69            System.out.println("执行状态码 : " + statusCode); 70 71            HttpEntity entity = response.getEntity(); 72            if (entity != null) { 73                InputStream instream = entity.getContent(); 74                result = IOUtils.toString(instream); 75            } 76        } catch (IOException e) { 77            e.printStackTrace(); 78        } 79        return result; 80    } 81 82    /** 83     * 发送 POST 请求(HTTP),不带输入数据 84     * 85     * @param apiUrl 86     * @return 87     */ 88    public static String doPost(String apiUrl) { 89        return doPost(apiUrl, new HashMap()); 90    } 91 92    /** 93     * 发送 POST 请求(HTTP),K-V形式 94     * 95     * @param apiUrl API接口URL 96     * @param params 参数map 97     * @return 98     */ 99    public static String doPost(String apiUrl, Map params) {100        CloseableHttpClient httpClient = HttpClients.createDefault();101        String httpStr = null;102        HttpPost httpPost = new HttpPost(apiUrl);103        CloseableHttpResponse response = null;104105        try {106            httpPost.setConfig(requestConfig);107            List pairList = new ArrayList(params.size());108            for (Map.Entry entry : params.entrySet()) {109                NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry110                        .getValue().toString());111                pairList.add(pair);112            }113            httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8")));114            response = httpClient.execute(httpPost);115            System.out.println(response.toString());116            HttpEntity entity = response.getEntity();117            httpStr = EntityUtils.toString(entity, "UTF-8");118        } catch (IOException e) {119            e.printStackTrace();120        } finally {121            if (response != null) {122                try {123                    EntityUtils.consume(response.getEntity());124                } catch (IOException e) {125                    e.printStackTrace();126                }127            }128        }129        return httpStr;130    }131132    /**133     * 发送 POST 请求(HTTP),JSON形式134     *135     * @param apiUrl136     * @param json   json对象137     * @return138     */139    public static String doPost(String apiUrl, Object json) {140        CloseableHttpClient httpClient = HttpClients.createDefault();141        String httpStr = null;142        HttpPost httpPost = new HttpPost(apiUrl);143        CloseableHttpResponse response = null;144145        try {146            httpPost.setConfig(requestConfig);147            StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");//解决中文乱码问题148            stringEntity.setContentEncoding("UTF-8");149            stringEntity.setContentType("application/json");150            httpPost.setEntity(stringEntity);151            response = httpClient.execute(httpPost);152            HttpEntity entity = response.getEntity();153            System.out.println(response.getStatusLine().getStatusCode());154            httpStr = EntityUtils.toString(entity, "UTF-8");155        } catch (IOException e) {156            e.printStackTrace();157        } finally {158            if (response != null) {159                try {160                    EntityUtils.consume(response.getEntity());161                } catch (IOException e) {162                    e.printStackTrace();163                }164            }165        }166        return httpStr;167    }168169    /**170     * 发送 SSL POST 请求(HTTPS),K-V形式171     *172     * @param apiUrl API接口URL173     * @param params 参数map174     * @return175     */176    public static String doPostSSL(String apiUrl, Map params) {177        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();178        HttpPost httpPost = new HttpPost(apiUrl);179        CloseableHttpResponse response = null;180        String httpStr = null;181182        try {183            httpPost.setConfig(requestConfig);184            List pairList = new ArrayList(params.size());185            for (Map.Entry entry : params.entrySet()) {186                NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry187                        .getValue().toString());188                pairList.add(pair);189            }190            httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("utf-8")));191            response = httpClient.execute(httpPost);192            int statusCode = response.getStatusLine().getStatusCode();193            if (statusCode != HttpStatus.SC_OK) {194                return null;195            }196            HttpEntity entity = response.getEntity();197            if (entity == null) {198                return null;199            }200            httpStr = EntityUtils.toString(entity, "utf-8");201        } catch (Exception e) {202            e.printStackTrace();203        } finally {204            if (response != null) {205                try {206                    EntityUtils.consume(response.getEntity());207                } catch (IOException e) {208                    e.printStackTrace();209                }210            }211        }212        return httpStr;213    }214215    /**216     * 发送 SSL POST 请求(HTTPS),JSON形式217     *218     * @param apiUrl API接口URL219     * @param json   JSON对象220     * @return221     */222    public static String doPostSSL(String apiUrl, Object json) {223        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();224        HttpPost httpPost = new HttpPost(apiUrl);225        CloseableHttpResponse response = null;226        String httpStr = null;227228        try {229            httpPost.setConfig(requestConfig);230            StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");//解决中文乱码问题231            stringEntity.setContentEncoding("UTF-8");232            stringEntity.setContentType("application/json");233            httpPost.setEntity(stringEntity);234            response = httpClient.execute(httpPost);235            int statusCode = response.getStatusLine().getStatusCode();236            if (statusCode != HttpStatus.SC_OK) {237                return null;238            }239            HttpEntity entity = response.getEntity();240            if (entity == null) {241                return null;242            }243            httpStr = EntityUtils.toString(entity, "utf-8");244        } catch (Exception e) {245            e.printStackTrace();246        } finally {247            if (response != null) {248                try {249                    EntityUtils.consume(response.getEntity());250                } catch (IOException e) {251                    e.printStackTrace();252                }253            }254        }255        return httpStr;256    }257258    /**259     * 创建SSL安全连接260     *261     * @return262     */263    private static SSLConnectionSocketFactory createSSLConnSocketFactory() {264        SSLConnectionSocketFactory sslsf = null;265        try {266            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {267268                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {269                    return true;270                }271            }).build();272            sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {273274                @Override275                public boolean verify(String arg0, SSLSession arg1) {276                    return true;277                }278279                @Override280                public void verify(String host, SSLSocket ssl) throws IOException {281                }282283                @Override284                public void verify(String host, X509Certificate cert) throws SSLException {285                }286287                @Override288                public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {289                }290            });291        } catch (GeneralSecurityException e) {292            e.printStackTrace();293        }294        return sslsf;295    }

我这个人比较懒还有查询,退款,jsapi支付,H5支付慢慢更新总结.今天就到这里了,拜拜



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3