赞
踩
本文章是介绍java对接(微信小程序)微信支付,包括微信预下单、支付、退款等等。
目录
6、根据支付订单号查询订单 (transaction_id)
详细操作流程参考官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml#part-1
配置完成需要以下信息:
开发语言:java ,编译工具:idea ,框架:springboot ,仓库:maven
- <dependency>
- <groupId>com.github.wechatpay-apiv3</groupId>
- <artifactId>wechatpay-java</artifactId>
- <version>0.2.10</version>
- </dependency>
#微信支付配置 wx: pay: #应用id(小程序id) appId: wx6b5xxxxxxxxxxxx #商户号 merchantId: 1xxxxxxxxx #商户API私钥 privateKey: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx #商户证书序列号 merchantSerialNumber: 315DDXXXXXXXXXXXXXXXXXXXXXXXXXXX #商户APIv3密钥 apiV3Key: XXXXXXXXXXXXXXXXXXXXXXXXXX #支付通知地址 payNotifyUrl: https://xxx.xxxx.xxx.xxx/xx/xxxx/xxxx/openapi/wx/payNotify #退款通知地址 refundNotifyUrl: https://xxx.xxx.xxx.xxx/xxxx/xxxx/xxxx/openapi/wx/refundNotify
-
- import lombok.Data;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.stereotype.Component;
-
- /**
- * @author caozhen
- * @ClassName WxPayConfig
- * @description: 微信支付配置类
- * @date 2024年01月03日
- * @version: 1.0
- */
- @Data
- @Component
- @ConfigurationProperties(prefix = "wx.pay")
- public class WxPayConfig {
- //APPID
- private String appId;
- //mchid
- private String merchantId;
- //商户API私钥
- private String privateKey;
- //商户证书序列号
- private String merchantSerialNumber;
- //商户APIv3密钥
- private String apiV3Key;
- //支付通知地址
- private String payNotifyUrl;
- //退款通知地址
- private String refundNotifyUrl;
- }

- import com.wechat.pay.java.core.RSAAutoCertificateConfig;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- import javax.annotation.Resource;
-
- /**
- * @author caozhen
- * @ClassName WxPayAutoCertificateConfig
- * @description: 微信支付证书自动更新配置
- * @date 2024年01月03日
- * @version: 1.0
- */
- @Configuration
- public class WxPayAutoCertificateConfig {
- @Resource
- private WxPayConfig wxPayConfig;
-
- /**
- * 初始化商户配置
- * @return
- */
- @Bean
- public RSAAutoCertificateConfig rsaAutoCertificateConfig() {
- RSAAutoCertificateConfig config = new RSAAutoCertificateConfig.Builder()
- .merchantId(wxPayConfig.getMerchantId())
- .privateKey(wxPayConfig.getPrivateKey())
- .merchantSerialNumber(wxPayConfig.getMerchantSerialNumber())
- .apiV3Key(wxPayConfig.getApiV3Key())
- .build();
- return config;
- }
- }

