news 2026/5/14 10:01:38

微信支付 微信转账 微信退款 订单流程链路指南文档

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
微信支付 微信转账 微信退款 订单流程链路指南文档

1.官网文档地址

https://pay.weixin.qq.com/doc/v3/merchant/4012791856

2.支付产品

JSAPI支付:提供商户在微信客户端内部浏览器网页中使用和小程序使用

APP支付:提供商户在自己的APP中使用

H5支付:提供商户在手机浏览器网页(非微信客户端内部浏览器)中使用

Native支付:提供商户在PC端网页浏览器中使用

小程序支付:后端调用接口和JSAPI共用,前端使用方式不同

付款码支付:超市收银出示付款码场景

合单支付:提供将多个商户的订单合并为一个订单进行支付的能力

刷脸支付

医保支付

3.时序图

例:预支付到支付成功回调 全过程。

例:退款申请 回调全流程

例:提现转账 全流程

4.具体使用

依赖:

<dependency> <groupId>com.github.wechatpay-apiv3</groupId> <artifactId>wechatpay-java</artifactId> <version>${wechatpay-java.version}</version> </dependency>
wx-pay: #回调使用 - 异步回调地址 notifyURI: https://yyjkb-*****xue.net/mrjkapi/ #商户密钥文件 keyPath: /wx/ap****nt_key.pem #微信应用ID #小程序/公众号 在微信公众平台获取 #App在:微信开发平台获取 openAppId: wxb32****71c5d #商户号 mchId: wxb3*****c5d #商户Api公钥证书序列号 SerialNo: 2B0DA37*******************2025C #回调使用 - 对称密钥 用来解密回调通知里的敏感数据 apiV3Key: oX2sS5E************D6dP
package net.quankeyixue.config; import com.wechat.pay.java.core.RSAAutoCertificateConfig; import com.wechat.pay.java.service.payments.app.AppService; import com.wechat.pay.java.service.payments.app.AppServiceExtension; import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension; public class WeChatConstants { //回调域名 public static final String NOTIFY_DOMAIN; //开放appid public static final String OPEN_APP_ID; //商户号 public static final String MCH_ID; public static final String WX_PAY_NOTIFY; public static final String WECHAT_PAY_KEY_PATH; public static final String SERIAL_NO; public static final String API_V3_KEY; public static final String WX_REFUND_NOTIFY; public static final RSAAutoCertificateConfig rsaConfig; public static final JsapiServiceExtension jsapiService; public static final AppServiceExtension appServiceExtension; public static final AppService appService; public static final String TRANSFER_NOTIFY_URL; static { OPEN_APP_ID = YamlConfigurerUtil.getStrYmlVal("wx-pay.openAppId"); MCH_ID = YamlConfigurerUtil.getStrYmlVal("wx-pay.mchId"); NOTIFY_DOMAIN = YamlConfigurerUtil.getStrYmlVal("wx-pay.notifyURI"); WECHAT_PAY_KEY_PATH = YamlConfigurerUtil.getStrYmlVal("wx-pay.keyPath"); SERIAL_NO = YamlConfigurerUtil.getStrYmlVal("wx-pay.serialNo"); API_V3_KEY = YamlConfigurerUtil.getStrYmlVal("wx-pay.apiV3Key"); WX_PAY_NOTIFY = NOTIFY_DOMAIN + "/api/v2/wxPay/notify"; WX_REFUND_NOTIFY = NOTIFY_DOMAIN + "/api/v2/wxRefund/notify"; TRANSFER_NOTIFY_URL = NOTIFY_DOMAIN + "/api/wxTransfer/notify"; rsaConfig = new RSAAutoCertificateConfig.Builder() .merchantId(MCH_ID) .privateKeyFromPath(WECHAT_PAY_KEY_PATH) .merchantSerialNumber(SERIAL_NO) .apiV3Key(API_V3_KEY) .build(); jsapiService = new JsapiServiceExtension.Builder().config(rsaConfig).build(); appServiceExtension = new AppServiceExtension.Builder().config(rsaConfig).build(); appService = new AppService.Builder().config(WeChatConstants.rsaConfig).build(); } }

例:以JSAPI 预支付 和 微信JSAPI 回调为例

package net.quankeyixue.controller; import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse; import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import net.quankeyixue.domain.response.BillResponse; import net.quankeyixue.domain.response.CallbackResponse; import net.quankeyixue.domain.response.CloseOrderResponse; import net.quankeyixue.domain.response.OrderQueryResponse; import net.quankeyixue.domain.response.PayResponse; import net.quankeyixue.domain.response.RefundQueryResponse; import net.quankeyixue.domain.response.RefundResponse; import net.quankeyixue.service.WechatPayService; import org.springframework.web.bind.annotation.*; /** * 微信支付控制器 * @author qinyu * @since 2026/4/28 10:55 */ @RestController @RequestMapping("/wechat_pay") public class WechatPayController { private final WechatPayService wechatPayService; public WechatPayController(WechatPayService wechatPayService) { this.wechatPayService = wechatPayService; } /** * JSAPI支付下单 */ @PostMapping("/jsapi_pay") public com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse jsapiPay() { return wechatPayService.jsapiPay(); } @PostMapping("/jsapi/callback") public void jsapiPayCallback(HttpServletRequest request, HttpServletResponse response) { wechatPayService.JsapiPayCallback(request,response); } }
package net.quankeyixue.service; import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import net.quankeyixue.domain.response.BillResponse; import net.quankeyixue.domain.response.CallbackResponse; import net.quankeyixue.domain.response.CloseOrderResponse; import net.quankeyixue.domain.response.OrderQueryResponse; import net.quankeyixue.domain.response.PayResponse; import net.quankeyixue.domain.response.RefundQueryResponse; import net.quankeyixue.domain.response.RefundResponse; /** * 微信支付服务接口 * @author qinyu * @since 2026/4/28 10:56 */ public interface WechatPayService { /** * JSAPI支付下单 */ com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse jsapiPay(); void JsapiPayCallback(HttpServletRequest request, HttpServletResponse response); }
package net.quankeyixue.service.impl; import com.alibaba.fastjson.JSON; import com.wechat.pay.java.core.http.Constant; import com.wechat.pay.java.core.notification.NotificationParser; import com.wechat.pay.java.core.notification.RequestParam; import com.wechat.pay.java.service.partnerpayments.app.model.Transaction; import com.wechat.pay.java.service.payments.app.AppService; import com.wechat.pay.java.service.payments.app.AppServiceExtension; import com.wechat.pay.java.service.payments.h5.H5Service; import com.wechat.pay.java.service.payments.h5.model.H5Info; import com.wechat.pay.java.service.payments.h5.model.SceneInfo; import com.wechat.pay.java.service.payments.h5.model.StoreInfo; import com.wechat.pay.java.service.payments.jsapi.JsapiService; import com.wechat.pay.java.service.payments.jsapi.model.CloseOrderRequest; import com.wechat.pay.java.service.payments.jsapi.model.Payer; import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse; import com.wechat.pay.java.service.payments.nativepay.model.Amount; import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest; import com.wechat.pay.java.service.payments.nativepay.NativePayService; import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import net.quankeyixue.config.WeChatConstants; import net.quankeyixue.domain.response.*; import net.quankeyixue.service.WechatPayService; import org.springframework.stereotype.Service; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.UUID; /** * 微信支付服务实现类 * @author qinyu * @since 2026/4/28 10:56 */ @Service @Slf4j public class WechatPayServiceImpl implements WechatPayService { @Override public com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse jsapiPay() { String spuName = "大容量水杯"; String orderNo = "dasdv236724"+"prepayLog本地表ID"; JsapiService build = new JsapiService.Builder().config(WeChatConstants.rsaConfig).build(); com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest prepayRequest = new com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest(); prepayRequest.setAppid(WeChatConstants.OPEN_APP_ID); prepayRequest.setMchid(WeChatConstants.MCH_ID); prepayRequest.setDescription("描述"); prepayRequest.setOutTradeNo(orderNo); prepayRequest.setTimeExpire("2026-06-08T10:34:56+08:00"); prepayRequest.setNotifyUrl("/wechat_pay/jsapi/callback"); com.wechat.pay.java.service.payments.jsapi.model.Amount amount = new com.wechat.pay.java.service.payments.jsapi.model.Amount(); amount.setTotal(100); amount.setCurrency("CNY"); prepayRequest.setAmount(amount); Payer payer = new Payer(); //每个端 内的唯一微信标识 payer.setOpenid("oKEA36xoFqOo89KlHHBkMPbF5t_4"); prepayRequest.setPayer(payer); com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse prepay = build.prepay(prepayRequest); PayResponse payResponse = new PayResponse(); payResponse.setAppId(WeChatConstants.OPEN_APP_ID); //当前时间 秒级时间 String timeStamp = String.valueOf(System.currentTimeMillis() / 1000); payResponse.setTimeStamp(timeStamp); String nonceStr = UUID.randomUUID().toString().replace("-", ""); payResponse.setNonceStr(nonceStr); String packageStr = "prepay_id=wx21201855730335ac86f8c43d1889123400"; payResponse.setPackageStr(packageStr); //签名算法 payResponse.setSignType("RSA"); //防篡改核心签名 PrepayWithRequestPaymentResponse prepayWithRequestPaymentResponse = WeChatConstants.jsapiService.prepayWithRequestPayment(prepayRequest); return prepayWithRequestPaymentResponse; } @Override public void JsapiPayCallback(HttpServletRequest request, HttpServletResponse response) { BufferedReader bufferedReader = null; // 先声明 try { // 1. 读取请求体 StringBuilder stringBuffer = new StringBuilder(); bufferedReader = new BufferedReader(new InputStreamReader(request.getInputStream())); String s; while ((s = bufferedReader.readLine()) != null) { stringBuffer.append(s); } // 2. 验签 + 解密 NotificationParser parser = new NotificationParser(WeChatConstants.rsaConfig); RequestParam requestParam = new RequestParam.Builder() .serialNumber(request.getHeader(Constant.WECHAT_PAY_SERIAL)) .nonce(request.getHeader(Constant.WECHAT_PAY_NONCE)) .signature(request.getHeader(Constant.WECHAT_PAY_SIGNATURE)) .timestamp(request.getHeader(Constant.WECHAT_PAY_TIMESTAMP)) .signType(request.getHeader("Wechatpay-Signature-Type")) .body(stringBuffer.toString()) .build(); Transaction parse = parser.parse(requestParam, Transaction.class); // ============== 微信规则:5秒内必须先返回! ============== response.setStatus(200); // 返回200 // ======================================================= // 3. 不是成功直接结束 if (!parse.getTradeState().equals(Transaction.TradeStateEnum.SUCCESS)) { log.error("微信支付回调失败:{}", JSON.toJSONString(parse)); return; } // 4. 解析参数 AttachDTO attachDTO = JSON.parseObject(parse.getAttach(), AttachDTO.class); String[] orderNoArr = parse.getOutTradeNo().split("_"); //交易号 String outTradeNo = parse.getOutTradeNo(); //交易状态 Transaction.TradeStateEnum tradeState = parse.getTradeState(); //使用解析出来的数据进行 // 1.订单状态变更 // 2.修改预支付记录表 // 3.对商品进行扣减库存,增加销量等 } catch (Exception e) { log.error("微信回调处理失败", e); // 异常返回失败 response.setStatus(500); } finally { // ===================== 关闭流 ===================== try { if (bufferedReader != null) { bufferedReader.close(); } } catch (Exception e) { log.error("关闭流失败", e); } // ================================================= } } }

5.可参考的表结构

表格

序号表名操作业务时机
1yy_orderINSERT / UPDATE创建订单、支付成功、订单取消
2yy_order_itemINSERT / UPDATE创建订单、虚拟商品发货
3yy_sub_orderINSERT下单创建
4yy_skuUPDATE扣库存 (下单)、回滚 (取消)、加销量 (支付)
5yy_prepay_logINSERT / UPDATE发起预支付、支付完成
6yy_member_points_detailUPDATE冻结、解冻、积分抵扣确认
7yy_order_feeINSERT支付成功生成分佣
8yy_activity_memberINSERT活动商品下单报名
9yy_order_status_recordsINSERT所有订单状态变更留痕
10yy_member_order_statsUPDATE用户订单数据统计

历史项目:核心接口清单

表格

接口地址请求入参响应出参
/jsapi/prepayPayRequestParamPrePayVO
/jsapi/rePrepay/{orderNo}orderNo (路径参数)PrePayVO
/notify微信原生回调 XML 报文固定返回200

历史项目:关键对应关系(你提供的接口 → 流程图步骤)

表格

你的接口方法对应流程图步骤业务说明
jsapiService.prepayWithRequestPayment()步骤③、⑲首次 / 重新支付:调用微信统一下单
appService.prepay()补充步骤APP 支付统一下单(同 JSAPI 官方地址)
jsapiService.closeOrder()步骤⑭、⑯主动 / 超时取消:调用微信关闭订单
POST /api/v2/wxPay/notify步骤⑪微信支付结果异步回调

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/14 10:01:00

5分钟高效激活:KMS_VL_ALL_AIO智能激活脚本完全指南

5分钟高效激活&#xff1a;KMS_VL_ALL_AIO智能激活脚本完全指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为Windows系统激活和Office授权而烦恼吗&#xff1f;每次重装系统后&#xf…

作者头像 李华
网站建设 2026/5/14 9:55:06

TVA 与传统工业视觉:技术内核与应用分野(6)

重磅预告&#xff1a;本专栏将独家连载新书《AI视觉技术&#xff1a;从入门到进阶》精华内容。本书是《AI视觉技术&#xff1a;从进阶到专家》的权威前导篇&#xff0c;特邀美国 TypeOne 公司首席科学家、斯坦福大学博士 Bohan 担任技术顾问。Bohan先生师从美国三院院士、“AI教…

作者头像 李华
网站建设 2026/5/14 9:55:06

汽车功率半导体市场现状与复苏路径分析

1. 行业现状&#xff1a;汽车电子为何“挂空挡”&#xff1f;最近和几个在车厂和Tier 1供应商的朋友聊天&#xff0c;大家普遍的感觉就是一个字&#xff1a;等。等订单恢复&#xff0c;等产线重启&#xff0c;等市场回暖。这种感觉&#xff0c;和EE Times那篇报道里描述的“Stu…

作者头像 李华
网站建设 2026/5/14 9:51:04

三款Java开发工具对比:IDEA、VS Code、Eclipse

1. IntelliJ IDEA核心定位Java生态的旗舰级IDE&#xff0c;分为免费社区版和付费旗舰版&#xff0c;是目前国内Java开发者的首选工具。核心优势- 智能体验拉满&#xff1a;代码补全、重构、静态分析能力极强&#xff0c;对Spring、Maven等生态的支持开箱即用- 调试体验优秀&…

作者头像 李华
网站建设 2026/5/14 9:50:51

第239章 黄昏对话(墨子与AI)

弦光纪元六十二年冬,墨子的生命已经进入最后的倒计时。一百二十七岁高龄的他,身体机能正以不可逆转的速度衰退,但意识却异常清醒。在这个飘着细雪的黄昏,他通过神经接口发出了一个特殊请求——与"弦光云脑"进行最后一次深度对话。这个由他参与设计、见证了整个文…

作者头像 李华