微信支付服务商模式开发流程_微信服务商怎么申请

微信支付服务商模式开发流程_微信服务商怎么申请背景小程序盛行时代,一般的企业中都都会包含多个小程序,而大部分的小程序通常都需要实现支付功能,本文将针对服务商模式进行微信支付进行详细讲解。微信支付的模式一般企业选用是服务商或者为渠道商模式,但是成为渠道商需要相关流量支撑才能申请,本文以服务商模式进行讲解。前期准备注册服务商服务商申请需

大家好,欢迎来到IT知识分享网。

背景

小程序盛行时代,一般的企业中都都会包含多个小程序,而大部分的小程序通常都需要实现支付功能,本文将针对服务商模式进行微信支付进行详细讲解。

微信支付的模式

图片.png

一般企业选用是服务商或者为渠道商模式,但是成为渠道商需要相关流量支撑才能申请,本文以服务商模式进行讲解。

前期准备

注册服务商

服务商申请需要通过已做过公司认证的公众号,登录公司的微信服务号,在【微信支付】>【服务商申请】,直接跟着官方引导一步步操作即可,具体申请流程如下:

图片.png

说明:所以企业需要申请公共号,才能申请注册服务商。

服务商入驻

通过服务商来开发的系统来帮助商户微信支付,首先需要完成商户号在服务商号中的入驻过程。服务商注册成功后,进入微信支付平台,登录服务商,进行商户入驻。一般商户入驻有两种,具体如下:

  • 页面入驻
  • 调用API方式入驻

页面入驻

图片.png

入驻可以看作是商户生成商户号的同时与服务商形成绑定关系。具体可以参考微信公众号中按流程指引一步步操作就行。

图片.png

说明:商户入驻完成后,此商户才能用于微信支付。

申请证书

商户号入驻成功后,需要申请API证书。

图片.png

说明:按照官方文档申请证书,设置密钥,设置好密钥后一定要在安全的前提下记住,之后只能重置不能查看。

重要参数说明

  • appid:服务商Appid
  • mchId:服务商的商户id
  • mchKey:证书的序列号
  • subAppId:子商户小程序Appid
  • subOpenId:子商户小程序用户的openId
  • subMchId:子商户的商户id

子商户支付流程

以下是子商户APP中调用支付的交互时序图

图片.png

流程说明:

  • 用户在商户APP中选择商品,选择微信支付,提交订单,如图中步骤1-3所示。
  • 调用服务商提供的下单接口,服务商后台收到下单请求,会返回签好名的订单数据,用于商户APP里面调起微信支付,如图中步骤3-5所示。
  • 用户确认支付,输入密码,支付完成,如图中步骤6-8所示。
  • 支付完成后,微信返回商户APP,回调APP实现的回调函数,此时需要根据单号调用服务商提供的查询结果,查询后台实际支付结果,再作用户页面展示和发货操作。如图步骤9-13.

实现方案

服务商模式的微信支付的具体实现方案,本文采用的是Spring Boot集成weixin-java-pay来实现微信支付。

实现步骤

jar包引入

<dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-pay</artifactId> <version>4.1.0</version> </dependency> 复制代码

支付配置

# 微信支付配置 wx: pay: #服务商id mchId: 12 #证书 keyPath: apiclient_cert.p12 #服务商appid appId: wxe12233 #支付回调通知地址 notifyUrl: https://localhost:8080/pay/resWxPay #服务商key的密钥 mchKey: 123444 复制代码

相关配置类

@Component
@ConfigurationProperties(prefix = "wx.pay") public class WxPayProperties { /** * 小程序appid */ private String appId; /** * 微信支付商户号 */ private String mchId; /** * 微信支付商户密钥 */ private String mchKey; /** * 服务商模式下的子商户公众账号ID */ private String subAppId; /** * 服务商模式下的子商户号 */ private String subMchId; /** * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定 */ private String keyPath; /** * 支付回调 */ private String notifyUrl; //省略get、set方法 } 复制代码

说明:读取微信支付的配置信息

/** * 微信支付配置类 */ @Configuration public class CustWxPayConfig { @Autowired private WxPayProperties properties; @Bean @ConditionalOnMissingBean public WxPayService wxService() { WxPayConfig payConfig = new WxPayConfig(); payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId())); payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId())); payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey())); payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId())); payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath())); payConfig.setNotifyUrl(StringUtils.trimToNull(this.properties.getNotifyUrl())); //设置微信支付参数 WxPayService wxPayService = new WxPayServiceImpl(); wxPayService.setConfig(payConfig); return wxPayService; } } 复制代码

说明:将微信支付的相关参数设置到wxjava中的cofig中。

业务实现类