- import com.alibaba.fastjson.JSONObject;
- import com.baomidou.mybatisplus.mapper.EntityWrapper;
- import com.baomidou.mybatisplus.mapper.Wrapper;
- import com.hvit.user.exception.DataAccessException;
- import com.hvit.user.util.DateUtils;
- import com.hvit.user.util.R;
- import com.hvit.user.yst.entity.WxOrderEntity;
- import com.hvit.user.yst.entity.WxPayLogEntity;
- import com.hvit.user.yst.request.CreateOrderReq;
- import com.hvit.user.yst.request.QueryOrderReq;
- import com.hvit.user.yst.request.WxNotifyReq;
- import com.hvit.user.yst.service.WKShoppingMallService;
- import com.hvit.user.yst.service.data.WxOrderDataService;
- import com.hvit.user.yst.service.data.WxPayLogDataService;
- import com.wechat.pay.java.core.RSAAutoCertificateConfig;
- import com.wechat.pay.java.core.exception.HttpException;
- import com.wechat.pay.java.core.exception.MalformedMessageException;
- import com.wechat.pay.java.core.exception.ServiceException;
- import com.wechat.pay.java.core.notification.NotificationParser;
- import com.wechat.pay.java.core.notification.RequestParam;
- import com.wechat.pay.java.service.payments.jsapi.*;
- import com.wechat.pay.java.service.payments.jsapi.model.*;
- import com.wechat.pay.java.service.payments.jsapi.model.Amount;
- import com.wechat.pay.java.service.payments.model.Transaction;
- import com.wechat.pay.java.service.refund.RefundService;
- import com.wechat.pay.java.service.refund.model.*;
- import io.swagger.annotations.ApiModelProperty;
- import io.swagger.models.auth.In;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.StringUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.scheduling.annotation.Async;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
-
- import javax.annotation.Resource;
- import javax.servlet.ServletInputStream;
- import javax.servlet.http.HttpServletRequest;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.math.BigDecimal;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.LinkedHashMap;
- import java.util.Map;
-
- /**
- * @author caozhen
- * @ClassName WxPayService
- * @description: 微信支付
- * @date 2024年01月03日
- * @version: 1.0
- */
- @Slf4j
- @Service
- public class WxPayService {
-
- @Resource
- private WxPayConfig wxPayConfig;
- @Autowired
- private RSAAutoCertificateConfig rsaAutoCertificateConfig;
- @Autowired
- private WxOrderDataService wxOrderDataService;
- @Autowired
- private WxPayLogDataService wxPayLogDataService;
-
- /***
- * 预支付订单
- * @param req
- * @return
- */
- public R createOrder(CreateOrderReq req) throws Exception {
- if (req == null) {
- return R.error("创建订单失败,缺少参数!");
- }
- //先解密
-
- String orderNo = req.getOutTradeNo();
- Integer totalFee = req.getTotal();
- //创建初始化订单
- //todo,创建订单这边你们自己来(后面我会放出表结构)
- //请求微信支付相关配置
- JsapiServiceExtension service =
- new JsapiServiceExtension.Builder()
- .config(rsaAutoCertificateConfig)
- .signType("RSA") // 不填默认为RSA
- .build();
- PrepayWithRequestPaymentResponse response = new PrepayWithRequestPaymentResponse();
- try {
- PrepayRequest request = new PrepayRequest();
- request.setAppid(wxPayConfig.getAppId());
- request.setMchid(wxPayConfig.getMerchantId());
- request.setDescription(description);
- request.setOutTradeNo(orderNo);
- request.setNotifyUrl(wxPayConfig.getPayNotifyUrl());
- Amount amount = new Amount();
- //amount.setTotal(totalFee.multiply(new BigDecimal("100")).intValue());
- amount.setTotal(totalFee);
- request.setAmount(amount);
- Payer payer = new Payer();
- payer.setOpenid(req.getWxOpenId());
- request.setPayer(payer);
- log.info("请求预支付下单,请求参数:{}", JSONObject.toJSONString(request));
- // 调用预下单接口
- response = service.prepayWithRequestPayment(request);
- log.info("订单【{}】发起预支付成功,返回信息:{}", orderNo, response);
- } catch (HttpException e) { // 发送HTTP请求失败
- log.error("微信下单发送HTTP请求失败,错误信息:{}", e.getHttpRequest());
- return R.error("下单失败");
- } catch (ServiceException e) { // 服务返回状态小于200或大于等于300,例如500
- log.error("微信下单服务状态错误,错误信息:{}", e.getErrorMessage());
- return R.error("下单失败");
- } catch (MalformedMessageException e) { // 服务返回成功,返回体类型不合法,或者解析返回体失败
- log.error("服务返回成功,返回体类型不合法,或者解析返回体失败,错误信息:{}", e.getMessage());
- return R.error("下单失败");
- }
-
- return R.ok().put("data", response);
- }
- }

