当前位置: 首页 > news >正文

springboot实现支付宝支付


maven引入

         <dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>3.7.4.AL</version></dependency>

配置

​package com.hyt.mall.pay.web.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

/**

  • @author zww

  • @Description:

  • @date 2022/9/14 11:13
    */
    @Configuration
    @PropertySource("classpath:alipay.properties")
    @ConfigurationProperties(prefix = "alipay")
    public class AlipayConfig {
    public static String appId;
    public static String privateKey;
    public static String publicKey;
    public static String notifyUrl;
    public static String returnUrl;
    public static String url;
    public static String charset;
    public static String format;
    public static String alipayPublicKey;
    public static String signType;
    public static String queryUrl;
    public static String refundUrl;
    public static String queryRefundUrl;
    public static String closeUrl;

    public String getAppId() {
    return appId;
    }

    public void setAppId(String appId) {
    AlipayConfig.appId = appId;
    }

    public String getPrivateKey() {
    return privateKey;
    }

    public void setPrivateKey(String privateKey) {
    AlipayConfig.privateKey = privateKey;
    }

    public String getPublicKey() {
    return publicKey;
    }

    public void setPublicKey(String publicKey) {
    AlipayConfig.publicKey = publicKey;
    }

    public String getNotifyUrl() {
    return notifyUrl;
    }

    public void setNotifyUrl(String notifyUrl) {
    AlipayConfig.notifyUrl = notifyUrl;
    }

    public String getReturnUrl() {
    return returnUrl;
    }

    public void setReturnUrl(String returnUrl) {
    AlipayConfig.returnUrl = returnUrl;
    }

    public String getUrl() {
    return url;
    }

    public void setUrl(String url) {
    AlipayConfig.url = url;
    }

    public String getCharset() {
    return charset;
    }

    public void setCharset(String charset) {
    AlipayConfig.charset = charset;
    }

    public String getFormat() {
    return format;
    }

    public void setFormat(String format) {
    AlipayConfig.format = format;
    }

    public String getAlipayPublicKey() {
    return alipayPublicKey;
    }

    public void setAlipayPublicKey(String alipayPublicKey) {
    AlipayConfig.alipayPublicKey = alipayPublicKey;
    }

    public String getSignType() {
    return signType;
    }

    public void setSignType(String signType) {
    AlipayConfig.signType = signType;
    }

    public String getQueryUrl() {
    return queryUrl;
    }

    public void setQueryUrl(String queryUrl) {
    AlipayConfig.queryUrl = queryUrl;
    }

    public String getRefundUrl() {
    return refundUrl;
    }

    public void setRefundUrl(String refundUrl) {
    AlipayConfig.refundUrl = refundUrl;
    }

    public String getQueryRefundUrl() {
    return queryRefundUrl;
    }

    public void setQueryRefundUrl(String queryRefundUrl) {
    AlipayConfig.queryRefundUrl = queryRefundUrl;
    }

    public String getCloseUrl() {
    return closeUrl;
    }

    public void setCloseUrl(String closeUrl) {
    AlipayConfig.closeUrl = closeUrl;
    }
    }
    实现类
    package com.hyt.mall.pay.web.service.impl.alipay;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.;
