去付款--支付宝沙箱的简单测试

news2024/11/27 21:02:45

alipay-demo

进入开发者中心–开发工具–沙箱–设置公钥
搜索电脑网上支付–查看Demo–查看配置类–查看业务逻辑
我们的基础配置类主要是初始化我们的alipay客户端
真正去付款的时候是提交了一个form表单达到一个真正的支付jsp,java代码首先初始化我买的Alipay客户端,拿到传过来的参数,通过aliPayClient去执行这个付款请求

实现:
新建module–导入依赖–配置jetty

jetty:run -Djetty.port=9100

在这里插入图片描述

启动alipayDemo,启动成功
在这里插入图片描述

测试,访问首页 localhost:9100/alipay-demo,到达订单页面
在这里插入图片描述
将付款金额改成1000,点击付款之后,到达alipay.trade.page.pay.jsp页面,在这个页面获取了AliPay客户端,获取前台传过来的参数,设置订单信息,执行请求获取一个form表单格式的字符串,输出到页面中。
如果没有登录,让你登录,否则进行一个扫码付款
在这里插入图片描述
接下来我们用沙箱账号进行登录,进入我们的支付页面
在这里插入图片描述
输入支付密码,支付成功
在这里插入图片描述
这时刷新沙箱账号页面,发现商家信息多了1000块钱,买家少了1000块钱。支付成功。
用了一个result,一个form表单。

同步通知和异步通知
同步通知,付款成功之后会去同步通知的商户页面。
为什么需要一个同步通知呢?
因为我们之前有订单了,订单付款之后订单的状态需要一个变更,是不是真的付款了,因为有的用户到付款页面之后就把付款页面给关闭了,不去付款。所以我们需要付款成功后跳回商户页面,对订单状态进行变更。
为什么需要一个异步通知?
因为付款完毕之后支付宝还有几秒是需要跳转页面的,而有的客户是不想等去跳转页面的因此会直接关闭页面不跳转到商户页面,那么我们对订单的状态的变更也就没法实现了。这个时候就会使用异步通知。

支付宝付款集成shop

导入依赖

在父项目中定义版本号,声明依赖
在订单系统中引入aplipay的依赖

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

写配置类

package com.alipay.config;

import java.io.FileWriter;
import java.io.IOException;

/* *
 *类名:AlipayConfig
 *功能:基础配置类
 *详细:设置帐户有关信息及返回路径
 *说明:
 *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
 *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
 */

public class AlipayConfig {

//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

	// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
	public static String app_id = "2021000122689739";

