微信V3版本支付下单、查询支付订单状态、订单退款接入正式项目中并引入策略模式实操
开篇介绍:
一、策略模式(Strategy Pattern)的概念
二、应用场景举例
三、角色
四、服务端OR客户端生成支付等二维码优缺点分析
五、 多渠道支付对接-策略模式+简单工厂模式编码实操
六、查询支付订单状态
七、再看下订单退款实操
开篇介绍:
本文介绍微信支付中的Native支付方式,版本是APIv3,其中Native和JSAPI的区别如下
Native支付:商家在系统中按微信支付协议生成支付二维码,用户扫码拉起微信收银台,确认并完成付款
JSAPI支付:商家张贴收款码物料,用户打开扫一扫,扫码后输入金额,完成付款
以下内容增加了支付接口调和策略模式的使用,支付的VO类,大家可以参照自己公司的VO字段,需要改动支付的部分业务参数即可。
注意:微信支付个人无法对接操作,需要有公司商户账号,一般开发过程中是产品经理或者相关负责人提供。
我们来看下支付成功和退款成功的截图,看完本博文后,你将学会在实际项目中完成微信支付。
首先我们将先复习下策略模式,前面4步骤都是策略模式,后面几步骤是代码实操,不要急,一步步来。
一、策略模式(Strategy Pattern)的概念
定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换
比如说淘宝天猫双十一,正在搞活动有打折的、有满减的、有返利的等等,这些算法只是一种策略,并且是随时都可能互相替换的, 我们就可以定义一组算法,将每个算法都封装起来,并且使它们之间可以互换
二、应用场景举例
。老王计划外出旅游,选择骑自行车、坐汽车、飞机等,每一种旅行方式都是一个策略
。 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么可以使用策略模式
。 不希望暴露复杂的、与算法有关的数据结构,那么可以使用策略模式来封装算法
。对接第三方支付里面,微信支付、支付宝支付等都可以是一种策略
三、角色
Context上下文:屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化(相当于中介)
Strategy策略角色:抽象策略角色,是对策略、算法家族的抽象,定义每个策略或算法必须具有的方法和属性
ConcreteStrategy具体策略角色:用于实现抽象策略中的操作,即实现具体的算法
四、服务端OR客户端生成支付等二维码优缺点分析
服务端生成二维码
优点:
引入二维码jar包统一生成
图片生成兼容性好,传输相对安全不易被篡改
缺点:
占据服务端CPU内存/资源、消耗传输带宽,性能较差
没法一并返回其他参数,定制化相对弱
客户端生成二维码(建议使用)
优点
在客户端生成二维码会降低服务器的运算与存储压力
选择框架要考虑兼容性,客户端根据js框架生成二维码
后端返回 二维码文本值,还可以携带其他参数(比如订单号,可以轮训支付状态)
缺点
客户端需要引入二维码生成js插件
需要考虑浏览器兼容性
五、 多渠道支付对接-策略模式+简单工厂模式编码实操
策略模式代码骨架分为以下几种:
策略接口开发 PayStrategy
策略上下文 PayStrategyContext开发
具体支付策略开发 AlipayStrategy、WechatPayStrategy
简单工厂类开发;
首先第一步我们从impl调用层开始倒推:
//这个是在实际service实现类中的调用,下面这段代码被controller层调用,//然后返回给前端,前端根据返回的code_url展示二维码信息@Autowiredprivate PayFactory payFactory;//调用支付信息String codeUrl = payFactory.pay(payInfoVO);if(StringUtils.isNotBlank(codeUrl)){Map<String,String> resultMap = new HashMap<>(2);resultMap.put("code_url",codeUrl);resultMap.put("out_trade_no",payInfoVO.getOutTradeNo());return JsonData.buildSuccess(resultMap);}
第二步再来看下PayFactory支付工厂类,里面的支付 做了什么:
package net.wnn.component;import lombok.extern.slf4j.Slf4j;
import net.wnn.enums.ProductOrderPayTypeEnum;
import net.wnn.vo.PayInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
@Slf4j
public class PayFactory {@Autowiredprivate AliPayStrategy aliPayStrategy;@Autowiredprivate WechatPayStrategy wechatPayStrategy;/*** 创建支付,简单工厂模式* @param payInfoVO* @return*/public String pay(PayInfoVO payInfoVO){String payType = payInfoVO.getPayType();if (ProductOrderPayTypeEnum.ALI_PAY.name().equals(payType)) {//支付宝支付PayStrategyContext payStrategyContext = new PayStrategyContext(aliPayStrategy);return payStrategyContext.executeUnifiedOrder(payInfoVO);} else if(ProductOrderPayTypeEnum.WECHAT_PAY.name().equals(payType)){//微信支付PayStrategyContext payStrategyContext = new PayStrategyContext(wechatPayStrategy);return payStrategyContext.executeUnifiedOrder(payInfoVO);}return "";}/*** 关闭订单* @param payInfoVO* @return*/public String closeOrder(PayInfoVO payInfoVO){String payType = payInfoVO.getPayType();if (ProductOrderPayTypeEnum.ALI_PAY.name().equals(payType)) {//支付宝支付PayStrategyContext payStrategyContext = new PayStrategyContext(aliPayStrategy);return payStrategyContext.executeCloseOrder(payInfoVO);} else if(ProductOrderPayTypeEnum.WECHAT_PAY.name().equals(payType)){//微信支付PayStrategyContext payStrategyContext = new PayStrategyContext(wechatPayStrategy);return payStrategyContext.executeCloseOrder(payInfoVO);}return "";}/*** 查询支付状态* @param payInfoVO* @return*/public String queryPayStatus(PayInfoVO payInfoVO){String payType = payInfoVO.getPayType();if (ProductOrderPayTypeEnum.ALI_PAY.name().equals(payType)) {//支付宝支付PayStrategyContext payStrategyContext = new PayStrategyContext(aliPayStrategy);return payStrategyContext.executeQueryPayStatus(payInfoVO);} else if(ProductOrderPayTypeEnum.WECHAT_PAY.name().equals(payType)){//微信支付PayStrategyContext payStrategyContext = new PayStrategyContext(wechatPayStrategy);return payStrategyContext.executeQueryPayStatus(payInfoVO);}return "";}/*** 退款接口* @param payInfoVO* @return*/public String refund(PayInfoVO payInfoVO){String payType = payInfoVO.getPayType();if (ProductOrderPayTypeEnum.ALI_PAY.name().equals(payType)) {//支付宝支付PayStrategyContext payStrategyContext = new PayStrategyContext(aliPayStrategy);return payStrategyContext.executeRefund(payInfoVO);} else if(ProductOrderPayTypeEnum.WECHAT_PAY.name().equals(payType)){//微信支付PayStrategyContext payStrategyContext = new PayStrategyContext(wechatPayStrategy);return payStrategyContext.executeRefund(payInfoVO);}return "";}}
由上面代码可见,支付的工厂是用来根据支付方式调用具体的实现方法 。
第三步,这一步我们来看一下PayStrategyContext支付上下文是什么东西:
package net.wnn.component;import net.wnn.vo.PayInfoVO;public class PayStrategyContext {private PayStrategy payStrategy;public PayStrategyContext(PayStrategy payStrategy){this.payStrategy = payStrategy;}/*** 根据策略对象,执行不同的下单接口* @return*/public String executeUnifiedOrder(PayInfoVO payInfoVO){return payStrategy.unifiedOrder(payInfoVO);}/*** 根据策略对象,执行不同的退款接口* @return*/public String executeRefund(PayInfoVO payInfoVO){return payStrategy.refund(payInfoVO);}/*** 根据策略对象,执行不同的关闭接口* @return*/public String executeCloseOrder(PayInfoVO payInfoVO){return payStrategy.closeOrder(payInfoVO);}/*** 根据策略对象,执行不同的查询订单状态接口* @return*/public String executeQueryPayStatus(PayInfoVO payInfoVO){return payStrategy.queryPayStatus(payInfoVO);}}
标准对Context上下文的解释就是:屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。通俗点说这就是个中介,根据传入的参数去调相应的实现接口,自己就干个调用
第四步、再看看PayStrategy
package net.wnn.component;import net.wnn.vo.PayInfoVO;public interface PayStrategy {/*** 统一下单接口* @param payInfoVO* @return*/String unifiedOrder(PayInfoVO payInfoVO);/*** 退款接口* @param payInfoVO* @return*/default String refund(PayInfoVO payInfoVO){ return ""; }/*** 查询支付状态* @param payInfoVO* @return*/default String queryPayStatus(PayInfoVO payInfoVO){ return ""; }/*** 关闭订单* @param payInfoVO* @return*/default String closeOrder(PayInfoVO payInfoVO){ return ""; }}
Strategy策略角色:抽象策略角色,是对策略、算法家族的抽象,定义每个策略或算法必须具有的方法和属性
第五步、再看看AliPayStrategy,这只是代码骨架,表明策略模式的实现方式,本文重点说的是微信支付,在第六步有
package net.wnn.component;import lombok.extern.slf4j.Slf4j;
import net.wnn.vo.PayInfoVO;
import org.springframework.stereotype.Service;@Service
@Slf4j
public class AliPayStrategy implements PayStrategy{@Overridepublic String unifiedOrder(PayInfoVO payInfoVO) {return null;}@Overridepublic String refund(PayInfoVO payInfoVO) {return null;}@Overridepublic String queryPayStatus(PayInfoVO payInfoVO) {return null;}@Overridepublic String closeOrder(PayInfoVO payInfoVO) {return null;}
}
ConcreteStrategy就是策略模式中的具体策略角色:用于实现抽象策略中的操作,即实现具体的算法
第六步、本文用的是微信支付,那就再看下WechatPayStrategy 下单的代码逻辑
package net.wnn.component;import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import net.wnn.config.WechatPayApi;
import net.wnn.config.WechatPayConfig;
import net.wnn.vo.PayInfoVO;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;@Service
@Slf4j
public class WechatPayStrategy implements PayStrategy{@Autowiredprivate WechatPayConfig payConfig;@Autowiredprivate CloseableHttpClient wechatPayClient;/*** 统一下单接口* @param payInfoVO* @return*/@Overridepublic String unifiedOrder(PayInfoVO payInfoVO) {//过期时间 RFC 3339格式SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");//支付订单过期时间String timeExpire = sdf.format(new Date(System.currentTimeMillis() + payInfoVO.getOrderPayTimeoutMills()));JSONObject amountObj = new JSONObject();//数据库存储是double比如,100.99元,微信支付需要以分为单位int amount = payInfoVO.getPayFee().multiply(BigDecimal.valueOf(60)).intValue();amountObj.put("total", amount);amountObj.put("currency", "CNY");JSONObject payObj = new JSONObject();payObj.put("mchid", payConfig.getMchId());payObj.put("out_trade_no", payInfoVO.getOutTradeNo());payObj.put("appid", payConfig.getWxPayAppid());payObj.put("description", "王姑娘之微信支付增加策略模式后的下单验证");payObj.put("notify_url", payConfig.getCallbackUrl());payObj.put("time_expire", timeExpire);payObj.put("amount", amountObj);//回调携带payObj.put("attach", "{\"accountNo\":" + payInfoVO.getAccountNo() + "}");// 处理请求body参数String body = payObj.toJSONString();log.debug("请求参数:{}",body);StringEntity entity = new StringEntity(body,"utf-8");entity.setContentType("application/json");HttpPost httpPost = new HttpPost(WechatPayApi.NATIVE_ORDER);httpPost.setHeader("Accept","application/json");httpPost.setEntity(entity);String result = "";try(CloseableHttpResponse response = wechatPayClient.execute(httpPost)){//响应码int statusCode = response.getStatusLine().getStatusCode();//响应体String responseStr = EntityUtils.toString(response.getEntity());log.debug("下单响应码:{},响应体:{}",statusCode,responseStr);if(statusCode == HttpStatus.OK.value()){JSONObject jsonObject = JSONObject.parseObject(responseStr);if(jsonObject.containsKey("code_url")){result = jsonObject.getString("code_url");}}else {log.error("下单响应失败:{},响应体:{}",statusCode,responseStr);}}catch (Exception e){log.error("微信支付响应异常:{}",e);}return result;}
}
第七步、下单验证截图
postman请求:
根据code_url生成的二维码,用微信客户端进行扫码支付:
下单支付接口调用的一些参数:
请求参数:{"time_expire":"2022-03-02T21:29:14+08:00","amount":{"total":60,"currency":"CNY"},"mchid":"1601xxxx","out_trade_no":"yb6gMTsnzyxxxxl4","appid":"wx5beac1xxxxc","description":"王姑娘之微信支付增加策略模式后的下单验证","attach":"{\"accountNo\":693232xxxx}","notify_url":"http://api.xxxx/shop-server/api/callback/order/v1/wechat"}
下单响应码:200,响应体:{"code_url":"weixin://wxpay/bizpayurl?pr=8L2yqCSzz"}
支付截图:
支付成功截图:
看到这你肯定有疑惑了,支付的那些参数等都是从哪来,怎么加载的?由于文章篇幅有限,基础的微信支付信息,写在了下面这篇博客中,可以直接点击查看,里面详细的介绍了微信支付的准备参数:
一文带你学会微信V3版本下单支付、退款、关单流程代码实操_8年开发工作经验的老王,积极分享工作中遇到的问题~-CSDN博客_wechatpay-apache-httpclient
六、查询支付订单状态
第一步实现类的调用:
@Overridepublic String queryProductOrderState(String outTradeNo) {PayInfoVO payInfoVO = PayInfoVO.builder().outTradeNo(outTradeNo).payType("WECHAT_PAY").build();String result = payFactory.queryPayStatus(payInfoVO);return result;}
第二步:
PayFactory的queryPayStatus方法,在上面下单的工厂类都有,这里不再赘述 PayStrategyContext的executeQueryPayStatus方法,上面也有,这里不再赘述
第三步:支付订单查询的具体操作代码
package net.wnn.component;import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import net.wnn.config.WechatPayApi;
import net.wnn.config.WechatPayConfig;import net.wnn.vo.PayInfoVO;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;@Service
@Slf4j
public class WechatPayStrategy implements PayStrategy{@Autowiredprivate WechatPayConfig payConfig;@Autowiredprivate CloseableHttpClient wechatPayClient;/*** 微信支付查询订单状态* @param payInfoVO* @return*/@Overridepublic String queryPayStatus(PayInfoVO payInfoVO) {String outTradeNo = payInfoVO.getOutTradeNo();String url = String.format(WechatPayApi.NATIVE_QUERY,outTradeNo,payConfig.getMchId());HttpGet httpGet = new HttpGet(url);httpGet.setHeader("Accept","application/json");String result = "";try(CloseableHttpResponse response = wechatPayClient.execute(httpGet)){//响应码int statusCode = response.getStatusLine().getStatusCode();//响应体String responseStr = EntityUtils.toString(response.getEntity());log.info("查询响应码:{},响应体:{}",statusCode,responseStr);if(statusCode == HttpStatus.OK.value()){JSONObject jsonObject = JSONObject.parseObject(responseStr);if(jsonObject.containsKey("trade_state")){result = jsonObject.getString("trade_state");}}else {log.error("查询支付状态响应失败:{},响应体:{}",statusCode,responseStr);}}catch (Exception e){log.error("微信支付响应异常:{}",e);}return result;}}
第四步 postman请求查询接口接口 传参 支付订单ID
查询返回结果: 订单支付成功
查询响应码:200,响应体:{"amount":{"currency":"CNY","payer_currency":"CNY","payer_total":60,"total":60},"appid":"wx5xxxc","attach":"{\"accountNo\":693232391484866560}","bank_type":"OTHERS","mchid":"16016xxxx",
"out_trade_no":"yb6gMTsnzyNrjb5iDa4Oxxx","payer":{"openid":"oiNKG04xxx"},"promotion_detail":[],"success_time":"2022-03-02T20:59:36+08:00","trade_state":"SUCCESS","trade_state_desc":"支付成功","trade_type":"NATIVE","transaction_id":"4200001363202203029043441628"}
七、再看下订单退款实操
第一步实现类的调用:
@Overridepublic String executeRefund(String outTradeNo) {PayInfoVO payInfoVO = PayInfoVO.builder().outTradeNo(outTradeNo).payType("WECHAT_PAY").build();String result = payFactory.refund(payInfoVO);return result;}
第二步:
PayFactory的refund方法,在上面下单的工厂类都有,这里不再赘述
PayStrategyContext的executeRefund方法,上面也有,这里不再赘述
第三步:支付订单退款的具体操作代码
package net.wnn.component;import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import net.wnn.config.WechatPayApi;
import net.wnn.config.WechatPayConfig;
import net.wnn.util.CommonUtil;
import net.wnn.vo.PayInfoVO;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;@Service
@Slf4j
public class WechatPayStrategy implements PayStrategy{@Autowiredprivate WechatPayConfig payConfig;@Autowiredprivate CloseableHttpClient wechatPayClient;@Overridepublic String refund(PayInfoVO payInfoVO) {String outTradeNo = "yb6gMTsnzyNrjb5iDa4OYFwiRc5nh7l4";String refundNo = CommonUtil.getStringNumRandom(32);// 请求body参数JSONObject refundObj = new JSONObject();//订单号refundObj.put("out_trade_no", outTradeNo);//退款单编号,商户系统内部的退款单号,商户系统内部唯一,// 只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔refundObj.put("out_refund_no", refundNo);refundObj.put("reason","商品已售完需要退款");refundObj.put("notify_url", payConfig.getCallbackUrl());JSONObject amountObj = new JSONObject();//退款金额amountObj.put("refund", 60);//实际支付的总金额amountObj.put("total", 60);amountObj.put("currency", "CNY");refundObj.put("amount", amountObj);String body = refundObj.toJSONString();log.info("请求参数:{}",body);StringEntity entity = new StringEntity(body,"utf-8");entity.setContentType("application/json");HttpPost httpPost = new HttpPost(WechatPayApi.NATIVE_REFUND_ORDER);httpPost.setHeader("Accept","application/json");httpPost.setEntity(entity);try(CloseableHttpResponse response = wechatPayClient.execute(httpPost)){//响应码int statusCode = response.getStatusLine().getStatusCode();//响应体String responseStr = EntityUtils.toString(response.getEntity());log.info("申请订单退款响应码:{},响应体:{}",statusCode,responseStr);}catch (Exception e){e.printStackTrace();}return "退款成功";}}
退款成功图片:
退款日志消息:
请求参数:{"reason":"商品已售完需要退款","amount":{"total":60,"currency":"CNY","refund":60},"out_trade_no":"yb6gMTsnzyNrjb5iDa4xxx","out_refund_no":"RbpQWZntjoxxxx","notify_url":"http://api.oxxxx/shop-server//wechat"}
申请订单退款响应码:200,响应体:{"amount":{"currency":"CNY","discount_refund":0,"from":[],"payer_refund":60,"payer_total":60,"refund":60,"settlement_refund":60,"settlement_total":60,"total":60},"channel":"ORIGINAL","create_time":"2022-03-02T21:25:00+08:00","funds_account":"AVAILABLE","out_refund_no":"RbpQWZntjoxxxxq","out_trade_no":"yb6gMTsnzyNrjb5iDa4xxxx","promotion_detail":[],"refund_id":"50300400982022xxxx","status":"PROCESSING","transaction_id":"420000136320xxx","user_received_account":"支付用户零钱"}
到这微信Native支付方式的下单、查询、退款操作就整合进实际开发项目中啦,大家引用到自己项里面的时候,只需要改动支付的部分业务参数即可。
基础参数不知道从哪来,证书不知道怎么加载的,看下下面这篇博客,跟本博客代码内容是上下两集:
一文带你学会微信V3版本下单支付、退款、关单流程代码实操_8年开发工作经验的老王,积极分享工作中遇到的问题~-CSDN博客_wechatpay-apache-httpclient本文介绍微信支付中的Native支付方式,版本是APIv3,其中Native和JSAPI的区别如下Native支付:商家在系统中按微信支付协议生成支付二维码,用户扫码拉起微信收银台,确认并完成付款JSAPI支付:商家张贴收款码物料,用户打开扫一扫,扫码后输入金额,完成付款以下博文没有掺杂过多业务逻辑,对象数据都是固定写的,方便将注意力集中在微信支付的接口使用上。正式对接到项目里面,只需要改动支付的部分业务参数即可。微信支付的文档还是很详细的,建议多看几遍,以下博文也都是根据官方文档的描述来操https://blog.csdn.net/wnn654321/article/details/122933324
微信支付回调验签流程
微信支付V3版本回调+验签流程_8年开发工作经验的老王,积极分享工作中遇到的问题~-CSDN博客回调验签流程介绍 官方文档 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_5.shtml https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml注意: 同样的通知可能会多次发送给商户系统,商户系统必须能够正确处理重复的通知 确保回调URL是外部可正常访问的,且不能携带后缀参数https://blog.csdn.net/wnn654321/article/details/123298162
微信V3版本支付下单、查询支付订单状态、订单退款接入正式项目中并引入策略模式实操相关推荐
- 一文带你学会微信V3版本下单支付、退款、关单流程代码实操
目录 开篇介绍 一.微信支付-Maven依赖加入和代码参数准备 二.商户私钥证书代码读取 三.微信订单支付系列接口URL配置 四.快速验证统一下单接口 五.查询订单支付状态验证 六.关闭订单状态验证 ...
- 微信支付分 - 查询支付分订单API
请求示例: https://api.mch.weixin.qq.com/v3/payscore/serviceorder?service_id=0000400000000053008245178793 ...
- srtp项目中关于引入Maven仓库中指定版本jar包的一些问题
文章目录 背景 问题 解决方案 打开Maven的搜索 搜索网址打开之后,直接将你想要查找的jar包全名输进去即可,类似于向下面这样. 指定之后仍然代码出错 背景 相信很多和我一样刚入门的新人对于另外一 ...
- 微信支付V3版本回调+验签流程
本文主要是接前面2篇微信V3支付参数准备和微信V3支付整合进项目中的后续之微信支付后的回调. 一.回调验签流程介绍 二.核心流程操作 本文主要是接前面2篇微信V3支付参数准备和微信V3支付整合进项目中 ...
- 微信支付:支付流程分析、微信扫码支付(HttpClient)、微信支付二维码生成、检测支付状态、订单状态操作准备工作、支付信息回调、MQ处理支付回调状态、定时处理订单状态
微信支付 微信支付开发的整体思路 生成支付二维码 查询支付状态(微信的服务器) 实现订单状态的修改.删除订单 支付状态回查->微信服务器将支付状态返回给支付微服务 MQ处理支付回调状态 Rabb ...
- 微信小程序微信支付《JSAPI支付》APIV3详细教程
文章目录 前提 整体介绍 我的maven依赖 1.整体流程 2.openid 的获取 3.统一下单Controller(预支付订单) 4.配置类和配置文件 5.工具类 6.前端接收到必要的参数,进行调 ...
- 微信支付之JSAPI支付开发流程
JSAPI支付 前言 准备 开发 1.流程说明 2.下单(预支付) 3.前端调起支付 4.支付结果异步通知 5.退款申请 6.退款结果异步通知 结语 前言 最近项目涉及到微信支付的功能,在这里简单分享 ...
- 微信支付和支付宝支付整合(含设计模式1)
微信支付和支付宝支付整合(含设计模式1) 1.说明: 设计模式:单例+策略模式+抽象 在开发中经常对接微信支付和支付宝支付,相对来说,阿里的文档比微信的接口文档清晰一点,这里用的第三方库(com.gi ...
- PC网站微信扫码支付之Native支付(模式二)
简介 Native支付是指商户系统按微信支付协议生成支付二维码,用户再用微信"扫一扫"完成支付的模式.该模式适用于PC网站.实体店单品或订单.媒体广告支付等场景. Native支付 ...
- 【开发技巧】-- 一篇女朋友也能看懂的Spring整合第三方支付(微信支付-扫码支付实现篇)
1.1 为什么要在项目中使用微信支付? 众所周知,支付宝与财付通(微信支付)是如今第三方支付的两大领头企业,同是微信是一个拥有大量用户群体的一个软件,在项目中整合微信支付在一定程度上可以方便用户购物支 ...
最新文章
- Django中的常用命令
- python链家数据分析统计服_链家数据分析一--数据离散化处理
- MySQL8.0 版本的安装
- python 列表嵌套字典 添加修改删除_【Python】列表嵌套字典修改字典里面的一个值却把全部的值都修改了。...
- 建立p2p互相连接的社区集群机器人设计(一)
- AjaxAtlas技术团队[公告]:请大家清理自己发布在团队页面上的post!
- 微信公号“架构师之路”学习笔记(七)-互联网搜索架构设计
- Redis安装(源码安装)
- python opencv视频流_python – PyQt显示来自opencv的视频流
- 一个优秀程序员必备的软件背景/桌面壁纸/集原美/鬼刀.....
- python转换为exe程序
- endnotex9安装后使用方法_EndNoteX9个人安装说明.PDF
- Java线程强制执行
- 海南信用社计算机试题,2021年海南农村信用社计算机笔试内容17
- 刷脸支付上线,追赶二维码支付指日可待?
- NOIP2017模拟赛总结(2017.10.30-2017.11.1)
- java:下拉列表框组件
- scada与MySQL连接_SCADA系统关系数据库转储
- (转载)基于TDOA声源定位算法仿真–MATLAB仿真
- 一、Glade-3安装配置
热门文章
- Mock.js数据模拟,rap2、postman可视化接口平台,Vue框架的接口链接应用
- 2020-12-09 blastp参数学习
- java pfx_java读取pfx或P12格式的个人交换库公私钥
- 停止内耗:过一个不累的人生-读书笔记
- 数学之路-python计算实战(4)-Lempel-Ziv压缩(2)
- 网页设计常用色彩搭配表 - 配色表
- 用opencv将左右眼3D图片转换为红蓝3D图片
- 全国省份、城市关联表 mysql(含城市名拼音)
- WeChat微信商户号JSAPI支付 支付授权目录无法添加:添加完成后不刷新再添加一遍
- 计算机动漫与游戏制作要画画基础吗,动漫制作要有绘画基础吗