调用第三方接口——支付宝付款

沙箱环境是支付宝开放平台为开发者提供的用于接口开发及主要功能联调的模拟环境。

参考 登录 - 支付宝

在沙箱环境下,已经分配好了用于模拟测试的应用信息、商家信息、买家信息等

小程序文档 - 支付宝文档中心

 内网穿透(支付宝付款需要在公网进行检查网站)

这里使用natapp内网穿透工具,参考 NATAPP-内网穿透 基于ngrok的国内高速内网映射工具

1.创建前端页面

订单列表页 order.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>订单列表</title>
    <style>
        tr{
            text-align: center;
        }
    </style>
</head>
<body>
    <table border="1px" width="700px" height="200px">
        <tr>
            <th>序号</th>
            <th>订单号</th>
            <th>订单名称</th>
            <th>订单金额</th>
            <th>下单时间</th>
            <td>操作</td>
        </tr>
        <tr>
            <td>1</td>
            <td>202312100001</td>
            <td>测试订单1</td>
            <td>¥1.0</td>
            <td>2023-12-10 10:30:21</td>
            <td>
                <a href="pay.html">去支付</a>
            </td>
        </tr>
        <tr>
            <td>2</td>
            <td>202312100002</td>
            <td>测试订单2</td>
            <td>¥1.0</td>
            <td>2023-12-10 10:30:21</td>
            <td>
                <a href="pay.html">去支付</a>
            </td>
        </tr>
        <tr>
            <td>3</td>
            <td>202312100003</td>
            <td>测试订单3</td>
            <td>¥1.0</td>
            <td>2023-12-10 10:30:21</td>
            <td>
                <a href="pay.html">去支付</a>
            </td>
        </tr>
    </table>
</body>
</html>

确认付款页 pay.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>确认付款</title>   
</head>
<body>
    <h2>确认付款</h2>
    <form id="payForm" method="post" action="http://localhost:8080/alipay/pay">
        <p>订单号:<input type="text" name="orderNo" value="202312100001"></p>
        <p>订单名称:<input type="text" name="subject" value="测试订单1"></p>
        <p>付款金额:<input type="text" name="totalAmount" value="1.0"></p>
        <p><input type="submit" value="付款"></p>
    </form>
</body>
</html>

后端界面:
引入相关的依赖:

processor是为了将配置类中的信息,一次性读取注入到属性中:

        <!--   支付宝     -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.34.0.ALL</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>

application.yml 

# 支付宝配置信息
alipay:
  appId: xxxxxxx
  appPrivateKey: xxxxxxx
  alipayPublicKey: xxxxxxx
  signType: RSA2
  charset: utf-8
  gatewayUrl: https://openapi-sandbox.dl.alipaydev.com/gateway.do
  notifyUrl: xxxxxxx
  returnUrl: http://127.0.0.1:5500/order.html

创建Alipay属性类:

@Data
@Component
@ConfigurationProperties(prefix = "alipay")
public class AlipayProperties {

    // 应用id
    private String appId;

    // 应用私钥
    private String appPrivateKey;

    // 支付宝公钥
    private String alipayPublicKey;

    // 签名方式
    private String signType;

    // 字符编码
    private String charset;

    // 支付宝网关
    private String gatewayUrl;

    // 异步通知地址
    private String notifyUrl;

    // 同步跳转地址,即支付完成后跳转的地址
    private String returnUrl;
}

 创建Alipay配置类

@Configuration
public class AlipayConfig {

    @Resource
    private AlipayProperties alipayProperties;

    /**
     * 创建支付客户端
     */
    @Bean
    public AlipayClient alipayClient(){
        AlipayClient alipayClient = new DefaultAlipayClient(
                alipayProperties.getGatewayUrl(),
                alipayProperties.getAppId(),
                alipayProperties.getAppPrivateKey(),
                "json",
                alipayProperties.getCharset(),
                alipayProperties.getAlipayPublicKey(),
                alipayProperties.getSignType());
        return alipayClient;
    }

    /**
     * 创建支付请求对象
     */
    @Bean
    public AlipayTradePagePayRequest alipayTradePagePayRequest(){
        AlipayTradePagePayRequest payRequest = new AlipayTradePagePayRequest();
        payRequest.setNotifyUrl(alipayProperties.getNotifyUrl());
        payRequest.setReturnUrl(alipayProperties.getReturnUrl());
        return payRequest;
    }
}

创建Alipay控制类:

package net.wanho.controller;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.wanho.properties.AlipayProperties;
import org.springframework.web.bind.annotation.*;

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

@RestController
@RequestMapping("/alipay")
@CrossOrigin
@Slf4j
public class AlipayController {
    @Resource
    private AlipayClient alipayClient;
    @Resource
    private AlipayTradePagePayRequest payRequest;
    @Resource
    private AlipayProperties alipayProperties;