	// 商户私钥,您的PKCS8格式RSA2私钥
	public static String merchant_private_key = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDKQ2LXAcegUdGkzsIXCyJ/Ugff7NwFpV0kDiY8zLm93Nr4/6KHM846kqUsQV9kZt4h0ZqesylSDvwKMKGm9o8fgmBlBg76TCJ+j65NxxuqQWOIGbo3VmO7t8dbHukBjTB2nboMDKNb1NYPERsIH3zcltw8+vCchCE+wra8HCmTHG5DVZY17/WdRnD7lMg5FEdd7o0xwT1DrTJTG76UTsc16PNTHb0Hd6PXKqSYeIvADoj3cNhZBo+MSp8+sYqRB6lx84KxtTpqB5t29by750h/jV+OmKljfUJJBWTNBuy06JhE6HDgyI3/KdfmprZU6obO71aib3xbfQZliRJsZmlpAgMBAAECggEAF1T+qd7CsHO/w0s2iIH4UMedsO8Z0mzo+afIMWtMYeKAQAj9LquDNq6D7z77ShGzviL3uybftV+VI3fIrgHzMKdRh1XTlHwD3qWkbcRyJIm2eZS+LnQAvT7N+GzwZAVtecFoHMu4bHd42fQXMjCvrqKYdVBdQTDcxOihO8Hj6dxBJREmShT68X+7vtEaICjIcPPk7Eu4aAVTYwwWuz3zjboSMMsKO1EGruDI/mQXD8CpDSv+EG7V2zyy+6nS82c/BvqH4Hd8/ERepwVqbWeMKA36v9hHGfWCWGHq37sG1RhyhPMo5lA6fJcCla5OAoTY4qDYWhGvplXI0RHk1VHgIQKBgQDxTt7KRAw7MhBeo4SoyxbPQaPOWlQoMS11h1fS4Dx4dSlg4sHrPQOoXRf0ATpQhLdKUngwoq8/iQ70ML+AYn1OrM5vKnGsvjXpO0UucbN/KfXLkxHAY8VPrgaSSlImLphJwKRJ9ucOwMW3zp2MMzz5ykTU+Yvs9e0wtfZoW/ZJkwKBgQDWk/I2keFkDakGvpHaCWNOmqe8ZaBk3GVYR5WJY7oJAdg6B1fsqmBo7Gkcb8pfZvcMVJ1AnuC3bRF315pQtaUXYFFFixP2HHeoowkXRP0DDKXXPUDIakv74y5j7YL6iIFaQOQONjx9/ziJ21L+wn7XQy9qzjQ64Bhlkn6wUk9ukwKBgQCvayB2dYVWuww/YCud8RVB0XvdFLk9BpL/b0Ye3DfZcYKFFhLWiWJRUGuLTCEyS2hbNRx+bqVrUJ14Ur/D+tURDnp7QaWlaBkU1atzGeDcvooaVW2AKIdVZzMLwc96RkEazFoiEsThaq3Q8viA5Pact7fWAxr/RcAJux3Hu6KM1QKBgCIs8hjq5yEOY+tlEsnNUPnF/A0vinpF+AY1cIWvUoP4vT2Qydox0KUlciBLVcoYFiTqnRkbtOLCBlQ2DKfqJl8wwgD3g7hhFFXRkbMZE8sWiptbcCP7ehqmNk9IFuJcN23ug+QXk07mBVU/j1pwE8+pLbYvHXZ7Fqemy3K9yVTtAoGASL5QeKvu1Si/gsUCu0ka9e+V6iHmWTLFCN2z/JZUVACUQ8uAvLWhxQNVW2GJQ0//yCm04jn8gaVa593Aj5i6GmbyggspVrRUekRtRDGcFLARj6g1/ChGzJfj4P/o/rBKocPAtIsDBZnq/+AsGIaatl32O6t48wJfzqjVUaUA0cQ=";

	// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
	public static String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAykNi1wHHoFHRpM7CFwsif1IH3+zcBaVdJA4mPMy5vdza+P+ihzPOOpKlLEFfZGbeIdGanrMpUg78CjChpvaPH4JgZQYO+kwifo+uTccbqkFjiBm6N1Zju7fHWx7pAY0wdp26DAyjW9TWDxEbCB983JbcPPrwnIQhPsK2vBwpkxxuQ1WWNe/1nUZw+5TI";

	// 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
	public static String notify_url = "http://srgrcv.natappfree.cc/shop-portal/order/callback";

	// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
	public static String return_url = "http://localhost:9096/shop-order/order/myOrder";

	// 签名方式
	public static String sign_type = "RSA2";

	// 字符编码格式
	public static String charset = "utf-8";

	// 支付宝网关
	public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";

	// 支付宝网关
	public static String log_path = "C:\\";


//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

