这阵子在公司做了关于网上支付的功能模块,包含了微信支付和支付宝支付,特此写下该笔记总结遇到的问题和解决方法。
编程语言为JAVA,采用的框架是SpringBoot+Mybatis,此篇主要介绍支付宝支付(包含H5,App)。
先上代码
控制层
/**
* @author Huang
* @version 创建时间:2017年6月2日 下午5:16:45
*/
@RestController
@RequestMapping("/alipay")
public class ALiPayController {
private static Logger LOG = Logger.getLogger(ALiPayController.class);
@Autowired
private ALiPayService aLiPayService;
@Autowired
//订单核心业务
private ShortRentOrderService ShortRentOrderService;
@Autowired
private PayService payService;
/**
* createOrder app统一下单
* @param billNo String 订单编号
* @return
*/
@RequestMapping("/app/createOrder")
public @ResponseBody Result createAppOrder(String tradeNo, HttpServletResponse response) {
// 获取订单详情
ShortRentOrderDto dto = ShortRentOrderService.getShortRentOrderDetail(tradeNo);
// 生成带时间戳的订单号,否则无法重复调起支付。
String newbillNo = payService.createNewOrderNo(tradeNo);
// 保存请求参数,回调时根据带时间戳的订单号获取到相应的真实订单号
payService.savePayRequest(newbillNo, dto, PayTypeEnums.ALIPAY.getIndex(), SourceTypeEnums.ANDROID.getIndex());
// 向支付宝发送请求
Result result = aLiPayService.createAppOrder(newbillNo, dto.getModelName(), dto.getModelName(),
dto.getOrderTotalPrice());
if (result.getCode() == Constants.FAILURE_CODE) {
return result;
}
return new Result(Constants.SUCCESS_CODE, "", result.getData());
}
/**
* createOrder h5统一下单
* @param billNo String 订单编号
* @return
*/
@RequestMapping("/h5/createOrder")
public @ResponseBody Result createH5Order(String tradeNo, HttpServletResponse response) {
// 获取订单详情
ShortRentOrderDto dto = ShortRentOrderService.getShortRentOrderDetail(tradeNo);
// 生成带时间戳的订单号,否则无法重复调起支付
String newbillNo = payService.createNewOrderNo(tradeNo);
// 保存请求参数
payService.savePayRequest(newbillNo, dto, PayTypeEnums.ALIPAY.getIndex(), SourceTypeEnums.H5.getIndex());
// 向支付宝发送请求
Result result = aLiPayService.createH5Order(newbillNo, dto.getModelName(), dto.getModelName(),
dto.getOrderTotalPrice());
if (result.getCode() == Constants.FAILURE_CODE) {
return result;
}
return new Result(Constants.SUCCESS_CODE, "", result.getData());
}
@RequestMapping("/orderQuery")
public Result orderQuery(String erpOrderId, String aliOrderId) {
// 向支付宝发送查询请求
return aLiPayService.orderQuery(erpOrderId, aliOrderId);
}
@RequestMapping(value = "/notify-url", method = { RequestMethod.POST })
public @ResponseBody String notifyUrl(HttpServletRequest request, HttpServletResponse response) {
Map<String, String> params = HttpUtils.getRequestParamMap(request);
// 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)
return aLiPayService.payNotify(params);
}
}
业务层
/**
* @author Huang
* @version 创建时间:2017年6月5日 上午11:02:21
*/
@Service
public class ALiPayServiceImpl implements ALiPayService {
private static Logger LOG = Logger.getLogger(ALiPayServiceImpl.class);
// 实例化客户端
private AlipayClient alipayClient = null;
@Autowired
private ALiPayProperties aliProperties;
@Autowired
private PayService payService;
@Override
public Result createAppOrder(String billNo, String subject, String body, BigDecimal totalAmount) {
// 实例化客户端
initClient();
// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//
// SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody(body);
model.setSubject(subject);
model.setOutTradeNo(billNo);
model.setTimeoutExpress(aliProperties.getOverTime());
model.setTotalAmount(String.valueOf(totalAmount.setScale(