springboot+Vue项目对接支付宝(最新)

 一、需要准备的内容

1.支付宝沙箱环境(需要获取应用ID、应用私钥、支付宝公钥、支付宝网关地址)

在支付宝沙箱网站登录自己的支付宝来获取以上四个参数,网址为https://openhome.alipay.com/develop/sandbox/app

登录进入该网站后

点开查看公钥

2.内网穿透

网址为https://natapp.cn/,登录进去后申请一个免费的隧道

然后点击客户端下载,根据自己的操作系统进行下载

注意:下载后只有natapp.exe一个文件,点开会闪退,此时还需要配置文件

将本地端口修改后就可以了,点击保存后返回到以上界面复制authtoken,填写至config.ini的相应位置即可

详细内容可以阅读文档https://natapp.cn/article/config_ini

注意:下载config.ini时浏览器可能会显示不安全无法下载,建议使用谷歌浏览器 

下载congfig.ini文件至natapp.exe一个包内,打开config.ini文件配置以下内容

#将本文件放置于natapp同级目录 程序将读取 [default] 段
#在命令行参数模式如 natapp -authtoken=xxx 等相同参数将会覆盖掉此配置
#命令行参数 -config= 可以指定任意config.ini文件
[default]
authtoken=                      #对应一条隧道的authtoken
clienttoken=                    #对应客户端的clienttoken,将会忽略authtoken,若无请留空,
log=none                        #log 日志文件,可指定本地文件, none=不做记录,stdout=直接屏幕输出 ,默认为none
loglevel=ERROR                  #日志等级 DEBUG, INFO, WARNING, ERROR 默认为 DEBUG
http_proxy=                     #代理设置 如 http://10.123.10.10:3128 非代理上网用户请务必留空

保存配置后点击natapp,

 

需要的内容就是红框里面的网址后加  /alipay/notify

以上步骤完成后需要在Java项目的application.yml文件当中写入以下内容

alipay:
  appId:  #获取到的id
  appPrivateKey:  #自己的应用私钥
  alipayPublicKey:  #支付宝公钥
  notifyUrl:  #

3.jar包的下载

下载地址为https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.16/hutool-all-5.8.16.jar

下载的路径为本地maven包内

4.添加依赖项

我添加的如下所示

        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.35.79.ALL</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.1.2</version>
        </dependency>

至此准备工作完成!

二、后端代码的编写

1.AlipayConfig