	/**
	 * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
	 * @param sWord 要写入日志里的文本内容
	 */
	public static void logResult(String sWord) {
		FileWriter writer = null;
		try {
			writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
			writer.write(sWord);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (writer != null) {
				try {
					writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

配置完之后,点击提交订单,传购物车列表和总金额到预订单页面,到预订单页面进行显示,然后再预订单页面点击确定提交订单后生成一个确定的订单,存入数据库中,传给确定订单页面订单参数等信息。在实际项目中这个确定订单走的是/order/submitOrder,注意存入数据库的同时,还需要将购物车中的信息清空。在确定订单页面中我们要点击去付款,付款的这个数据来自我们确定订单中的数据,因此我们在付款的时候需要查询数据库,防止出现bug,并且在付款页面我们需要传过去订单编号和总金额。也就是进入/order/payment进行真正的付款,获取支付宝阿里云客户端,根据前端传过来的参数去数据库中进行查询,设置alipayRequest的请求参数,客户端执行请求,返回一个form表单格式的字符串,跳转到一个页面中去显示这个字符串的信息。因此需要将该字符串放到request域中,用el表达式取出来。

/**
	 * 跳转到预订单页面
	 *
	 * @return
	 */
	@RequestMapping("/preOrder")
	public String preOrder(Model model, HttpServletRequest request) {
		Admin admin = (Admin) request.getSession().getAttribute("user");
		model.addAttribute("cartResult", cartService.getCartList(admin));
		return "order/preOrder";
	}

	/**
	 * 跳转到订单提交页面.这是一个确定的订单
	 * 在这里查询一个订单信息,可能查询出来的订单需要判断是否为空,因为根据订单编号查出来的订单是唯一的,因此还需要判断是否大小大于1,如果大于1,则返回空。
	 *
	 * @return
	 */
	@RequestMapping("/submitOrder")
	public String submitOrder(Model model, HttpServletRequest request) {
		Admin admin = (Admin) request.getSession().getAttribute("user");
		CartResult cartResult = cartService.getCartList(admin);
		//1.存入订单信息
		BaseResult baseResult = orderService.orderSave(admin, cartResult);
		//2.清除购物车信息
		cartService.clearCart(admin);
		//总价
		model.addAttribute("totalPrice", cartResult.getTotalPrice());
		//订单编号
		model.addAttribute("orderSn", baseResult.getMessage());
		//3.页面跳转
		return "order/submitOrder";
	}

	/**
	 * 去付款,点击付款按钮去pay-ment,前台传过来订单编号,查询订单,执行付款请求,得到一个form表单格式的字符串,显示到个付款页面,因此会使用到Model。
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping("payment")
	public String payment(HttpServletRequest request,Model model,String orderSn) {
		try {
			//获得初始化的AlipayClient
			AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id,
					AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key,
					AlipayConfig.sign_type);

			//设置请求参数
			AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
			alipayRequest.setReturnUrl(AlipayConfig.return_url);
			alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

			//从数据库中去查询订单
			Order order = orderService.selectOrderByOrderSn(orderSn);

			//商户订单号,商户网站订单系统中唯一订单号,必填
			String out_trade_no = orderSn;
			//付款金额,必填
			String total_amount = String.valueOf(order.getTotalAmount());
			//订单名称,必填
			String subject = "用户为"+order.getUserId()+"的订单";
			//商品描述,可空
			String body = "";

			alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
					+ "\"total_amount\":\"" + total_amount + "\","
					+ "\"subject\":\"" + subject + "\","
					+ "\"body\":\"" + body + "\","
					+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

			//若想给BizContent增加其他可选请求参数,以增加自定义超时时间参数timeout_express来举例说明
			//alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
			//		+ "\"total_amount\":\""+ total_amount +"\","
			//		+ "\"subject\":\""+ subject +"\","
			//		+ "\"body\":\""+ body +"\","
			//		+ "\"timeout_express\":\"10m\","
			//		+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
			//请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节

			//请求
			String result = alipayClient.pageExecute(alipayRequest).getBody();
			//输出
			System.out.println(result);
			model.addAttribute("result",result);
			return "order/payment";
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

异步通知:当用户将跳转页面关闭后,通过异步通知告诉我们用户的支付订单是成功,可以进行订单状态的更改。
在这里插入图片描述我们的支付宝去调用我们的页面,我们的页面是运行在localhost上的,支付宝是不可能调用我们的这个localhost上面的页面的,只能是公网,支付宝才可以调用,怎么解决呢?
1、把项目运行在服务器上,购买域名,挂在公网上面,支付宝通过公网域名调用我们的页面。
2、通过内网穿透,将公网的地址映射到我们的地址,可以通过公网地址访问我们的页面。

内网穿透

首先进入官网
官网:https://natapp.cn/
点击下载选择适用于自己电脑的版本
购买隧道–配置隧道–解压文件–修改natapp.nin–运行natapp.exe–在前台页面中写Controller跳转页面,写一个页面展示“”success“”。

   /**
     * 跳转回调页面
     * @param model
     * @return
     */
    @RequestMapping("callback")
    public String callback(Model model){
        model.addAttribute("result","success");
        System.out.println("异步通知成功!!!!!");
        return "order/callback";
    }
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
</head>
<body>
${result}
</body>
</html>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

瑞吉外卖 - 新增分类功能(11)

某马瑞吉外卖单体架构项目完整开发文档&#xff0c;基于 Spring Boot 2.7.11 JDK 11。预计 5 月 20 日前更新完成&#xff0c;有需要的胖友记得一键三连&#xff0c;关注主页 “瑞吉外卖” 专栏获取最新文章。 相关资料&#xff1a;https://pan.baidu.com/s/1rO1Vytcp67mcw-PD…

网安学习踩坑经验篇

回想学习网络安全一年来&#xff0c;踩了不少坑走了不少弯路&#xff0c;在此稍作总结&#xff0c;希望可以帮助那些想要入门 web 安全或者是想打CTF的同学们一些建议 坑点 先总结一下&#xff0c;我在学习中遇到的坑点 只看视频&#xff0c;眼高手低&#xff0c;不练习&…

【嵌入式Linux】设备树基本语法

设备树基本语法 1_总领-本期设备树视频要怎么讲&#xff1f;讲什么&#xff1f;_哔哩哔哩_bilibili 基本的 特殊的 中断控制 描述GIC控制器 时钟 CPU GPIO 个数&#xff0c;保留范围&#xff08;起始、长度&#xff09;&#xff0c;个数对应的名字 GPIO映射-这个脚被用了换一…

chatgpt赋能Python-numpy_归一化

NumPy归一化&#xff1a;理解数据规范化的重要性 什么是归一化&#xff1f; 在数据科学和机器学习中&#xff0c;归一化是预处理数据的一种常用技术。归一化是指将数据缩放到一个特定的范围内&#xff0c;通常是0到1或-1到1之间。 例如&#xff0c;我们可能比较一家医院的三…

渗透测试--5.3.使用john破解密码

前言 由于Linux是Internet最流行的服务器操作系统&#xff0c;因此它的安全性备受关注。这种安全主要靠口令实现。 Linux使用一个单向函数crypt&#xff08;&#xff09;来加密用户口令。单向函数crypt&#xff08;&#xff09;从数学原理上保证了从加密的密文得到加密前的明…

Java笔记_22(反射和动态代理)

Java笔记_22 一、反射1.1、反射的概述1.2、获取class对象的三种方式1.3、反射获取构造方法1.4、反射获取成员变量1.5、反射获取成员方法1.6、综合练习1.6.1、保存信息1.6.2、跟配置文件结合动态创建 一、反射 1.1、反射的概述 什么是反射? 反射允许对成员变量&#xff0c;成…

基于IC5000烧录器使用winIDEA烧写+调试程序(S32K324的软件烧写与调试)

目录 一、iSYSTEM简介二、如何使用iSYSTEM winIDEA烧写调试程序2.1 打开winIDEA&#xff1a;2.2 新建一个Workspace;2.3 硬件配置:2.4 选择CPU芯片型号&#xff1a;2.5 加载烧写文件&#xff1a;2.6 开始烧录程序&#xff1a;2.7 程序调试Debug&#xff1a;2.7.1 运行程序&…

PCL点云处理之单点选择的交互操作(一百六十七)

PCL点云处理之单点选择的交互操作(一百六十七) 一、效果展示二、实现代码一、效果展示 交互选择点,输出点信息,具体如下图所示 二、实现代码 #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/visualization/pcl_visu

Spring Cloud Alibaba(二)Nacos统一配置管理

目录 一、为什么需要配置中心 二、常用的配置中心 Nacos 的几个概念 三、Nacos配置中心的使用 &#xff08;一&#xff09;properties格式 1、导入依赖 2、在配置中心新建配置 3、修改配置文件名为bootstrap.yml 4、在微服务中添加nacos config服务地址的配置 5、测试…

chatgpt赋能Python-numpy精度

Numpy精度介绍 Numpy是一个用于进行科学计算的Python库&#xff0c;它提供了多维数组对象以及一系列用于操作数组的函数。Numpy的广泛使用使其成为数据科学中的重要组成部分。然而&#xff0c;Numpy中的精度问题却常常被忽视。 浮点数精度问题 在Numpy中&#xff0c;浮点数是…

STL与string类的认识及简单使用

STL与string类的认识及简单使用 一、STL二、string类构造函数容量操作访问及遍历操作迭代器 修改操作非成员函数重载关系运算符重载getline 三、总结 一、STL STL(standard template libaray-标准模板库)&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组…

【计算机毕设】基于SringBoot+Vue的校园二手交易平台(含支付)

在导师的严格指导下&#xff0c;我的毕业设计终于完成了&#xff0c;毕设被推优算是给大学生活画上了圆满的句号&#xff0c;几个月的努力也没白费。在开发的过程中收获了很多&#xff0c;也遇到很多问题&#xff0c;但因怕时间来不及&#xff08;根本不知道截止时间TvT&#x…

点餐小程序实战教程04-餐品分类及餐品数据源设计

我们已经利用一定篇幅实现了店铺信息展示的功能,本篇我们来实现一下点餐的逻辑。点餐的逻辑有以下: 用户打开点餐页面,利用侧边栏导航来切换菜品初始状态用户未点餐,显示一个加号的图标点击加号显示数量,需要将菜品加入购物车,购物车显示选购菜品的数量和总价点击减号可以…

[日记]LeetCode算法·二十五——二叉树⑤ AVL树(插入+删除)附代码实现

本章的代码实现基于上一篇BST与优先队列的基类进行平衡二叉树&#xff0c;即AVL树。 文章目录 AVL的概念AVL查询效率AVL的插入1.插入节点2.更新平衡因子BF3.旋转调整树的结构3.1 LL 右旋3.2 RR 左旋3.3 LR 左右双旋3.4 RL 右左双旋 4 插入总结 AVL的删除1.寻找删除节点2.更新平…

窗口组件元素识别工具

inspect.exe 微软官方工具集成于 Windows SDK 官网下载&#xff1a;https://developer.microsoft.com/zh-cn/windows/downloads/windows-sdk/ FlaUInspect&#xff1a; 第三方开源的识别工具 https://github.com/FlaUI/FlaUInspect UIRecorder&#xff1a; WinAppDriver里…

无状态子域名爆破工具(附下载)

ksubdomain是一款基于无状态子域名爆破工具&#xff0c;支持在Windows/Linux/Mac上使用&#xff0c;它会很快的进行DNS爆破&#xff0c;在Mac和Windows上理论最大发包速度在30w/s,linux上为160w/s的速度。 总的来说&#xff0c;ksubdomain能爆破/验证域名&#xff0c;并且快和…

【P25】JMeter 取样器超时(Sample Timeout)

文章目录 一、准备工作二、测试计划设计 一、准备工作 慕慕生鲜&#xff1a; http://111.231.103.117/#/login 进入网页后&#xff0c;登录&#xff0c;页面提供了账户和密码 搜索框输入“虾” 右键检查或按F12&#xff0c;打开调试工具&#xff0c;点击搜索 二、测试计划设…

CHATGPT:北京打响大模型地方战第一枪

5月16日消息&#xff0c;最近&#xff0c;“北京市促进通用人工智能创新发展的若干措施&#xff08;2023-2025年&#xff09;&#xff08;征求意见稿&#xff09;”&#xff08;以下简称“措施”&#xff09;公布。这个措施从算力、数据、算法、应用、监管五个方向出发&#xf…

Redis学习---03

一、redis事务 (1) Redis单条命令保证原子性&#xff0c;但事务不保证原子性。 Redis 事务不是严格意义上的事务&#xff0c;只是用于帮助用户在一个步骤中执行多个命令。单个 Redis 命令的执行是原子性的&#xff0c;但 Redis 没有在事务上增加任何维持原子性的机制&#xf…