提交 0a19d3dc 编写于 作者: zhouweidong's avatar zhouweidong

支持微信支付

上级 e352a8db
...@@ -32,7 +32,9 @@ public class PayTradeAspect { ...@@ -32,7 +32,9 @@ public class PayTradeAspect {
Object serviceParam =args[0]; Object serviceParam =args[0];
if(serviceParam instanceof PayTrade){ if(serviceParam instanceof PayTrade){
PayTrade entity=(PayTrade)serviceParam; PayTrade entity=(PayTrade)serviceParam;
entity.setTradeId((String) entity.getDefaultKey(true));
entity.setTradeName(entity.getSubject()); entity.setTradeName(entity.getSubject());
entity.setTradeStatus("NOTPAY");
payTradeService.save(entity); payTradeService.save(entity);
} }
} }
......
...@@ -2,6 +2,7 @@ package cn.ibizlab.core.extensions.service; ...@@ -2,6 +2,7 @@ package cn.ibizlab.core.extensions.service;
import cn.ibizlab.core.extensions.service.wechat.WXPay; import cn.ibizlab.core.extensions.service.wechat.WXPay;
import cn.ibizlab.core.extensions.service.wechat.WechatPayConfig; import cn.ibizlab.core.extensions.service.wechat.WechatPayConfig;
import cn.ibizlab.core.extensions.service.wechat.WechatPayDomain;
import cn.ibizlab.core.pay.domain.PayOpenAccess; import cn.ibizlab.core.pay.domain.PayOpenAccess;
import cn.ibizlab.core.pay.domain.PayTrade; import cn.ibizlab.core.pay.domain.PayTrade;
import cn.ibizlab.core.pay.service.IPayOpenAccessService; import cn.ibizlab.core.pay.service.IPayOpenAccessService;
...@@ -37,7 +38,10 @@ public class PayCoreService { ...@@ -37,7 +38,10 @@ public class PayCoreService {
IPayTradeService tradeService; IPayTradeService tradeService;
@Value("${ibz.pay.ali.pagepay.returnurl:http://127.0.0.1:8080/pay/trade/pagepay/callback}") @Value("${ibz.pay.ali.pagepay.returnurl:http://127.0.0.1:8080/pay/trade/pagepay/callback}")
private String ali_return_url; private String ali_notify_url;
@Value("${ibz.pay.wechat.returnurl:http://127.0.0.1:8080/pay/trade/callback}")
private String wechat_notify_url;
@Value("${ibz.pay.ali.gateway:https://openapi.alipaydev.com/gateway.do}") @Value("${ibz.pay.ali.gateway:https://openapi.alipaydev.com/gateway.do}")
private String ali_gateway; private String ali_gateway;
...@@ -53,11 +57,12 @@ public class PayCoreService { ...@@ -53,11 +57,12 @@ public class PayCoreService {
*/ */
@SneakyThrows @SneakyThrows
public String pagePay(PayTrade trade){ public String pagePay(PayTrade trade){
PayOpenAccess openAccess=getOpenAccess(trade); PayOpenAccess openAccess=getOpenAccess(trade.getAccessId());
trade.setAccessId(openAccess.getId());
AlipayClient alipayClient = getAliPayClient(openAccess); AlipayClient alipayClient = getAliPayClient(openAccess);
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setReturnUrl(openAccess.getRedirectUri()); request.setReturnUrl(openAccess.getRedirectUri());
request.setNotifyUrl(ali_return_url); request.setNotifyUrl(ali_notify_url);
request.setBizContent( request.setBizContent(
"{\"out_trade_no\":\""+ trade.getOutTradeNo() +"\"," "{\"out_trade_no\":\""+ trade.getOutTradeNo() +"\","
+ "\"total_amount\":\""+ trade.getTotalAmount() +"\"," + "\"total_amount\":\""+ trade.getTotalAmount() +"\","
...@@ -79,7 +84,6 @@ public class PayCoreService { ...@@ -79,7 +84,6 @@ public class PayCoreService {
* @return * @return
*/ */
public String pagePayCallBack(HttpServletRequest req){ public String pagePayCallBack(HttpServletRequest req){
JSONObject paramMap=new JSONObject(); JSONObject paramMap=new JSONObject();
Enumeration names = req.getParameterNames(); Enumeration names = req.getParameterNames();
while(names.hasMoreElements()) { while(names.hasMoreElements()) {
...@@ -87,26 +91,18 @@ public class PayCoreService { ...@@ -87,26 +91,18 @@ public class PayCoreService {
String value = req.getParameter(key); String value = req.getParameter(key);
paramMap.put(key,value); paramMap.put(key,value);
} }
// String result_code=paramMap.getString("code");
// String result_sub_code=paramMap.getString("sub_code");
String out_trade_no=paramMap.getString("out_trade_no"); String out_trade_no=paramMap.getString("out_trade_no");
// String app_id=paramMap.getString("app_id");
String total_amount=paramMap.getString("total_amount"); String total_amount=paramMap.getString("total_amount");
String trade_status=paramMap.getString("trade_status"); String trade_status=paramMap.getString("trade_status");
if(StringUtils.isEmpty(out_trade_no)) if(StringUtils.isEmpty(out_trade_no))
return String.format("没有找到[%s]订单信息",out_trade_no); return String.format("没有找到[%s]订单信息",out_trade_no);
// String tradeId= DigestUtils.md5DigestAsHex(String.format(out_trade_no+"||"+app_id).getBytes()); PayTrade trade = tradeService.getOne(Wrappers.<PayTrade>lambdaQuery().eq(PayTrade::getOutTradeNo,out_trade_no).eq(PayTrade::getTradeStatus,"NOTPAY"));
PayTrade trade = tradeService.getOne(Wrappers.<PayTrade>lambdaQuery().eq(PayTrade::getOutTradeNo,out_trade_no).eq(PayTrade::getTradeStatus,"pending"));
if(trade==null) if(trade==null)
return String.format("没有找到[%s]待付款订单",out_trade_no); return String.format("没有找到[%s]待付款订单",out_trade_no);
//确认订单金额 //确认订单金额
if(!total_amount.equals(trade.getTotalAmount())) if(!total_amount.equals(trade.getTotalAmount()))
return String.format("交易订单金额[%s]与支付平台金额[%s]不吻合",total_amount,trade.getTotalAmount()); return String.format("交易订单金额[%s]与支付平台金额[%s]不吻合",total_amount,trade.getTotalAmount());
PayOpenAccess openAccess=trade.getOpenaccess(); PayOpenAccess openAccess=trade.getOpenaccess();
if(openAccess==null){ if(openAccess==null){
openAccess= openAccessService.get(trade.getAccessId()); openAccess= openAccessService.get(trade.getAccessId());
...@@ -114,7 +110,6 @@ public class PayCoreService { ...@@ -114,7 +110,6 @@ public class PayCoreService {
String notify_url=openAccess.getNotifyUrl(); String notify_url=openAccess.getNotifyUrl();
if(StringUtils.isEmpty(notify_url)) if(StringUtils.isEmpty(notify_url))
return String.format("无法获取[%s]开放平台回调地址",trade.getAccessId()); return String.format("无法获取[%s]开放平台回调地址",trade.getAccessId());
//修改订单状态 //修改订单状态
if(trade_status.equals("TRADE_SUCCESS")){ if(trade_status.equals("TRADE_SUCCESS")){
trade.setTradeStatus("success"); trade.setTradeStatus("success");
...@@ -129,200 +124,88 @@ public class PayCoreService { ...@@ -129,200 +124,88 @@ public class PayCoreService {
} }
/** /**
* 预创建订单,生成支付二维码 * 下订单,获取支付链接
* @param trade * @param trade 订单信息
* @return
*/
public JSONObject preCreate(PayTrade trade){
JSONObject rs=new JSONObject();
PayOpenAccess openAccess=getOpenAccess(trade);
switch (openAccess.getOpenType()){
case "aliyun":
// qrcode=aliPayPreCreate(openAccess,trade);
break;
case "wechat":
rs= wechatPreCreate(openAccess,trade);
break;
}
return rs;
}
/**
* 查询订单
* @param trade
* @return * @return
*/ */
public JSONObject query(PayTrade trade){
JSONObject rs=new JSONObject();
PayOpenAccess openAccess=getOpenAccess(trade);
switch (openAccess.getOpenType()){
case "aliyun":
// aliPayQuery(openAccess,trade);
break;
case "wechat":
rs=wechatPayQuery(openAccess,trade);
break;
}
return rs;
}
/**
* 取消订单
* @param trade
* @return
*/
public JSONObject cancel(PayTrade trade){
JSONObject rs=new JSONObject();
PayOpenAccess openAccess=getOpenAccess(trade);
switch (openAccess.getOpenType()){
case "aliyun":
// aliPayCancel(openAccess,trade);
break;
case "wechat":
rs=wechatPayCancel(openAccess,trade);
break;
}
return rs;
}
// /**
// * 交易预创建,生成正扫二维码
// * @param trade
// */
// @SneakyThrows
// private String aliPayPreCreate(PayOpenAccess openAccess,PayTrade trade){
// AlipayClient alipayClient = getAliPayClient(openAccess);
// AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
// request.setBizContent("{" +
// "\"out_trade_no\":\""+trade.getOutTradeNo()+"\"," +
// "\"subject\":\""+trade.getSubject()+"\"," +
// "\"total_amount\":"+trade.getTotalAmount()+"," +
// " }");
// AlipayTradePrecreateResponse response = alipayClient.execute(request);
// if(response.isSuccess()){
// System.out.println("调用成功");
// } else {
// System.out.println("调用失败");
// }
// return response.getQrCode();
// }
//
// /**
// * 交易查询
// * @param trade
// */
// @SneakyThrows
// private String aliPayQuery(PayOpenAccess openAccess,PayTrade trade){
// AlipayClient alipayClient = getAliPayClient(openAccess);
// AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
// request.setBizContent("{" +
// "\"out_trade_no\":\""+trade.getOutTradeNo()+"\"," +
// " }");
// AlipayTradeQueryResponse response = alipayClient.execute(request);
// if(response.isSuccess()){
// System.out.println("调用成功");
// } else {
// System.out.println("调用失败");
// }
// return response.getBody();
// }
//
// /**
// * 撤销交易
// * @param trade
// */
// @SneakyThrows
// private String aliPayCancel(PayOpenAccess openAccess,PayTrade trade) {
// AlipayClient alipayClient = getAliPayClient(openAccess);
// AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
// request.setBizContent("{" +
// "\"out_trade_no\":\""+trade.getOutTradeNo()+"\"," +
// " }");
// AlipayTradeCancelResponse response = alipayClient.execute(request);
// if(response.isSuccess()){
// System.out.println("调用成功");
// } else {
// System.out.println("调用失败");
// }
// return response.getOutTradeNo();
// }
/**
* 微信预创建订单
* @param trade
*/
@SneakyThrows @SneakyThrows
private JSONObject wechatPreCreate(PayOpenAccess openAccess,PayTrade trade) { public JSONObject preCreate(PayTrade trade){
JSONObject rs=new JSONObject(); PayOpenAccess openAccess=getOpenAccess(trade.getAccessId());
trade.setAccessId(openAccess.getId());
WechatPayConfig config = getWechatPayConfig(openAccess); WechatPayConfig config = getWechatPayConfig(openAccess);
WXPay wxpay = new WXPay(config); WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<String, String>(); Map<String, String> data = new HashMap<String, String>();
data.put("body", trade.getSubject()); data.put("body", trade.getSubject());
data.put("out_trade_no", trade.getOutTradeNo()); data.put("out_trade_no", trade.getOutTradeNo());
// data.put("device_info", "");
data.put("fee_type", "CNY"); data.put("fee_type", "CNY");
data.put("total_fee",trade.getTotalAmount()); data.put("total_fee",trade.getTotalAmount());
// data.put("spbill_create_ip", "123.12.12.123"); data.put("notify_url", wechat_notify_url);
data.put("notify_url", openAccess.getRedirectUri());
data.put("trade_type", "NATIVE"); // 此处指定为扫码支付 data.put("trade_type", "NATIVE"); // 此处指定为扫码支付
// data.put("product_id", "12"); return getResult(wxpay.unifiedOrder(data));
Map resp = wxpay.unifiedOrder(data);
if(resp!=null){
rs=new JSONObject(resp);
}
return rs;
} }
/** /**
* 微信:订单查询 * 查询订单
* @param trade * @param accessId 开放平台配置标识
* @param outTradeNo 订单号
* @return
*/ */
@SneakyThrows @SneakyThrows
private JSONObject wechatPayQuery(PayOpenAccess openAccess,PayTrade trade) { public JSONObject query(String accessId,String outTradeNo){
JSONObject rs=new JSONObject(); PayOpenAccess openAccess=getOpenAccess(accessId);
WechatPayConfig config = getWechatPayConfig(openAccess); WechatPayConfig config = getWechatPayConfig(openAccess);
WXPay wxpay = new WXPay(config); WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<String, String>(); Map<String, String> data = new HashMap<String, String>();
data.put("out_trade_no", trade.getOutTradeNo()); data.put("out_trade_no", outTradeNo);
Map resp = wxpay.orderQuery(data); Map rsMap=wxpay.orderQuery(data);
if(resp!=null){ JSONObject rs=getResult(rsMap);
rs=new JSONObject(resp); String trade_status=rs.getString("trade_state");
if(!StringUtils.isEmpty(trade_status)){
//更新订单状态
PayTrade trade=new PayTrade();
trade.setAccessId(openAccess.getId());
trade.setOutTradeNo(outTradeNo);
trade.setTradeStatus(trade_status);
trade.setTradeId((String) trade.getDefaultKey(true));
tradeService.update(trade);
if("SUCCESS".equals(trade_status)){
//回调业务系统
HttpUtils.post(openAccess.getNotifyUrl(), null, new JSONObject(rsMap));
}
} }
return rs; return rs;
} }
/** /**
* 微信:取消订单 * 取消订单
* @param trade * @param accessId 开放平台配置标识
* @param outTradeNo 订单号
* @return
*/ */
@SneakyThrows @SneakyThrows
private JSONObject wechatPayCancel(PayOpenAccess openAccess,PayTrade trade) { public JSONObject cancel(String accessId,String outTradeNo){
JSONObject rs=new JSONObject(); PayOpenAccess openAccess=getOpenAccess(accessId);
WechatPayConfig config = getWechatPayConfig(openAccess); WechatPayConfig config = getWechatPayConfig(openAccess);
WXPay wxpay = new WXPay(config); WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<String, String>(); Map<String, String> data = new HashMap<String, String>();
data.put("out_trade_no", trade.getOutTradeNo()); data.put("out_trade_no", outTradeNo);
Map resp = wxpay.closeOrder(data); return getResult(wxpay.closeOrder(data));
if(resp!=null){
rs=new JSONObject(resp);
}
return rs;
} }
public String callBack(HttpServletRequest req){
return "success";
}
/** /**
* 获取开放平台信息 * 获取开放平台信息
* @param trade * @param id
* @return * @return
*/ */
private PayOpenAccess getOpenAccess(PayTrade trade){ private PayOpenAccess getOpenAccess(String id){
PayOpenAccess openAccess=null; PayOpenAccess openAccess=null;
String accessId=trade.getAccessId(); if(!StringUtils.isEmpty(id))
String appId=trade.getAppId(); openAccess=openAccessService.getOne(Wrappers.<PayOpenAccess>lambdaQuery().eq(PayOpenAccess::getAccessKey,id).or().eq(PayOpenAccess::getId,id));
if(!StringUtils.isEmpty(accessId))
openAccess=openAccessService.getOne(Wrappers.<PayOpenAccess>lambdaQuery().eq(PayOpenAccess::getAccessKey,appId).or().eq(PayOpenAccess::getId,accessId));
if(ObjectUtils.isEmpty(openAccess) || (openAccess.getDisabled()!=null && openAccess.getDisabled()==1)) if(ObjectUtils.isEmpty(openAccess) || (openAccess.getDisabled()!=null && openAccess.getDisabled()==1))
throw new BadRequestAlertException("获取开放平台配置失败","PayCoreService","pagePay"); throw new BadRequestAlertException("获取开放平台配置失败","PayCoreService","pagePay");
trade.setAccessId(openAccess.getId());
return openAccess; return openAccess;
} }
...@@ -346,12 +229,34 @@ public class PayCoreService { ...@@ -346,12 +229,34 @@ public class PayCoreService {
* @param openAccess * @param openAccess
* @return * @return
*/ */
@SneakyThrows
private WechatPayConfig getWechatPayConfig(PayOpenAccess openAccess) { private WechatPayConfig getWechatPayConfig(PayOpenAccess openAccess) {
WechatPayConfig config=new WechatPayConfig(); WechatPayConfig config=new WechatPayConfig();
config.setAppID(openAccess.getAccessKey()); config.setAppID(openAccess.getAccessKey());
config.setKey(openAccess.getAccessKey()); config.setKey(openAccess.getSecretKey());
config.setMchID(openAccess.getRegionId()); config.setMchID(openAccess.getAccessToken());
config.setWXPayDomain(null); config.setWXPayDomain(new WechatPayDomain());
return config; return config;
} }
/**
* 移除敏感信息
* @param resp
* @return
*/
private JSONObject getResult(Map resp){
JSONObject rs=new JSONObject();
if(resp!=null){
rs=new JSONObject(resp);
rs.remove("device_info");
rs.remove("nonce_str");
rs.remove("appid");
rs.remove("sign");
rs.remove("mch_id");
rs.remove("prepay_id");
rs.remove("return_code");
rs.remove("return_msg");
}
return rs;
}
} }
package cn.ibizlab.core.extensions.service.wechat; package cn.ibizlab.core.extensions.service.wechat;
import lombok.Data; import lombok.Data;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
@Data @Data
...@@ -22,44 +17,4 @@ public class WechatPayConfig extends WXPayConfig { ...@@ -22,44 +17,4 @@ public class WechatPayConfig extends WXPayConfig {
private InputStream certStream; private InputStream certStream;
private IWXPayDomain WXPayDomain; private IWXPayDomain WXPayDomain;
// public WechatPayConfig() throws Exception {
// String certPath = "/path/to/apiclient_cert.p12";
// File file = new File(certPath);
// InputStream certStream = new FileInputStream(file);
// this.certData = new byte[(int) file.length()];
// certStream.read(this.certData);
// certStream.close();
// }
//
// public String getAppID() {
// return "wx8888888888888888";
// }
//
// public String getMchID() {
// return "12888888";
// }
//
// public String getKey() {
// return "88888888888888888888888888888888";
// }
// public InputStream getCertStream() {
// ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
// return certBis;
// }
// public int getHttpConnectTimeoutMs() {
// return 8000;
// }
//
// public int getHttpReadTimeoutMs() {
// return 10000;
// }
// @Override
// IWXPayDomain getWXPayDomain() {
// return null;
// }
} }
\ No newline at end of file
package cn.ibizlab.core.extensions.service.wechat;
public class WechatPayDomain implements IWXPayDomain {
@Override
public void report(String domain, long elapsedTimeMillis, Exception ex) {
}
@Override
public DomainInfo getDomain(WXPayConfig config) {
return new DomainInfo("api.mch.weixin.qq.com",true);
}
}
...@@ -10,11 +10,10 @@ import org.springframework.context.annotation.Lazy; ...@@ -10,11 +10,10 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
@RestController @RestController
public class PayCoreResource { public class PayCoreResource {
...@@ -34,15 +33,23 @@ public class PayCoreResource { ...@@ -34,15 +33,23 @@ public class PayCoreResource {
} }
@ApiOperation(value = "查询订单", tags = {"查询订单" }, notes = "查询订单") @ApiOperation(value = "查询订单", tags = {"查询订单" }, notes = "查询订单")
@RequestMapping(method = RequestMethod.POST,value = "/pay/trade/query") @RequestMapping(method = RequestMethod.GET,value = "/pay/trade/query")
public ResponseEntity<JSONObject> query(@Validated @RequestBody PayTradeDTO dto){ public ResponseEntity<JSONObject> query(@Validated @NotBlank(message = "开放平台配置标识不允许为空")@RequestParam("accessid") String accessId,
return ResponseEntity.status(HttpStatus.OK).body(payCoreService.query(payTradeMapping.toDomain(dto))); @NotBlank(message = "订单号不允许为空") @RequestParam("out_trade_no") String outTradeNo){
return ResponseEntity.status(HttpStatus.OK).body(payCoreService.query(accessId,outTradeNo));
} }
@ApiOperation(value = "取消订单", tags = {"取消订单" }, notes = "取消订单") @ApiOperation(value = "取消订单", tags = {"取消订单" }, notes = "取消订单")
@RequestMapping(method = RequestMethod.POST,value = "/pay/trade/cancel") @RequestMapping(method = RequestMethod.GET,value = "/pay/trade/cancel")
public ResponseEntity<JSONObject> cancel(@Validated @RequestBody PayTradeDTO dto){ public ResponseEntity<JSONObject> cancel(@Validated @NotBlank(message = "开放平台配置标识不允许为空")@RequestParam("accessid") String accessId,
return ResponseEntity.status(HttpStatus.OK).body(payCoreService.cancel(payTradeMapping.toDomain(dto))); @NotBlank(message = "订单号不允许为空") @RequestParam("out_trade_no") String outTradeNo){
return ResponseEntity.status(HttpStatus.OK).body(payCoreService.cancel(accessId,outTradeNo));
}
@ApiOperation(value = "支付回调", tags = {"支付回调" }, notes = "支付回调")
@RequestMapping(value = "/pay/trade/callback")
public ResponseEntity<String> callBack(HttpServletRequest req) {
return ResponseEntity.status(HttpStatus.OK).body(payCoreService.callBack(req));
} }
@ApiOperation(value = "网页支付", tags = {"网页支付" }, notes = "网页支付") @ApiOperation(value = "网页支付", tags = {"网页支付" }, notes = "网页支付")
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册