@Service @Transactional(rollbackFor =Exception.class) public class CustWxPayServiceImpl implements CustWxPayService { private Logger logger = LoggerFactory.getLogger(CustWxPayService.class); @Autowired private WxPayService wxService; public void createWxPayOrder(WxPayObject payObject) { logger.info("Create wx pay order."); //并发控制 WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest(); request.setTradeType(payObject.getTradeType()); int payMoney = payObject.getPayMoney() .multiply(new BigDecimal(100)).intValue(); // totalFee单位为(分) request.setTotalFee(payMoney); //第三方订单号 request.setOutTradeNo(payObject.getOrderNo()); //用户OpenID(支付小程序) request.setSubOpenid(payObject.getSubOpenid()); //支付小程序APPID request.setSubAppId(payObject.getSubAppId()); request.setNonceStr(getRandomString(32)); request.setBody(payObject.getBody()); request.setFeeType(payObject.getFeeType()); HttpServletRequest httpRequest = ((ServletRequestAttributes) RequestContextHolder .getRequestAttributes()).getRequest(); //IP地址 request.setSpbillCreateIp(IpUtil.getIpAddr(httpRequest)); //配置回调地址 request.setNotifyUrl(wxService.getConfig().getNotifyUrl()); //收款子商户 String subMchId = wxService.getConfig().getSubAppId(); request.setSubMchId(subMchId); //DeviceID request.setDeviceInfo(payObject.getDeviceInfo()); //支付类型: request.setTradeType(payObject.getTradeType()); //创建建订单 WxPayMpOrderResult wxPayMpOrderResult =null; try { wxPayMpOrderResult = wxService.createOrder(request); if (wxPayMpOrderResult == null) { logger.info("Create Wx Order Success. Result is null."); } else { logger.info("Create Wx Order Success. Result:{}", JSON.toJSONString(wxPayMpOrderResult)); } } catch (WxPayException e) { logger.error("createWxPayOrder error",e); throw new SysException("create wx order error",e); } } @Override public void resWxPay(String xmlData) { logger.info("Wx Pay Response, param[{}]", xmlData); WxPayOrderNotifyResult result =null; try { result = wxService .parseOrderNotifyResult(xmlData); //支付失败 if ("FAIL".equalsIgnoreCase(result.getResultCode()) || "FAIL".equalsIgnoreCase(result.getReturnCode())) { //记录支付失败错误日志 throw new SysException(result.getErrCodeDes()); } //获取订单号 String outTradeNo = result.getOutTradeNo(); if (StringUtils.contains(outTradeNo, "_")) { outTradeNo = outTradeNo.substring(0, outTradeNo.indexOf("_")); } //执行具体业务逻辑 //记录流水 //更新订单状态 } catch (WxPayException e) { throw new SysException("wx pay error",e); } } @Override public WxPayOrderQueryResult queryOrder(String outTradeNo) { WxPayOrderQueryResult wxPayOrderQueryResult =null; try { wxPayOrderQueryResult= wxService.queryOrder(null, outTradeNo); } catch (WxPayException e) { throw new SysException("query wx order error",e); } return wxPayOrderQueryResult; } public static String getRandomString(int length) { String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { int number = random.nextInt(base.length()); sb.append(base.charAt(number)); } return sb.toString(); } } 复制代码

说明:实现微信创建订单、支付回调、查询订单接口。

测试类

@RestController @RequestMapping("/pay/wxpay/") public class WxPayController { private Logger logger =LoggerFactory.getLogger(WxPayController.class); @Autowired private CustWxPayService custWxPayService; /** * * @param subAppId 小程序AppId * @param subOpenid 用户在小程序的openid * @param payMoney 支付金额 * @param orderNo 第三方订单号 * @return */ @PostMapping("/reqWxPay") public Result reqWxPay(@RequestBody WxPayObject wxPayObject) { //支付参数验证 logger.info("Req Wx Pay,param:{}",JSON.toJSONString(wxPayObject)); Result result =new Result(); try { //创建订单 custWxPayService.createWxPayOrder(wxPayObject); } catch(Exception e) { logger.error("Req Wx Pay Error.", e); return Result.error("Req Wx Pay error"+e); } return Result.success(result); } /** * 异步回调 * @param xmlData * @return */ @PostMapping("/resWxPay") public String resWxPay(@RequestBody String xmlData) { logger.info("Wx Pay Response, Data:[{}]", xmlData); try { custWxPayService.resWxPay(xmlData); } catch(Exception e) { logger.error("Wx Pay Response Process Error.", e); return WxPayNotifyResponse.fail("订单支付失败."); } logger.info("Wx Pay Response Process Success."); return WxPayNotifyResponse.success("付款成功"); } @GetMapping("/queryOrder") public Result queryOrder(String outTradeNo) { WxPayOrderQueryResult wxPayOrderQueryResult = custWxPayService.queryOrder(outTradeNo); logger.info(wxPayOrderQueryResult.toString()); return Result.success(wxPayOrderQueryResult); } } 复制代码

相关测试

创建支付订单

请求参数

图片.png

说明:

  • subAppId:子商户的小程序id
  • subOpenid:小程序用户的openid

响应结果

图片.png

说明:returnCode为success,则说明创建微信支付订单成功。

查询订单

订单创建成功后,需要查询订单状态。

请求参数

图片.png

响应结果

图片.png

微信异步回调

关于微信支付回调,需要绑定外网域名,在内网需要测试的话,需要进行内网穿透,微信异步回调可能由于网络原因出现延迟,所以在业务上需要提供主动查询和异步回调结合的方式,关于具体实现将在后续的文章中进行讲解。

总结

本文服务商模式实现微信支付进行详细的讲解,实现过程还是比较复杂,订单支付中涉及到重复提交、幂等性验证、同步+异步的轮询处理等问题将在后续的文章中进行讲解。

作者:剑圣无痕

链接:https://juejin.cn/post/7134982531786473480

来源:稀土掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/29033.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信