简单几步实现商城订单支付!!!!

spring bootapp 支付宝支付 springboot集成支付宝_支付宝

首先,在我们的pom.xml里面引入依赖 

spring bootapp 支付宝支付 springboot集成支付宝_支付宝_02

<!--        沙箱支付-->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-easysdk</artifactId>
            <version>2.2.0</version>
        </dependency>

<!-- hutool  -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.20</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>

依次导入我们需要的编码,编码用到Lombok简化了代码

spring bootapp 支付宝支付 springboot集成支付宝_spring_03

<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

 下面是我们的文件位置

spring bootapp 支付宝支付 springboot集成支付宝_System_04

 1.新建一个AlipayConfig.java

spring bootapp 支付宝支付 springboot集成支付宝_spring_05

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AliPayConfig {
    private String appId;
    private String appPrivateKey;
    private String alipayPublicKey;
    private String notifyUrl;


    @PostConstruct
    public void init() {
        // 设置参数(全局只需设置一次)
        Config config = new Config();
        config.protocol = "https";
        config.gatewayHost = "openapi.alipaydev.com";
        config.signType = "RSA2";
        config.appId = this.appId;
        config.merchantPrivateKey = this.appPrivateKey;
        config.alipayPublicKey = this.alipayPublicKey;
        config.notifyUrl = this.notifyUrl;
        Factory.setOptions(config);
        System.out.println("=======支付宝SDK初始化成功=======");
    }

}

 2.放入我们的alipay实体类

spring bootapp 支付宝支付 springboot集成支付宝_java_06

import lombok.Data;

@Data
public class AliPay {
    private String traceNo;
    private String totalAmount;
    private String subject;
//    private String alipayTraceNo;
}

 3.然后是我们的控制层Controller

spring bootapp 支付宝支付 springboot集成支付宝_支付宝_07

 

spring bootapp 支付宝支付 springboot集成支付宝_spring boot_08

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.example.demo.controller.dto.AliPay;
import com.example.demo.mapper.OrdersMapper;
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 java.util.HashMap;
import java.util.Map;

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

    @Resource
    private OrdersMapper ordersMapper;


    @GetMapping("/pay") // &subject=xxx&traceNo=xxx&totalAmount=xxx
    public String pay(AliPay aliPay) {
        AlipayTradePagePayResponse response;
        try {
            //  发起API调用(以创建当面付收款二维码为例)
            response = Factory.Payment.Page()
                    .pay(aliPay.getSubject(), aliPay.getTraceNo(), aliPay.getTotalAmount(), "");
        } catch (Exception e) {
            System.err.println("调用遭遇异常,原因:" + e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        }
        return response.getBody();
    }


    @PostMapping("/notify")  // 注意这里必须是POST接口
    public String 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));
                // System.out.println(name + " = " + request.getParameter(name));
            }

            String tradeNo = params.get("out_trade_no");
            String gmtPayment = params.get("gmt_payment");
            String alipayTradeNo = params.get("trade_no");
            // 支付宝验签
            if (Factory.Payment.Common().verifyNotify(params)) {
                // 验签通过
                System.out.println("交易名称: " + params.get("subject"));
                System.out.println("交易状态: " + params.get("trade_status"));
                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
                System.out.println("商户订单号: " + params.get("out_trade_no"));
                System.out.println("交易金额: " + params.get("total_amount"));
                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
                System.out.println("买家付款时间: " + params.get("gmt_payment"));
                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
                // 更新订单未已支付
                ordersMapper.updateState(tradeNo, "已支付", gmtPayment, alipayTradeNo);
            }
        }
        return "success";
    }
}

 然后是我们的数据库

订单表:

