引入依赖
<!--微信支付SDK-->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.4.9</version>
</dependency>
<!--json-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
配置文件
#小程序appid
wxpay.app-id=
#小程序密钥
wxpay.key=
#商户ID
wxpay.mch-id=
#证书序列号
wxpay.serial-no=
#密钥文件路径
wxpay.private-key-path=file/apiclient_key.pem
#APIv3密钥
wxpay.apiv3-key=
#回调地址,这里是我租的域名,映射到我本地服务器
wxpay.notify-url=http://att.natapp1.cc
#微信服务地址
wxpay.notify-domain=https://api.mch.weixin.qq.com
#支付方式
wxpay.trade-type=JSAPI
配置类
@Configuration
@PropertySource("classpath:wxpay.properties")
@ConfigurationProperties(prefix = "wxpay")
@Data
public class WxPayConfig {
// 小程序appid
public String appId;
// 小程序密钥
private String key;
// 商户ID
private String mchId;
// 证书序列号
private String serialNo;
//私钥文件路径
private String privateKeyPath;
// apiv3密钥
private String apiv3Key;
// 微信服务地址
private String notifyDomain;
// 微信服务地址
private String notifyUrl;
// public final static String payUrl= "https://api.mch.weixin.qq.com/pay/unifiedorder"; // 统一下单地址
// 统一下单地址
private String payUrl;
// 支付方式
private String tradeType;
/**
* 获取随机字符串
* @author Xuehao
* @return
* 2016年8月4日 上午9:26:07
*/
public String createNonceStr() {
String s = UUID.randomUUID().toString();
// 去掉“-”符号
return s.replaceAll( "\\-","").toUpperCase();
}
/**
* 获取时间戳
* @author Xuehao
* @return
* 2016年8月4日 上午9:26:07
*/
public long createTimestamp() {
return System.currentTimeMillis();
}
/**
* 获取商户私钥文件
* @param fileName
* @return
*/
private PrivateKey getPrivateKey(String fileName) {
// InputStream inputStream = new FileInputStream(fileName);
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(fileName);
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
inputStream);
return merchantPrivateKey;
}
/**
* 获取签名验证器
* @return
* @throws HttpCodeException
* @throws GeneralSecurityException
* @throws IOException
* @throws NotFoundException
*/
@Bean
public Verifier getVerifier() throws HttpCodeException, GeneralSecurityException, IOException, NotFoundException {
//获取商户私钥
PrivateKey privateKey = getPrivateKey(privateKeyPath);
//私钥签名对象
PrivateKeySigner privateKeySigner = new PrivateKeySigner(serialNo, privateKey);
byte[] b = new byte[1024];
Signer.SignatureResult sign = privateKeySigner.sign(b);
String sign1 = sign.getSign();
System.out.println("签名:"+sign1);
//身份认证对象
WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(mchId, privateKeySigner);
// 获取证书管理器实例
CertificatesManager certificatesManager = CertificatesManager.getInstance();
// 向证书管理器增加需要自动更新平台证书的商户信息
certificatesManager.putMerchant(mchId, wechatPay2Credentials, apiv3Key.getBytes(StandardCharsets.UTF_8));
Verifier verifier = certificatesManager.getVerifier(mchId);
return verifier;
}
/**
* 获取http请求对象
*/
@Bean(value = "wxPayClient")
public CloseableHttpClient getWxPayClient(Verifier verifier) {
// 从证书管理器中获取verifier
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, serialNo, getPrivateKey(privateKeyPath))
.withValidator(new WechatPay2Validator(verifier));
// ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient
// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
CloseableHttpClient httpClient = builder.build();
// 后面跟使用Apache HttpClient一样
// CloseableHttpResponse response = httpClient.execute(...);
return httpClient;
}
/**
* 获取http请求对象-用于下载账单
*/
@Bean(value = "wxPayClientOfBill")
public CloseableHttpClient getWxPayClientOfBill() {
// 从证书管理器中获取verifier
WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, serialNo, getPrivateKey(privateKeyPath))
.withValidator(response -> true);
// ... 接下来,你仍然可以通过builder设置各种参数,来配置你的HttpClient
// 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新
CloseableHttpClient httpClient = builder.build();
// 后面跟使用Apache HttpClient一样
// CloseableHttpResponse response = httpClient.execute(...);
return httpClient;
}
}
支付订单实体类
@Data
@Accessors(chain = true)
@TableName("order_pay")
@ApiModel(value="order_pay对象", description="订单支付表")
public class OrderPay {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "主键")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty(value = "订单号")
@TableField("out_trade_no")
private String outTradeNo;
@ApiModelProperty(value = "应用ID")
@TableField("appid")
private String appid;
@ApiModelProperty(value = "直连商户号")
@TableField("mchid")
private String mchid;
@ApiModelProperty(value = "商品描述")
@TableField("description")
private String description;
@ApiModelProperty(value = "订单优惠标记")
@TableField("goods_tag")
private String goodsTag;
@ApiModelProperty(value = "电子发票入口开放标识")
@TableField("support_fapiao")
private String supportFapiao;
@ApiModelProperty(value = "总金额")
@TableField("amount_total")
private String amountTotal;
@ApiModelProperty(value = "货币类型")
@TableField("currency")
private String currency;
@ApiModelProperty(value = "支付者")
@TableField("openid")
private String openid;
@ApiModelProperty(value = "交易类型")
@TableField("trade_type")
private String tradeType;
@ApiModelProperty(value = "二维码")
@TableField("code_url")
private String codeUrl;
@ApiModelProperty(value = "交易状态")
@TableField("trade_state")
private String tradeState;
@ApiModelProperty(value = "交易状态描述")
@TableField("trade_state_desc")
private String tradeStateDesc;
@ApiModelProperty(value = "创建时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@ApiModelProperty(value = "修改时间")
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@ApiModelProperty(value = "创建人ID")
@TableField(fill = FieldFill.INSERT)
private Long creatorId;
@ApiModelProperty(value = "修改人ID")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updaterId;
@ApiModelProperty(value = "创建人")
@TableField(fill = FieldFill.