有道无术,术尚可求,有术无道,止于术。
文章目录
- 前言
- 1. 环境搭建
- 2. 特约商户进件
- 3. 统一下单
- 总结
前言
在上篇文档中,我们做好了接入前准备工作,接下来使用开源框架集成服务商相关API
。
一个简单的支付系统完成支付流程图如下所示:
1. 环境搭建
引入开源微信支付框架。
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-pay-spring-boot-starter</artifactId>
<version>4.4.8.B</version>
</dependency>
配置上篇文档中我们获取到的参数、秘钥、证书。
wx:
pay:
appId: wx7xxxxx # 服务商应用ID(公众号)
mchId: xxxxx # 服务商收款账号
apiV3Key: UDuLFDcmy5Eb6o0xxxxx # 服务商API V3密钥
certSerialNo: 34345964330B66427E0D3D2882xxxxx # 服务商商户证书序列
privateKeyPath: classpath:cert/apiclient_key.pem # 服务商apiclient_key.pem证书文件的绝对路径或者以classpath:开头的类路径
privateCertPath: classpath:cert/apiclient_cert.pem # 服务商apiclient_cert.pem证书文件的绝对路径或者以classpath:开头的类路径
新建商户管理表、支付订单表等~
2. 特约商户进件
官方API文档
该支付系统,首先需要入驻子商户,可以集成微信提供的进件接口,这样自由度和管理更方便。
该框架的Applyment4SubService
接口实现类已经集成微信特约商户进件API
,我们只需要设置对应的请求参数对象即可,如果是直接集成微信SDK
,还需要封装参数、解析响应比较麻烦。
public interface Applyment4SubService {
/**
* 提交申请单API
*/
WxPayApplymentCreateResult createApply(WxPayApplyment4SubCreateRequest request) throws WxPayException;
/**
* 通过业务申请编号查询申请状态
*
* @param businessCode 业务申请编号
* 1、只能由数字、字母或下划线组成,建议前缀为服务商商户号。
* 2、服务商自定义的唯一编号。
* 3、每个编号对应一个申请单,每个申请单审核通过后生成一个微信支付商户号。
* 4、若申请单被驳回,可填写相同的“业务申请编号”,即可覆盖修改原申请单信息。
* 示例值:1900013511_10000
*/
ApplymentStateQueryResult queryApplyStatusByBusinessCode(String businessCode) throws WxPayException;
/**
* 通过申请单号查询申请状态
*/
ApplymentStateQueryResult queryApplyStatusByApplymentId(String applymentId) throws WxPayException;
/**
* 根据特约子商户ID查询结算账户
*/
SettlementInfoResult querySettlementBySubMchid(String subMchid) throws WxPayException;
/**
* 修改结算帐号
*/
String modifySettlement(String subMchid, ModifySettlementRequest request) throws WxPayException;
}
示例代码如下:
@Operation(summary = "提交申请单")
@GetMapping("/createApply")
public R<String> createApply(@RequestParam(required = false) String applymentId) throws WxPayException {
WxPayApplyment4SubCreateRequest request = new WxPayApplyment4SubCreateRequest();
// 主体资料:主体类型、是否是金融机构、营业执照、登记证书、组织机构代码证、单位证明函照片、经营者/法人身份证件、最终受益人信息列表(UBO)、小微辅助证明材料(subjectType为小微商户时必填)
WxPayApplyment4SubCreateRequest.SubjectInfo subjectInfo = WxPayApplyment4SubCreateRequest.SubjectInfo.builder().build()
.setFinanceInstitution(false)
.setBusinessLicenseInfo(null);// 省略.......
request.setSubjectInfo(subjectInfo);
// 补充材料
WxPayApplyment4SubCreateRequest.AdditionInfo additionInfo=new WxPayApplyment4SubCreateRequest.AdditionInfo();
additionInfo.setBusinessAdditionMsg("补充说明");
additionInfo.setBusinessAdditionPics(null) ;// 补充材料
additionInfo.setLegalPersonCommitment("法人开户承诺函");
additionInfo.setLegalPersonVideo("法人开户意愿视频");
request.setAdditionInfo(additionInfo);
// 结算银行账户
WxPayApplyment4SubCreateRequest.BankAccountInfo bankAccountInfo=new WxPayApplyment4SubCreateRequest.BankAccountInfo();
bankAccountInfo.setBankAccountType(BankAccountTypeEnum.BANK_ACCOUNT_TYPE_CORPORATE); // 账户类型:对公银行账户
bankAccountInfo.setAccountName("开户名称"); // 开户名称
bankAccountInfo.setAccountBank("开户银行");
bankAccountInfo.setBankAddressCode("开户银行省市编码");
bankAccountInfo.setBankBranchId("开户银行联行号");
bankAccountInfo.setBankName("开户银行全称(含支行)");
bankAccountInfo.setAccountNumber("银行账号");
request.setBankAccountInfo(bankAccountInfo);
// 业务申请编号
request.setBusinessCode("业务申请编号");
// 经营资料
request.setBusinessInfo(null); // 省略.......
// 超级管理员信息
request.setContactInfo(null);// 省略.......
// 结算规则
request.setSettlementInfo(null);// 省略.......
// 调用微信API
Applyment4SubService applyment4SubService=new Applyment4SubServiceImpl(wxPayService);
WxPayApplymentCreateResult apply = applyment4SubService.createApply(request);
String applyMentId = apply.getApplymentId(); // 返回申请单ID
return R.success(applyMentId);
}
@Operation(summary = "通过申请单号查询申请状态")
@GetMapping("/queryApply")
public R<ApplymentStateQueryResult> queryApply(@RequestParam(required = true) String applymentId) throws WxPayException {
// 调用API 查询申请状态
Applyment4SubService applyment4SubService=new Applyment4SubServiceImpl(wxPayService);
ApplymentStateQueryResult result = applyment4SubService.queryApplyStatusByApplymentId(applymentId);
return R.success(result);
}
3. 统一下单
在EcommerceService
接口实现类中,集成了服务商下单API。多种支付方式时,使用同一个方法即可。
public interface EcommerceService {
/**
* <pre>
* 服务商模式普通支付API(APP支付、JSAPI支付、H5支付、NATIVE支付).
* 请求URL:https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi
* 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/transactions_sl.shtml
* </pre>
*
* @param tradeType 支付方式
* @param request 请求对象
* @return 调起支付需要的参数 transactions result
* @throws WxPayException the wx pay exception
*/
TransactionsResult partner(TradeTypeEnum tradeType, PartnerTransactionsRequest request) throws WxPayException;
/**
* <pre>
* 普通查询订单API
* 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/ecommerce/e_transactions/chapter3_5.shtml
* </pre>
*
* @param request 商户订单信息
* @return 支付订单信息
* @throws WxPayException the wx pay exception
*/
PartnerTransactionsResult queryPartnerTransactions(PartnerTransactionsQueryRequest request) throws WxPayException;
/**
* <pre>
* 关闭普通订单API
* 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/ecommerce/e_transactions/chapter3_6.shtml
* </pre>
*
* @param request 关闭普通订单请求
* @throws WxPayException the wx pay exception
* @return
*/
String closePartnerTransactions(PartnerTransactionsCloseRequest request) throws WxPayException;
}
示例代码如下:
@Operation(summary = "统一下单/(V3)")
@PostMapping("/ecommerceNative")
public R<?> ecommerceNative(OrderEntity mchOrder,String subMchId) throws Exception {
try {
// 1. 创建请求对象
PartnerTransactionsRequest orderRequest=new PartnerTransactionsRequest();
// 2. 根据订单系统传过来的订单信息组装支付参数,创建支付订单
orderRequest.setSpMchid(subMchId); // 子商户号
orderRequest.setDescription("示例值:Image形象店-深圳腾大-QQ公仔"); // 商品描述:示例值:Image形象店-深圳腾大-QQ公仔
PartnerTransactionsRequest.Amount amount = new PartnerTransactionsRequest.Amount();
amount.setTotal(1); // 订单金额信息
orderRequest.setAmount(amount);
orderRequest.setOutTradeNo(mchOrder.getOutTradeNo()); // 商户订单号,商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一
orderRequest.setNotifyUrl("https://8da1-120-227-23-190.jp.ngrok.io/pay/wechat/notify"); // 通知地址
// 3. 发起V3 服务商发起NATIVE支付
EcommerceServiceImpl ecommerceService=new EcommerceServiceImpl(wxPayService);
TransactionsResult result = ecommerceService.partner(com.github.binarywang.wxpay.bean.ecommerce.enums.TradeTypeEnum.NATIVE, orderRequest);
log.info("NATIVE支付成功,返回二维码URL" + result.getCodeUrl());
// 4. 省略后续操作
return R.success(result);
} catch (Exception e) {
log.error("微信支付失败!,原因:{}", e.getMessage());
e.printStackTrace();
return R.fail();
}
}
总结
在weixin-java-pay
框架中,几乎所有的微信API
都帮我们集成好了,我们只需要设置对应的参数即可,甚至每个方法对应的官网API文档也贴上去了,好像实在也没什么可讲的~