CREATE TABLE `orders` (
  `id` int NOT NULL AUTO_INCREMENT,
  `user_id` int DEFAULT NULL COMMENT '用户ID',
  `alipay_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_turkish_ci DEFAULT NULL COMMENT '支付宝流水号',
  `name` varchar(255) COLLATE utf8mb4_turkish_ci DEFAULT NULL COMMENT '名称',
  `no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_turkish_ci DEFAULT NULL COMMENT '编号',
  `total_price` decimal(10,2) DEFAULT NULL COMMENT '总金额',
  `state` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_turkish_ci DEFAULT '待付款' COMMENT '状态',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '订单创建时间',
  `pay_time` varchar(255) COLLATE utf8mb4_turkish_ci DEFAULT NULL COMMENT '订单付款时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_turkish_ci;

spring bootapp 支付宝支付 springboot集成支付宝_java_09

 做完这些我们就开始进行支付,在支付之前我们要先到支付宝平台申请一下开放

支付宝开放平台 (alipay.com)

 进入到界面,我们登录然后进行获取

spring bootapp 支付宝支付 springboot集成支付宝_System_10

 

spring bootapp 支付宝支付 springboot集成支付宝_java_11

 

spring bootapp 支付宝支付 springboot集成支付宝_System_12

 以上内容按照步骤进行就可以,然后是我们的配置application.yml

spring bootapp 支付宝支付 springboot集成支付宝_spring_13

spring bootapp 支付宝支付 springboot集成支付宝_System_14

alipay:
  appId: 你的AppId
  appPrivateKey: 应用私钥
  alipayPublicKey: 应用公钥
  notifyUrl: natapp获取

 然后我们还需要一个工具natapp,内网穿透:https://natapp.cn/

spring bootapp 支付宝支付 springboot集成支付宝_支付宝_15

申请一个免费的隧道然后进行配置

 

spring bootapp 支付宝支付 springboot集成支付宝_支付宝_16

 本地端口号就是你的后台的端口号,我这里是9090

然后下好工具之后,复制我们的authtoken

spring bootapp 支付宝支付 springboot集成支付宝_支付宝_17

spring bootapp 支付宝支付 springboot集成支付宝_java_18

 在外面的bat里面换成我们自己的这个authtoken

spring bootapp 支付宝支付 springboot集成支付宝_spring_19

 当你看见下面的内容时就说明连接成功了

spring bootapp 支付宝支付 springboot集成支付宝_System_20

 然后将我们的这个http放入刚刚的配置里面

spring bootapp 支付宝支付 springboot集成支付宝_System_21

记住,一定要加上/alipay/notify !!!!!!!!!!!!!!!!!

然后我们就配置成功了,就可以进行支付

前台页面

<template>
  <div style="width: 1300px; padding-left: 200px">
    <div style="margin: 10px 0">
      <el-button type="primary" @click="$router.push('/home')" style="float: left; margin-right: 20px">首页</el-button>
    </div>
    <el-table style="top: 10px" :data="tableData" border stripe :header-cell-class-name="headerBg" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55"></el-table-column>
      <el-table-column prop="name" label="商品名称" ></el-table-column>
      <el-table-column prop="no" label="订单编号" ></el-table-column>
      <el-table-column prop="totalPrice" label="总金额" ></el-table-column>
      <el-table-column prop="phone" label="联系方式" ></el-table-column>
      <el-table-column prop="username" label="收件人" ></el-table-column>
      <el-table-column prop="address" label="收货地址"></el-table-column>
      <el-table-column prop="state" label="订单状态"></el-table-column>
      <el-table-column label="我的快递">
        <template v-slot="scope">
          <el-button type="success" slot="reference" @click="changeState(scope.row, '收货')" :disabled="scope.row.state !== '发货'">收货</el-button>
        </template>
      </el-table-column>
      <el-table-column label="查看商品">
        <template slot-scope="scope">
          <el-button type="primary" slot="reference" style="margin-left: 5px" @click="viewGoods(scope.row.id)">查看商品</el-button>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="150">
        <template slot-scope="scope">
          <el-popconfirm
              class="ml-5"
              confirm-button-text='确认'
              cancel-button-text='取消'
              icon="el-icon-info"
              icon-color="red"
              title="您确定取消该笔订单吗?"
              @confirm="del(scope.row.id)">
            <el-button type="danger" slot="reference" style="margin-left: 5px">取消</el-button>
            <el-button type="primary" slot="reference" style="margin-left: 5px" @click="pay(scope.row)">支付</el-button>
<!--            <el-button type="success" slot="reference" @click="changeState(scope.row, '确认收货')" :disabled="scope.row.state !== '发货'">确认收货</el-button>-->
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
    <div style="padding: 10px 0">
      <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="pageNum"
          :page-sizes="[ 5, 10]"
          :page-size="pageSize"
          layout="total, prev, pager, next"
          :total="total">
      </el-pagination>
    </div>
    <el-dialog title="商品信息" :visible.sync="dialogFormVisible1" width="50%" :close-on-click-model="false">
      <el-table :data="goodsList" border stripe >
        <el-table-column prop="name" label="商品名称" width="80"></el-table-column>
        <el-table-column prop="url" label="商品图片">
          <template slot-scope="scope">
            <el-image :src="scope.row.url" :preview-src-list="[scope.row.id]"></el-image>
          </template>
        </el-table-column>
        <el-table-column prop="price" label="单价" width="80"></el-table-column>
        <el-table-column prop="num" label="库存" width="80" ></el-table-column>
        <el-table-column prop="type" label="类型" width="80"></el-table-column>
        <el-table-column prop="number" label="购买数量" width="80"></el-table-column>
        <el-table-column prop="refer" label="描述" width="500"></el-table-column>
        <el-table-column prop="creatTime" label="上架时间" width="120"></el-table-column>
      </el-table>
    </el-dialog>
  </div>
</template>

<script>
const baseUrl = "http://localhost:9090"
export default {
  name: "Orders",
  data() {
    return {
      tableData: [],
      goodsList: [],
      total: 0,
      pageNum: 1,
      pageSize: 5,
      username: "",
      form: {},
      dialogFormVisible: false,
      dialogFormVisible1: false,
      multipleSelection: [],
      headerBg: "headerBg",
      roles: [],
      user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {}
    }
  },
  created() {
    this.load()
  },
  methods: {
    viewGoods(orderId) {
      this.request.get("orders/getGoodsById/" + orderId).then(res => {
        this.goodsList = res.data
        this.dialogFormVisible1 = true
        setTimeout(() => {
          this.dialogFormVisible1 = false
        }, 5000)
      })
    },
    load: function () {
      this.request.get("/orders/page", {
        params: {
          pageNum: this.pageNum,
          pageSize: this.pageSize,
          name: this.name,
        }
      }).then(res => {
        this.tableData = res.data.records
        this.total = res.data.total
      })
      this.request.get("/role").then(res => {
        this.roles = res.data
      })
    },
    changeState(row, state) {
      this.form = JSON.parse(JSON.stringify(row))
      this.form.state = state;
      this.save();
    },
    del(id) {
      this.request.delete("/orders/" + id).then(res => {
        if (res.code === '200') {
          this.$message.success("取消订单成功")
          this.load()
        } else {
          this.$message.error("取消订单失败")
        }
      })
    },
    save() {
      this.request.post("/orders", this.form).then(res => {
        if (res.code === '200') {
          this.$message.success("保存成功")
          this.dialogFormVisible = false
          this.load()
        } else {
          this.$message.error("保存失败")
        }
      })
    },
    pay(row) {
      // window.open('http://localhost:9090/alipay/pay?subject=${row.name}&traceNo=${row.no}&totalAmount=${row.totalPrice}');
      window.open("http://localhost:9090/alipay/pay?subject=" + row.name + "&traceNo=" + row.no + "&totalAmount=" + row.totalPrice)
      this.load()
    },
    handleSelectionChange(val) {
      console.log(val)
      this.multipleSelection = val;
    },
    reset() {
      this.name = ""
      this.load()
    },
    handleSizeChange(pageSize) {
      console.log(pageSize)
      this.pageSize = pageSize
      this.load()
    },
    handleCurrentChange(pageNum) {
      console.log(pageNum)
      this.pageNum = pageNum
      this.load()
    },
  }
}
</script>

<style>
.headerBg {
  background: #eee!important;
}
</style>

spring bootapp 支付宝支付 springboot集成支付宝_spring boot_22

 核心代码:进行调用我们的支付宝沙箱支付接口

pay(row) {
      // window.open('http://localhost:9090/alipay/pay?subject=${row.name}&traceNo=${row.no}&totalAmount=${row.totalPrice}');
      window.open("http://localhost:9090/alipay/pay?subject=" + row.name + "&traceNo=" + row.no + "&totalAmount=" + row.totalPrice)
      this.load()
    },

然后我们访问URL进行测试,测试的url格式:http://localhost:9090/alipay/pay?subject=商品名称&traceNo=一个订单号&totalAmount=1000(totalAmount为订单支付价格)

 如何我们的账号在我们的页面有提供

spring bootapp 支付宝支付 springboot集成支付宝_java_23

 输入账号和密码就可以进行付款了

spring bootapp 支付宝支付 springboot集成支付宝_System_24

 

spring bootapp 支付宝支付 springboot集成支付宝_java_25

 然后我们就可以看见有一个接口回调:

spring bootapp 支付宝支付 springboot集成支付宝_spring_26

代码回调在我们的Controller里面有:

@PostMapping("/notify")  // 注意这里必须是POST接口
    public String 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));
                // System.out.println(name + " = " + request.getParameter(name));
            }

            String tradeNo = params.get("out_trade_no");
            String gmtPayment = params.get("gmt_payment");
            String alipayTradeNo = params.get("trade_no");
            // 支付宝验签
            if (Factory.Payment.Common().verifyNotify(params)) {
                // 验签通过
                System.out.println("交易名称: " + params.get("subject"));
                System.out.println("交易状态: " + params.get("trade_status"));
                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
                System.out.println("商户订单号: " + params.get("out_trade_no"));
                System.out.println("交易金额: " + params.get("total_amount"));
                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
                System.out.println("买家付款时间: " + params.get("gmt_payment"));
                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
                // 更新订单未已支付
                ordersMapper.updateState(tradeNo, "已支付", gmtPayment, alipayTradeNo);
            }
        }
        return "success";
    }

 最后在我们的数据库就可以看见信息了

spring bootapp 支付宝支付 springboot集成支付宝_System_27

 然后我们的前台页面也可以看见信息

用户:

spring bootapp 支付宝支付 springboot集成支付宝_spring_28

 然后用户就可以进行操作啦!!!

管理员:

spring bootapp 支付宝支付 springboot集成支付宝_spring_29

就可以进行订单操作,用户也可以看见信息啦!!!!