微信支付JSAPI

本文档详细介绍了微信支付的集成步骤,包括商户号认证、设置安全密钥、下载证书、使用第三方SDK(wxpay-sdk)进行支付操作。在Java环境中,展示了配置类、工具类、实体类和控制器的代码示例,实现了微信支付的统一下单、回调处理等功能。回调处理中包含了验签、业务逻辑处理等关键步骤。
摘要由CSDN通过智能技术生成
  • 首先申请商户号 需要支付300元认证费以及一些相关证件

  • 微信支付关联商户 在这里插入图片描述

  • 设置安全密钥 下载证书在这里插入图片描述

  • 下面就是程序了

第三方SDK

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

yml 这个是回调地址

wxapplet:
  config:
    weixinpay:
      notifyurl: https://域名/pay/wxPayCallback

工具类

package com.adleading.itask.configure.wxpay;/**
 * @description:
 * @Author EDZ
 * @data 2021/6/1 13:43
 * @param: itask
 * @return: $
 */
import com.github.wxpay.sdk.WXPayConfig;

import java.io.InputStream;
import java.util.Map;
/**
 * @description:
 * @author     :xww
 * @date       :2021/6/1 13:43
 */
public class WXConfig implements WXPayConfig{

    private byte[] certData;
    /**
     * 获取 App ID
     *
     * @return App ID
     */
    @Override
    public String getAppID() {
        return "你自己的appid";
    }

    /**
     * 获取 Mch ID
     *
     * @return Mch ID
     */
    @Override
    public String getMchID() {
        return "你自己的商户号";
    }


    /**
     * 获取 API 密钥
     *
     * @return API密钥
     */
    @Override
    public String getKey() {
        return "你自己的API密钥";
    }

    /**
     * 获取商户证书内容
     * 这里是读取resources根目录下面的证书文件
     * @return 商户证书内容
     */
    @Override
    public InputStream getCertStream() {
        InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("apiclient_cert.p12");
        return certStream;
    }

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

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

public class WXMiniPayConfig {
    //api秘钥  从微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 获取
    public static final String KEY = "";
    //    微信支付分配的公众账号ID(企业号corpid即为此appId)
    public static final String APP_ID = "";
    //微信支付分配的商户号
    public static final String MCH_ID = "";
}

工具类

package com.adleading.itask.utils;/**
 * @description:
 * @Author EDZ
 * @data 2021/6/1 13:54
 * @param: itask
 * @return: $
 */
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

/**
 * @description:
 * @author     :xww
 * @date       :2021/6/1 13:54
 */
public class WeiXinPayUtil {

    private static final String PREFIX_XML = "<xml>";
    private static final String SUFFIX_XML = "</xml>";

    private static final String PREFIX_CDATA = "<![CDATA[";

    private static final String SUFFIX_CDATA = "]]>";

