java 微信 H5支付

目录

使用须知:

一:maven

二:java代码

三:页面调用

四:测试


使用须知:

    需先在微信中开通支付宝H5支付,开通细节暂不描述。。

一:maven

        <dependency>
            <groupId>com.github.wxpay</groupId>
            <artifactId>wxpay-sdk</artifactId>
            <version>0.0.3</version>
        </dependency>

二:java代码

package com.vrv.Govern.controller.Wx;

import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.vrv.Govern.util.DateUtils;
import com.vrv.Govern.util.PrintWriterUtils;
import com.vrv.Govern.util.ResultEntitylayui;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/Home_WxPay")
public class Home_WxPayController {
    /**
     * Created By Mengkai
     * 微信发起回调页面
     *
     * @return
     */
    @RequestMapping("/index")
    public String index() {
        return "Wx/index";
    }

    /**
     * Created By Mengkai
     * 支付成功回调页面
     *
     * @return
     */
    @RequestMapping(value = "succ", produces = "application/json;charset=utf-8")
    @ResponseBody
    public String succ() {
        return "Wx/succ";
    }

    /**
     * Created By Mengkai
     * 发起支付方法
     *
     * @param response
     * @param request
     */
    @RequestMapping(value = "pay", produces = "application/json;charset=utf-8")
    @ResponseBody
    public void pay(HttpServletResponse response, HttpServletRequest request) {
        Gson gson = new GsonBuilder().serializeNulls().setDateFormat(DateUtils.DateFormat4).create();
        ResultEntitylayui mResultEntity = new ResultEntitylayui();
        try {
            long time = System.currentTimeMillis();
            XCFWXPayConfig xcfwxPayConfig = new XCFWXPayConfig(request);
            WXPay wxPay = new WXPay(xcfwxPayConfig);
            String spbill_create_ip = request.getParameter("ip");
            Map<String, String> map = new HashMap<>();
            map.put("nonce_str", WXPayUtil.generateNonceStr());
            map.put("body", "缴纳");
            map.put("out_trade_no", "Dj" + time);
            map.put("total_fee", "1");
            map.put("spbill_create_ip", spbill_create_ip);

            map.put("notify_url", "http://cs/cs/css/payNotify.active");
            map.put("trade_type", "MWEB");
            Map<String, String> res = wxPay.unifiedOrder(map);

            //拼接链接
            String mweb_url = "";
            if (res.containsKey("mweb_url")) {
                String redirectUrl = "http://cs/cs/cs/succ.active";
                mweb_url = res.get("mweb_url") + "&redirect_url=" + URLEncoder.encode(redirectUrl, "GBK");
            }

            //返回链接,为前台提供跳转mweb_url,唤起微信
            mResultEntity.setData(mweb_url);
            PrintWriterUtils.printWriter(response, gson.toJson(mResultEntity));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * Created By Mengkai
     * 处理回调
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "payNotify", produces = "application/json;charset=utf-8")
    @ResponseBody
    public synchronized void payNotify(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("进入回调");
        try {
            String resXml = "";
            XCFWXPayConfig xcfwxPayConfig = new XCFWXPayConfig(request);
            WXPay wxPay = new WXPay(xcfwxPayConfig);
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            outSteam.close();
            inStream.close();
            String result = new String(outSteam.toByteArray(), "utf-8");// 获取微信调用我们notify_url的返回信息
            Map<String, String> map = WXPayUtil.xmlToMap(result); //微信回调后详细参数
            if (wxPay.isPayResultNotifySignatureValid(map)) {
                //TODO::业务处理开始
                System.out.println("业务处理开始");
                //订单入库

                //TODO::业务处理结束
            }
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

特别说明:

这两个工具类是调用及返回json数据的工具类,在使用时可换为自己使用的方式调用

此工具类为实体类,用于封装数据,使用时也可换为自己使用的方式,内容示例,

回调地址:

这两项需更换,其他页面跳转自行调整

工具类

package com.vrv.Govern.controller.Wx;


import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;

/**
 * Http客户端工具类<br/>
 * 这是内部调用类,请不要在外部调用。
 *
 * @author miklchen
 *
 */
public class HttpUtil {

	private final static int CONNECT_TIMEOUT = 5000; // in milliseconds
	private final static String DEFAULT_ENCODING = "UTF-8";

	public static String postData(String urlStr, String data) {
		return postData(urlStr, data, null);
	}

	public static String postData(String urlStr, String data, String contentType) {
		BufferedReader reader = null;
		try {
			URL url = new URL(urlStr);
			URLConnection conn = url.openConnection();
			conn.setDoOutput(true);
			conn.setConnectTimeout(CONNECT_TIMEOUT);
			conn.setReadTimeout(CONNECT_TIMEOUT);
			if (contentType != null)
				conn.setRequestProperty("content-type", contentType);
			OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);
			if (data == null)
				data = "";
			writer.write(data);
			writer.flush();
			writer.close();

			reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));
			StringBuilder sb = new StringBuilder();
			String line = null;
			while ((line = reader.readLine()) != null) {
				sb.append(line);
				sb.append("\r\n");
			}
			return sb.toString();
		} catch (IOException e) {
		} finally {
			try {
				if (reader != null)
					reader.close();
			} catch (IOException e) {
			}
		}
		return null;
	}
	/**
	 * 获取真实ip地址 通过阿帕奇代理的也能获取到真实ip
	 * @param request
	 * @return
	 */
	public static String getRealIp(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

}

配置类:

package com.vrv.Govern.controller.Wx;

import com.github.wxpay.sdk.WXPayConfig;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

/**
 * Created by 15117 on 2018/11/27.
 */

public class XCFWXPayConfig implements WXPayConfig {

    private byte[] certData;

    public XCFWXPayConfig(HttpServletRequest request) throws Exception {
        //获取apiclient_cert.pem的路径
        String savedDir = request.getSession().getServletContext().getRealPath("/");
        String certPath = savedDir + "common/Wx/cert/apiclient_cert.pem";

        File file = new File(certPath);
        InputStream stream = new FileInputStream(file);
        this.certData = new byte[(int) file.length()];
        stream.read(this.certData);
        stream.close();
    }

    @Override
    public String getAppID() {
        return "wx311357d055a3595wa";
    }

    @Override
    public String getMchID() {
        return "15352222781";
    }

    @Override
    public String getKey() {
        return "YzCkxvBtqdJbLxHM3333GxwoeGLUUcb";
    }

    @Override
    public InputStream getCertStream() {
        return new ByteArrayInputStream(this.certData);
    }

    @Override
    public int getHttpConnectTimeoutMs() {
        return 8000;
    }

    @Override
    public int getHttpReadTimeoutMs() {
        return 10000;
    }
}

特别注意:

此文件下载地址:https://download.csdn.net/download/qq_41712834/11694154

绑定appid

按照申请的微信支付的数值填入

三:页面调用

页面访问:

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" isELIgnored="false" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>微信支付</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
    <!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
    <!--[if lt IE 9]>
    <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
    <![endif]-->
</head>
<body>
<div class="container">
    <h1>微信支付!!</h1>

    <form role="form">
        <div class="form-group">
            <label for="price">支付金额</label>
            <input type="text" class="form-control" value="0.01" readonly id="price" placeholder="">
        </div>

        <button type="button" onclick="sub()" class="btn btn-default">提交</button>
    </form>
</div>

<script type="text/javascript" src="../common/js/jquery-3.3.1.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="../common/app/js/bootstrap.min.js"></script>
<script src="https://pv.sohu.com/cityjson?ie=utf-8"></script>
<script>
        var ip = returnCitySN.cip;
        function sub(){
        $.ajax({
            url:"../Home_WxPay/pay.active",
            data:{'ip':ip},
            type:'post',
            dataType:'json',
            success:function(r){
                location.href=r.data;
            }
        });
    }

</script>
</body>
</html>

使用时需要更换jquery  的路径

成功或失败调用的页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" isELIgnored="false" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>支付成功</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
    <!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
    <!--[if lt IE 9]>
    <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
    <![endif]-->
</head>
<body>
<h1><span class="glyphicon glyphicon-ok"></span> 支付成功!</h1>
<script src="../common/app/js/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="../common/app/js/bootstrap.min.js"></script>

</body>
</html>

使用时需要更换jquery  的路径

四:测试

调用页面

ps:不清楚的可私聊哦,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值