import com.alipay.api.response.
;
import com.hyt.mall.pay.web.config.AlipayConfig;
import com.hyt.mall.pay.web.req.OrderQueryReq;
import com.hyt.mall.pay.web.req.OrderRefundReq;
import com.hyt.mall.pay.web.req.OrderPayReq;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**

  • @author zww

  • @Description:

  • @date 2022/9/14 13:19
    */
    @Service
    public class AlipayServiceImpl {

    private static final Logger LOG = LoggerFactory.getLogger(AlipayServiceImpl.class);

    private AlipayClient alipayClient() {
    return new DefaultAlipayClient(AlipayConfig.url,AlipayConfig.appId,AlipayConfig.privateKey,
    AlipayConfig.format,AlipayConfig.charset,AlipayConfig.alipayPublicKey,AlipayConfig.signType);
    }

    /**

    • 支付接口
    • @return string
      */
      public String pay(OrderPayReq param) {
      LOG.info("支付参数:{}", param.toString());
      AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
      request.setNotifyUrl(AlipayConfig.notifyUrl);
      JSONObject bizContent = new JSONObject();
      bizContent.put("out_trade_no", param.getOrderNo());
      bizContent.put("total_amount", param.getAmount());
      bizContent.put("subject", param.getGoodsTitle());
      //bizContent.put("product_code", "QUICK_MSECURITY_PAY");
      request.setBizContent(bizContent.toString());
      try {
      AlipayTradeAppPayResponse response = alipayClient().sdkExecute(request);
      if(response.isSuccess()){
      return response.getBody();
      } else {
      return "error";
      }
      } catch (AlipayApiException e) {
      LOG.error("支付调用异常:{}", e.getMessage());
      return "error";
      }
      }

    /**

    • 统一收单线下交易查询
    • @return string
      */
      public String query(OrderQueryReq param) {
      AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
      JSONObject bizContent = new JSONObject();
      bizContent.put("out_trade_no", param.getOrderNo());
      //bizContent.put("trade_no", "2014112611001004680073956707");
      request.setBizContent(bizContent.toString());
      try {
      AlipayTradeQueryResponse response = alipayClient().execute(request);
      if(response.isSuccess()){
      return "success";
      } else {
      return "error";
      }
      } catch (AlipayApiException e) {
      LOG.error("交易查询调用异常:{}", e.getMessage());
      return "error";
      }
      }

    /**

    • 统一收单交易退款接口

    • @return string
      */
      public String refund(OrderRefundReq param) {
      LOG.info("退款参数:{}", param.toString());
      AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
      JSONObject bizContent = new JSONObject();
      bizContent.put("out_trade_no", param.getOrderNo());
      bizContent.put("refund_amount", param.getRefund());
      bizContent.put("out_request_no", param.getRefundNo());
      //bizContent.put("refund_reason", param.getReason());

      //// 返回参数选项,按需传入
      //JSONArray queryOptions = new JSONArray();
      //queryOptions.add("refund_detail_item_list");
      //bizContent.put("query_options", queryOptions);

      request.setBizContent(bizContent.toString());
      try {
      AlipayTradeRefundResponse response = alipayClient().execute(request);
      //JSONObject obj = (JSONObject) JSONObject.parse(JSON.toJSONString(response));
      if(response.isSuccess()){
      return "success";
      } else {
      return "error";
      }
      } catch (AlipayApiException e) {
      LOG.error("退款调用异常:{}", e.getMessage());
      return "error";
      }
      }

    /**

    • 统一收单交易退款查询

    • @return string
      */
      public String refundQuery(Map<String, Object> param) {
      AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
      JSONObject bizContent = new JSONObject();
      bizContent.put("out_trade_no", param.get("order_no"));
      bizContent.put("out_request_no", param.get("out_request_no"));

      //// 返回参数选项,按需传入
      //JSONArray queryOptions = new JSONArray();
      //queryOptions.add("refund_detail_item_list");
      //bizContent.put("query_options", queryOptions);

      request.setBizContent(bizContent.toString());
      try {
      AlipayTradeFastpayRefundQueryResponse response = alipayClient().execute(request);
      if(response.isSuccess()){
      return "success";
      } else {
      return "error";
      }
      } catch (AlipayApiException e) {
      LOG.error("易退款查询调用异常:{}", e.getMessage());
      return "error";
      }
      }

    /**

    • 统一收单交易关闭接口
    • @return string
      */
      public String close(OrderQueryReq param) {
      LOG.info("关闭参数:{}", param.toString());
      AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
      JSONObject bizContent = new JSONObject();
      bizContent.put("out_trade_no", param.getOrderNo());
      request.setBizContent(bizContent.toString());
      try {
      AlipayTradeCloseResponse response = alipayClient().execute(request);
      if(response.isSuccess()){
      return "success";
      } else {
      return "error";
      }
      } catch (AlipayApiException e) {
      LOG.error("关闭调用异常:{}", e.getMessage());
      return "error";
      }
      }

    public String notify(HttpServletRequest request, HttpServletResponse response) {
    Map<String, String> params = new HashMap<String, String>();
    try {
    //从支付宝回调的request域中取值
    Map<String, String[]> requestParams = request.getParameterMap();
    for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext()😉 {
    String name = iter.next();
    String[] values = requestParams.get(name);
    String valueStr = "";
    for (int i = 0; i < values.length; i++) {
    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
    }
    // 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
    // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
    params.put(name, valueStr);
    }
    //商品订单号
    String out_trade_no = request.getParameter("out_trade_no"); // 商户订单号
    // 当前交易状态
    String tradeStatus = request.getParameter("trade_status"); //交易状态
    // 支付金额
    String totalAmount = request.getParameter("total_amount"); //交易状态
    // 支付时间
    String payDate = request.getParameter("gmt_payment"); //交易状态
    //3.签名验证(对支付宝返回的数据验证,确定是支付宝返回的)调用SDK验证签名
    boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipayPublicKey, AlipayConfig.charset, AlipayConfig.signType);
    //返回状态存入redis中
    //对验签进行处理
    if (signVerified) {
    //验签通过
    if(tradeStatus.equals("TRADE_SUCCESS")) {
    return "success";
    } else {
    return "error";
    }
    } else { //验签不通过
    LOG.error("验签失败");
    return "failure";
    }
    } catch (AlipayApiException e) {
    LOG.error("验签失败:{}", e.getMessage());
    return "failure";
    }
    }
    }
    调用类
    package com.hyt.mall.pay.web.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hyt.mall.pay.web.service.impl.alipay.AlipayServiceImpl;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.hyt.mall.pay.web.config.WxpayConfig;