- import java.util.HashMap;
- import java.util.Map;
-
- /**
- *
- * @author 曹震
- * @date 2024-1-03
- */
- public class R extends HashMap<String, Object> {
-
- private static final long serialVersionUID = 1L;
-
- public R() {
- put("code", 0);
- }
-
- public R(Integer code) {
- put("code", code);
- put("data", new HashMap<String, Object>());
- }
-
- public R(Integer code, String msg) {
- put("code", code);
- put("msg", msg);
- put("data", new HashMap<String, Object>());
- }
-
- public static R error() {
- return error(500, "未知异常,请联系管理员");
- }
-
- public static R errorDebug(String message) {
- return error(500, "未知异常 " + message + ",请联系管理员");
- }
-
- public static R error(String msg) {
- return error(500, msg);
- }
-
-
- public static R error(int code, String msg) {
- R r = new R();
- r.put("code", code);
- r.put("msg", msg);
- return r;
- }
-
- public R errorInfo(String msg) {
- this.put("errorMsg", msg);
- return this;
- }
-
- public static R ok(String msg) {
- R r = new R();
- r.put("msg", msg);
- r.put("data", new HashMap<String, Object>());
- return r;
- }
-
- public static R ok(Map<String, Object> map) {
- R r = new R();
- r.putAll(map);
- r.put("data", new HashMap<String, Object>());
- return r;
- }
-
- public static R ok() {
- return new R().put("msg", "success").put("data", new HashMap<String, Object>());
- }
-
- public static R ok(Integer size) {
- return new R().put("data", new HashMap<String, Object>((int)Math.round(size / 0.75)));
- }
-
- @Override
- public R put(String key, Object value) {
- super.put(key, value);
- return this;
- }
-
- /**
- * 添加返回结果数据
- *
- * @param key
- * @param value
- * @return
- */
- public R putData(String key, Object value) {
- Map<String, Object> map = (HashMap<String, Object>)this.get("data");
- map.put(key, value);
- return this;
- }
-
-
- }

