贴个官网,建议down下来他的源码,对照着开发更方便,因为备注很详尽。
其它不多废话了,我直接写步骤了。
1. Maven引入
时间2023年5月,目前最新版本是4.5.0
<dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-miniapp</artifactId> <version>4.5.0</version> </dependency> <dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-pay</artifactId> <version>4.5.0</version> </dependency>
2. 微信小程序参数配置
考虑到多微信小程序和微信支付多商户的问题,我们的配置将会是以集合的形式存在
2.1 propertie格式
wx.mini.configs[0].appid:wx0123948575wx.mini.configs[0].secret:4023c4f58d704d9wx.mini.configs[1].appid:wx01239485jowx.mini.configs[1].secret:4023c4f58d
每组的配置项以类似下标的形式区分开
2.2 yaml格式
wx: mini: login: configs: - appid: wx02792790 secret: 4023c4f58d704d9 pay: configs: - mchId: xxxxx
" - " 后面表示一组数据, 登录和支付的必传参数,自己补全吧
yaml的格式应该是有问题的,各位自己注意下就好
3. 类
3.1 Properties对应的对象
@Data@ConfigurationProperties(prefix = "wx.mini.login")public class WxMpLoginProperties { private List<Config> configs; @Data public static class Config { /** * 设置微信小程序的appid */ private String appid; /** * 设置微信小程序的Secret */ private String secret; /** * 设置微信小程序消息服务器配置的token */ private String token; /** * 设置微信小程序消息服务器配置的EncodingAESKey */ private String aesKey; /** * 消息格式,XML或者JSON */ private String msgDataFormat; }}
@Data@ConfigurationProperties(prefix = "wx.mini.pay")public class WxMpPayProperties {private List<Config> configs;@Datapublic static class Config { private String mchId; private String wxApiV3Key; private String notify_url; /** * 证书-序列号 * 1D685BC1A16B008C7714E3A255C9408607D1738C */ private String mchSerialNo; /** * https://api.mch.weixin.qq.com/v3/certificates */ private String v3CertUrl; /** * 证书所在服务器位置 如 /payment/yfyxs/apiclient_key.pem */ private String keyPath; /** * apiclient_key.pem证书文件的内容 */ private String apiClientKey; /** * apiclient_cert.pem证书文件的内容 */ private String apiClientCert; /** * 商户签名使用 商户私钥 ,证书序列号包含在请求HTTP头部的 Authorization的serial_no * 微信支付签名使用微信支付平台私钥,证书序列号包含在应答HTTP头部的Wechatpay-Serial * 商户上送敏感信息时使用微信支付平台公钥加密,证书序列号包含在请求HTTP头部的 Wechatpay-Serial */}}
这2个类编写完之后
@ConfigurationProperties
会报错,但是先不要管它。
3.2 WxMpConfig
@Slf4j@Configuration@EnableConfigurationProperties({WxMpLoginProperties.class,WxMpPayProperties.class})public class WxMpConfig { private final WxMpLoginProperties loginProperties; private final WxMpPayProperties payProperties; public WxMpConfig(WxMpLoginProperties loginProperties, WxMpPayProperties payProperties) { this.loginProperties = loginProperties; this.payProperties = payProperties; } /** * 与微信小程序有关的总service * @return WxMaService */ @Bean public WxMaService wxMaService() { List<WxMpLoginProperties.Config> configs = this.loginProperties.getConfigs(); if (configs == null) { throw new ApiException("没有微信小程序配置啊"); } WxMaServiceImpl maService = new WxMaServiceImpl(); Map<String, WxMaDefaultConfigImpl> multiConfigs = configs.stream() .map(cof -> { WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl(); config.setAppid(cof.getAppid()); config.setSecret(cof.getSecret()); config.setToken(cof.getToken()); config.setAesKey(cof.getAesKey()); config.setMsgDataFormat(cof.getMsgDataFormat()); return config; }) .collect(Collectors.toMap(WxMaDefaultConfigImpl::getAppid, Function.identity(), (o, n) -> o)); maService.setMultiConfigs(multiConfigs); return maService; } @Bean public WxPayService wxPayService() { List<WxMpPayProperties.Config> configs = this.payProperties.getConfigs(); if (configs == null) { throw new ApiException("没有微信小程序配置啊"); } WxPayService wxPayService = new WxPayServiceImpl(); this.payProperties.getConfigs().stream().forEach(merchant -> { WxPayConfig payConfig = new WxPayConfig(); payConfig.setMchId(merchant.getMchId()); payConfig.setCertSerialNo(merchant.getMchSerialNo()); payConfig.setApiV3Key(merchant.getWxApiV3Key()); payConfig.setPrivateKeyContent(merchant.getApiClientKey().getBytes()); payConfig.setPrivateCertContent(merchant.getApiClientCert().getBytes()); wxPayService.addConfig(merchant.getMchId(), payConfig); // 可以指定是否使用沙箱环境 payConfig.setUseSandboxEnv(false); }); return wxPayService; } }
到目前为止我们的准备工作就做完了。剩下的就是业务逻辑代码的开发了。
4. 业务代码编写
4.1 登录的code2session demo
具体的完整的微信登录流程不会写在这里,我们只是看下如果使用binary-wang
给我们封装的接口(再强调下,只是demo所以整体无关规范问题,在此service层不面向接口编程)
@Service@Slf4jpublic class WeiXinLoginDemoService { @Autowired private WxMaService wxMaService; public void weixinCode2SessionDemo(String appId) { if (!wxMaService.switchover(appId)) { throw new ApiException(String.format("未找到对应appid=[%s]的配置,请核 实!", appId)); } //code 2 session WxMaJscode2SessionResult jscode2SessionResult = wxMaService.getUserService().getSessionInfo(wcp.getCode()); log.info("result:{}", jscode2SessionResult.toString()); }}
4.2 微信支付demo
具体的微信支付逻辑这里也不会写,只是告诉你用binary-wang
做微信支付的话我们需要准备什么东西。
@Service@Slf4jpublic class WeiXinPayDemoService { @Autowired private WxPayService wxPayService; /** * 统一下单demo **/ public void weixinUnifiedOrderV3Demo(String mchId) { if (!wxPayService.switchover(mchId)) { throw new ApiException(String.format("未找到对应mchid=[%s]的配置,请核 实!", mchId)); } //调用统一下单接口,WxPayUnifiedOrderV3Request具体需要的逻辑参数需要参考官方文档,但是我们阅读unifiedOrderV3这个接口的源码 //就能知道appId mchId 以及url都不需要我们传入,我们只要传具体的业务参数即可比如贵司生成的orderId WxPayUnifiedOrderV3Result wxPayUnifiedOrderV3Result = wxPayService.unifiedOrderV3(TradeTypeEnum.H5, new WxPayUnifiedOrderV3Request()); log.info("result:{}", wxPayUnifiedOrderV3Result.toString()); }}
以上差不多了。有错误的话,感谢指出。有问题的话,共同讨论。