import com.hyt.mall.pay.web.req.OrderQueryReq;
import com.hyt.mall.pay.web.req.OrderRefundReq;
import com.hyt.mall.pay.web.req.OrderPayReq;
import com.hyt.mall.pay.web.req.TransferDetailReq;
import com.hyt.mall.pay.web.service.IPayService;
import com.hyt.mall.pay.web.service.IUrlService;
import com.hyt.mall.pay.web.service.impl.wechat.WechatAppServiceImpl;
import com.hyt.mall.pay.web.service.impl.wechat.WechatMiniServiceImpl;
import com.hyt.mall.pay.web.util.AesUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**

  • @author zww

  • @Description:

  • @date 2023/3/3 14:08
    */
    @Service
    public class PayServiceImpl implements IPayService {

    private static final Logger LOG = LoggerFactory.getLogger(PayServiceImpl.class);

    @Resource
    private WechatMiniServiceImpl wechatMiniService;
    @Resource
    private WechatAppServiceImpl wechatAppService;
    @Resource
    private AlipayServiceImpl alipayService;
    @Resource
    private IUrlService urlService;

    private RSAAutoCertificateConfig config;

    @Autowired
    public void setConfig(){

     // 检查文件是否存在  防止本地调试时,项目启动异常File file = new File(WxpayConfig.privateKeyPath);if (!file.exists()) {LOG.error("\033[31m警告:未找到微信支付私钥文件,微信支付功能将被禁用\033[0m");return;}config = new RSAAutoCertificateConfig.Builder().merchantId(WxpayConfig.mchId).privateKeyFromPath(WxpayConfig.privateKeyPath).merchantSerialNumber(WxpayConfig.mchSerialNo).apiV3Key(WxpayConfig.apiV3Key).build();
    

    }

    @Override
    public String pay(OrderPayReq param){
    switch (param.getPayType()) {
    case 1:
    return wechatMiniService.pay(param,config);
    case 2:
    return wechatAppService.pay(param,config);
    case 3:
    return alipayService.pay(param);
    default:
    return null;
    }
    }

    @Override
    public String query(OrderQueryReq param) {
    switch (param.getPayType()) {
    case 1:
    return wechatMiniService.query(param,config);
    case 2:
    return wechatAppService.query(param,config);
    case 3:
    return alipayService.query(param);
    default:
    return null;
    }
    }

    @Override
    public String refund(OrderRefundReq param) {
    switch (param.getPayType()) {
    case 1:
    return wechatMiniService.refund(param,config);
    case 2:
    return wechatAppService.refund(param,config);
    case 3:
    return alipayService.refund(param);
    default:
    return null;
    }
    }

    @Override
    public String refundQuery(Map<String, Object> param) {
    switch (param.get("payType").toString()) {
    case "1":
    return wechatMiniService.refundQuery(param, config);
    case "2":
    return wechatAppService.refundQuery(param, config);
    case "3":
    return alipayService.refundQuery(param);
    default:
    return null;
    }
    }

    @Override
    public String close(OrderQueryReq param) {
    switch (param.getPayType()) {
    case 1:
    return wechatMiniService.close(param, config);
    case 2:
    return wechatAppService.close(param, config);
    case 3:
    return alipayService.close(param);
    default:
    return null;
    }
    }

    @Override
    public String notify(HttpServletRequest request, HttpServletResponse response) {
    return null;
    }

    @Override
    public Map<String,String> wxNotify(JSONObject jsonObject) {
    //应答体
    Map<String,String> map = new HashMap<>();
    try {
    String key = WxpayConfig.apiV3Key;
    LOG.info("支付回调结果:{}", JSON.toJSONString(jsonObject));
    String paymentId = jsonObject.getString("id");
    JSONObject resourceObj = JSONObject.parseObject(JSON.toJSONString(jsonObject.get("resource")),JSONObject.class);
    String associated_data = resourceObj.getString("associated_data");
    String ciphertext = resourceObj.getString("ciphertext");
    String nonce = resourceObj.getString("nonce");

         String decryptData = new AesUtil(key.getBytes(StandardCharsets.UTF_8)).decryptToString(associated_data.getBytes(StandardCharsets.UTF_8),nonce.getBytes(StandardCharsets.UTF_8), ciphertext);//验签成功JSONObject obj = JSONObject.parseObject(decryptData, JSONObject.class);if (obj.get("trade_state").toString().equals("SUCCESS")) {String orderNo = obj.get("out_trade_no").toString();//String tradeType = obj.get("trade_type").toString();int result = urlService.updateOrderStatus(orderNo, 1, obj.get("transaction_id").toString());if (result > 0) {map.put("code","SUCCESS");map.put("message","成功");} else {LOG.info("单号:{}, 异常:{}", obj.get("out_trade_no").toString(), "修改订单状态失败!");map.put("code","FAIL");map.put("message","失败");}} else {LOG.info("单号:{}, 交易状态:{},异常:{}", obj.get("out_trade_no").toString(), obj.get("trade_state").toString(), "微信支付失败!");map.put("code","FAIL");map.put("message","失败");}return map;} catch (Exception e){LOG.info("params{}, 异常:", jsonObject.toJSONString(), e);map.put("code","FAIL");map.put("message","失败");return map;}
    

    }

    @Override
    public Map<String,String> wxRefundNotify(JSONObject jsonObject) {
    //应答体
    Map<String,String> map = new HashMap<>();
    try {
    String key = WxpayConfig.apiV3Key;
    JSONObject resourceObj = JSONObject.parseObject(JSON.toJSONString(jsonObject.get("resource")),JSONObject.class);
    String associated_data = resourceObj.getString("associated_data");
    String ciphertext = resourceObj.getString("ciphertext");
    String nonce = resourceObj.getString("nonce");

         String decryptData = new AesUtil(key.getBytes(StandardCharsets.UTF_8)).decryptToString(associated_data.getBytes(StandardCharsets.UTF_8),nonce.getBytes(StandardCharsets.UTF_8), ciphertext);//验签成功JSONObject obj = JSONObject.parseObject(decryptData, JSONObject.class);switch (obj.get("refund_status").toString()) {case "SUCCESS":JSONObject amountObj = JSONObject.parseObject(JSON.toJSONString(obj.get("amount")), JSONObject.class);Integer refundAmount = (Integer) amountObj.get("payer_refund");BigDecimal amount = BigDecimal.valueOf(refundAmount.floatValue()/100);int result = urlService.updateOrderRefundStatus(obj.get("out_trade_no").toString(), amount.setScale(2, BigDecimal.ROUND_HALF_UP));LOG.info("result:{}", result);if (result > 0) {map.put("code","SUCCESS");map.put("message","成功");} else {LOG.info("单号:{}, 异常:{}", obj.get("out_trade_no").toString(), "退款修改订单状态失败!");map.put("code", "FAIL");map.put("message", "退款关闭!");}return map;case "CLOSED":LOG.info("单号:{}, 异常:{}", obj.get("out_trade_no").toString(), "退款关闭!");map.put("code", "FAIL");map.put("message", "退款关闭!");break;case "ABNORMAL":LOG.info("单号:{}, 异常:{}", obj.get("out_trade_no").toString(), "退款异常,用户的卡作废或者冻结了!");map.put("code", "FAIL");map.put("message", "失败!退款异常,用户的卡作废或者冻结了!");break;default:map.put("code", "FAIL");map.put("message", "失败");break;}return map;}catch (Exception e){LOG.info("params{}, 异常:", jsonObject.toJSONString(), e);map.put("code","FAIL");map.put("message","失败");return map;}
    

    }

    @Override
    public String initiateBatchTransfer(TransferDetailReq param) {
    if (param.getTransferAmount().compareTo(BigDecimal.ZERO) <= 0) {
    LOG.info("initiateBatchTransfer:{}", param.toString());
    return null;
    }
    // String result = wechatMiniService.initiateBatchTransfer(param, config);
    // JSONObject json = JSONObject.parseObject(result, JSONObject.class);
    return wechatMiniService.initiateBatchTransfer(param, config);
    }

    @Override
    public String initiateBatchTransferList(List list) {
    if (ObjectUtils.isEmpty(list) || list.size() < 1) {
    return null;
    }
    return wechatMiniService.initiateBatchTransferList(list, config);
    }
    }

http://www.hskmm.com/?act=detail&tid=30997

相关文章:

  • Pendle Finance 详解:DeFi 中的“收益拆分器”——新手指南
  • 阅读笔记1
  • 17
  • springboot实现微信支付
  • Hyperliquid 主链的技术栈详解
  • trading
  • pringcloud 中的gateway详解一下,其中的原理
  • Hive -2025/8/19
  • MyBatisPlus
  • 2025年10月学术会议全名单!科研人请抢先收藏,别错过关键节点!
  • 用 Python + Vue3 打造超炫酷音乐播放器:网易云歌单爬取 + Three.js 波形可视化
  • 读书笔记:时间戳(TIMESTAMP)类型:比日期更强大的时间管理工具
  • python对比“解包赋值”和 match 语句中的“解构”
  • 2025 防静电/耐高温/耐低温/耐湿耐水/防油/耐酸耐碱/进口原料塑烧板厂家推荐榜单:聚焦高效过滤解决方案
  • 2025 优质的数控/空心管/螺旋/钢带/方向盘/伺服/液压/不锈钢带/桶箍/抱箍/卡箍/弹簧打圈机厂家推荐榜单:聚焦精度与服务的实力之选
  • 在线PS(Photoshop网页版)如何加马赛克,保护隐私的小技巧
  • 2025 深圳点胶机厂家实用推荐榜:从精密制造到行业适配的优选指南
  • 观点分享:Oracle数据库GRID升级的案例的闲聊
  • 2025 广东洗头机厂家推荐榜:从家用到商用的品质之选
  • 2025北京优质拆迁/征地/征拆/动迁/腾退/强拆/房产/烂尾楼/行政诉讼/行政赔偿律师事务所所推荐:聚焦专业实力与服务价值
  • excel单元格粘贴显示科学计数法,需要展示完整的字符串的解决方法
  • 2025 佛山高尔夫模拟器厂家推荐:从家庭到专业场景的靠谱之选
  • UML复习
  • 跨越三年周期、几十部门、上千零部件:庞大整车研发项目如何被清晰掌控?
  • 【SPIE出版】2025计算机视觉和影像计算国际学术会议
  • 2025 年济南画室最新推荐排行榜权威发布,含小班教学、全封闭管理机构及素描课、寒暑假班、高考集训选择指南
  • 2025 年贴片机优质厂家最新推荐排行榜:涵盖高精度高速固晶点胶等设备,助力企业精准选品高速/固晶/点胶/芯片/光模块贴片机厂家推荐
  • 2025 年真空共晶回流焊炉生产厂家最新推荐排行榜:聚焦国内优质品牌,助力企业精准采购真空共晶炉/真空回流焊炉/真空甲酸炉/半导体焊接炉厂家推荐
  • 高速采集卡:解锁海量数据洪流,驱动精准测量新时代
  • 基于MATLAB的HOG+SVM行人检测