千家信息网

java如何实现微信jsApi支付

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,java如何实现微信jsApi支付,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。标注:1、必须在微信内置浏览器进行支付;2、open i
千家信息网最后更新 2026年11月03日java如何实现微信jsApi支付

java如何实现微信jsApi支付,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

标注:1、必须在微信内置浏览器进行支付;2、open id必须获取;3、获取code必须请求后台服务器,将code获取到返回前端,再请求获取openid,将openid存在自己服务器的session中

一、账户准备

1、在微信公众平台开通服务号并付费300元认证(只有企业才能开通)获取appid,在微信支付商户平台注册超级管理员并付费300认证,获取mch_id(商户id)。

2、在微信公众平台获取 appid,appsecret。在商户平台获取mch_id,api安全中获取API密钥(paternerKey)

二、平台配置

1、商户平台:产品中心开发配置,属于支付页面

2、公众平台:账户详情功能设置,配置网页授权域名,(将txt文件放在一级域名以及目录中,可通过域名/txt(文件全称)访问,测试是否可以获取txt内容。如果不行,则进行nginx配置域名访问目录)

3、公众平台:开发,基本设置,配置服务器地址(需要写接口并返回echostr,验证服务器),令牌随便写,消息密钥(随机生成),加密模式:兼容模式。

三、开发(下载javasdk。将微信中的工具类导入https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1)

