支付宝支付 第十集:支付回调

2023-10-30

支付宝支付 第十集:支付回调



一、注意
  • 这里的支付回调最好是自己有一个服务器(阿里云服务器一年70多也不是很贵),博主自己尝试了一下,本机和使用虚拟机模拟服务器的话,支付宝的授权回调信息是传不过来的,无法进行支付回调!!!
  • 怎样使用阿里云服务器运行Java项目?
  • 为什么接收不到回调信息?
    一定要注意在沙盒设置中的授权回调地址,一般自己的服务器都是http不是https!!!写错了的话是接收不到回调信息的!!!

    在这里插入图片描述

  • 为什么接收到了支付宝回调信息,写不到数据库中?
    检查自己传给支付宝的参数的名称,与传回来的解析名称是否一致,我传过去的时候是ID,接受回调信息进行解析的时候,写的是Id,导致一直无法识别回调信息。。。。

    在这里插入图片描述

    在这里插入图片描述



二、代码
  • 目录结构

    在这里插入图片描述

    在这里插入图片描述

  • 更新AlipayController.java
    package com.dzy.alipay.web;
    
    import com.alibaba.fastjson.JSONObject;
    import com.alipay.api.internal.util.StringUtils;
    import com.dzy.alipay.service.AlipayService;
    import com.dzy.alipay.service.pay.PayCommonService;
    import com.dzy.alipay.vo.PayVo;
    import lombok.extern.log4j.Log4j2;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.servlet.http.HttpServletRequest;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    
    @Controller
    @Log4j2
    public class AlipayController {
        private final AlipayService alipayService;
    
        private final PayCommonService payCommonService;
    
        public AlipayController(AlipayService alipayService, PayCommonService payCommonService) {
            this.alipayService = alipayService;
            this.payCommonService = payCommonService;
        }
    
        @GetMapping("/alipay/pay")
        @ResponseBody
        public byte[] alipay(String courseID) {
            PayVo payVo = new PayVo();
            payVo.setCourseid(courseID);
            payVo.setUserId("1");
            return alipayService.alipay(payVo);
        }
    
        /**
         * 定义支付回调的地址
         */
        @ResponseBody
        @RequestMapping("/aliPayNotifyUr")
        public String notify_url(HttpServletRequest request) throws Exception {
            boolean result = alipayCallback(request);
            if (result) {
                System.out.println("success");
                return "success"; // 请不要修改或删除
            } else {
                // 验证失败
                System.out.println("fail");
                return "fail";
            }
        }
    
        /**
         * 支付宝回调
         */
        private boolean alipayCallback(HttpServletRequest request) throws Exception {
            // 获取支付宝GET过来反馈信息
            Map<String, String> params = new HashMap<String, String>();
            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 < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i]
                            : valueStr + values[i] + ",";
                }
                params.put(name, new String(valueStr.getBytes("ISO-8859-1"), "UTF-8"));
            }
    
            // 计算得出通知验证结果
            log.info("1:---->获取支付宝回传的参数---------------------------------->" + params);
            // 支付宝返回的请求参数body
            String extparamString = request.getParameter("extra_common_param");
    
    
            log.info("2---->:支付宝交易返回的参数:{}", extparamString);
            String tradeno = params.get("trade_no");;
            //交易完成
            String body = params.get("body");
            if (StringUtils.isEmpty(tradeno)) {
                tradeno = params.get("trade_no");
            }
    
    
            log.info("3---->:【支付宝】交易的参数信息是:{},流水号是:{}", body, tradeno);
            try {
                JSONObject bodyJson = JSONObject.parseObject(body);
                String userId = bodyJson.getString("userId");
                String ptype = bodyJson.getString("ptype");
                String orderNumber = bodyJson.getString("orderNumber");
                log.info("4---->:【支付宝】交易的参数信息是:ptype:{},orderNumber是:{}",  ptype,orderNumber);
                // 课程支付成功,保存的订单交易明细
                if (ptype != null && ptype.equalsIgnoreCase("productcourse")) {
                    payCommonService.payproductcourse(bodyJson, userId, orderNumber, tradeno, "1");
                }
            } catch (Exception ex) {
                log.info("支付宝支付出现了异常.....");
                ex.printStackTrace();
                return false;
            }
            return true;
        }
    
    
    
    }
    
  • 更新PayCommonService.java
    package com.dzy.alipay.service.pay;
    import com.alibaba.fastjson.JSONObject;
    
    import com.dzy.alipay.entity.OrderDetail;
    import com.dzy.alipay.entity.ProductCourse;
    import com.dzy.alipay.mapper.OrderDetailMapper;
    import com.dzy.alipay.mapper.ProductCourseMapper;
    import lombok.extern.log4j.Log4j2;
    import org.springframework.stereotype.Component;
    
    @Component
    @Log4j2
    public class PayCommonService {
        private final OrderDetailMapper orderDetailMapper;
        private final ProductCourseMapper productCourseMapper;
    
        public PayCommonService(OrderDetailMapper orderDetailMapper, ProductCourseMapper productCourseMapper) {
            this.orderDetailMapper = orderDetailMapper;
            this.productCourseMapper = productCourseMapper;
        }
    
        /**
         * 支付课程回调封装
         */
        public void payproductcourse(JSONObject jsonObject, String userId, String orderNumber, String transaction_id, String paymethod) {
            String courseId = jsonObject.getString("courseID");
            String money = jsonObject.getString("money");
            ProductCourse productCourse = productCourseMapper.selectById(courseId);
            if (productCourse == null) {
                log.info("【" + (paymethod.equals("2") ? "微信" : "支付宝") + "】你支付的课程被删除了:{}", courseId);
                return;
            }
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setUserid(userId);
            orderDetail.setCourseid(courseId);
            orderDetail.setUsername("飞哥");
            orderDetail.setPaymethod(paymethod);
            orderDetail.setCoursetitle(productCourse.getTitle());
            orderDetail.setCourseimg(productCourse.getImg());
            orderDetail.setOrdernumber(orderNumber);
            orderDetail.setTradeno(transaction_id);
            orderDetail.setPrice(money == null ? "0.01" : money);
            orderDetailMapper.insert(orderDetail);
        }
    }
    
  • 更新AlipayServiceImpl.java
    package com.dzy.alipay.service;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import com.alipay.api.AlipayApiException;
    import com.alipay.api.AlipayClient;
    import com.alipay.api.DefaultAlipayClient;
    import com.alipay.api.domain.AlipayTradePrecreateModel;
    import com.alipay.api.request.AlipayTradePrecreateRequest;
    import com.alipay.api.response.AlipayTradePrecreateResponse;
    import com.dzy.alipay.config.AlipayConfig;
    import com.dzy.alipay.entity.ProductCourse;
    import com.dzy.alipay.qrcode.QRCodeUtil;
    import com.dzy.alipay.qrcode.QrCodeResponse;
    import com.dzy.alipay.qrcode.QrResponse;
    import com.dzy.alipay.service.course.ProductCourseService;
    import com.dzy.alipay.util.GenerateNum;
    import com.dzy.alipay.vo.PayVo;
    import lombok.extern.log4j.Log4j2;
    import org.springframework.stereotype.Service;
    import org.springframework.util.FileCopyUtils;
    import org.springframework.util.ResourceUtils;
    
    import javax.imageio.ImageIO;
    import javax.imageio.stream.ImageOutputStream;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    
    @Service
    @Log4j2
    public class AlipayServiceImpl implements AlipayService {
    
        private final ProductCourseService productCourseService;
    
        private final AlipayConfig alipayConfig;
    
        public AlipayServiceImpl(AlipayConfig alipayConfig, ProductCourseService productCourseService) {
            this.alipayConfig = alipayConfig;
            this.productCourseService = productCourseService;
        }
    
        /*
         * @Author
         * @Description 阿里支付 -打赏
         * @Date 23:59 2020/9/8
         * @Param [payVo]
         * @return byte[]
         **/
        @Override
        public byte[] alipay(PayVo payVo) {
            try {
                ProductCourse productCourse = productCourseService.getById(payVo.getCourseid());
                if(productCourse==null){
                    return null;
                }
                // 1:支付的用户
                String userId = payVo.getUserId();
                // 2: 支付金额
                String money = productCourse.getPrice().toString();
                // 3: 支付的产品
                String title = productCourse.getTitle();
                // 4: 支付的订单编号
                String orderNumber = GenerateNum.generateOrder();
                // 5:支付宝携带的参数在回调中可以通过request获取
                JSONObject json = new JSONObject();
                json.put("userId", userId);
                json.put("orderNumber", orderNumber);
                json.put("money", money);
                json.put("ptype","productcourse");
                json.put("courseID",payVo.getCourseid());
                String params = json.toString();
                // 6:设置支付相关的信息
                AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
                model.setOutTradeNo(orderNumber); // 自定义订单号
                model.setTotalAmount(money);// 支付金额
                model.setSubject(title);// 支付的产品名称
                model.setBody(params);// 支付的请求体参数
                model.setTimeoutExpress("30m");// 支付的超时时间
                model.setStoreId(userId + "");// 支付的库存id
                QrCodeResponse qrCodeResponse = qrcodePay(model);
                ByteArrayOutputStream output = new ByteArrayOutputStream();
                String logoPath ="";
                try {
                    logoPath = ResourceUtils.getFile("classpath:favicon.png").getAbsolutePath();
                }catch (Exception ex){
                    logoPath = new File("/www/wwwroot/aliPay/favicon.png").getAbsolutePath();
                }
                BufferedImage buffImg = QRCodeUtil.encode(qrCodeResponse.getQr_code(), logoPath, false);//获取二维码
                ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);
                ImageIO.write(buffImg, "JPEG", imageOut);
                imageOut.close();
                ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
                return FileCopyUtils.copyToByteArray(input);
            } catch (Exception ex) {
                ex.printStackTrace();
                return null;
            }
        }
    
        /**
         * 扫码运行代码
         * 验签通过返回QrResponse
         * 失败打印日志信息
         * 参考地址:https://opendocs.alipay.com/apis/api_1/alipay.trade.app.pay
         */
        public QrCodeResponse qrcodePay(AlipayTradePrecreateModel model) {
            // 1: 获取阿里请求客户端
            AlipayClient alipayClient = getAlipayClient();
            // 2: 获取阿里请求对象
            AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
            // 3:设置请求参数的集合,最大长度不限
            request.setBizModel(model);
            // 设置异步回调地址
            request.setNotifyUrl(alipayConfig.getNotify_url());
            // 设置同步回调地址
            request.setReturnUrl(alipayConfig.getReturn_url());
            AlipayTradePrecreateResponse alipayTradePrecreateResponse = null;
            try {
                alipayTradePrecreateResponse = alipayClient.execute(request);
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            assert alipayTradePrecreateResponse != null;
            QrResponse qrResponse = JSON.parseObject(alipayTradePrecreateResponse.getBody(), QrResponse.class);
            return qrResponse.getAlipay_trade_precreate_response();
        }
    
        /**
         * 获取AlipayClient对象
         */
        private AlipayClient getAlipayClient() {
            return new DefaultAlipayClient(alipayConfig.getGatewayUrl(), alipayConfig.getApp_id(), alipayConfig.getMerchant_private_key(), "JSON", alipayConfig.getCharset(), alipayConfig.getAlipay_public_key(), alipayConfig.getSign_type());
        }
    }
    
  • 更新OrderDetail.java
    package com.dzy.alipay.entity;
    import com.baomidou.mybatisplus.annotation.*;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import lombok.ToString;
    import lombok.experimental.Accessors;
    import java.util.Date;
    
    @Data
    @ToString
    @AllArgsConstructor
    @NoArgsConstructor
    @Accessors(chain = true)
    @TableName("kss_order_detail")
    public class OrderDetail {
        // 主键
        @TableId(value = "id", type = IdType.ASSIGN_ID)
        private Long id;
        // 支付课程id
        private String courseid;
        // 支付课程标题
        private String coursetitle;
        // 支付课程封面
        private String courseimg;
        // 支付价格
        private String price;
        // 支付用户
        private String userid;
        // 支付用户昵称
        private String username;
        // 支付流水订单号
        private String ordernumber;
        // 支付交易号
        private String tradeno;
        // 1 alipay 2 weixin
        private String paymethod;
        // 课程创建时间
        @TableField(fill = FieldFill.INSERT)
        private Date createTime;
        // 课程更新时间
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private Date updateTime;
    }
    
  • 更新OrderDetailMapper.java
    package com.dzy.alipay.mapper;
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    
    import com.dzy.alipay.entity.OrderDetail;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface OrderDetailMapper extends BaseMapper<OrderDetail> {
    }
    
  • 更新OrderDetailServiceImpl.java
    package com.dzy.alipay.service.order;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    
    import com.dzy.alipay.entity.OrderDetail;
    import com.dzy.alipay.mapper.OrderDetailMapper;
    import org.springframework.stereotype.Service;
    
    @Service
    public class OrderDetailServiceImpl extends ServiceImpl<OrderDetailMapper, OrderDetail> implements OrderDetailService {
    }
    
  • 然后将Java项目打jar包,上传至服务器中,以下是Linux操作命令
    nohup java -jar aliPay.jar >>1.txt &  # 后台运行jar包
    tail -f 1.txt   # 查看日志
    netstat -anp | grep 8989     # 利用管道查看端口号8989有没有被占用
    sudo lsof -i:8989   # 查看端口号8989的进程的PID
    sudo kill -9 9851   # 利用PID杀死进程
    
  • 扫描二维码进行支付


三、成功截图
  • 服务器成功收到支付宝传回的支付回调信息

    在这里插入图片描述

  • 成功将订单信息保存至数据库中

    在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

支付宝支付 第十集:支付回调 的相关文章

随机推荐