Java 实现支付宝支付、退款、订单查询

您所在的位置:网站首页 支付宝中如何退款 Java 实现支付宝支付、退款、订单查询

Java 实现支付宝支付、退款、订单查询

2024-07-10 20:49| 来源: 网络整理| 查看: 265

最在开发一款APP,需要实现支付宝支付,记录一下实现过程

流程整体交互图如下所示 在这里插入图片描述

一、引入pom依赖 com.aliyun aliyun-java-sdk-core 4.0.3 二、初始化请求对象 @SneakyThrows(value = AlipayApiException.class) public AlipayClient initAlipay() { //构造client CertAlipayRequest certAlipayRequest = new CertAlipayRequest(); //设置网关地址 certAlipayRequest.setServerUrl(AliPayUtil.SERVER_URL); //设置应用Id certAlipayRequest.setAppId(AliPayUtil.APP_ID); //设置应用私钥 certAlipayRequest.setPrivateKey(AliPayUtil.PRIVATE_KEY); //设置请求格式,固定值json certAlipayRequest.setFormat(AliPayUtil.FORMAT); //设置字符集 certAlipayRequest.setCharset(AliPayUtil.CHARSET); //设置签名类型 certAlipayRequest.setSignType(AliPayUtil.SIGN_TYPE); //设置应用公钥证书路径 certAlipayRequest.setCertPath(AliPayUtil.CERT_PATH); //设置支付宝公钥证书路径 certAlipayRequest.setAlipayPublicCertPath(AliPayUtil.ALIPAY_PUBLIC_CER_PATH); //设置支付宝根证书路径 certAlipayRequest.setRootCertPath(AliPayUtil.ROOT_CER_PATH); //构造client return new DefaultAlipayClient(certAlipayRequest); } 三、生成支付宝订单

注意,这里返回orderStr需要返回前端、用于唤起支付宝APP

@SneakyThrows(value = AlipayApiException.class) public String alipayRecharge(AliPayModel aliPayModel) { //初始化配置信息 AlipayClient alipayClient = initAlipay(); //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest(); //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。 AlipayTradeAppPayModel model = new AlipayTradeAppPayModel(); String orderNumber = aliPayModel.getOrderNumber(); model.setBody(aliPayModel.getBody()); model.setSubject(aliPayModel.getSubject()); model.setOutTradeNo(orderNumber); model.setTimeoutExpress(AliPayUtil.TIME_OUT_EXPRESS); model.setTotalAmount(aliPayModel.getTotalAmount()); request.setBizModel(model); //异步通知地址 request.setNotifyUrl(AliPayUtil.NOTIFY_URL); try { //业务处理 //dosomething //这里和普通的接口调用不同,使用的是sdkExecute AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request); if (!response.isSuccess()) { log.error("接口调用错误:{}",response.getBody()); throw new AlipayApiException("接口调用错误"); } AliPayUtil.NOT_CLOSE_ORDER.put(orderNumber,aliPayModel); return response.getBody(); //就是orderString 可以直接给客户端请求,无需再做处理。 }catch(AlipayApiException e) { log.error("生成支付订单错误:",e); return null; } } 三、回调方法

用户在支付宝支付成功之后会回调此方法,接口在步骤二设置。

public String aliPayNotify(HttpServletRequest request) { // 将异步通知中收到的待验证所有参数都存放到map中 Map params = AliPayUtil.convertRequestParamsToMapWith(request); String paramsJson = JSON.toJSONString(params); log.info("支付宝回调,{}", paramsJson); try { // 调用SDK验证签名 boolean signVerified = AlipaySignature.rsaCertCheckV1(params, AliPayUtil.ALIPAY_PUBLIC_CER_PATH, AliPayUtil.CHARSET, AliPayUtil.SIGN_TYPE); if (signVerified) { // 按照支付结果异步通知中的描述,对支付结果中的业务内容进行1\2\3\4二次校验,校验成功后在response中返回success,校验失败返回failure AliPayUtil.check(params); String tradeStatus = params.get("trade_status"); String outTradeNo = params.get("out_trade_no"); String tradeNo = params.get("trade_no"); //通知状态为TRADE_SUCCESS或TRADE_FINISHED时,支付宝才会认定为买家付款成功 if(tradeStatus.equals(AliPayUtil.TRADE_SUCCESS) || tradeStatus.equals(AliPayUtil.TRADE_FINISHED)){ //业务逻辑处理 //do something } return "success"; } else { log.info("支付宝回调签名认证失败,signVerified=false, paramsJson:{}", paramsJson); return "failure"; } } catch (AlipayApiException e) { log.error("支付宝回调签名认证失败,paramsJson:{},errorMsg:{}", paramsJson, e.getMessage()); return "failure"; } }

注意:此处需返回给支付宝状态 success 或 failure

四、查询订单 @SneakyThrows(value = AlipayApiException.class) public String getAlipayOutTradeNo(Long outTradeNo, Long tradeNo) { //初始化支付宝配置 AlipayClient alipayClient = initAlipay(); AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); AlipayTradeQueryModel model = new AlipayTradeQueryModel(); model.setOutTradeNo(outTradeNo.toString()); if(tradeNo != null){ model.setTradeNo(tradeNo.toString()); } request.setBizModel(model); AlipayTradeQueryResponse response = alipayClient.certificateExecute(request); return response.getBody(); }

注意:查询订单时可用商品订单号(自己生成的订单号)或支付订单号(支付宝返回的订单号)进行查询,两个都有的情况下优先使用支付宝订单号~

五、退款 @SneakyThrows(value = AlipayApiException.class) public Boolean refund(String outTradeNo,String refundAmount,String refundReason) { AlipayClient alipayClient = initAlipay(); AlipayTradeRefundRequest alipayTradeCloseRequest =new AlipayTradeRefundRequest(); //请求参数集合对象,除了公共参数之外,所有参数都可通过此对象传递 AlipayTradeRefundModel alipayTradeRefundModel =new AlipayTradeRefundModel(); //退款的订单号,传入生成支付订单时的订单号即可 alipayTradeRefundModel.setOutTradeNo(outTradeNo); //退款金额 alipayTradeRefundModel.setRefundAmount(refundAmount); //退款的原因 alipayTradeRefundModel.setRefundReason(refundReason); alipayTradeCloseRequest.setBizModel(alipayTradeRefundModel); //退款的执行流程与支付不太一样,支付时成功之后,需要通知回调接口,而退款则不需要,只需判断响应 参数 refundResponse.getFundChange().equals("Y") 判断是否发生了资金变化, equals("Y")表示资金发生了变化,退款成功 AlipayTradeRefundResponse response = alipayClient.execute(alipayTradeCloseRequest); return response.isSuccess() && response.getFundChange().equals("Y"); }

注意:退款需要传三个参数,商品订单号(自己生成的订单号)、退款原因和退款金额

六、使用到的工具类(仅供参考)

工具类包含支付宝初始化参数、订单号生成方法、解析支付宝消息方法、订单金额验证方法和签名验证方法

@Slf4j public class AliPayUtil { public static Map NOT_CLOSE_ORDER = new HashMap(); public static String TIME_OUT_EXPRESS = "30m"; public static String APP_ID = ""; public static String SERVER_URL = ""; public static String PRIVATE_KEY = ""; public static String NOTIFY_URL = ""; public static String CERT_PATH = ""; public static String ALIPAY_PUBLIC_CER_PATH = ""; public static String ROOT_CER_PATH = ""; public static String CHARSET = "utf-8"; public static String FORMAT = "json"; public static String SIGN_TYPE = "RSA2"; public static String TRADE_SUCCESS = "TRADE_SUCCESS"; public static String TRADE_FINISHED = "TRADE_FINISHED"; private static final Random random = new Random(); public static String generateOrderNumber(int userId, int productId) { // 获取当前时间戳 long timestamp = System.currentTimeMillis(); // 生成6位随机数 int randomNum = random.nextInt(900000) + 100000; // 组装订单号 return String.format("%d%d%d%d", timestamp, randomNum, userId, productId); } /** * request 转 map * * @param request * @return */ public static Map convertRequestParamsToMapWith(HttpServletRequest request) { Map params = new HashMap(); Map requestParams = request.getParameterMap(); for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) { String name = (String) iter.next(); String[] values = (String[]) requestParams.get(name); String valueStr = ""; for (int i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3