1、支付前获取基本参数

  /**     * 微信中请求打开页面     */    @RequestMapping(value = "/toJob")    public String  toJob(HttpServletResponse response){        String appId = WxConstants.APPID;        String tologin =redirectURL;        return "redirect:https://open.weixin.qq.com/connect/oauth3/authorize?appid="+appId+"&redirect_uri="+tologin+"&response_type=code&scope=snsapi_base#wechat_redirect";    }    /**     * 微信请求打开页面重定向到该接口,获取code     * 然后重定向到自己页面     */    @RequestMapping(value = "/tologin")    public String  tologin(String code ,HttpServletResponse response){        return "redirect:"+loginUrl+code;    }    /**     * 获取open id     */    @RequestMapping("/getOpenId")    @ResponseBody    public String getOpenId( @RequestParam("code") String code,HttpServletRequest request){        logger.info("code  code:" + code);        Map result = new HashMap<>();        //页面获取openId接口        String getopenid_url = "https://api.weixin.qq.com/sns/oauth3/access_token";        Map param = new HashMap<>();        param.put("appid", WxConstants.APPID);        param.put("secret", WxConstants.SECRET);        param.put("code", code);        param.put("grant_type", "authorization_code");        //向微信服务器发送get请求获取openIdStr        String openIdStr = HttpClientUtil.doGet(getopenid_url, param);        JSONObject jsonObject = JSON.parseObject(openIdStr);        logger.info("opendID  JSON:" + openIdStr);        String openid =  jsonObject.getString("openid");        //将open id存入session。        //如果直接重定向到该接口,openid存不到session中,只会存在腾讯的session中        //微信中打开页面只能请求后台接口,后台获取到code拼接到前台页面后面        //前台获取到code,然后请求获取open id的接口,可以将open id存到我们自己服务器中        request.getSession().setAttribute("openid", openid);        //返回登录页        return openid;    }    /**     * 微信测试接口     * @param request     * @return     */    @RequestMapping("/Token")    @ResponseBody    public String Token(HttpServletRequest request){        logger.info(JSON.toJSONString(request.getParameterMap()));        return request.getParameter("echostr");    }

2、支付、回调

/**     * 简历微信支付     * @param request     * @param isUpdate 是否是认证订单     */    @RequestMapping(value = "/wxPayJob")    @ResponseBody    public Map wxpay(HttpServletRequest request,                                    @RequestParam("isUpdate") Integer isUpdate,                                     @RequestParam("jobUserId") Long jobUserId,                                     @RequestParam("totalAmount") String totalAmount) {        String openId = (String) request.getSession().getAttribute("openid");        logger.info("opendID  pay:" + openId);        //获取openId        String ip = WxUtils.getIpAddress(request);        //将元转化为分        String totalFee =  AmountUtils.changeY2F(totalAmount);        Map result = wxService.orderPayment(openId, ip, totalFee, jobUserId, isUpdate);        return result;    }    /**     * 微信支付回调     * @param request     * @param response     * @return     */    @RequestMapping(value = "/wxPayJobNotify")    @ResponseBody    public  String wxPayJobNotify(HttpServletRequest request, HttpServletResponse response) {        InputStream is = null;        try {            is = request.getInputStream();//获取请求的流信息(这里是微信发的xml格式所有只能使用流来读)            String xml =  IOUtils.toString(is, "utf-8");            Map notifyMap = WXPayUtil.xmlToMap(xml);//将微信发的xml转map            if(notifyMap.get("return_code").equals("SUCCESS")){                if(notifyMap.get("result_code").equals("SUCCESS")){                    String orderNum = notifyMap.get("out_trade_no");//商户订单号                    String amountpaid = notifyMap.get("total_fee");//实际支付的订单金额:单位 分                    String  amount =  AmountUtils.changeF2Y(amountpaid);                    //String openid = notifyMap.get("openid");  //如果有需要可以获取                    //String trade_type = notifyMap.get("trade_type");                    //修改认证状态,订单状态                    jobOrderDtoService.updateState(orderNum);                    }                }            //告诉微信服务器收到信息了,不要在调用回调action了========这里很重要回复微信服务器信息用流发送一个xml即可            response.getWriter().write("");            is.close();        } catch (Exception e) {            e.printStackTrace();        }        return null;    }

3、支付统一下单主体

 //微信支付----异步回调(接口:payForOrder)    @Value(value = "${WxConfig.wxJObNotifyUrl}")    private String wxJObNotifyUrl;    /**     *  调用微信支付     */    @Override    public Map orderPayment(String openId, String ip, String totalAmount, Long jobUserId, Integer isUpdate) {        Map payMap = new HashMap();        try{            String OrderNum = OrderNumUtil.outtradeno("JOB");            String body = "认证";            Map  mapBody =  setSortedMap(openId,OrderNum,body,totalAmount,ip);            String xml = WXPayUtil.mapToXml(mapBody);//将所有参数(map)转xml格式            // 统一下单            String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";            //发送post请求"统一下单接口"返回预支付id:prepay_id            Map xmlMap = new HashMap<>();            xmlMap.put("xml",xml);            String xmlStr = HttpClientUtil.doPostJson(unifiedorder_url, xml);            //返回前端页面的json数据            payMap = resultMap(xmlStr);                       //插入简历订单                    } catch (Exception e) {            e.printStackTrace();        }            return payMap;     }    /**     * 下单主体信息     */    public Map setSortedMap(String openId,String OrderNum,String body,String totalFee,String ip) throws  Exception{        //拼接统一下单地址参数        Map paraMap = new HashMap();        paraMap.put("appid", WxConstants.APPID);        paraMap.put("body", body);        paraMap.put("mch_id", WxConstants.MCHID);        paraMap.put("nonce_str", WXPayUtil.generateNonceStr());//生成uuID        paraMap.put("openid", openId);        paraMap.put("out_trade_no", OrderNum);//订单号        paraMap.put("spbill_create_ip", ip);        paraMap.put("total_fee",totalFee);//金额 单位 分        paraMap.put("trade_type", WxConstants.WX_TRADE_JSAPI);        paraMap.put("notify_url",wxJObNotifyUrl);// 此路径是微信服务器调用支付结果通知路径随意写        String sign = WXPayUtil.generateSignature(paraMap, WxConstants.KEY);        paraMap.put("sign", sign);        return paraMap;    }    /**     * 返回前端页面的json数据     */    public  Map resultMap(String xmlStr)throws  Exception{        Map json = WXPayUtil.xmlToMap(xmlStr);        //JSONObject json = JSONObject.parseObject(xmlStr);//转成Json格式        LOGGER.info("prepay_id  JSON:" + json);        //获取prepay_id        String prepay_id = json.get("prepay_id");//预支付id        if (xmlStr.indexOf("SUCCESS") != -1) {            Map map = WXPayUtil.xmlToMap(xmlStr);            prepay_id = (String) map.get("prepay_id");        }        Map payMap = new HashMap();        payMap.put("appId", WxConstants.APPID);        payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp()+"");        payMap.put("nonceStr", WXPayUtil.generateNonceStr());        payMap.put("signType", "MD5");        payMap.put("package", "prepay_id=" + prepay_id);        String paySign = WXPayUtil.generateSignature(payMap, WxConstants.KEY);        payMap.put("paySign", paySign);        return payMap;    }

4、工具类:

元转分,分转元

public class AmountUtils {    /**金额为分的格式 */    public static final String CURRENCY_FEN_REGEX = "\\-?[0-9]+";    /**     * 将分为单位的转换为元并返回金额格式的字符串 (除100)     *     * @param amount     * @return     * @throws Exception     */    public static String changeF2Y(Long amount) throws Exception{        if(!amount.toString().matches(CURRENCY_FEN_REGEX)) {            throw new Exception("金额格式有误");        }        int flag = 0;        String amString = amount.toString();        if(amString.charAt(0)=='-'){            flag = 1;            amString = amString.substring(1);        }        StringBuffer result = new StringBuffer();        if(amString.length()==1){            result.append("0.0").append(amString);        }else if(amString.length() == 2){            result.append("0.").append(amString);        }else{            String intString = amString.substring(0,amString.length()-2);            for(int i=1; i<=intString.length();i++){                if( (i-1)%3 == 0 && i !=1){                    result.append(",");                }                result.append(intString.substring(intString.length()-i,intString.length()-i+1));            }            result.reverse().append(".").append(amString.substring(amString.length()-2));        }        if(flag == 1){            return "-"+result.toString();        }else{            return result.toString();        }    }    /**     * 将分为单位的转换为元 (除100)     *     * @param amount     * @return     * @throws Exception     */    public static String changeF2Y(String amount) throws Exception{        if(!amount.matches(CURRENCY_FEN_REGEX)) {            throw new Exception("金额格式有误");        }        return BigDecimal.valueOf(Long.valueOf(amount)).divide(new BigDecimal(100)).toString();    }    /**     * 将元为单位的转换为分 (乘100)     *     * @param amount     * @return     */    public static String changeY2F(Long amount){        return BigDecimal.valueOf(amount).multiply(new BigDecimal(100)).toString();    }    /**     * 将元为单位的转换为分 替换小数点,支持以逗号区分的金额     *     * @param amount     * @return     */    public static String changeY2F(String amount){        String currency =  amount.replaceAll("\\$|\\¥|\\,", "");  //处理包含, ¥ 或者$的金额        int index = currency.indexOf(".");        int length = currency.length();        Long amLong = 0l;        if(index == -1){            amLong = Long.valueOf(currency+"00");        }else if(length - index >= 3){            amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));        }else if(length - index == 2){            amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);        }else{            amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");        }        return amLong.toString();    }    public static void main(String[] args) {//        try {//            System.out.println("结果:"+changeF2Y("-000a00"));//        } catch(Exception e){//            System.out.println("----------->>>"+e.getMessage());////          return e.getErrorCode();//        }//      System.out.println("结果:"+changeY2F("1.00000000001E10"));        System.out.println(AmountUtils.changeY2F("1.33"));        try {            System.out.println(AmountUtils.changeF2Y("1322"));        } catch (Exception e) {            e.printStackTrace();        }//        System.out.println(Long.parseLong(AmountUtils.changeY2F("1000000000000000")));//        System.out.println(Integer.parseInt(AmountUtils.changeY2F("10000000")));//        System.out.println(Integer.MIN_VALUE);//        long a = 0;//        System.out.println(a);    }}

http doPost doGet 请求

import org.apache.http.NameValuePair;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.entity.ContentType;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.message.BasicNameValuePair;import org.apache.http.util.EntityUtils;import java.io.IOException;import java.net.URI;import java.util.ArrayList;import java.util.List;import java.util.Map;public class HttpClientUtil {        public static String doGet(String url, Map param) {                // 创建Httpclient对象                CloseableHttpClient httpclient = HttpClients.createDefault();                String resultString = "";                CloseableHttpResponse response = null;                try {                        StringBuilder sb = new StringBuilder(url+"?");                        for (String key : param.keySet()) {                                sb.append(key+"="+param.get(key)+"&");                        }                        sb.deleteCharAt(sb.length()-1);                        URI uri = new URI(sb.toString());                        // 创建http GET请求                        HttpGet httpGet = new HttpGet(uri);                        // 执行请求                        response = httpclient.execute(httpGet);                        // 判断返回状态是否为200                        if (response.getStatusLine().getStatusCode() == 200) {                                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");                        }                } catch (Exception e) {                        e.printStackTrace();                } finally {                        try {                                if (response != null) {                                        response.close();                                }                                httpclient.close();                        } catch (IOException e) {                                e.printStackTrace();                        }                }                return resultString;        }        public static String doGet(String url) {                return doGet(url, null);        }        public static String doPost(String url, Map param) {                // 创建Httpclient对象                CloseableHttpClient httpClient = HttpClients.createDefault();                CloseableHttpResponse response = null;                String resultString = "";                try {                        // 创建Http Post请求                        HttpPost httpPost = new HttpPost(url);                        // 创建参数列表                        if (param != null) {                                List paramList = new ArrayList<>();                                for (String key : param.keySet()) {                                        paramList.add(new BasicNameValuePair(key, param.get(key)));                                }                                // 模拟表单                                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);                                httpPost.setEntity(entity);                        }                        // 执行http请求                        response = httpClient.execute(httpPost);                        resultString = EntityUtils.toString(response.getEntity(), "utf-8");                } catch (Exception e) {                        e.printStackTrace();                } finally {                        try {                                response.close();                        } catch (IOException e) {                                // TODO Auto-generated catch block                                e.printStackTrace();                        }                }                return resultString;        }        public static String doPost(String url) {                return doPost(url, null);        }                public static String doPostJson(String url, String json) {                // 创建Httpclient对象                CloseableHttpClient httpClient = HttpClients.createDefault();                CloseableHttpResponse response = null;                String resultString = "";                try {                        // 创建Http Post请求                        HttpPost httpPost = new HttpPost(url);                        // 创建请求内容                        StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);                        httpPost.setEntity(entity);                        // 执行http请求                        response = httpClient.execute(httpPost);                        resultString = EntityUtils.toString(response.getEntity(), "utf-8");                } catch (Exception e) {                        e.printStackTrace();                } finally {                        try {                                response.close();                        } catch (IOException e) {                                // TODO Auto-generated catch block                                e.printStackTrace();                        }                }                return resultString;        }}

微信工具类

import com.alibaba.fastjson.JSON;import org.apache.commons.lang3.StringUtils;import org.dom4j.Document;import org.dom4j.DocumentHelper;import org.dom4j.Element;import javax.servlet.http.HttpServletRequest;import java.util.*;public class WxUtils {    //请求xml组装    public static String getRequestXml(Map parameters){        StringBuffer sb = new StringBuffer();        sb.append("");        Set es = parameters.entrySet();        Iterator it = es.iterator();        while(it.hasNext()) {            Map.Entry entry = (Map.Entry)it.next();            sb.append("<"+entry.getKey()+">"+entry.getValue()+"");        }        sb.append("");        return sb.toString();    }    /**     * 随机字符串生成     */    public static String getRandomString(int length) { //length表示生成字符串的长度        String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";        Random random = new Random();        StringBuffer sb = new StringBuffer();        for (int i = 0; i < length; i++) {            int number = random.nextInt(base.length());            sb.append(base.charAt(number));        }        return sb.toString();    }    /**     * 将xml格式的字符串转换成Map对象     *     * @param xmlStr xml格式的字符串     * @return Map对象     * @throws Exception 异常     */    public static Map xmlStrToMap(String xmlStr) throws Exception {        if(StringUtils.isEmpty(xmlStr)) {            return null;        }        Map map = new HashMap<>();        //将xml格式的字符串转换成Document对象        Document doc = DocumentHelper.parseText(xmlStr);        //获取根节点        Element root = doc.getRootElement();        //获取根节点下的所有元素        List children = root.elements();        //循环所有子元素        if(children != null && children.size() > 0) {            for(int i = 0; i < children.size(); i++) {                Element child = (Element)children.get(i);                map.put(child.getName(), child.getTextTrim());            }        }        return map;    }    public static  T  xmlStrToBean(String xmlStr, Class clazz) throws InstantiationException, IllegalAccessException {        T obj = clazz.newInstance();        try {            // 将xml格式的数据转换成Map对象            Map map = xmlStrToMap(xmlStr);            //将map对象的数据转换成Bean对象            obj = JSON.parseObject(JSON.toJSONString(map),clazz);        } catch(Exception e) {            e.printStackTrace();        }        return obj;    }    public static String getIpAddress(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.getHeader("HTTP_CLIENT_IP");        }        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {            ip = request.getHeader("HTTP_X_FORWARDED_FOR");        }        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {            ip = request.getRemoteAddr();        }        return ip;    }}

微信常量类

public class WxConstants {    //微信统一下单请求xml参数    public static final String APPID="wx1111111"; //appid是微信公众账号或开放平台APP的唯一标识    public static final String MCHID="111111";//商户申请微信支付后,由微信支付分配的商户收款账号    public static final String SECRET="aaaaaaaa";//AppSecret是APPID对应的接口密码    public static final String KEY="1111111111";//交易过程生成签名的密钥 同API密钥    public static final String NONCE_STR="nonce_str";    public static final String SIGN="sign";//生成签名    public static final String ATTACH="attach";    public static final String TIMESTAMP = "timeStamp";    public static final String NONCESTR = "noncestr";    public static final String PREPAYID = "prepayid";    public static final String PARTNERID = "111111";//API密钥    public static final String PACKAGE = "package";    public static final String OPENID ="OPENID";//用户唯一标识    public static final int getHttpConnectTimeoutMs = 8000;//连接时间    public static final int getHttpReadTimeoutMs = 10000; //超时时间    /**     * 微信 JSAPI支付(或小程序支付)微信中调用网页支付     */    public static final String WX_TRADE_JSAPI = "JSAPI";    /**     * 微信 Native支付     */    public static final String WX_TRADE_NATIVE = "NATIVE";    /**     * 微信 H5支付     */    public static final String WX_TRADE_MWEB = "MWEB";    /**     * 微信 app支付     */    public static final String WX_TRADE_APP = "APP";    }

看完上述内容,你们掌握java如何实现微信jsApi支付的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

支付 接口 格式 服务 对象 平台 服务器 页面 商户 字符 字符串 订单 生成 公众 参数 密钥 金额 统一 认证 配置 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 小米移动互联网科技园 新华互联网科技 互联网是第几次科技革命的成果 云之行互联网科技 重生之互联网科技帝国 美国互联网科技巨头监管 伴你行互联网科技有限公司 互联网科技网站 上海电发互联网科技有限公司 云创客互联网科技公司 现代科技和互联网有关系吗 科技与互联网的利与弊 江苏南京365互联网科技 随着互联网科技发展 江阴互联网智能科技产品进口 翼展科技 首家互联网医院 互联网金融科技名词解释 中科明德北京互联网科技 科技发展第三阶段互联网时代 互联网 科技节活动 微视频大赛 云信互联网科技有限公司 美国互联网保险保险科技 互联网软件和科技 互联网5g黑科技有哪些 速维有品互联网信息科技(苏州)有限公司 阿里互联网科技企业 明优互联网科技有限公司 郑州欣桑互联网科技有限公司 易企秀互联网科技是做什么的 广东猫王互联网科技有限公司电话
0