    /**
     * 微信回调参数解析
     *
     * @param request
     * @return
     */
    public static String getPostStr(HttpServletRequest request) {
        StringBuffer sb = new StringBuffer();
        try {
            ServletInputStream is = request.getInputStream();
            InputStreamReader isr = new InputStreamReader(is, "UTF-8");
            BufferedReader br = new BufferedReader(isr);
            String s = "";

            while ((s = br.readLine()) != null) {
                sb.append(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        String xml = sb.toString(); //次即为接收到微信端发送过来的xml数据
        return xml;

    }

    /**
     * 转化成xml, 单层无嵌套
     * @param
     * @param isAddCDATA
     * @return
     */
    public  String mapToXml(Map<String, String> parm, boolean isAddCDATA) {
        StringBuffer strbuff = new StringBuffer(PREFIX_XML);
        if (null != parm) {
            for (Entry<String, String> entry : parm.entrySet()) {
                strbuff.append("<").append(entry.getKey()).append(">");
                if (isAddCDATA) {
                    strbuff.append(PREFIX_CDATA);
                    if (null != entry.getValue()) {
                        strbuff.append(entry.getValue());
                    }
                    strbuff.append(SUFFIX_CDATA);
                } else {
                    if (null != entry.getValue()) {
                        strbuff.append(entry.getValue());
                    }
                }
                strbuff.append("</").append(entry.getKey()).append(">");
            }
        }
        return strbuff.append(SUFFIX_XML).toString();
    }
}

实体类

package com.adleading.itask.model.vo;/**
 * @description:
 * @Author EDZ
 * @data 2021/6/1 14:26
 * @param: itask
 * @return: $
 */

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

/**
 * @description:
 * @author     :xww
 * @date       :2021/6/1 14:26
 */
@ApiModel(value = "支付--VO")
public class PayVO {

    @ApiModelProperty(value = "用户openId")
    @NotBlank
    private String openid;

    @ApiModelProperty(value = "充值面额ID")
    @NotNull
    private Integer rechargeId;

    public String getOpenid() {
        return openid;
    }

    public void setOpenid(String openid) {
        this.openid = openid;
    }

    public Integer getRechargeId() {
        return rechargeId;
    }

    public void setRechargeId(Integer rechargeId) {
        this.rechargeId = rechargeId;
    }

    @Override
    public String toString() {
        return "PayVO{" +
                "openid='" + openid + '\'' +
                ", rechargeId=" + rechargeId +
                '}';
    }
}

Controller类

package com.adleading.itask.controller;/**
 * @description:
 * @Author EDZ
 * @data 2021/6/1 14:06
 * @param: itask
 * @return: $
 */

import com.adleading.itask.common.base.ResultData;
import com.adleading.itask.configure.wxpay.WXMiniPayConfig;
import com.adleading.itask.model.vo.PayVO;
import com.adleading.itask.model.vo.WithDrawVO;
import com.adleading.itask.service.impl.WXPayServiceImpl;
import com.adleading.itask.service.inf.WXPayService;
import com.adleading.itask.utils.WeiXinPayUtil;
import com.github.wxpay.sdk.WXPayUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
/**
 * @description:
 * @author     :xww
 * @date       :2021/6/1 14:06
 */
@Api(value = "微信支付",tags = "微信支付")
@RestController
@RequestMapping("/pay")
public class WXPayController {

    private static final Logger LOGGER = LoggerFactory.getLogger(WXPayController.class);
    @Autowired
    WXPayService wxPayService;

    @ApiOperation(value = "微信支付[xww]")
    @PostMapping("/doUnifiedOrder")
    public ResultData doUnifiedOrder(@Valid @RequestBody @ApiParam(value = "payVO") PayVO payVO, BindingResult bindingResult) throws Exception {
        return wxPayService.doUnifiedOrder(payVO);
    }

    @ApiOperation(value = "微信支付回调[xww]")
    @PostMapping("/wxPayCallback")
    public void  wxappletpaycallback(HttpServletRequest request, HttpServletResponse response) {
        wxPayService.wxappletpaycallback(request,response);
    }

//    @ApiOperation(value = "微信发红包[xww]")
//    @PostMapping("/wxSendRedPack")
//    public ResultData  wxSendRedPack(WithDrawVO withDrawVO) throws Exception {
//        return wxPayService.wxSendRedPack(withDrawVO);
//    }

}

Service接口

package com.adleading.itask.service.inf;

import com.adleading.itask.common.base.ResultData;
import com.adleading.itask.model.vo.PayVO;
import com.adleading.itask.model.vo.WithDrawVO;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * @description:
 * @Author EDZ
 * @data 2021/6/1 13:38
 * @param: itask
 * @return: $
 */
public interface WXPayService {

    /**
     * 下单
     * @param payVO
     * @return
     * @throws Exception
     */
    ResultData doUnifiedOrder(PayVO payVO) ;

    /**
     * 微信支付回调
     * @param request
     * @param response
     */
    void wxappletpaycallback(HttpServletRequest request, HttpServletResponse response);

    //微信发红包
    ResultData wxSendRedPack(WithDrawVO withDrawVO) throws Exception;

    //微信退款
    ResultData wxBackMoney(WithDrawVO withDrawVO) throws Exception;
}

Impl实现类

package com.adleading.itask.service.impl;/**
 * @description:
 * @Author EDZ
 * @data 2021/6/1 13:39
 * @param: itask
 * @return: $
 */

import com.adleading.itask.common.base.ResultData;
import com.adleading.itask.configure.wxpay.WXConfig;
import com.adleading.itask.configure.wxpay.WXMiniPayConfig;
import com.adleading.itask.dao.UserGoldGeneralViewMapper;
import com.adleading.itask.dao.UserGoldLogMapper;
import com.adleading.itask.model.po.OrderLog;
import com.adleading.itask.model.po.SendRedPackPo;
import com.adleading.itask.model.po.SysRecharge;
import com.adleading.itask.model.po.UserGoldLog;
import com.adleading.itask.model.vo.PayVO;
import com.adleading.itask.model.vo.WithDrawVO;
import com.adleading.itask.service.inf.UserCapitalService;
import com.adleading.itask.service.inf.WXPayService;
import com.adleading.itask.utils.UUIDHexGenerator;
import com.adleading.itask.utils.WeiXinPayUtil;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import net.sf.jsqlparser.expression.StringValue;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @description:
 * @author     :xww
 * @date       :2021/6/1 13:39
 */
@Service
public class WXPayServiceImpl implements WXPayService {

    private static final Logger LOGGER = LoggerFactory.getLogger(WXPayServiceImpl.class);

    @Value("${wxapplet.config.weixinpay.notifyurl}")
    public String notifyurl ;
    //public static final String NOTIFY_URL = "http://feb9434a2fb8.ngrok.io/payback/wxappletpaycallback"; //内网穿透  80端口才行http://feb9434a2fb8.ngrok.io
    public static final String TRADE_TYPE_JSAPI = "JSAPI";

    @Autowired
    private UserCapitalService userCapitalService;
    @Resource
    private UserGoldGeneralViewMapper userGoldGeneralViewMapper;
    @Resource
    private UserGoldLogMapper userGoldLogMapper;

    @Override
    public ResultData doUnifiedOrder(PayVO payVO)  {
        // 获取该商品的价格  根据自己的业务
       ...
        WXConfig config = null;
        WXPay wxpay = null;
        try {
            config = new WXConfig();
            wxpay = new WXPay(config);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //生成的随机字符串
        String nonce_str = WXPayUtil.generateNonceStr();
        //获取客户端的ip地址
        //获取本机的ip地址
        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        String spbill_create_ip = addr.getHostAddress();
        //支付金额,需要转成字符串类型,否则后面的签名会失败 测试就直接定义死了,根据自己的业务修改
        String totalFee = "1"
        //商品描述
        String body = "金币充值";
        //商户订单号
        String out_trade_no = WXPayUtil.generateNonceStr();
        //统一下单接口参数
        HashMap<String, String> data = new HashMap<String, String>();
        try {
            data.put("appid", config.getAppID());
            data.put("body", body);
            data.put("mch_id", config.getMchID());
            data.put("nonce_str", nonce_str);
            data.put("notify_url", notifyurl);
            data.put("openid", payVO.getOpenid());
            data.put("out_trade_no", out_trade_no);
            data.put("spbill_create_ip", spbill_create_ip);
            data.put("total_fee", totalFee);
            data.put("trade_type", TRADE_TYPE_JSAPI);
            data.put("sign", WXPayUtil.generateSignature(data, config.getKey(), WXPayConstants.SignType.MD5));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            Map<String, String> rMap = wxpay.unifiedOrder(data);
            //System.out.println("统一下单接口返回: " + rMap);
            LOGGER.error("统一下单接口返回:[{}] " , rMap);
            String return_code = (String) rMap.get("return_code");
            String result_code = (String) rMap.get("result_code");
            String nonceStr = WXPayUtil.generateNonceStr();
            Map resultMap = new ConcurrentHashMap();
            resultMap.put("nonceStr", nonceStr);
            Long timeStamp = System.currentTimeMillis() / 1000;
            if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) {
                String prepayid = rMap.get("prepay_id");
                resultMap.put("package", "prepay_id=" + prepayid);
                resultMap.put("signType", "MD5");
                //这边要将返回的时间戳转化成字符串,不然小程序端调用wx.requestPayment方法会报签名错误
                resultMap.put("timeStamp", timeStamp + "");
                //再次签名,这个签名用于小程序端调用wx.requesetPayment方法
                resultMap.put("appId", config.getAppID());
                String sign = WXPayUtil.generateSignature(resultMap, config.getKey());
                resultMap.put("paySign", sign);
                LOGGER.info("生成的签名paySign-->[{}]",sign);
                // 生成预定单信息 自己的业务
                ...
                return ResultData.success(resultMap);
            } else {
                return ResultData.fail("333","支付失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultData.fail("332","统一下单接口返回失败");
        }
    }

    /**
     * 微信支付回调
     * @param request
     * @param response
     */
    @Override
    public void wxappletpaycallback(HttpServletRequest request, HttpServletResponse response) {
        String resultCode = null;
        String resultMsg = null;
        //1 获取微信支付异步回调结果
        String xmlResult = WeiXinPayUtil.getPostStr(request);
        LOGGER.error("微信回调信息-->[{}]",xmlResult);
        Map<String, String> resultMap = null;
        try {
            //将结果转成map
            resultMap = WXPayUtil.xmlToMap(xmlResult);
        } catch (Exception e1) {
            e1.printStackTrace();
            LOGGER.error("回调信息转化成map异常!");
        }
        //订单号
        String orderNo = resultMap.get("out_trade_no");
        String result_code = resultMap.get("result_code");
        if(result_code.equals("SUCCESS")){
            //回调返回的加密签名 保存下来 下面会进行对比
            String sign = resultMap.get("sign");
            //去掉sign和利用微信回调回来的信息重新加密
            resultMap.remove("sign");
            String sign1 = "";
            try {
                //重新加密 获取加密的签名
                sign1 = WXPayUtil.generateSignature(resultMap, WXMiniPayConfig.KEY); //签名
            } catch (Exception e) {
                e.printStackTrace();
                LOGGER.error("重新加密异常!");
            }
            //对比微信回调的加密与重新加密是否一致  一致即为通过 不一致说明呗改动过 加密不通过
            if (sign.equals(sign1)) { //验签通过
                // 更新用户金币以及更新订单信息 根据自己的业务
                ...
                resultCode = "SUCCESS";
                resultMsg = "成功";
            } else {
                resultCode = "FAIL";
                resultMsg = "验签未通过";
                ...//自己的业务
            }
        }else {
            resultCode = "FAIL";
            resultMsg = "验签未通过";
            ...//自己的业务
        }
        Map<String, String> returnMap = new HashMap<>();
        returnMap.put("return_code", resultCode);
        returnMap.put("return_msg", resultMsg);
        try {
            String resultStr = WXPayUtil.mapToXml(returnMap);
            response.getWriter().write(resultStr);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("map-to-xml异常!");
        }
    }

    /**
     * @author: xww
     * @description: 微信发红包
     * @date: 2021/6/16 13:38
     * @param
     * @return
     */
    @Override
    public ResultData wxSendRedPack(WithDrawVO withDrawVO) throws Exception {
        UUIDHexGenerator uuidHexGenerator=new UUIDHexGenerator();
        WXConfig config = null;
        WXPay wxpay = null;
        try {
            config = new WXConfig();
            wxpay = new WXPay(config);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 获取uuid作为随机字符串
        String nonceStr = uuidHexGenerator.generate();
        String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String code = uuidHexGenerator.createCode(10);
        String mch_id =config.getMchID();//商户号
        String appid = config.getAppID();
        String opendid = withDrawVO.getUserOpenid(); //发送给指定微信用户的openid
        SendRedPackPo sendRedPackPo = new SendRedPackPo();
        String totalAmount = "1";

        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        String clientIp = addr.getHostAddress();
        sendRedPackPo.setNonce_str(nonceStr);
        sendRedPackPo.setMch_billno(mch_id + today + code);
        sendRedPackPo.setMch_id(mch_id);
        sendRedPackPo.setWxappid(appid);
        sendRedPackPo.setNick_name("xxx");
        sendRedPackPo.setSend_name("xxx");
        sendRedPackPo.setRe_openid(opendid);
        sendRedPackPo.setTotal_amount(totalAmount);
        sendRedPackPo.setMin_value(totalAmount);
        sendRedPackPo.setMax_value(totalAmount);
        sendRedPackPo.setTotal_num("1");
        sendRedPackPo.setWishing("祝您新年快乐!");
        sendRedPackPo.setClient_ip(clientIp); //IP
        sendRedPackPo.setAct_name("小游戏");
        sendRedPackPo.setRemark("快来抢红包!");

        //把请求参数打包成数组
        Map<String, String> sParaTemp = new HashMap<String, String>();
        sParaTemp.put("nonce_str", sendRedPackPo.getNonce_str());
        sParaTemp.put("mch_billno", sendRedPackPo.getMch_billno());
        sParaTemp.put("mch_id", sendRedPackPo.getMch_id());
        sParaTemp.put("wxappid", sendRedPackPo.getWxappid());
        sParaTemp.put("nick_name", sendRedPackPo.getNick_name());
        sParaTemp.put("send_name", sendRedPackPo.getSend_name());
        sParaTemp.put("re_openid", sendRedPackPo.getRe_openid());
        sParaTemp.put("total_amount", sendRedPackPo.getTotal_amount());
        sParaTemp.put("min_value", sendRedPackPo.getMin_value());
        sParaTemp.put("max_value", sendRedPackPo.getMax_value());
        sParaTemp.put("total_num", sendRedPackPo.getTotal_num());
        sParaTemp.put("wishing", sendRedPackPo.getWishing());
        sParaTemp.put("client_ip", sendRedPackPo.getClient_ip());
        sParaTemp.put("act_name", sendRedPackPo.getAct_name());
        sParaTemp.put("remark", sendRedPackPo.getRemark());
        sendRedPackPo.setSign(WXPayUtil.generateSignature(sParaTemp, config.getKey(), WXPayConstants.SignType.MD5));
        sParaTemp.put("sign", sendRedPackPo.getSign());


        String respXml = WXPayUtil.mapToXml(sParaTemp);

        // 将解析结果存储在HashMap中
        Map<String, String> map = new HashMap<String, String>();

        KeyStore keyStore  = KeyStore.getInstance("PKCS12");
        FileInputStream instream = new FileInputStream(new File("/usr/project/itask/apiclient_cert.p12")); //此处为证书所放的绝对路径

        try {
            keyStore.load(instream, mch_id.toCharArray());
        } finally {
            instream.close();
        }


        // Trust own CA and all self-signed certs
        SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, mch_id.toCharArray())
                .build();
        // Allow TLSv1 protocol only
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslcontext,
                new String[] { "TLSv1" },
                null,
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .build();
        try {


            HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack");

            StringEntity reqEntity  = new StringEntity(respXml, "utf-8");

            // 设置类型
            reqEntity.setContentType("application/x-www-form-urlencoded");

            httpPost.setEntity(reqEntity);

            System.out.println("executing request" + httpPost.getRequestLine());


            CloseableHttpResponse response = httpclient.execute(httpPost);
            try {
                HttpEntity entity = response.getEntity();
                System.out.println(response.getStatusLine());
                if (entity != null) {


                    // 从request中取得输入流
                    InputStream inputStream = entity.getContent();
                    // 读取输入流
                    SAXReader reader = new SAXReader();
                    Document document = reader.read(inputStream);
                    // 得到xml根元素
                    Element root = document.getRootElement();
                    // 得到根元素的所有子节点
                    List<Element> elementList = root.elements();


                    // 遍历所有子节点
                    for (Element e : elementList)
                        map.put(e.getName(), e.getText());


                    // 释放资源
                    inputStream.close();
                    inputStream = null;


                }
                EntityUtils.consume(entity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }

        // 返回状态码
        String return_code = map.get("return_code");
        LOGGER.info("return_code---------------[{}]",return_code);
// 返回信息
        String return_msg = map.get("return_msg");
        LOGGER.info("return_msg---------------[{}]",return_msg);
// 业务结果
        String result_code = map.get("result_code");
        LOGGER.info("result_code---------------[{}]",result_code);
// 错误代码
        String err_code = map.get("err_code");
        LOGGER.info("err_code---------------[{}]",err_code);
// 错误代码描述
        String err_code_des = map.get("err_code_des");
        LOGGER.info("err_code_des---------------[{}]",err_code_des);

/**
 * 根据以上返回码进行业务逻辑处理
 */
        return null;
    }

    /**
     * @author: xww
     * @description: 微信退款
     * @date: 2021/7/1 17:12
     * @param
     * @return
     */
    @Override
    public ResultData wxBackMoney(WithDrawVO withDrawVO) throws Exception {
        WXConfig config = null;
        //把请求参数打包成数组
        Map<String, String> sParaTemp = new HashMap<String, String>();
        sParaTemp.put("nonce_str", WXPayUtil.generateNonceStr());
        sParaTemp.put("mch_id", config.getMchID());
        sParaTemp.put("wxappid", config.getAppID());

        sParaTemp.put("out_refund_no", "123");
        sParaTemp.put("out_refund_no", "123");
        sParaTemp.put("total_fee", "1");
        sParaTemp.put("refund_fee", "1");
        sParaTemp.put("sign", WXPayUtil.generateSignature(sParaTemp, config.getKey(), WXPayConstants.SignType.MD5));

        String respXml = WXPayUtil.mapToXml(sParaTemp);
        // 将解析结果存储在HashMap中
        Map<String, String> map = new HashMap<String, String>();

        KeyStore keyStore  = KeyStore.getInstance("PKCS12");
        FileInputStream instream = new FileInputStream(new File("/usr/project/itask/apiclient_cert.p12")); //此处为证书所放的绝对路径

        try {
            keyStore.load(instream, config.getMchID().toCharArray());
        } finally {
            instream.close();
        }


        // Trust own CA and all self-signed certs
        SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, config.getMchID().toCharArray())
                .build();
        // Allow TLSv1 protocol only
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslcontext,
                new String[] { "TLSv1" },
                null,
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .build();
        try {


            HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack");

            StringEntity reqEntity  = new StringEntity(respXml, "utf-8");

            // 设置类型
            reqEntity.setContentType("application/x-www-form-urlencoded");

            httpPost.setEntity(reqEntity);

            System.out.println("executing request" + httpPost.getRequestLine());


            CloseableHttpResponse response = httpclient.execute(httpPost);
            try {
                HttpEntity entity = response.getEntity();
                System.out.println(response.getStatusLine());
                if (entity != null) {


                    // 从request中取得输入流
                    InputStream inputStream = entity.getContent();
                    // 读取输入流
                    SAXReader reader = new SAXReader();
                    Document document = reader.read(inputStream);
                    // 得到xml根元素
                    Element root = document.getRootElement();
                    // 得到根元素的所有子节点
                    List<Element> elementList = root.elements();


                    // 遍历所有子节点
                    for (Element e : elementList)
                        map.put(e.getName(), e.getText());


                    // 释放资源
                    inputStream.close();
                    inputStream = null;


                }
                EntityUtils.consume(entity);
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
        // 返回状态码
        String return_code = map.get("return_code");
        LOGGER.info("return_code---------------[{}]",return_code);
// 返回信息
        String return_msg = map.get("return_msg");
        LOGGER.info("return_msg---------------[{}]",return_msg);
// 业务结果
        String result_code = map.get("result_code");
        LOGGER.info("result_code---------------[{}]",result_code);
// 错误代码
        String err_code = map.get("err_code");
        LOGGER.info("err_code---------------[{}]",err_code);
// 错误代码描述
        String err_code_des = map.get("err_code_des");
        LOGGER.info("err_code_des---------------[{}]",err_code_des);

        return ResultData.success(respXml);
    }

    /**
     * 添加预订单信息  自己的业务
     * @param orderNo
     * @param openid
     * @param sysRecharge
     */
   
}

证书路径 resources下

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Uniapp是一种跨平台的开发框架,可以用于同时开发iOS、Android和H5应用。而H5是指在网页上运行的应用程序。微信支付JSAPI是微信提供的一种支付接口,通过调用JSAPI接口,可以在H5应用中实现微信支付功能。 在Uniapp中使用微信支付JSAPI,可以通过以下步骤进行操作: 1. 首先,在Uniapp项目中引入微信支付的相关配置文件和SDK库文件。 2. 在需要使用微信支付的页面中,引入微信支付的JS文件,并初始化微信支付参数。支付参数包括商户号、appid、签名等信息。 3. 创建统一下单接口的后端处理程序,用于生成预支付订单并返回支付预处理参数给前端。 4. 在支付页面中,调用微信支付JSAPI的方法,传入预支付处理参数和支付回调方法。 5. 当用户点击支付按钮后,会弹出微信支付界面,用户可以选择支付方式进行支付操作。 6. 支付成功后,微信会将支付结果返回给前端,并通过支付回调方法进行处理,可以展示支付成功的提示信息和更新订单状态等操作。 需要注意的是,使用微信支付JSAPI需要在微信开放平台上注册并申请相关的权限。同时,在使用过程中,还需要确保支付参数的正确性、支付安全性和业务逻辑的完善性。 总之,Uniapp可以很好地支持H5应用中的微信支付JSAPI,通过合理的配置和调用,可以方便地在H5应用中实现微信支付功能,为用户提供更加便捷的支付体验。 ### 回答2: Uniapp是一款跨平台的应用开发框架,可以让开发者使用Vue.js语法来开发同时兼容多个平台的应用程序。Uniapp支持在H5平台中使用微信支付JSAPI。 微信支付JSAPI是微信提供的一组用于在网页中实现微信支付功能的JavaScriptAPI接口。通过调用微信支付JSAPI,开发者可以在H5页面中调起微信支付功能,用户可以使用微信支付完成支付操作。 在Uniapp中使用微信支付JSAPI,首先需要引入微信支付的JS文件。可以在页面的头部引入:<script src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>。 然后,在需要使用微信支付的地方,可以通过uni.request方法向服务器请求获取支付参数。获取到支付参数后,可以使用wx.requestPayment方法调起微信支付界面,并传入支付参数。支付成功后,微信会返回支付结果给开发者的回调函数,开发者可以在回调函数中处理支付结果。 需要注意的是,在使用微信支付JSAPI的过程中需要保证支付参数的安全性,避免支付参数被恶意篡改。通常可以在服务器端生成支付参数,并通过服务器端返回给前端,以确保支付参数的安全性。 总结起来,Uniapp可以在H5平台中使用微信支付JSAPI来实现微信支付功能,开发者需要引入微信支付的JS文件,通过uni.request方法获取支付参数,调用wx.requestPayment方法调起支付,处理支付结果的回调函数,并确保支付参数的安全性。 ### 回答3: Uniapp 是一款跨平台开发框架,可以同时开发小程序、H5 和APP。Uniapp 提供了对微信支付的支持,可以使用微信支付的 JSAPI(JavaScript API)来进行支付功能的开发。 Uniapp H5 微信支付 JSAPI 的实现过程如下: 1. 首先,需要在微信支付商户平台上注册并获取到自己的商户号(mch_id),同时生成随机字符串(nonce_str)和当前时间戳(timestamp)。 2. 接下来,在前端页面中引入微信支付的 JS 文件,可以通过在页面头部添加以下代码进行引入: ``` <script src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script> ``` 3. 在页面中设置要支付的订单信息,包括订单号(out_trade_no)、订单总金额(total_fee)等,并将这些信息以及商户号、随机字符串和时间戳等传递给后端服务器。 4. 后端服务器在接收到前端传递的支付信息后,根据微信支付 API 的要求,生成签名(sign)并返回给前端。 5. 前端页面收到后端返回的签名后,调用微信支付的 JSAPI 方法,传入订单信息和签名等参数,即可发起支付请求。 6. 微信客户端会弹出支付窗口,用户输入密码或进行指纹验证后,支付完成。 注意事项: - 在使用 Uniapp 进行微信支付开发时,需要确保页面已经获得了微信公众号的授权,因为微信支付是需要通过公众号的权限进行的。 - 需要合理处理支付结果的回调,根据支付结果进行相应的处理,如跳转到支付成功页面或给予支付失败的提示等。 通过使用 Uniapp H5 微信支付 JSAPI,我们可以方便地在 Uniapp 框架下进行微信支付的开发,实现支付功能的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值