package com.example.mybatisplus.common.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayConfig {
    // 支付宝的AppId
    private String appId;
    // 应用私钥
    private String appPrivateKey;
    // 支付宝公钥
    private String appPublicKey;
    //支付宝通知本地的接口完整地址
    private String notifyUrl;

    public String getAppId(){
        return appId;
    }

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

    public String getAppPrivateKey() {
        return appPrivateKey;
    }

    public void setAppPrivateKey(String appPrivateKey) {
        this.appPrivateKey = appPrivateKey;
    }

    public String getAppPublicKey() {
        return appPublicKey;
    }

    public void setAppPublicKey(String appPublicKey) {
        this.appPublicKey = appPublicKey;
    }

    public String getNotifyUrl(){
        return notifyUrl;
    }

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

2.AlipayController类

package com.example.mybatisplus.web.controller;

import cn.hutool.json.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.AlipayTradePagePayRequest;
import com.example.mybatisplus.common.config.AlipayConfig;
import com.example.mybatisplus.model.domain.Orders;
import com.example.mybatisplus.service.OrdersService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
@RequestMapping("/alipay")
public class AliPayController {

    // 支付宝沙箱网关地址
    private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "UTF-8";
    private static final String SIGN_TYPE = "RSA2";

    @Resource
    private AlipayConfig alipayConfig;

    @Resource
    private OrdersService ordersService;

    @GetMapping("/pay") //alipay/pay?orderNo=xxx
    public void pay(String oid,HttpServletResponse httpResponse) throws Exception {
        //查询订单信息
        Orders orders = ordersService.selectByOrderID(oid);
        if(orders==null) return;
        //1. 创建CLinet,通过SDK提供的Client,负责调用支付宝的API
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, alipayConfig.getAppId(),
                alipayConfig.getAppPrivateKey(), FORMAT, CHARSET, alipayConfig.getAppPublicKey(), SIGN_TYPE);

        //2. 创建Request并设置Request参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); //发送请求的类
        request.setNotifyUrl(alipayConfig.getNotifyUrl());
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orders.getOid());  //订单编号
        bizContent.put("total_amount", orders.getPrice());   //订单总金额
        bizContent.put("subject", orders.getHid());  //支付的酒店名
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
        request.setBizContent(bizContent.toString());
        request.setReturnUrl("http://localhost:3000/#/main/user/myorders"); //支付成功返回至订单界面
        //执行请求,拿到响应的结果,返回浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        httpResponse.getWriter().write(form);
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }
        @PostMapping("/notify")  // 注意这里必须是POST接口
        public void payNotify(HttpServletRequest request) throws Exception {
            if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
                System.out.println("=========支付宝异步回调========");
                Map<String, String> params = new HashMap<>();
                Map<String,String[]>requestParams = request.getParameterMap();
                for (String name : requestParams.keySet()) {
                    params.put(name,request.getParameter(name));
                }
                String sign = params.get("sign");
                String content = AlipaySignature.getSignCheckContentV1(params);
                boolean checkSignature =AlipaySignature.rsa256CheckContent(content,sign,alipayConfig.getAppPublicKey(),"UTF-8");
                //支付宝验证
                if(checkSignature){
                    //输出一些支付信息
                    System.out.println("交易金额"+params.get("total_amount"));
                    String oid = params.get("out_trade_no");
                    Orders orders = ordersService.selectByOrderID(oid);
                    orders.setStatus(2);
                }
            }
        }
}

3.OrderService

在你原有的内容里添加一条

Orders selectByOrderID(String oid);

我的完整代码(仅供参考)

package com.example.mybatisplus.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.mybatisplus.model.domain.Orders;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author team7
 * @since 2023-01-04
 */
public interface OrdersService extends IService<Orders> {

    List<Orders> showorderdetail(Orders orders);

    List<Orders> showOrderDetailByHid(Orders orders);

    List<Orders> showAllOrders(Orders orders);

    Long insertOrder(Orders order);

    boolean updateOrderTo2(Orders curOid);

    boolean updateOrderTo3(Orders curOid);

    int deleteCurOrder(Orders curOid);

    void exportorders(HttpServletResponse response, Orders orders);

    void exportMorders(HttpServletResponse response, Orders orders);

    void exportHorders(HttpServletResponse response, Orders orders);

    Orders selectByOrderID(String oid);
}

4.OrderServiceImpl

在你之前的代码里添加

    @Override
    public Orders selectByOrderID(String oid) {
        return ordersMapper.selectById(oid);
    }

以下是我的完整内容(仅供参考)