- import io.swagger.annotations.ApiModelProperty;
- import lombok.Data;
-
-
- /**
- * @author caozhen
- * @ClassName CreateOrderReq
- * @description: TODO
- * @date 2024年01月03日
- * @version: 1.0
- */
- @Data
- public class CreateOrderReq {
-
- @ApiModelProperty(name = "description", value = "商品描述")
- private String description;
-
- @ApiModelProperty(name = "wxOpenId", value = "用户小程序openid")
- private String wxOpenId;
-
- @ApiModelProperty(name = "outTradeNo", value = "商户订单号")
- private String outTradeNo;
-
- @ApiModelProperty(name = "totalFee", value = "支付金额,单位:分")
- private Long totalFee;

- /***
- * 微信支付回调通知
- * @param request
- * @return
- * @throws IOException
- */
- @Transactional
- public synchronized String payNotify(HttpServletRequest request) throws Exception {
- log.info("------收到支付通知------");
- // 请求头Wechatpay-Signature
- String signature = request.getHeader("Wechatpay-Signature");
- // 请求头Wechatpay-nonce
- String nonce = request.getHeader("Wechatpay-Nonce");
- // 请求头Wechatpay-Timestamp
- String timestamp = request.getHeader("Wechatpay-Timestamp");
- // 微信支付证书序列号
- String serial = request.getHeader("Wechatpay-Serial");
- // 签名方式
- String signType = request.getHeader("Wechatpay-Signature-Type");
- // 构造 RequestParam
- RequestParam requestParam = new RequestParam.Builder()
- .serialNumber(serial)
- .nonce(nonce)
- .signature(signature)
- .timestamp(timestamp)
- .signType(signType)
- .body(HttpServletUtils.getRequestBody(request))
- .build();
-
- // 初始化 NotificationParser
- NotificationParser parser = new NotificationParser(rsaAutoCertificateConfig);
- // 以支付通知回调为例,验签、解密并转换成 Transaction
- log.info("验签参数:{}", requestParam);
- Transaction transaction = parser.parse(requestParam, Transaction.class);
- log.info("验签成功!-支付回调结果:{}", transaction.toString());
-
- Map<String, String> returnMap = new HashMap<>(2);
- returnMap.put("code", "FAIL");
- returnMap.put("message", "失败");
- //修改订单前,建议主动请求微信查询订单是否支付成功,防止恶意post
- Wrapper wrapper = new EntityWrapper<WxOrderEntity>();
- wrapper.eq("out_trade_no", transaction.getOutTradeNo());
- //wrapper.eq("transaction_id", transaction.getTransactionId());
- WxOrderEntity wxOrderEntity = wxOrderDataService.selectOne(wrapper);
- if (wxOrderEntity != null) {
- if (wxOrderEntity.getPayStatus() == 1) {
- //此时已经是支付成功,不在处理订单信息
- returnMap.put("code", "SUCCESS");
- returnMap.put("message", "成功");
- return JSONObject.toJSONString(returnMap);
- }
- }
- if (Transaction.TradeStateEnum.SUCCESS != transaction.getTradeState()) {
- log.info("内部订单号【{}】,微信支付订单号【{}】支付未成功", transaction.getOutTradeNo(), transaction.getTransactionId());
- if (wxOrderEntity != null) {
- wxOrderEntity.setUpdateTime(new Date());
- wxOrderEntity.setPayStatus(2);
- wxOrderEntity.setPayNonce(nonce);
- wxOrderEntity.setTransactionId(transaction.getTransactionId());
- //修改订单信息
- wxOrderDataService.updateById(wxOrderEntity);
- }
- return JSONObject.toJSONString(returnMap);
- }
- if (wxOrderEntity != null) {
- wxOrderEntity.setUpdateTime(new Date());
- wxOrderEntity.setPayTime(DateUtils.stringToDateTime(transaction.getSuccessTime()));
- wxOrderEntity.setPayDate(DateUtils.stringToDateTime(transaction.getSuccessTime()));
- wxOrderEntity.setPayStatus(1);
- wxOrderEntity.setPayNonce(nonce);
- wxOrderEntity.setTransactionId(transaction.getTransactionId());
- //修改订单信息
- wxOrderDataService.updateById(wxOrderEntity);
- //同时处理支付记录
- Wrapper payWrapper = new EntityWrapper<WxPayLogEntity>();
- wrapper.eq("out_trade_no", transaction.getOutTradeNo());
- wrapper.eq("pay_status", 1);//支付
- WxPayLogEntity wxPayLogEntity = wxPayLogDataService.selectOne(payWrapper);
- if (wxPayLogEntity == null) {
- wxPayLogEntity = new WxPayLogEntity();
- wxPayLogEntity.setCreateTime(new Date());
- wxPayLogEntity.setOutTradeNo(wxOrderEntity.getOutTradeNo());
- wxPayLogEntity.setPayStatus(1);
- wxPayLogEntity.setTotalFee(wxOrderEntity.getTotalFee());
- wxPayLogEntity.setTransactionId(wxOrderEntity.getTransactionId());
- wxPayLogEntity.setWxOpenId(wxOrderEntity.getWxOpenId());
- wxPayLogDataService.insert(wxPayLogEntity);
- }
- }
-
- returnMap.put("code", "SUCCESS");
- returnMap.put("message", "成功");
- return JSONObject.toJSONString(returnMap);
- }

- /***
- * 根据商户订单号查询订单 outTradeNo
- * @param req
- * @return
- */
- @Transactional
- public R queryOrderByOrderNo(QueryOrderReq req) {
- QueryOrderByOutTradeNoRequest queryRequest = new QueryOrderByOutTradeNoRequest();
- queryRequest.setMchid(wxPayConfig.getMerchantId());
- queryRequest.setOutTradeNo(req.getOrderNo());
- try {
- JsapiServiceExtension service =
- new JsapiServiceExtension.Builder()
- .config(rsaAutoCertificateConfig)
- .signType("RSA") // 不填默认为RSA
- .build();
- Transaction result = service.queryOrderByOutTradeNo(queryRequest);
- LinkedHashMap retmap = new LinkedHashMap();
- //支付成功
- if (Transaction.TradeStateEnum.SUCCESS == result.getTradeState()) {
- log.info("内部订单号【{}】,微信支付订单号【{}】支付成功", result.getOutTradeNo(), result.getTransactionId());
- retmap.put("out_trade_no", result.getOutTradeNo());
- retmap.put("transaction_id", result.getTransactionId());
- retmap.put("success", true);
- retmap.put("msg", "支付成功!");
- retmap.put("success_time", DateUtils.getDateTimeString(DateUtils.stringToDateTime(result.getSuccessTime())));
- //主动查询
- Wrapper wrapper = new EntityWrapper<WxOrderEntity>();
- wrapper.eq("out_trade_no", req.getOrderNo());
- WxOrderEntity wxOrderEntity = wxOrderDataService.selectOne(wrapper);
- if (wxOrderEntity != null) {
- if (wxOrderEntity.getPayStatus() != 1) {
- wxOrderEntity.setPayStatus(1);
- wxOrderEntity.setTransactionId(result.getTransactionId());
- wxOrderEntity.setPayDate(DateUtils.stringToDateTime(result.getSuccessTime()));
- wxOrderEntity.setPayTime(DateUtils.stringToDateTime(result.getSuccessTime()));
- wxOrderEntity.setUpdateTime(new Date());
- wxOrderDataService.updateById(wxOrderEntity);
- //同时处理支付记录
- Wrapper payWrapper = new EntityWrapper<WxPayLogEntity>();
- wrapper.eq("out_trade_no", req.getOrderNo());
- WxPayLogEntity wxPayLogEntity = wxPayLogDataService.selectOne(payWrapper);
- if (wxPayLogEntity == null) {
- wxPayLogEntity = new WxPayLogEntity();
- wxPayLogEntity.setCreateTime(new Date());
- wxPayLogEntity.setOutTradeNo(wxOrderEntity.getOutTradeNo());
- wxPayLogEntity.setPayStatus(1);
- wxPayLogEntity.setTotalFee(wxOrderEntity.getTotalFee());
- wxPayLogEntity.setTransactionId(result.getTransactionId());
- wxPayLogEntity.setWxOpenId(wxOrderEntity.getWxOpenId());
- wxPayLogDataService.insert(wxPayLogEntity);
- }
- }
- }
- } else {
- log.info("内部订单号【{}】,微信支付订单号【{}】支付未成功", result.getOutTradeNo(), result.getTransactionId());
- retmap.put("out_trade_no", result.getOutTradeNo());
- retmap.put("transaction_id", result.getTransactionId());
- retmap.put("success", false);
- retmap.put("msg", "支付失败!");
- retmap.put("success_time", null);
- }
- return R.ok().put("data", retmap);
- } catch (ServiceException e) {
- log.error("订单查询失败,返回码:{},返回信息:{}", e.getErrorCode(), e.getErrorMessage());
- return R.error("订单查询失败!");
- }
- }

- mport io.swagger.annotations.ApiModelProperty;
- import lombok.Data;
-
- /**
- * @author caozhen
- * @ClassName QueryOrderReq
- * @description: 支付查询
- * @date 2024年01月04日
- * @version: 1.0
- */
- @Data
- public class QueryOrderReq {
- @ApiModelProperty(name = "paymentNo", value = "微信支付订单号,同:transaction_id")
- private String paymentNo;
-
- @ApiModelProperty(name = "orderNo", value = "商户订单号,同:out_trade_no")
- private String orderNo;
- }

- /***
- * 根据支付订单号查询订单 paymentNo
- * @param req
- * @return
- */
- @Transactional
- public R queryOrderByPaymentNo(QueryOrderReq req) {
- QueryOrderByIdRequest queryRequest = new QueryOrderByIdRequest();
- queryRequest.setMchid(wxPayConfig.getMerchantId());
- queryRequest.setTransactionId(req.getPaymentNo());
- try {
- JsapiServiceExtension service =
- new JsapiServiceExtension.Builder()
- .config(rsaAutoCertificateConfig)
- .signType("RSA") // 不填默认为RSA
- .build();
- Transaction result = service.queryOrderById(queryRequest);
- LinkedHashMap map = new LinkedHashMap();
- //支付成功
- if (Transaction.TradeStateEnum.SUCCESS == result.getTradeState()) {
- log.info("内部订单号【{}】,微信支付订单号【{}】支付成功", result.getOutTradeNo(), result.getTransactionId());
- map.put("out_trade_no", result.getOutTradeNo());
- map.put("transaction_id", result.getTransactionId());
- map.put("success", true);
- map.put("msg", "支付成功!");
- map.put("success_time", DateUtils.getDateTimeString(DateUtils.stringToDateTime(result.getSuccessTime())));
- //主动查询
- Wrapper wrapper = new EntityWrapper<WxOrderEntity>();
- wrapper.eq("transaction_id", req.getPaymentNo());
- WxOrderEntity wxOrderEntity = wxOrderDataService.selectOne(wrapper);
- if (wxOrderEntity != null) {
- if (wxOrderEntity.getPayStatus() != 1) {
- wxOrderEntity.setPayStatus(1);
- wxOrderEntity.setPayDate(DateUtils.stringToDateTime(result.getSuccessTime()));
- wxOrderEntity.setPayTime(DateUtils.stringToDateTime(result.getSuccessTime()));
- wxOrderEntity.setUpdateTime(new Date());
- wxOrderDataService.updateById(wxOrderEntity);
- //同时处理支付记录
- Wrapper payWrapper = new EntityWrapper<WxPayLogEntity>();
- wrapper.eq("transaction_id", req.getPaymentNo());
- WxPayLogEntity wxPayLogEntity = wxPayLogDataService.selectOne(payWrapper);
- if (wxPayLogEntity == null) {
- wxPayLogEntity = new WxPayLogEntity();
- wxPayLogEntity.setCreateTime(new Date());
- wxPayLogEntity.setOutTradeNo(wxOrderEntity.getOutTradeNo());
- wxPayLogEntity.setPayStatus(1);
- wxPayLogEntity.setTotalFee(wxOrderEntity.getTotalFee());
- wxPayLogEntity.setTransactionId(result.getTransactionId());
- wxPayLogEntity.setWxOpenId(wxOrderEntity.getWxOpenId());
- wxPayLogDataService.insert(wxPayLogEntity);
- }
- }
- }
- } else {
- log.info("内部订单号【{}】,微信支付订单号【{}】支付未成功", result.getOutTradeNo(), result.getTransactionId());
- map.put("out_trade_no", result.getOutTradeNo());
- map.put("transaction_id", result.getTransactionId());
- map.put("success", false);
- map.put("msg", "支付失败!");
- map.put("success_time", null);
- }
- return R.ok().put("data", map);
- } catch (ServiceException e) {
- log.error("订单查询失败,返回码:{},返回信息:{}", e.getErrorCode(), e.getErrorMessage());
- return R.error("订单查询失败!");
- }
- }

- /***
- * 微信申请退款
- * @param outTradeNo 商户订单号
- * @param totalAmount
- * @return
- */
- public R createRefund(String outTradeNo, Long totalAmount) {
- //返回参数
- LinkedHashMap map = new LinkedHashMap();
- map.put("out_trade_no", outTradeNo);
- map.put("success", false);
- map.put("msg", "正在申请退款中!");
- String outRefundNo = "REFUND_" + outTradeNo;
- map.put("out_refund_no", outRefundNo);
- //申请退款订单,需要变更订单记录
- Wrapper wrapper = new EntityWrapper<WxOrderEntity>();
- wrapper.eq("out_trade_no", outTradeNo);
- WxOrderEntity wxOrderEntity = wxOrderDataService.selectOne(wrapper);
- if (wxOrderEntity == null) {
- return R.error("订单不存在,申请退款不存在!");
- }
- wxOrderEntity.setPayStatus(4);//退款中
- wxOrderEntity.setUpdateTime(new Date());
- wxOrderDataService.updateById(wxOrderEntity);
- try {
- // 构建退款service
- RefundService service = new RefundService.Builder()
- .config(rsaAutoCertificateConfig)
- .build();
- CreateRequest request = new CreateRequest();
- // 调用request.setXxx(val)设置所需参数,具体参数可见Request定义
- request.setOutTradeNo(outTradeNo);
- request.setOutRefundNo(outRefundNo);
-
- AmountReq amount = new AmountReq();
- amount.setTotal(totalAmount);
- amount.setRefund(totalAmount);
- amount.setCurrency("CNY");
-
- request.setAmount(amount);
- request.setNotifyUrl(wxPayConfig.getRefundNotifyUrl());
-
- //接收退款返回参数
- Refund refund = service.create(request);
- log.info("退款返回信息:{}", refund);
- if (refund.getStatus().equals(Status.SUCCESS)) {
- map.put("success", true);
- map.put("msg", "退款成功!");
- //说明退款成功,开始接下来的业务操作
- //主动查询
- Wrapper againWrapper = new EntityWrapper<WxOrderEntity>();
- againWrapper.eq("out_trade_no", outTradeNo);
- WxOrderEntity orderEntity = wxOrderDataService.selectOne(againWrapper);
- if (orderEntity != null) {
- orderEntity.setPayStatus(3);//退款成功
- orderEntity.setUpdateTime(new Date());
- wxOrderDataService.updateById(orderEntity);
- //同时处理退款记录
- Wrapper payWrapper = new EntityWrapper<WxPayLogEntity>();
- payWrapper.eq("out_trade_no", outTradeNo);
- payWrapper.eq("pay_status", 2);//退款
- WxPayLogEntity wxPayLogEntity = wxPayLogDataService.selectOne(payWrapper);
- if (wxPayLogEntity == null) {
- wxPayLogEntity = new WxPayLogEntity();
- wxPayLogEntity.setCreateTime(new Date());
- wxPayLogEntity.setOutTradeNo(outTradeNo);
- wxPayLogEntity.setPayStatus(2);
- wxPayLogEntity.setTotalFee(totalAmount.intValue());
- wxPayLogEntity.setTransactionId(wxOrderEntity.getTransactionId());
- wxPayLogEntity.setOutRefundNo(outRefundNo);
- wxPayLogEntity.setWxOpenId(wxOrderEntity.getWxOpenId());
- wxPayLogDataService.insert(wxPayLogEntity);
- }
- }
- }
- } catch (ServiceException e) {
- log.error("退款失败!,错误信息:{}", e.getMessage());
- return R.error("退款失败!");
- } catch (Exception e) {
- log.error("服务返回成功,返回体类型不合法,或者解析返回体失败,错误信息:{}", e.getMessage());
- return R.error("退款失败!");
- }
- return R.ok().put("data", map);
- }

待续......有需要的再联系我!
- SET NAMES utf8mb4;
- SET FOREIGN_KEY_CHECKS = 0;
-
- -- ----------------------------
- -- Table structure for t_wx_order
- -- ----------------------------
- DROP TABLE IF EXISTS `t_wx_order`;
- CREATE TABLE `t_wx_order` (
- `uuid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
- `trade_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '商品名称',
- `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '订单描述',
- `out_trade_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '(商户)订单流水号',
- `transaction_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '微信订单号',
- `total_fee` int(10) NULL DEFAULT NULL COMMENT '订单金额(单位:分)',
- `pay_nonce` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '支付成功后的随机32位字符串',
- `pay_time` datetime NULL DEFAULT NULL COMMENT '支付时间',
- `pay_date` date NULL DEFAULT NULL COMMENT '支付日期',
- `pay_status` int(3) NULL DEFAULT 0 COMMENT '0:待支付,1:支付成功,2:支付失败,3:退款成功,4:正在退款中,5:未知',
- `wx_open_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '微信小程序openid',
- `status` int(2) NULL DEFAULT 0 COMMENT '0:未删除,1:已删除',
- `create_time` datetime NULL DEFAULT NULL COMMENT '创建订单时间',
- `update_time` datetime NULL DEFAULT NULL COMMENT '修改订单时间',
- PRIMARY KEY (`uuid`) USING BTREE
- ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '微信商品订单表' ROW_FORMAT = Dynamic;
-
- -- ----------------------------
- -- Table structure for t_wx_pay_log
- -- ----------------------------
- DROP TABLE IF EXISTS `t_wx_pay_log`;
- CREATE TABLE `t_wx_pay_log` (
- `uuid` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
- `wx_open_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '微信用户openid',
- `out_trade_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '(商户)订单流水号',
- `out_refund_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '(商户)退款流水号',
- `transaction_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '微信订单号',
- `total_fee` int(10) NULL DEFAULT NULL COMMENT '支付金额',
- `pay_status` int(2) NULL DEFAULT NULL COMMENT '1:支付,2:退款',
- `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
- PRIMARY KEY (`uuid`) USING BTREE
- ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '微信用户支付记录表' ROW_FORMAT = Dynamic;
-
- SET FOREIGN_KEY_CHECKS = 1;

退款回调通知,和controller就不写了,如果需要,联系我即可!
哎呀呀呀,缺少了一个类,代码如下:
- import javax.servlet.ServletInputStream;
- import javax.servlet.http.HttpServletRequest;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- /**
- * @author caozhen
- * @ClassName HttpServletUtils
- * @description: TODO
- * @date 2024年01月04日
- * @version: 1.0
- */
- public class HttpServletUtils {
- /**
- * 获取请求体
- *
- * @param request
- * @return
- * @throws IOException
- */
- public static String getRequestBody(HttpServletRequest request) throws IOException {
- ServletInputStream stream = null;
- BufferedReader reader = null;
- StringBuffer sb = new StringBuffer();
- try {
- stream = request.getInputStream();
- // 获取响应
- reader = new BufferedReader(new InputStreamReader(stream));
- String line;
- while ((line = reader.readLine()) != null) {
- sb.append(line);
- }
- } catch (IOException e) {
- throw new IOException("读取返回支付接口数据流出现异常!");
- } finally {
- reader.close();
- }
- return sb.toString();
- }
- }

如果你在微信支付回调通知中出现 “签名错误”,并且你是windows服务器,请在HttpServletUtils 类中,将reader = new BufferedReader(new InputStreamReader(stream)); 替换成:reader = new BufferedReader(new InputStreamReader(stream,"UTF-8"));
替换完整代码:
- import javax.servlet.ServletInputStream;
- import javax.servlet.http.HttpServletRequest;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- /**
- * @author caozhen
- * @ClassName HttpServletUtils
- * @description: TODO
- * @date 2024年01月04日
- * @version: 1.0
- */
- public class HttpServletUtils {
- /**
- * 获取请求体
- *
- * @param request
- * @return
- * @throws IOException
- */
- public static String getRequestBody(HttpServletRequest request) throws IOException {
- ServletInputStream stream = null;
- BufferedReader reader = null;
- StringBuffer sb = new StringBuffer();
- try {
- stream = request.getInputStream();
- // 获取响应
- reader = new BufferedReader(new InputStreamReader(stream,"UTF-8"));
- String line;
- while ((line = reader.readLine()) != null) {
- sb.append(line);
- }
- } catch (IOException e) {
- throw new IOException("读取返回支付接口数据流出现异常!");
- } finally {
- reader.close();
- }
- return sb.toString();
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。