本文主要是采用工厂模式+策略模式的设计模式来实现微信支付(V3)和支付宝支付(easysdk),也可以在此基础上新增其他渠道的支付,对接的前端是uniapp
一,准备
1,开通微信支付以及拿到微信支付的相关参数和证书
#微信支付参数
#appid
wx.appId=xxxx
#证书序列号
wx.serialNo=xxxx
#秘钥路径(格式.pem) apiclient_key.pem
wx.keyPath=xxxx
#CA证书(格式.pem) apiclient_cert.pem
wx.certPath=xxxx
#CA证书(格式.p12) apiclient_cert.p12
wx.certP12Path=xxxx
#平台证书路径(格式.pem) wechatpay_xxxxxxxxx.pem
#平台证书如何获取:https://github.com/wechatpay-apiv3/CertificateDownloader
wx.platformCertPath=xxxxxx
#服务商id/商户id
wx.mchId=xxxx
#自定义 apiwx 秘钥
wx.apiKey3=xxxx
#apiKey
wx.apiKey=xxxx
#项目域名
wx.domain=xxxx
#支付成功异步地址
wx.wxNotifyUrl=xxxx
#微信h5支付结束后重定向地址
wx.redirectUrl=xxxx
微信的证书工具 https://kf.qq.com/faq/161222NneAJf161222U7fARv.html
2,开通支付宝支付以及拿到支付宝的相关证书
#支付宝支付参数
#protocol
ali.protocol=https
#gateway
ali.gatewayHost=openapi.alipay.com
#signType
ali.signType=RSA2
#appid
ali.appId=xxxx
#应用私钥 app_private_key.txt
#支付宝推荐从文件中读取私钥字符串而不是写入源码中
ali.merchantPrivateKey=xxxx
#应用证书(格式.crt)alipayCertPublicKey_RSA2.crt
ali.merchantCertPath=xxxx
#支付宝公钥证书(格式.crt)alipayCertPublicKey_RSA2.crt
ali.alipayCertPath=xxxx
#支付宝根证书(格式.crt)alipayRootCert.crt
ali.alipayRootCertPath=xxxx
#支付成功异步地址
ali.aliNotifyUrl=xxxx
#quitUrl 付款途中退出返回的地址
ali.quitUrl=xxxx
#returnUrl 付款成功的返回地址
ali.returnUrl=xxxx
支付宝证书工具:https://ideservice.alipay.com/ide/getPluginUrl.htm?clientType=assistant&platform=win&channelType=WEB
二,依赖
微信支付是v3版本,支付宝是easysdk
<!-- alipay-easysdk -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-easysdk</artifactId>
<version>2.1.2</version>
</dependency>
<!-- IJPay-WxPay -->
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-WxPay</artifactId>
<version>2.7.1</version>
</dependency>
<!-- springboot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.3.7.RELEASE</version>
</dependency>
三,代码编写
1,配置文件:
-
微信配置类
/** * create by: zxx * desc: 微信配置类 */ @Data @Configuration @PropertySource(value = "classpath:application-pay-${spring.profiles.active}.properties",encoding = "utf-8") @ConfigurationProperties(prefix = "wx") public class WxPayConfig { private String appId; private String keyPath; private String serialNo; private String certPath; private String certP12Path; private String platformCertPath; private String mchId; private String apiKey3; private String apiKey; private String domain; private String wxNotifyUrl; private String redirectUrl; }
-
支付宝配置类
/** * create by: zxx * desc: 支付宝配置类 */ @Data @Configuration @PropertySource(value = "classpath:application-pay-${spring.profiles.active}.properties",encoding = "utf-8") @ConfigurationProperties(prefix = "ali") public class AliPayConfig { private String protocol; private String gatewayHost; private String appId; private String signType; //应用私钥 private String merchantPrivateKey; //应用公钥证书 private String merchantCertPath; //支付宝公钥证书 private String alipayCertPath; //支付宝根证书 private String alipayRootCertPath; //支付成功异步地址 private String aliNotifyUrl; //支付途中推出url private String quitUrl; //支付成功url private String returnUrl; /** * 设置参数 * @return */ @Bean public Config ConfigAliPay() throws Exception { Config config = new Config(); config.protocol = protocol; config.gatewayHost = gatewayHost; config.signType = signType; config.appId = appId; config.merchantPrivateKey = ReadTxtUtil.readTxtFile(new ClassPathResource(merchantPrivateKey).getStream()); config.merchantCertPath = new ClassPathResource(merchantCertPath).getPath(); config.alipayCertPath = new ClassPathResource(alipayCertPath).getPath(); config.alipayRootCertPath = new ClassPathResource(alipayRootCertPath).getPath(); config.notifyUrl = aliNotifyUrl; Factory.setOptions(config); return config; } }
2,自定义注解 @PayPlatform
自定义注解用来表明打了注解的策略类是哪个支付平台
/**
* create by: zxx
* desc: 自定义支付平台注解,支付平台 1-微信 2-支付宝
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.TYPE})
@Documented
public @interface PayPlatform {
int platform();
}
3,支付策略类
/**
* create by: zxx
* desc: 支付策略
*/
public interface PayStrategy {
//h5统一下单
TradeWapResponse tradeWap(TradeWapParam param);
//app统一下单
TradeAppResponse tradeApp(TradeAppParam param);
//下单异步
void callBack(HttpServletRequest request);
//单笔查询
TradeQueryResponse tradeQuery(TradeQueryParam param);
}
@Data
@ApiModel("统一参数参数")
public class OrderParam {
@ApiModelProperty(value = "支付平台")
@NotNull
private Integer payPlatform;
@ApiModelProperty(value = "支付的用户")
private String userId;
}
@Data
@ApiModel("h5支付请求参数")
public class TradeWapParam extends OrderParam{
@ApiModelProperty(value = "商品标题")
@NotEmpty
private String title;
@ApiModelProperty(value = "订单编号")
@NotEmpty
private String orderNo;
@ApiModelProperty(value = "支付金额 单位:元")
@NotEmpty
private String amount;
@ApiModelProperty(value = "付款中途退出跳转的地址")
@NotEmpty
private String quitUrl;
@ApiModelProperty(value = "付款成功跳转的地址")
@NotEmpty
private String returnUrl;
}
@Data
@ApiModel("app下单请求参数")
public class TradeAppParam extends OrderParam {
@ApiModelProperty(value = "商品标题")
@NotEmpty
private String title;