2019-2020 注定是不安的一年,楼主经历了p2p公司倒闭(倒闭之前楼主已经溜了),但是之前在公司投入的资金也没要到。后来入职的公司5个月后因非法获取用户信息,某日早上公司全部技术人员都被请去“喝茶”直到24小时后才重获自由,然后发誓以后一定要做一个守法公民。然后计划着回武汉发展,然而还没成行就爆发了新冠,一地鸡毛无力吐槽。因此2019年基本上没有精力来更新博客,这次给大家带来微信app支付与支付app支付相关代码吧
我仿照着支付宝的模式提供了一个微信app支付的sdk有java版的跟scala版的,然后又做了一个集合了微信app支付与支付宝app支付的scala版的sdk但是这个sdk是耦合了公司业务的不好直接分享出来,这次就先分享微信app支付java版的sdk,有scala版本需求的可以私下联系我,好了开始上代码了
<groupId>com.xxx.wxpay</groupId>
<artifactId>wxpay-sdk-java</artifactId>
<version>1.0-5-SNAPSHOT</version>
这里是打成jar包的插件,如果要将源码上传到maven私服需要 maven-source-plugin
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- 要将源码放上去,需要加入这个插件 -->
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<attach>true</attach>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
下面是调微信相关接口需要的相关类库包括:
com.thoughtworks.xstream 处理xml参数与javabean转换
com.squareup.retrofit2 调用微信相关接口的网络框架
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.10</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.11.0</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-simplexml</artifactId>
<version>2.3.0</version>
</dependency>
下面需要配置的就是你的maven私服地址,上传sdk包需要用到
<distributionManagement>
<repository>
<id>xxx-releases</id>
<name>trj Release Maven Repository Group</name>
<url>http://xxx.xxx.xxx.xxx:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>xxx-snapshots</id>
<name>trj Snapshot Maven Repository Group</name>
<url>http://xxx.xxx.xxx.xxx:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
首先我们定义了一个需要调用微信相关接口的接口类
public interface WXPayExecute {
/**
* 统一下单
* @param body
* @return
*/
@POST("/pay/unifiedorder")
Call<WXPayResponse> unifiedOrder(@Body RequestBody body);
/**
* 申请退款
* @param body
* @return
*/
@POST("/secapi/pay/refund")
Call<WXPayRefundResponse> refund(@Body RequestBody body);
/**
* 订单查询
* @param body
* @return
*/
@POST("/pay/orderquery")
Call<WXOrderQueryResponse> query(@Body RequestBody body);
/**
* 退款查询
* @param body
* @return
*/
@POST("/pay/refundquery")
Call<WXRefundQueryResponse> refundQuery(@Body RequestBody body);
/**
* 交易关单
* @param body
* @return
*/
@POST("/pay/closeorder")
Call<WXPayCloseResponse> closeOrder(@Body RequestBody body);
/**
* 沙箱环境获取签名key接口
* @param body
* @return
*/
@POST("/sandboxnew/pay/getsignkey")
Call<WXSignkeyResponse> getSignKey(@Body RequestBody body);
}
然后定义我们自己需要提供给业务方的service,并在service里面封装相关参数,通过Retrofit调用微信的相关方法
其中微信相关参数封装,加密等utils方法网上一搜一堆,就不一一提供了
public class WXPayService {
private static final String SANDBOXNEW = "/sandboxnew/";
private WXPayProperties wxPayProperties;
public WXPayService(String gateway, String appId, String appSecret, String mchId, String mchKey){
wxPayProperties = new WXPayProperties();
wxPayProperties.setGateway(gateway);
wxPayProperties.setAppId(appId);
wxPayProperties.setAppSecret(appSecret);
wxPayProperties.setMchId(mchId);
wxPayProperties.setMchKey(mchKey);
}
/*微信支付预下单接口*/
public WXPayResponse appPrePay(PayRequest request) {
WXPayRequest wxPayRequest = new WXPayRequest();
wxPayRequest.setOutTradeNo(request.getOrderNO());
wxPayRequest.setTotalFee(request.getAmount());
wxPayRequest.setBody(request.getGoodsName());
wxPayRequest.setAttach(request.getAttach());
wxPayRequest.setSpbillCreateIp(request.getSpbillCreateIp());
wxPayRequest.setTradeType("APP");
wxPayRequest.setTimeExpire(request.getTimeExpire());
wxPayRequest.setNotifyUrl(request.getNotifyUrl());
WXPayResponse response = unifiedOrder(wxPayRequest);
//response.setSign(wxPayRequest.getSign());
return response;
}
/*微信支付统一下单*/
private WXPayResponse unifiedOrder(WXPayRequest wxPayRequest) {
//配置秘钥信息
wxPayRequest.setAppid(wxPayProperties.getAppId());
wxPayRequest.setMchId(wxPayProperties.getMchId());
wxPayRequest.setNotifyUrl(wxPayRequest.getNotifyUrl());
wxPayRequest.setNonceStr(RandomUtil.getRandomStr());
wxPayRequest.setTimeExpire(wxPayRequest.getTimeExpire());
String signKey = wxPayProperties.getMchKey();
/*if(!wxPayProperties.getGateway().endsWith(SANDBOXNEW)){
signKey = getSignKey();
}*/
//签名
wxPayRequest.setSign(SignatureUtil.sign(BuildDataUtil.buildMap(wxPayRequest), signKey));
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(wxPayProperties.getGateway())
//xml转化器 SimpleXmlConverterFactory 需要另外添加依赖 不在retrofit2中
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
String xml = XmlUtil.toXMl(wxPayRequest);
RequestBody body = RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml);
//System.out.println("xml : " + xml);
Call<WXPayResponse> call = retrofit.create(WXPayExecute.class).unifiedOrder(body);
Response<WXPayResponse> retrofitResponse = null;
try {
retrofitResponse = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
if (!retrofitResponse.raw().isSuccessful()) {
throw new RuntimeException("【微信统一支付】发起支付, 网络异常");
}
WXPayResponse response = retrofitResponse.body();
if (!response.getReturnCode().equals("SUCCESS")) {
throw new RuntimeException("【微信统一支付】发起支付, returnCode != SUCCESS, returnMsg = " + response.getReturnMsg());
}
return response;
}
/*微信支付查询接口*/
public WXOrderQueryResponse query(WXOrderQueryRequest wxQueryRequest) {
wxQueryRequest.setAppid(wxPayProperties.getAppId());
wxQueryRequest.setMchId(wxPayProperties.getMchId());
wxQueryRequest.setNonceStr(RandomUtil.getRandomStr());
String signKey = wxPayProperties.getMchKey();
/*if(!wxPayProperties.getGateway().endsWith(SANDBOXNEW)){
signKey = getSignKey();
}*/
wxQueryRequest.setSign(SignatureUtil.sign(BuildDataUtil.buildMap(wxQueryRequest), signKey));
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(wxPayProperties.getGateway())
//xml转化器 SimpleXmlConverterFactory 需要另外添加依赖 不在retrofit2中
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
String xml = XmlUtil.toXMl(wxQueryRequest);
RequestBody body = RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml);
Call<WXOrderQueryResponse> call = retrofit.create(WXPayExecute.class).query(body);
Response<WXOrderQueryResponse> retrofitResponse = null;
try {
retrofitResponse = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
if (!retrofitResponse.isSuccessful()) {
throw new RuntimeException("【微信支付订单查询】查询失败, 网络异常");
}
WXOrderQueryResponse response = retrofitResponse.body();
/*if (!response.getReturnCode().equals("SUCCESS")) {
throw new RuntimeException("【微信统一支付】发起支付, returnCode != SUCCESS, returnMsg = " + response.getReturnMsg());
}*/
return response;
}
/*微信支付交易关单接口*/
public WXPayCloseResponse closeOrder(WXPayCloseRequest wxPayCloseRequest) {
wxPayCloseRequest.setAppid(wxPayProperties.getAppId());
wxPayCloseRequest.setMchId(wxPayProperties.getMchId());
wxPayCloseRequest.setNonceStr(RandomUtil.getRandomStr());
String signKey = wxPayProperties.getMchKey();
/* if(!wxPayProperties.getGateway().endsWith(SANDBOXNEW)){
signKey = getSignKey();
}*/
wxPayCloseRequest.setSign(SignatureUtil.sign(BuildDataUtil.buildMap(wxPayCloseRequest), signKey));
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(wxPayProperties.getGateway())
//xml转化器 SimpleXmlConverterFactory 需要另外添加依赖 不在retrofit2中
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
String xml = XmlUtil.toXMl(wxPayCloseRequest);
RequestBody body = RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml);
Call<WXPayCloseResponse> call = retrofit.create(WXPayExecute.class).closeOrder(body);
Response<WXPayCloseResponse> retrofitResponse = null;
try {
retrofitResponse = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
if (!retrofitResponse.isSuccessful()) {
throw new RuntimeException("【微信支付退款订单查询】查询失败, 网络异常");
}
WXPayCloseResponse response = retrofitResponse.body();
return response;
}
/*微信支付退款接口*/
public WXPayRefundResponse refund(WXPayRefundRequest wxPayRefundRequest, String keyPath) {
String signKey = wxPayProperties.getMchKey();
/* if(!wxPayProperties.getGateway().endsWith(SANDBOXNEW)){
signKey = getSignKey();
}*/
wxPayRefundRequest.setSign(SignatureUtil.sign(BuildDataUtil.buildMap(wxPayRefundRequest), signKey));
//初始化证书
if (wxPayProperties.getSslContext() == null) {
wxPayProperties.initSSLContext(keyPath);
}
OkHttpClient.Builder okHttpClient = new OkHttpClient()
.newBuilder()
.sslSocketFactory(wxPayProperties.getSslContext().getSocketFactory());
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(wxPayProperties.getGateway())
.addConverterFactory(SimpleXmlConverterFactory.create())
.client(okHttpClient.build())
.build();
String xml = XmlUtil.toXMl(wxPayRefundRequest);
System.out.println("refund request body ;" + xml);
RequestBody body = RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml);
Call<WXPayRefundResponse> call = retrofit.create(WXPayExecute.class).refund(body);
Response<WXPayRefundResponse> retrofitResponse = null;
try {
retrofitResponse = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
if (!retrofitResponse.isSuccessful()) {
throw new RuntimeException("【微信退款】发起退款, 网络异常");
}
WXPayRefundResponse response = retrofitResponse.body();
/*if (!response.getReturnCode().equals("SUCCESS")) {
throw new RuntimeException("【微信退款】发起退款, returnCode != SUCCESS, returnMsg = " + response.getReturnMsg());
}
if (!response.getResultCode().equals("SUCCESS")) {
throw new RuntimeException("【微信退款】发起退款, resultCode != SUCCESS, err_code = " + response.getErrCode() + " err_code_des=" + response.getErrCodeDes());
}*/
return response;
}
/*微信支付退款查询接口*/
public WXRefundQueryResponse refundQuery(WXRefundQueryRequest wxRefundQueryRequest) {
wxRefundQueryRequest.setAppid(wxPayProperties.getAppId());
wxRefundQueryRequest.setMchId(wxPayProperties.getMchId());
wxRefundQueryRequest.setNonceStr(RandomUtil.getRandomStr());
String signKey = wxPayProperties.getMchKey();
/*if(!wxPayProperties.getGateway().endsWith(SANDBOXNEW)){
signKey = getSignKey();
}*/
wxRefundQueryRequest.setSign(SignatureUtil.sign(BuildDataUtil.buildMap(wxRefundQueryRequest), signKey));
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(wxPayProperties.getGateway())
//xml转化器 SimpleXmlConverterFactory 需要另外添加依赖 不在retrofit2中
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
String xml = XmlUtil.toXMl(wxRefundQueryRequest);
RequestBody body = RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml);
Call<WXRefundQueryResponse> call = retrofit.create(WXPayExecute.class).refundQuery(body);
Response<WXRefundQueryResponse> retrofitResponse = null;
try {
retrofitResponse = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
if (!retrofitResponse.isSuccessful()) {
throw new RuntimeException("【微信支付退款订单查询】查询失败, 网络异常");
}
WXRefundQueryResponse response = retrofitResponse.body();
return response;
}
/*沙箱环境获取微信沙箱密钥*/
public String getSignKey() {
WXSignkeyRequest signkeyRequest = new WXSignkeyRequest();
signkeyRequest.setMchId(wxPayProperties.getMchId());
signkeyRequest.setNonceStr(UUID.randomUUID().toString().replaceAll("-", ""));
signkeyRequest.setSign(SignatureUtil.sign(BuildDataUtil.buildMap(signkeyRequest),wxPayProperties.getMchKey()));
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(wxPayProperties.getGateway())
//xml转化器 SimpleXmlConverterFactory 需要另外添加依赖 不在retrofit2中
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
String xml = XmlUtil.toXMl(signkeyRequest);
RequestBody body = RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml);
Call<WXSignkeyResponse> call = retrofit.create(WXPayExecute.class).getSignKey(body);
Response<WXSignkeyResponse> retrofitResponse = null;
try {
retrofitResponse = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
if (!retrofitResponse.isSuccessful()) {
throw new RuntimeException("【微信沙箱】获取沙箱signKey, 网络异常");
}
WXSignkeyResponse response = retrofitResponse.body();
if (!response.getReturnCode().equals("SUCCESS")) {
throw new RuntimeException("【微信沙箱】获取沙箱signKey, returnCode != SUCCESS, returnMsg = " + response.getReturnMsg());
}
return response.getSandboxSignkey();
}
}
通过maven deploy 就将 sdk包上传到了maven私服上,在其他应用中就可以使用maven坐标直接引用像这样:
<!-- 微信支付 -->
<dependency>
<groupId>com.xxx.wxpay</groupId>
<artifactId>wxpay-sdk-java</artifactId>
<version>1.0.5-SNAPSHOT</version>
</dependency>
在应用中引用方式举例,具体如何实例化WXPayService可以用 @bean注解
@Bean WXPayService wxPayService(){
return new WXPayService(getGateway, getAppId, getMchKey, getMchId, getMchKey)
}
@Resouce
WXPayService wxPayService
method{
wxPayService.appPrePay(payRequest)
}
欢迎小伙伴加微信探讨
源码已经提交到码云 https://gitee.com/tianji_luhaichuan/pay/tree/master/pay-sdk-scala
补充一句,加微信别老是您您您的,都是打工人,不必这么客气,我也才18啊哈哈
也请大家关注下博客谢谢