package com.example.mybatisplus.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mybatisplus.common.utls.ExcelUtil;
import com.example.mybatisplus.mapper.OrdersMapper;
import com.example.mybatisplus.model.domain.Orders;
import com.example.mybatisplus.service.OrdersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author team7
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    @Autowired(required = false)

    private OrdersMapper ordersMapper;

    // 显示个人所有订单,用于用户端
    @Override
    public List<Orders> showorderdetail(Orders orders) {
        List<Orders> orderDetail = ordersMapper.selectId(orders);
        return orderDetail;
    }

    // 显示酒店订单,用于酒店管理端
    @Override
    public List<Orders> showOrderDetailByHid(Orders orders) {
        List<Orders> hotelOrderDetail = ordersMapper.selectHid(orders);
        return hotelOrderDetail;
    }

    // 显示所有订单,用于管理员端
    @Override
    public List<Orders> showAllOrders(Orders orders){
        List<Orders> allOrderDetail = ordersMapper.selectAll(orders);
        return allOrderDetail;
    }



    @Override
    public Long insertOrder(Orders order) {
        ordersMapper.insert(order);
        Long b = order.getOid();
        return b;
    }

    @Override
    public boolean updateOrderTo2(Orders curOid) {
        boolean b=ordersMapper.updateOrderTo2(curOid);
        return b;
    }

    @Override
    public boolean updateOrderTo3(Orders curOid) {
        boolean b=ordersMapper.updateOrderTo3(curOid);
        return b;
    }

    @Override
    public void exportorders(HttpServletResponse response, Orders orders) {
        List<Orders> pageList = showAllOrders(orders);
        //导出
        //创建表格对象
        try {
            ExcelUtil.exportOrders(response,pageList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void exportMorders(HttpServletResponse response, Orders orders) {
        List<Orders> pageList = showorderdetail(orders);
        //导出
        //创建表格对象
        try {
            ExcelUtil.exportOrders(response,pageList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void exportHorders(HttpServletResponse response, Orders orders) {
        List<Orders> pageList = showOrderDetailByHid(orders);
        //导出
        //创建表格对象
        try {
            ExcelUtil.exportOrders(response,pageList);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Orders selectByOrderID(String oid) {
        return ordersMapper.selectById(oid);
    }


    @Override
    public int deleteCurOrder(Orders curOid) {
        int b =ordersMapper.deleteById(curOid.getOid());
        return  b;
    }


}

5.OrdersMapper

在你的代码基础上添加

@Select("select * from orders where oid= #{orderNo}")
    Orders selectById(String oid);

以下是我的完整代码(仅供参考)

package com.example.mybatisplus.mapper;

import com.example.mybatisplus.model.domain.Orders;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author team7
 * @since 2023-01-04
 */
public interface OrdersMapper extends BaseMapper<Orders> {

    List<Orders> selectId(@Param("orders") Orders orders);

    List<Orders> selectHid(@Param("orders") Orders orders);

    List<Orders> selectAll(@Param("orders") Orders orders);

    boolean updateOrderTo2(@Param("orderData") Orders curOid);

    boolean updateOrderTo3(@Param("orderData") Orders curOid);

    @Select("select * from orders where oid= #{orderNo}")
    Orders selectById(String oid);
}

以上则是我后端代码的全部内容

三、前端代码的编写

注意:内网穿透时的端口号就是你前端代码运行的端口号,由于我用的是vue3,所以还需要在build文件夹下的webpack.dev.conf.js里面的devServer方法中添加一行,添加成功后运行vue项目就可以在你申请的网站上运行了

disableHostCheck:true,

支付订单界面的按钮部分

            <div class="payBtn">
              <el-button type="primary" @click="pay">支付</el-button>
              <el-button @click="orderDialogVisible=false">取消</el-button>
            </div>

点击支付按钮后调用pay函数

    pay () {
      window.open('http://localhost:8088/alipay/pay?oid=' + this.selectOrder.oid)
    },

前端相关代码如下:

          <el-button type="text" size="small" :disabled="scope.row.status!=1" @click="showNoOrder(scope.row)">支付
          </el-button>
          <!--          支付界面-->
          <el-dialog :data="curOrder" :visible.sync="orderDialogVisible" width="60%" center
                     :modal-append-to-body='false'>
               <span>
                <el-descriptions width="80%" class="margin-top" title="支付订单" :column="1" border>

                  <el-descriptions-item>
          <template slot="label">
         <i class="el-icon-user"></i>
        酒店名称
         </template>
           {{ curOrder.hotel }}
       </el-descriptions-item>
                       <el-descriptions-item>
          <template slot="label">
         <i class="el-icon-house"></i>
            房间类型
         </template>
             {{ curOrder.room }}
       </el-descriptions-item>
                  <el-descriptions-item>
          <template slot="label">
         <i class="el-icon-food"></i>
            有无早餐
         </template>
             {{ curOrder.breakfast }}
       </el-descriptions-item>
                       <el-descriptions-item>
          <template slot="label">
         <i class="el-icon-coin"></i>
        需要支付金额
         </template>
            {{ curOrder.price }}
       </el-descriptions-item>
                   <el-descriptions-item>
          <template slot="label">
         <i class="el-icon-time"></i>
        预计入住时间
         </template>
            {{ curOrder.checkIn }}
       </el-descriptions-item>
                    <el-descriptions-item>
          <template slot="label">
         <i class="el-icon-time"></i>
        预计退房时间
         </template>
            {{ curOrder.checkOut }}
       </el-descriptions-item>
                   <el-descriptions-item>
          <template slot="label">
         <i class="el-icon-time"></i>
        订单提交时间
         </template>
            {{ curOrder.time }}
       </el-descriptions-item>
                  </el-descriptions>
               </span>
            <div class="payBtn">
              <el-button type="primary" @click="pay">支付</el-button>
              <el-button @click="orderDialogVisible=false">取消</el-button>
            </div>
          </el-dialog>

四、数据库的内容

       由于在数据库设计时未考虑到实际生活中的订单会自动生成多位订单编号,所以获取订单内容的时候我拿oid凑数了,如果有需求可以将以上代码中查询oid的内容修改为查询订单编号(根据自己的需求进行更改)

五、效果展示

当我点击支付后就会根据查询到的订单内容跳转到支付界面

此处的账户密码可以使用沙箱配置时提供的账号进行测试

完成支付后会自动跳转到订单界面,至此所有流程结束。

配置到不同的项目里面可能会有些许的bug,细心检查修改一下一定会成功的!!!

六、总结

这是在实习过程中学习到的一点点内容,由于项目经历较少,学习这一部分内容的时候也参考了网上的一些教程,同时感谢各位博主的奉献。

新手小白第一次写博客,各位看官不喜勿喷!!!祝各位新年快乐

  • 22
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
你好!感谢你的提问。关于uniapp对接支付宝沙箱,你可以按照以下步骤进行操作: 1. 首先,你需要在支付宝开放平台注册开发者账号,并创建应用。确保你已经完成了开发者身份认证和应用信息填写。 2. 在uniapp项目中,安装uni-app插件管理器(HBuilderX工具中的插件市场中下载安装),然后搜索并安装"uni-app支付宝小程序插件"。 3. 打开HBuilderX工具,进入项目根目录,在manifest.json文件中配置插件,将"uni-app支付宝小程序插件"添加到"mp-alipay"的"plugins"节点下。 4. 在uniapp项目中创建一个支付页面,可以命名为"alipay",该页面用于支付宝支付的相关操作。 5. 在支付页面的js文件中,引入支付宝支付插件,并初始化支付参数。示例代码如下: ``` import alipay from '@/uni_modules/uni-alipay-app/uni-alipay-app.js'; export default { data() { return { orderInfo: {}, // 支付订单信息,包括订单号、金额等 }; }, methods: { // 调用支付宝支付 async aliPay() { const result = await alipay.tradeAppPay({ orderStr: 'YourOrderString', // 支付订单字符串,由后端生成 isTest: true, // 是否使用沙箱环境 }); // 处理支付结果 if (result.resultCode === '9000') { // 支付成功 // TODO: 处理支付成功逻辑 } else { // 支付失败 // TODO: 处理支付失败逻辑 } }, }, }; ``` 6. 在支付页面的wxml文件中,添加一个按钮,并绑定上一步中定义的aliPay方法。 7. 最后,你需要在支付宝开放平台的开发者中心,配置沙箱环境下的支付回调地址,并将该地址填写到你的应用支付配置中。 以上是基本的步骤,你可以根据实际需求进行调整和扩展。希望对你有所帮助!如果有任何问题,请随时向我提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值