    /**
     * 支付方法
     */
    @SneakyThrows
    @PostMapping("/pay")
    public void pay(String orderNo, String subject, Double totalAmount, HttpServletResponse response) {
        //封装业务参数
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderNo);//订单号
        bizContent.put("subject", subject); //订单名称
        bizContent.put("total_amount", totalAmount); //订单总金额
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY"); // 产品码,固定值
        bizContent.put("timeout_express", "15m"); //超时时间,15min
        payRequest.setBizContent(bizContent.toString());

        //向支付宝发起支付请求
        String result = alipayClient.pageExecute(payRequest).getBody();
        //将结果返回给前端,进入支付用户登录界面
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print(result);
    }

    /**
     * 异步通知
     */
    @SneakyThrows
    @PostMapping("/notify")
    public String notify(@RequestParam Map<String, String> params) {
        System.out.println(params);
        /**
         * 进行验签操作,防止签名被窜改
         */
        boolean flag = AlipaySignature.rsaCheckV1(params, alipayProperties.getAlipayPublicKey(), alipayProperties.getCharset(), alipayProperties.getSignType());
        if (!flag) {
            log.info("验证签名失败!");
            return "fail";
        }
        /**
         * 判断返回的订单号、订单总金额是否与发送的一致,防止数据被篡改
         */
        String out_trade_no = params.get("out_trade_no");
        String total_amount = params.get("total_amount");

        /**
         * 判断支付宝返回的状态是否正常
         */
        String trade_status = params.get("trade_status");
        if (!trade_status.equals("TRADE_SUCCESS")) {
            log.info("交易失败!");
            return "fail";
        }

        /**
         * 更新相应的订单状态,例如将订单标记为已支付、更新库存等
         */
//        orderService.updateOrderStatus();
        return "success";
    }

}

实现效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/596655.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MybatisPlus也能轻松生成三层架构代码?

&#x1f469;&#x1f3fd;‍&#x1f4bb;个人主页&#xff1a;阿木木AEcru &#x1f525; 系列专栏&#xff1a;《Docker容器化部署系列》 《Java每日面筋》 &#x1f4b9;每一次技术突破&#xff0c;都是对自我能力的挑战和超越。 目录 一、前言三层架构的流程图为什么使用…

为什么需要自动化测试?自动化有哪些优势?

前言 自动化测试&#xff0c;最近些年可谓是大火。招聘上的要求也好&#xff0c;培训班的广告也罢&#xff0c;比比皆是&#xff0c;足以说明它在业内的火爆程度。 虽然说会写自动化测试并不能说明你就很牛批&#xff0c;但是你不会的话&#xff0c;那么很抱歉&#xff0c;你…

保持 Hiti 证卡打印机清洁的重要性和推荐的清洁用品

在证卡印刷业务中&#xff0c;保持印刷设备的清洁至关重要。特别是对于 Hiti 证卡打印机来说&#xff0c;它们是生产高质量证卡的关键工具。保持设备清洁不仅可以保证打印质量和效率&#xff0c;还可以延长其使用寿命。本文将探讨保持 Hiti 证卡打印机清洁卡的重要性&#xff0…

数码管的显示

静态数码管显示 数码管有两种一种的负电压促发,一种是正电压促发,上图是单数码管的引脚 上图是数码管模组的引脚,采用了引脚复用技术 咱们这个单片机由8个单数码管,所以要用上38译码器,如下图 74138使能端,单片机上电直接就默认接通了 74HC245的作用是稳定输入输出,数据缓冲作…

Rust Course学习(编写测试)

如果友友你的计算机上没有安装Rust&#xff0c;可以直接安装&#xff1a;Rust 程序设计语言 (rust-lang.org)https://www.rust-lang.org/zh-CN/ Introduce 介绍 Testing in Rust involves writing code specifically designed to verify that other code works as expected. It…

线上线下包搭建小程序/公众号/H5 支持二开!

网上交友有以下三个积极影响&#xff1a; 1. 扩展社交圈和增加社交机会&#xff1a;网上交友可以让人们接触到不同地区、不同背景、不同文化的人&#xff0c;拓展人们的社交圈并且增加交友机会。这些新的社交联系对于个人的成长和发展有积极的影响&#xff0c;可以让人们学习新…

奶爸预备 |《P.E.T.父母效能训练:让亲子沟通如此高效而简单:21世纪版》 / 托马斯·戈登——读书笔记

目录 引出致中国读者译序前言第1章 父母总是被指责&#xff0c;而非受训练第2章 父母是人&#xff0c;不是神第3章 如何听&#xff0c;孩子才会说&#xff1a;接纳性语言第4章 让积极倾听发挥作用第5章 如何倾听不会说话的婴幼儿第6章 如何听&#xff0c;孩子才肯听第8章 通过改…

[每日AI·0506]巴菲特谈 AI,李飞飞创业,苹果或将推出 AI 功能,ChatGPT 版搜索引擎

