java版 支付宝和微信 h5支付

1.支付宝微信支付


        
            com.alipay.sdk
            alipay-sdk-java
            4.38.60.ALL
        
AliPayment.java
package com.ruoyi.coupon.payment;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.domain.ExtendParams;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.coupon.payment.dto.PayParam;
import com.ruoyi.coupon.payment.dto.RefundParam;
import com.ruoyi.coupon.service.ICouponConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 阿里支付类
 */
@Service
@Slf4j
public class AliPayment {
    private static Map aliCertClientMap = new HashMap();

    /*public static String appid="";
    //应用私钥 参考 https://opendocs.alipay.com/support/01rauw
    public static String privateKey="";
    //服务商的账户pid 参考 https://opendocs.alipay.com/open/194/105190?pathHash=e479c7e4#%E8%BF%94%E4%BD%A3
    public static String sysServiceProviderId="";*/

    public static String appid="";
    //应用私钥 参考 https://opendocs.alipay.com/support/01rauw
    public static String privateKey="";
    //服务商的账户pid 参考 https://opendocs.alipay.com/open/194/105190?pathHash=e479c7e4#%E8%BF%94%E4%BD%A3
    public static String sysServiceProviderId="";

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ICouponConfigService couponConfigService;

    /**
     * 获取客户端
     * @return
     */
    public DefaultAlipayClient getAliCertClient() {
        DefaultAlipayClient aliCertClient = aliCertClientMap.get("aliCertClient");
        if(aliCertClient != null){
            return aliCertClient;
        }

        File appCert = new File("aliPayCert/appCertPublicKey_2021004*******.crt");
        File alipayCert = new File("aliPayCert/alipayCertPublicKey_RSA2.crt");
        File alipayRootCert = new File("aliPayCert/alipayRootCert.crt");

        try {
            if (!appCert.exists()) {
                InputStream stream = AliPayment.class.getResourceAsStream("/aliPayCert/appCertPublicKey_2021004*******.crt");
                FileUtils.copyInputStreamToFile(stream, appCert);
            }
            if (!alipayCert.exists()) {
                InputStream stream = AliPayment.class.getResourceAsStream("/aliPayCert/alipayCertPublicKey_RSA2.crt");
                FileUtils.copyInputStreamToFile(stream, alipayCert);
            }
            if (!alipayRootCert.exists()) {
                InputStream stream = AliPayment.class.getResourceAsStream("/aliPayCert/alipayRootCert.crt");
                FileUtils.copyInputStreamToFile(stream, alipayRootCert);
            }
        } catch (IOException e) {
            log.error(e.getMessage());
            throw new GlobalException(e.getMessage());
        }

        String appCertPath = appCert.getAbsolutePath();
        String alipayCertPath = alipayCert.getAbsolutePath();
        String alipayRootCertPath = alipayRootCert.getAbsolutePath();


        String privateKey=this.privateKey;

        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");
        certAlipayRequest.setAppId(this.appid);
        certAlipayRequest.setPrivateKey(privateKey);
        certAlipayRequest.setFormat("JSON");
        certAlipayRequest.setCharset("utf-8");
        certAlipayRequest.setSignType("RSA2");
        certAlipayRequest.setCertPath(appCertPath);
        certAlipayRequest.setAlipayPublicCertPath(alipayCertPath);
        certAlipayRequest.setRootCertPath(alipayRootCertPath);

        DefaultAlipayClient alipayClient = null;

        try {
            alipayClient = new DefaultAlipayClient(certAlipayRequest);
            aliCertClientMap.put("aliCertClient",alipayClient);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return alipayClient;
    }

    /**
     * 下单
     * @param payParam
     * @return
     */
    public String pay(PayParam payParam) {
        String apiUrl = couponConfigService.getValue("online_domain");

        //证书公钥模式
        DefaultAlipayClient alipayClient = this.getAliCertClient();
        // 创建API对应的request(网页版)
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();

        request.setNotifyUrl(apiUrl + "/api/payment/alipay/notify");
        //request.setNotifyUrl("http://egevdr.natappfree.cc" + "/payment/alipay/notify");

        request.setReturnUrl("");

        /******必传参数******/
        JSONObject bizContent = new JSONObject();
        //商户订单号,商家自定义,保持唯一性
        bizContent.put("out_trade_no", payParam.getOutTradeNo());
        //支付金额,最小值0.01元
        bizContent.put("total_amount",payParam.getTotalAmount());
        //订单标题,不可使用特殊符号
        bizContent.put("subject", payParam.getSubject());

        /******可选参数******/
        //手机网站支付默认传值FAST_INSTANT_TRADE_PAY
        bizContent.put("product_code", "QUICK_WAP_WAY");
        //bizContent.put("time_expire", "2022-08-01 22:00:00");

        request.setBizContent(bizContent.toString());

        try {
            AlipayTradeWapPayResponse alipayTradeWapPayResponse = alipayClient.pageExecute(request);
            String body = alipayTradeWapPayResponse.getBody();
            return body;
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 退款
     * @param pefundParam
     * @return
     */
    public Boolean refundOrder(RefundParam pefundParam) {
        DefaultAlipayClient alipayClient = this.getAliCertClient();
        String apiUrl = couponConfigService.getValue("online_domain");;

        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", pefundParam.getOutTradeNo());
        bizContent.put("refund_amount", pefundParam.getRefund());
        bizContent.put("refund_reason",pefundParam.getBody());

        request.setBizContent(bizContent.toString());
        //request.setNotifyUrl(apiUrl + "/api/payment/alipay/notify");
        try {
            AlipayTradeRefundResponse response = alipayClient.certificateExecute(request);
            return response.isSuccess();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 查询订单接口 https://opendocs.alipay.com/open/02ivbt?scene=common&pathHash=8abc6ffe
     * @param orderNum
     * @return
     */
    public Map orderQuery(String  orderNum) {
        DefaultAlipayClient alipayClient = this.getAliCertClient();
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderNum);
        //bizContent.put("trade_no", "2014112611001004680073956707");
        request.setBizContent(bizContent.toString());

        try {
            AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.certificateExecute(request);

            Map map=new HashMap();
            map.put("tradeState",alipayTradeQueryResponse.getTradeStatus());
            /**
             * 交易状态:WAIT_BUYER_PAY(交易创建,等待买家付款)、TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、TRADE_SUCCESS(交易支付成功)、TRADE_FINISHED(交易结束,不可退款)
             */
            return map;
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 公钥证书模式效验签名
     * @param request
     * @return
     */
    public boolean ZSRsaCheck(HttpServletRequest request){
        /**
         * 支付宝线上的验签需要的支付宝公钥证书
         */
        File alipayCert = new File("aliPayCert/alipayCertPublicKey_RSA2.crt");
        try {
            if (!alipayCert.exists()) {
                InputStream stream = AliPayment.class.getResourceAsStream("/aliPayCert/alipayCertPublicKey_RSA2.crt");
                FileUtils.copyInputStreamToFile(stream, alipayCert);
            }

        } catch (IOException e) {
            log.error("alipayCertPublicKey 证书文件未找到:{}",e.getMessage());
            throw new GlobalException(e.getMessage());
        }
        //支付宝公钥证书
        String alipayPublicCertPath=alipayCert.getAbsolutePath();
        /**
         * 这种方式效率高一点
         */
        //签名方式
        String sign_type="RSA2";
        //对待签名字符串数据通过&进行拆分
        Map requestParams = request.getParameterMap();
        LinkedHashMap map =  new LinkedHashMap();
        //把拆分数据放在map集合内
        for (Object o : requestParams.keySet()) {
            String name = (String) o;
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            map.put(name, valueStr);
        }

        try {
            return AlipaySignature.rsaCertCheckV1(map, alipayPublicCertPath, "utf-8",sign_type);
        } catch (AlipayApiException e) {
            log.error("支付宝异步验签失败:{}",e.getMessage());
            return false;
        }
    }

    /**
     * 支付宝转账
     * @param param
     * @return
     */
    public Map alipayTransfer(Map param){
        //获得公钥证书模式支付宝客户端
        DefaultAlipayClient aliCertClient = getAliCertClient();

        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
        request.setBizContent("{" +
                "\"out_biz_no\":\""+param.get("outBizNo")+"\"," +
                "\"trans_amount\":"+param.get("transAmount")+"," +
                "\"product_code\":\"TRANS_ACCOUNT_NO_PWD\"," +
                "\"biz_scene\":\"DIRECT_TRANSFER\"," +
                "\"order_title\":\""+param.get("orderTitle")+"\"," +
                "\"payee_info\":{" +
                "\"identity_type\":\"ALIPAY_LOGON_ID\"," +
                "\"identity\":\""+param.get("identity")+"\"," +
                "\"name\":\""+param.get("name")+"\"" +
                "}," +
                "\"remark\":\""+param.get("remark")+"\"," +
                "\"business_params\":{\"payer_show_name_use_alias\":\"true\"}" +
                "}");

        //返回的map
        Map rmap=new HashMap();
        try {
            AlipayFundTransUniTransferResponse response = aliCertClient.certificateExecute(request);
            rmap.put("isSuccess",response.isSuccess());
            rmap.put("subMsg",response.getSubMsg());
            return  rmap;
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return rmap;
        }
    }
}
AlipayNotify.java
package com.ruoyi.api.controller.coupon.payment.rest;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.coupon.payment.AliPayment;
import com.ruoyi.coupon.payment.enums.AliPayStatusEnum;
import com.ruoyi.coupon.payment.event.PaymentEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/payment/alipay")
public class AlipayNotify {

    @Autowired
    private AliPayment aliPayment;
    @Autowired
    private ApplicationEventPublisher publisher;


    @RequestMapping(value = "/notify", method = {RequestMethod.GET, RequestMethod.POST})
    @SuppressWarnings("all")
    public ResponseEntity notify(HttpServletRequest request) throws UnsupportedEncodingException {
        Map parameterMap = request.getParameterMap();
        //内容验签,防止黑客篡改参数
        //if (alipayUtils.rsaCheck(request,alipay)) {
        if(aliPayment.ZSRsaCheck(request)){
            //交易状态
            String tradeStatus = getRequestParameter(request, "trade_status");
            // 商户订单号
            String outTradeNo = getRequestParameter(request, "out_trade_no");
            //支付宝交易号
            String tradeNo = getRequestParameter(request, "trade_no");
            //付款金额
            String totalAmount = getRequestParameter(request, "total_amount");
            //退款金额
            String refundFee = getRequestParameter(request, "refund_fee");

            //获取回传参数paymentType
            String passbackParams = getRequestParameter(request, "passback_params");
            Map map=new HashMap<>();
            if(StringUtils.isNotBlank(passbackParams)){
                passbackParams= java.net.URLDecoder.decode(passbackParams,"UTF-8");
                String[] split = StringUtils.split(passbackParams, ";");
                for (int i=0;i>>>> 交易状态: {}, 商户订单号: {}, 支付宝交易号: {}, 退款金额: {}", tradeStatus, outTradeNo, tradeNo, refundFee);
                //验证
                if (AliPayStatusEnum.CLOSED.getValue().equals(tradeStatus)) {
                    // outTradeNo 退款成功
                    publisher.publishEvent(new PaymentEvent(this, outTradeNo,1,map,refundFee));
                }
            } else if (StringUtils.isNotEmpty(totalAmount)) {
                log.info(">>>>> 交易状态: {}, 商户订单号: {}, 支付宝交易号: {}, 付款金额: {}", tradeStatus, outTradeNo, tradeNo, totalAmount);
                //验证
                if (AliPayStatusEnum.SUCCESS.getValue().equals(tradeStatus) || AliPayStatusEnum.FINISHED.getValue().equals(tradeStatus)) {
                    // outTradeNo 支付成功
                    publisher.publishEvent(new PaymentEvent(this, outTradeNo,0,map,totalAmount));
                }
            } else {
                log.info(">>>>> 交易状态: {}, 商户订单号: {}, 支付宝交易号: {}", tradeStatus, outTradeNo, tradeNo);
            }
            return new ResponseEntity<>("success",HttpStatus.OK);//返回success ,让支付宝不在重复调起回调
        }
        return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
    }

    private String getRequestParameter(HttpServletRequest request, String valname) {
        String value = request.getParameter(valname);
        if (value != null) {
            return new String(value.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        }
        return value;
    }
}

2.微信支付


            com.github.wechatpay-apiv3
            wechatpay-java
            0.2.11
        
WeChatPayment.java
package com.ruoyi.coupon.payment;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.coupon.payment.dto.PayParam;
import com.ruoyi.coupon.payment.dto.RefundParam;
import com.ruoyi.coupon.payment.utils.IpUtil;
import com.ruoyi.coupon.service.ICouponConfigService;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.h5.H5Service;
import com.wechat.pay.java.service.payments.h5.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.payments.model.TransactionAmount;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 微信支付服务类
 */
@Service
@Slf4j
public class WeChatPayment {

    private static final String mchId = ""; // 商户号
    private static final String mchSerialNo = ""; // 商户证书序列号
    //商户私钥 //https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay3_1.shtml
    private static final String privateKey = "";
    // 你的微信支付平台证书
    private static final String apiV3Key = "";

    private static final String appid="";

    /** 商户API私钥路径 */
    public static String privateKeyPath = "C:\\Users\\Administrator\\Desktop\\coupon\\wxpay\\apiclient_key.pem";

    @Autowired
    private ICouponConfigService couponConfigService;

    /**
     * 获得H5客户端
     * @return
     */
    public H5Service getH5Service () {
        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(mchId)
                        .privateKey(privateKey)
                        //.privateKeyFromPath(privateKeyPath)
                        .merchantSerialNumber(mchSerialNo)
                        .apiV3Key(apiV3Key)
                        .build();
        H5Service build = new H5Service.Builder().config(config).build();
        return build;
    }

    public String pay(PayParam payParam) {
        String apiUrl = couponConfigService.getValue("online_domain");
        BigDecimal bigDecimal = new BigDecimal(100);
        int payPrice = bigDecimal.multiply(new BigDecimal(payParam.getTotalAmount())).intValue();

        H5Service h5Service = getH5Service();

        //获取客户端
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(payPrice);

        H5Info h5Info = new H5Info();
        h5Info.setType("Wap");

        //场景信息
        SceneInfo sceneInfo = new SceneInfo();
        sceneInfo.setPayerClientIp("qy.gsjf.cc");
        sceneInfo.setH5Info(h5Info);

        request.setAmount(amount);
        request.setAppid(appid);
        request.setMchid(mchId);
        request.setDescription(payParam.getSubject());
        //request.setNotifyUrl("http://egevdr.natappfree.cc" + "/payment/weChatPay/payment/notify");
        request.setNotifyUrl(apiUrl +"api" + "/payment/weChatPay/payment/notify");
        request.setOutTradeNo(payParam.getOutTradeNo());
        request.setAttach(payParam.getPassbackParams());//携带其他参数
        request.setSceneInfo(sceneInfo);

        // 调用下单方法,得到应答
        PrepayResponse prepay = h5Service.prepay(request);
        return prepay.getH5Url();
    }

    /**
     * 申请退款
     * @param refundParam
     */
    public void refundOrder(RefundParam refundParam) {
        String apiUrl = couponConfigService.getValue("online_domain");
        BigDecimal bigDecimal = new BigDecimal(100);
        int total = bigDecimal.multiply(new BigDecimal(refundParam.getTotal())).intValue();

        int refund = bigDecimal.multiply(new BigDecimal(refundParam.getRefund())).intValue();

        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(mchId)
                        .privateKey(privateKey)
                        .merchantSerialNumber(mchSerialNo)
                        .apiV3Key(apiV3Key)
                        .build();
        RefundService service = new RefundService.Builder().config(config).build();

        //生成随机退款订单号
        String s = UUID.randomUUID().toString().replace("-","");

        CreateRequest request = new CreateRequest();

        //金额信息
        AmountReq amount = new AmountReq();
        amount.setCurrency("CNY");
        amount.setTotal(Long.valueOf(total));
        amount.setRefund(Long.valueOf(refund));

        request.setAmount(amount);
        request.setOutTradeNo(refundParam.getOutTradeNo());
        request.setOutRefundNo(s);
        //request.setNotifyUrl("http://egevdr.natappfree.cc" + "/payment/weChatPay/refund/notify");
        request.setNotifyUrl(apiUrl +"api" + "/payment/weChatPay/refund/notify");

        //发送请求
        Refund refund1 = service.create(request);
    }

    /**
     * 根据订单号查询订单信息,目前只返回了订单状态 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_3_2.shtml
     * @param orderNum
     * @return
     */
    public Map queryOrderByOutTradeNo(String orderNum) {
        H5Service h5Service = getH5Service();
        QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
        request.setMchid(mchId);
        request.setOutTradeNo(orderNum);

        Transaction transaction = h5Service.queryOrderByOutTradeNo(request);

        Map map=new HashMap();
        map.put("tradeState",transaction.getTradeState());
        /**
         * 交易状态,枚举值:
         * SUCCESS:支付成功
         * REFUND:转入退款
         * NOTPAY:未支付
         * CLOSED:已关闭
         * REVOKED:已撤销(仅付款码支付会返回)
         * USERPAYING:用户支付中(仅付款码支付会返回)
         * PAYERROR:支付失败(仅付款码支付会返回)
         */
        return map;
    }

    /**
     * 支付成功验签
     * @param request
     * @return
     */
    public Map paySuccessCheck(HttpServletRequest request) {
        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(mchId)
                        .privateKey(privateKey)
                        .merchantSerialNumber(mchSerialNo)
                        .apiV3Key(apiV3Key)
                        .build();

        // 从请求头中获取信息
        String timestamp                        = request.getHeader("Wechatpay-Timestamp");
        String nonce                            = request.getHeader("Wechatpay-Nonce");
        String signature                        = request.getHeader("Wechatpay-Signature");
        String singType                         = request.getHeader("Wechatpay-Signature-Type");
        String wechatPayCertificateSerialNumber = request.getHeader("Wechatpay-Serial");

        String requestBody = getRequestBody(request);

        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(wechatPayCertificateSerialNumber)
                .nonce(nonce)
                .signature(signature)
                .signType(singType)
                .timestamp(timestamp)
                .body(requestBody)
                .build();

        // 初始化解析器 NotificationParser
        NotificationParser parser = new NotificationParser((NotificationConfig) config);

        // 这个Transaction是微信包里面的
        Transaction decryptObject = parser.parse(requestParam, Transaction.class);

        TransactionAmount amount = decryptObject.getAmount();
        String outTradeNo = decryptObject.getOutTradeNo();
        String attach = decryptObject.getAttach();

        Map map=new HashMap();
        map.put("amount",amount.getTotal());
        map.put("outTradeNo",outTradeNo);
        map.put("attach",attach);
        return map;
    }

    public Map refundSuccessCheck(HttpServletRequest request) {
        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(mchId)
                        .privateKey(privateKey)
                        .merchantSerialNumber(mchSerialNo)
                        .apiV3Key(apiV3Key)
                        .build();

        // 从请求头中获取信息
        String timestamp                        = request.getHeader("Wechatpay-Timestamp");
        String nonce                            = request.getHeader("Wechatpay-Nonce");
        String signature                        = request.getHeader("Wechatpay-Signature");
        String singType                         = request.getHeader("Wechatpay-Signature-Type");
        String wechatPayCertificateSerialNumber = request.getHeader("Wechatpay-Serial");

        String requestBody = getRequestBody(request);

        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(wechatPayCertificateSerialNumber)
                .nonce(nonce)
                .signature(signature)
                .signType(singType)
                .timestamp(timestamp)
                .body(requestBody)
                .build();

        // 初始化解析器 NotificationParser
        NotificationParser parser = new NotificationParser((NotificationConfig) config);

        // 这个Transaction是微信包里面的
        RefundNotification decryptObject = parser.parse(requestParam, RefundNotification.class);

        com.wechat.pay.java.service.refund.model.Amount amount = decryptObject.getAmount();
        String outTradeNo = decryptObject.getOutTradeNo();

        Map map=new HashMap();
        map.put("amount",amount.getTotal());
        map.put("outTradeNo",outTradeNo);
        return map;
    }

    // 获取请求头里的数据
    private String getRequestBody(HttpServletRequest request) {
        StringBuffer sb = new StringBuffer();
        try (
                ServletInputStream inputStream = request.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        ) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            System.out.println("读取数据流异常:"+e);
        }
        return sb.toString();
    }
}
WeChatPayNotify.java
package com.ruoyi.api.controller.coupon.payment.rest;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.coupon.payment.WeChatPayment;
import com.ruoyi.coupon.payment.event.PaymentEvent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
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 java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 商城支付项微信支付的回调接口
 */
@Slf4j
@RestController
@RequestMapping("/payment/weChatPay")
public class WeChatPayNotify {
    @Autowired
    private ApplicationEventPublisher publisher;

    @Autowired
    private WeChatPayment weChatPayment;

    /**
     * 微信支付/充值回调
     */
    @PostMapping("/payment/notify")
    public ResponseEntity.BodyBuilder  renotify(HttpServletRequest request) {
        Map map = weChatPayment.paySuccessCheck(request);

        Integer amount = (Integer)map.get("amount");
        String outTradeNo = (String)map.get("outTradeNo");

        String attach = (String)map.get("attach");
        Map map1 = new HashMap<>();
        //将附加信息 attach 解析到 map1 中,因为现在没有传递任何参数,所以没有解析

        BigDecimal divide = new BigDecimal(amount).divide(new BigDecimal("100"));

        publisher.publishEvent(new PaymentEvent(this, outTradeNo,0,map1,divide.toString()));

        return ResponseEntity.status(HttpStatus.OK);
    }

    /**
     * 微信退款回调
     */
    @PostMapping("/refund/notify")
    public ResponseEntity.BodyBuilder parseRefundNotifyResult(HttpServletRequest request) {
        Map map = weChatPayment.refundSuccessCheck(request);

        Long amount = (Long)map.get("amount");
        String outTradeNo = (String)map.get("outTradeNo");

        BigDecimal divide = new BigDecimal(amount).divide(new BigDecimal("100"));

        publisher.publishEvent(new PaymentEvent(this, outTradeNo,1,null,divide.toString()));
        return ResponseEntity.status(HttpStatus.OK);
    }
}

 前端 uniapp 的调起方式



createOrder(data).then(res=>{
					uni.hideLoading()
					this.payType=''
					if(res.data.payType=="aliPayH5"){
						this.formContent=res.data.payStrand
						this.$nextTick(() => {
							document.forms['punchout_form'].submit(); 
						})
					}else if(res.data.payType=="weChatH5"){ 
						const platform = uni.getSystemInfoSync().platform 
						let mweb_url = res.data.payStrand 
						var a=document.createElement('a'); 
						switch (platform) {
							case 'android':
								a.href=mweb_url
								a.click() 
								break;
							case 'ios':
							a.href=mweb_url
								a.click() 
								break;
							default:
								break;
						} 
					}else if(res.data.payType=="balance"){
						uni.showToast({
							title:res.data.payStrand
						})
					}
					uni.navigateTo({
						url:"/pages/mine/order/order"
					}) 
				})

你可能感兴趣的:(java,微信,python)