微信小程序-微信支付和微信退款(Java后台)

微信支付流程

都是我自己工作中开发的,亲测可用,不喜勿喷。

  • controller中我是这么写的,你们需要根据自己的业务需求改动。ResponseBean是我自己封装的,你们可以改成你们想要的形式。`
 /**
     * 微信统一下单接口
     * @return
     */
    @RequestMapping(value = "/doUnifiedOrder", method = RequestMethod.POST)
    public ResponseBean doUnifiedOrder(@RequestBody Map<String,Object> req) {
        Map resultMap=new HashMap();
        String openid = (String) req.get("openId");

        WXPay wxpay =null;

        try {
            //初始化证书
            myConfig.initCert();
            wxpay= new WXPay(myConfig);
        } 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 payOutMoney = WxMoney.changeY2F(String.valueOf(req.get("money")));
        String tradeName = (String) req.get("tradeName");
        if(tradeName!=null&&tradeName.length()>0){

        }else{
            tradeName = "课程支付";
        }
        String body = tradeName;
        //商户订单号
        String out_trade_no= WXPayUtil.generateNonceStr();
        //统一下单接口参数
        HashMap<String, String> data = new HashMap<String, String>();
        data.put("appid", 你的appid);
        data.put("mch_id", 商户id);
        data.put("nonce_str", nonce_str);
        data.put("body", body);
        data.put("out_trade_no",out_trade_no);
        data.put("total_fee", payOutMoney);
        data.put("spbill_create_ip", "127.0.0.1");
        data.put("notify_url", 回调地址);
        data.put("trade_type","JSAPI");
        data.put("openid", openid);
        try {
            Map<String, String> rMap = wxpay.unifiedOrder(data);
            String return_code = (String) rMap.get("return_code");
            String result_code = (String) rMap.get("result_code");
            String nonceStr = WXPayUtil.generateNonceStr();
            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",myConfig.getAppID());
                    String sign = WXPayUtil.generateSignature(resultMap, myConfig.getKey());
                    resultMap.put("paySign", sign);
                    resultMap.put("out_trade_no",out_trade_no);
                    ResponseBean responseBean = new ResponseBean(HttpStatus.OK.value(),"微信支付",resultMap);
                    return responseBean;

            }else{
                ResponseBean responseBean = new ResponseBean(HttpStatus.OK.value(),"微信支付失败","微信支付失败");
                return  responseBean;
            }
        } catch (Exception e) {
            ResponseBean responseBean = new ResponseBean(HttpStatus.OK.value(),"微信支付失败","微信支付失败");
            e.printStackTrace();
            return  responseBean;
        }
    }

微信退款代码(需要传退款的订单id)

    public ResponseBean refund(Map<String, Object> req) {
        Map resultMap=new HashMap();
        String buyId = (String) req.get("buyId");
        WXPay wxpay =null;
        try {
            myConfig.initCert();//初始化证书
            wxpay= new WXPay(myConfig);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //生成的随机字符串
        String nonce_str = WXPayUtil.generateNonceStr();
        //获取客户端的ip地址
        //获取本机的ip地址
        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        //支付金额,需要转成字符串类型,否则后面的签名会失败
//        int  total_fee= (int) req.get("money");
        String payOutMoney = WxMoney.changeY2F(String.valueOf(req.get("money")));

//        String body = (String) req.get("z");
        //商户订单号
        String out_trade_no= WXPayUtil.generateNonceStr();
        //统一下单接口参数
        HashMap<String, String> data = new HashMap<String, String>();

        try {
            data.put("appid", myConfig.getAppID());
            data.put("mch_id", myConfig.getMchID());
            data.put("nonce_str", nonce_str);
            data.put("sign_type", "MD5");
            data.put("out_trade_no",buyId);//微信订单号
            data.put("out_refund_no", out_trade_no);//商户退款单号
            data.put("total_fee",payOutMoney);//支付金额,微信支付提交的金额是不能带小数点的,且是以分为单位,这边需要转成字符串类型,否则后面的签名会失败
            data.put("refund_fee",payOutMoney);//退款总金额,订单总金额,单位为分,只能为整数
            //MD5运算生成签名,这里是第一次签名,用于调用统一下单接口
            String sign = WXPayUtil.generateSignature(data, myConfig.getKey());
            data.put("sign", sign);

            Map<String, String> rMap = wxpay.refund(data);
            String return_code = (String) rMap.get("return_code");
            String result_code = (String) rMap.get("result_code");

            Long timeStamp = System.currentTimeMillis() / 1000;
            if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) {

                ResponseBean responseBean = new ResponseBean(HttpStatus.OK.value(),"微信退款成功",rMap);
                return responseBean;

            }else{
                ResponseBean responseBean = new ResponseBean(HttpStatus.OK.value(),"微信退款失败","微信支付失败");
                return  responseBean;
            }


        } catch (Exception e) {
            ResponseBean responseBean = new ResponseBean(HttpStatus.OK.value(),"微信退款失败","微信支付失败");
            e.printStackTrace();
            return  responseBean;
        }
    }

需要用到的工具类
在这里插入图片描述
然后在MyConfig中配置一下你们的小程序参数就行了,如果需要添加退款功能必须配置商户证书(对应在你项目中的位置)。不需要的话就把initCert方法去掉。

public class MyConfig extends WXPayConfig {
    @Value("${res.imgPath}")
    public String imgPath;

    private byte[] certData;


    @Override
    public String getAppID() {
        return "你的小程序id";
    }

    @Override
    public String getMchID() {
        return "商户id";
    }

    @Override
    public String getKey() {
        return "商户秘钥";
    }

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

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

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

    @Override
    IWXPayDomain getWXPayDomain() {
        return new IWXPayDomain() {
            @Override
            public void report(String domain, long elapsedTimeMillis, Exception ex) {
            }

            @Override
            public DomainInfo getDomain(WXPayConfig config) {
                return new DomainInfo("api.mch.weixin.qq.com", false);
            }
        };
    }
    
    @Override
    public void initCert() throws Exception {
        String certPath = this.imgPath+"/upload/cert/"+"apiclient_cert.p12";//从微信商户平台下载的安全证书存放的目录
        System.out.println(certPath);
        File file = new File(certPath);
        InputStream certStream = new FileInputStream(file);
        this.certData = new byte[(int) file.length()];
        certStream.read(this.certData);
        certStream.close();
    }
}

在这里插入图片描述
关注公众号回复微信支付获取工具类文件。

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 以下是微信小程序统一下单的Java后台代码示例: ``` import java.util.HashMap; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import org.apache.commons.codec.digest.DigestUtils; public class WechatPay { // 微信支付接口地址 private static final String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; // 微信支付商户号 private static final String MCH_ID = "your_mch_id"; // 微信支付密钥 private static final String KEY = "your_api_key"; /** * 统一下单方法 * * @param openid 用户openid * @param body 商品描述 * @param totalFee 订单总金额,单位为分 * @param spbillCreateIp 用户端实际ip * @param outTradeNo 商户订单号 * @param notifyUrl 支付结果通知地址 * @return 统一下单结果 * @throws Exception */ public static Map<String, String> unifiedOrder(String openid, String body, int totalFee, String spbillCreateIp, String outTradeNo, String notifyUrl) throws Exception { // 构造请求参数 SortedMap<String, String> parameters = new TreeMap<>(); parameters.put("appid", "your_app_id"); parameters.put("mch_id", MCH_ID); parameters.put("nonce_str", String.valueOf(System.currentTimeMillis())); parameters.put("body", body); parameters.put("out_trade_no", outTradeNo); parameters.put("total_fee", String.valueOf(totalFee)); parameters.put("spbill_create_ip", spbillCreateIp); parameters.put("notify_url", notifyUrl); parameters.put("trade_type", "JSAPI"); parameters.put("openid", openid); parameters.put("sign", sign(parameters)); // 发送请求 String xml = HttpUtil.post(UNIFIED_ORDER_URL, XmlUtil.toXml(parameters)); Map<String, String> result = XmlUtil.toMap(xml); // 验证返回结果 if (!"SUCCESS".equals(result.get("return_code"))) { throw new Exception(result.get("return_msg")); } if (!"SUCCESS".equals(result.get("result_code"))) { throw new Exception(result.get("err_code_des")); } return result; } /** * 生成签名 * * @param parameters 请求参数 * @return 签名字符串 */ private static String sign(SortedMap<String, String> parameters) { StringBuilder sb = new StringBuilder(); for (String key : parameters.keySet()) { String value = parameters.get(key); if (value != null && !"".equals(value) && !"sign".equals(key) && !"key".equals(key)) { sb.append(key).append("=").append(value).append("&"); } } sb.append("key=").append(KEY); return DigestUtils.md5Hex(sb.toString()).toUpperCase(); } } ``` 这段代码实现了微信小程序的统一下单功能,其中包括了生成签名、构造请求参数、发送请求、解析响应等功能。你需要将代码中的`your_app_id`、`your_mch_id`、`your_api_key`替换为自己的实际值,并引入Apache Commons Codec和HttpUtil、XmlUtil工具类。 ### 回答2: 微信小程序统一下单是指在用户使用微信小程序进行支付时,通过后台Java代码来完成支付的过程。 要实现微信小程序统一下单,首先需要在代码中引入微信支付的SDK。然后,在后台Java代码中,需要编写处理统一下单逻辑的方法。 在这个方法中,首先需要获取到用户传递过来的支付参数,包括小程序的ID、密钥、订单号、金额等信息。然后,通过调用微信支付SDK提供的统一下单接口,向微信支付平台发送请求。这个接口会返回一个预支付交易会话标识prepay_id。 接下来,需要将prepay_id返回给小程序端,小程序将根据prepay_id生成签名等信息,用于调起支付接口。同时,后台Java代码还需要保存订单相关的信息,以便后续查询或退款等操作。 当用户确认支付并完成支付后,微信支付平台会向后台发送支付通知。后台Java代码需要编写处理支付通知的方法,用于更新订单状态或处理其他业务逻辑。 需要注意的是,在进行统一下单时,要保证传递给微信支付平台的数据的准确性和安全性,以避免支付中出现问题。 总的来说,微信小程序统一下单的后台Java代码主要包括获取支付参数、调用微信支付SDK进行统一下单、处理支付通知等步骤。这样,就可以通过后台Java代码实现微信小程序的支付功能。 ### 回答3: 微信小程序统一下单是指用户在微信小程序中发起支付请求,并将支付相关的参数传递给后台服务器进行处理。下面是一个简单的微信小程序统一下单的后台Java代码示例: ```java import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; public class WechatPay { public static String unifiedOrder(String openid, String totalFee) { SortedMap<String, Object> params = new TreeMap<>(); params.put("appid", "your_appid"); params.put("mch_id", "your_mch_id"); params.put("nonce_str", WechatPayUtil.generateNonceStr()); params.put("body", "支付测试"); params.put("out_trade_no", WechatPayUtil.generateOutTradeNo()); params.put("total_fee", totalFee); params.put("spbill_create_ip", "your_client_ip"); params.put("notify_url", "your_notify_url"); params.put("trade_type", "JSAPI"); params.put("openid", openid); params.put("sign", WechatPayUtil.generateSign(params, "your_api_key")); String xmlParams = WechatPayUtil.mapToXml(params); String result = HttpUtil.sendPost("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlParams); Map<String, Object> resultMap = WechatPayUtil.xmlToMap(result); return resultMap.get("prepay_id").toString(); } } ``` 上述代码中,WechatPay类的unifiedOrder方法接收openId和totalFee参数,并根据微信支付接口要求将相关参数进行组装,其中your_appid、your_mch_id、your_notify_url、your_api_key需要替换成真实的值。最后,通过HttpUtil类发送POST请求到https://api.mch.weixin.qq.com/pay/unifiedorder接口,获取返回结果,并从结果中解析出prepay_id,作为小程序发起支付的参数返回给前端。 这只是一个简单的示例,实际开发中还需要考虑异常处理、支付结果的回调通知等。希望对你有帮助!
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值