AI 资讯 苹果或将推出 AI 功能&#xff0c;随 iPhone 发布2024 年巴菲特股东大会&#xff0c;巴菲特将 AI 类比为核技术 巴菲特股东大会 5 万字实录消息称 OpenAI 将于 5 月 9 日发布 ChatGPT 版搜索引擎路透社消息&#xff0c;斯坦福大学 AI 领军人物李飞飞打造“空间智能”创…

leetCode75. 颜色分类

leetCode75. 颜色分类 题目思路 代码 class Solution { public:void sortColors(vector<int>& nums) {for(int i 0, j 0, k nums.size() - 1; i < k;){if(nums[i] 0) swap(nums[i],nums[j]);else if(nums[i] 2) swap(nums[i],nums[k--]);else if(nums[i] …

基于Springboot+Vue+Java的学生就业管理系统

&#x1f49e; 文末获取源码联系 &#x1f649; &#x1f447;&#x1f3fb; 精选专栏推荐收藏订阅 &#x1f447;&#x1f3fb; &#x1f380;《Java 精选实战项目-计算机毕业设计题目推荐-期末大作业》&#x1f618; 更多实战项目~ https://www.yuque.com/liuyixin-rotwn/ei3…

Docker容器:Docker-Consul 的容器服务更新与发现

目录 前言 一、什么是服务注册与发现 二、 Docker-Consul 概述 1、Consul 概念 2、Consul 提供的一些关键特性 3、Consul 的优缺点 4、传统模式与自动发现注册模式的区别 4.1 传统模式 4.2 自动发现注册模式 5、Consul 核心组件 5.1 Consul-Template组件 5.2 Consu…

自动驾驶融合定位:IMU内参模型及标定

自动驾驶融合定位&#xff1a;IMU内参模型及标定 一、 概述 标定的本质是参数辨识。首先明确哪些参数可辨识&#xff0c;其次弄清怎样辨识。 参数包括陀螺仪和加速度计各自的零偏、标度因数、安装误差。 辨识就比较丰富了&#xff0c;如果让各位先不局限于标定任务&#xf…

HCIP-Datacom-ARST必选题库_BGP【道题】

1.关于summary automatic命令和BGP聚合的描述,错误的是? 该命令用于实现自动聚合,其优先级高于手动聚合 配置该命令后,BGP将按自然网段聚合路由 该命令用来使能对本地引入的路由进行自动聚合 配置该命令后,BGP只向对等体发送聚合后的路由 1.关于summary automatic命令和BGP聚…

C++初阶学习第五弹——类与对象(下)——类与对象的收官战

类与对象&#xff08;上&#xff09;&#xff1a;C初阶学习第三弹——类与对象&#xff08;上&#xff09;——初始类与对象-CSDN博客 类与对象&#xff08;中&#xff09;&#xff1a;C初阶学习第四弹——类与对象&#xff08;中&#xff09;——刨析类与对象的核心点-CSDN博…

Linux环境下的事件驱动力量:探索Libevent的高性能I/O架构

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的Linux高性能服务器编程系列之《Linux环境下的事件驱动力量&#xff1a;探索Libevent的高性能I/O架构》&#xff0c;在这篇文章中&#xff0c;你将会学习到Libevent的高性能I/O原理以及应用&#xff0c;并且我会给出源码…

云仓酒庄携手央视共筑品牌新高度,酒类行业广告战略迈向新征程

随着酒类市场的日益繁荣与竞争的加剧&#xff0c;品牌宣传与推广在酒类行业中的地位愈发凸显。近日&#xff0c;云仓酒庄宣布与中视中州&#xff08;央视代理机构&#xff09;达成2024-2025年度央视广告战略合作&#xff0c;云仓酒庄副总裁周玄代表云仓酒庄签约&#xff0c;这一…

Ubuntu系统安装nvfortran详细步骤【笔记】

实践设备&#xff1a;华硕FX-PRO&#xff08;NVIDIA GeForce GTX 960M&#xff09; Ubuntu系统安装NVFORTRAN&#xff08;NVIDIA Fortran Compiler&#xff09;步骤如下&#xff1a; 安装依赖项&#xff1a;在安装NVFORTRAN之前&#xff0c;你需要确保系统已经安装了一些必要…

Linux学习(一)-- 简单的认识

目录 1. Linux的诞生 2.Linux发行版 拓展&#xff1a; &#xff08;1&#xff09;什么是Linux系统的内核&#xff1f; &#xff08;2&#xff09;什么是Linux系统发行版&#xff1f; 1. Linux的诞生 Linux创始人: 林纳斯 托瓦兹 Linux 诞生于1991年&#xff0c;作者上大学…

Java特性之设计模式【享元模式】

一、享元模式 概述 享元模式&#xff08;Flyweight Pattern&#xff09;主要用于减少创建对象的数量&#xff0c;以减少内存占用和提高性能。这种类型的设计模式属于结构型模式&#xff0c;它提供了减少对象数量从而改善应用所需的对象结构的方式 享元模式尝试重用现有的同类对…

LeetCode 226.翻转二叉树(全网最多的解法)

LeetCode 226.翻转二叉树 1、题目 题目链接&#xff1a;226. 翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#…