支付宝沙箱环境 支付
一 什么是沙箱:
沙箱环境是支付宝开放平台为开发者提供的安全低门槛的测试环境
支付宝正式和沙箱环境的区别 :
AI:
-
从沙箱到正式环境:
-
当应用程序开发完成后,需要将应用程序从沙箱环境迁移到正式环境。
-
这通常涉及到更新应用程序中的配置文件,更换正式的 AppID 和密钥等凭证。
二 注册使用
网址:登录 - 支付宝 点击 进行注册

查看信息:appid

点击查看 应用密钥与支付宝公钥 :appPrivateKey 与 publiceKey

记录一下卖家信息:

三 实现
支付实现的步骤:1.导入依赖 2.配置参数 3.调用方法(API调用) 4.处理响应或异常
具体实现可查看官网文档: 小程序文档 - 支付宝文档中心
小程序文档 - 支付宝文档中心

简易版概述小程序文档 - 支付宝文档中心
小程序文档 - 支付宝文档中心
查看api使用规范 根据需求选择对应的接口方法


比如下面我们要实现的电脑网站的支付功能
对应的就是 Factory.Payment.Page.pay()
Easy 版
有拦截器的 注意放开路径
3.1 导入项目依赖
<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-easysdk -->
<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-easysdk</artifactId><version>2.2.0</version>
</dependency>
3.2 编写配置信息:
其中关于//@PostConstruct 是一个 Java 注解,用于标记需要在依赖注入完成后执行的方法。它表示该方法应该在对象创建和属性注入完毕后由容器自动调用,以完成初始化工作。
@Component
@ConfigurationProperties(prefix = "alipay")
@Datapublic class AlipayConfig {// 应用Idprivate String appId;// 应用私钥private String appPrivateKey;// 支付宝公钥private String publiceKey;// 回调接口路径private String notifyUrl;// 支付宝网关地址private String gatewayHost;@PostConstruct//@PostConstruct 是一个 Java 注解,用于标记需要在依赖注入完成后执行的方法。// 它表示该方法应该在对象创建和属性注入完毕后由容器自动调用,以完成初始化工作。// 此注解的方法无参数,返回类型可为空或其他类型。主要用于确保对象完全初始化。public void init(){Config config = new Config();// 基础配置config.protocol = "https";config.gatewayHost = this.gatewayHost;// 支付宝网关地址config.signType = "RSA2";// 业务配置config.appId = this.appId;config.merchantPrivateKey = this.appPrivateKey;config.alipayPublicKey = this.publiceKey;config.notifyUrl = this.notifyUrl;// 将配置信息, 添加到相应的工厂类Factory.setOptions(config);System.out.println("支付宝初始化配置完成");}
}
application.properties
其中 appid appPrivateKey publiceKey 在开发者平台获取
gatewayHost 大家都一样 无需更改
notifyUrl 是内网穿透这里使用不到 现在随便写都可以
alipay.appid=9021000139682312
alipay.appPrivateKey=MIIEvwIBADANBgkqhkiG9w0BAQEFAAS...
alipay.publiceKey=MIIBIjANBgkqhkiG9w0BAQEFAAOC.......
alipay.notifyUrl=http://xxxxxxx/api/alipay/notify
alipay.gatewayHost=openapi-sandbox.dl.alipaydev.com
3.3 调用支付方法
我这里直接在cotroller层编写
@RestController
@RequestMapping("/api/alipay")
public class PayController {/*** 订单支付接口, 核心是调用支付宝的 Factory.Payment.Page().pay() 方法* @param subject 支付对象信息* @param outTradeNo 订单号* @param totalAmount 订单金额* @param returnUrl 支付成功以后返回的页面地址* @return*/@GetMapping("/pay")public void pay(String subject, String outTradeNo, String totalAmount, String returnUrl, HttpServletResponse httpResponse) throws Exception {// 使用支付宝支付页面接口进行支付AlipayTradePagePayResponse response = Factory.Payment.Page().pay(subject, outTradeNo, totalAmount, returnUrl);System.out.println(response);// response.getBody();// 设置HTTP响应内容类型为HTML,编码为UTF-8httpResponse.setContentType("text/html;charset=utf-8");// 向HTTP响应写入支付宝支付页面接口返回的响应体httpResponse.getWriter().write(response.getBody());// 刷新HTTP响应输出流,确保数据立即发送到客户端httpResponse.getWriter().flush();// 关闭HTTP响应输出流,释放资源httpResponse.getWriter().close();}}
Java
可以进行测试后端了!!!!!!!!
可以进行测试后端了!!!!!!!!
可以进行测试后端了!!!!!!!!
http://localhost:8080/api/alipay/pay?subject=%E7%81%AB%E8%BD%A6%E7%A5%A8%E6%94%AF%E4%BB%98&outTradeNo=63172637&totalAmount=16.8&returnUrl=http%3A%2F%2Flocalhost%3A8080%2Fpayok.html%3ForderId%3D312323
3.4 回调方法 配合内网穿透使用
回调就是支付宝在进行扣款操作之后 调用我们的后端 告诉我们支付结果
回调方法如下:
回调中有个验证操作来源于:调用官方给我们提供的方法来验证数据的真实性。

@PostMapping("/notify")public String notify(@RequestParam Map parameterMap) throws Exception {String tradeStatus = parameterMap.getOrDefault("trade_status","").toString();if (tradeStatus.trim().equals("TRADE_SUCCESS")) {// 验证请求的有效性if (Factory.Payment.Common().verifyNotify(parameterMap)) {System.out.println("通过支付宝的验证");System.out.println("订单id:" + parameterMap.get("out_trade_no"));}else {System.out.println("支付验证不通过");}}return "success";}
需要先开启内网穿透
服务器为localhost:8080 支付宝无法调用:
注意:如果是部署云服务器就不需要内网穿透了 只不过需要我我们对回调的参数进行相对应的修改!!!!
3.5 内网穿透工具
1.路由侠-局域网变公网

设置 信息 主机号

查看内网映射:

测试: 说明映射是没有问题的 成功调用了后端

修改 alipay.notifyUrl 的 配置信息
alipay.notifyUrl=http://xxxk.w1.luyouxia.net/api/alipay/notify
再次进行支付测试:s
这里加上vue进行测试:
前端 vue:
3.6 前端
<template><h2>支付</h2><el-form :inline="true" :model="form" class="demo-form-inline"><el-form-item label="支付对象信息"><el-input v-model="form.subject" placeholder="请输入" clearable /></el-form-item><el-form-item label="订单号"><el-input v-model="form.outTradeNo" placeholder="请输入" clearable /></el-form-item><el-form-item label="订单金额"><el-input-number v-model="form.totalAmount" placeholder="请输入" clearable /></el-form-item><el-form-item label="支付成功以后返回的页面地址"><el-input v-model="form.returnUrl" placeholder="请输入" clearable /></el-form-item><el-form-item><el-button type="primary" @click="onSubmit">提交</el-button></el-form-item></el-form><br><h2>退款</h2><el-form :inline="true" :model="form2" class="demo-form-inline"><el-form-item label="退款单号"><el-input v-model="form2.outTradeNo" placeholder="请输入" clearable /></el-form-item><el-form-item label="退款金额"><el-input-number v-model="form2.refundAmount" placeholder="请输入" clearable /></el-form-item><el-form-item><el-button type="primary" @click="onSubmit2">提交</el-button></el-form-item></el-form>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import dayjs from 'dayjs';
import router from '@/router';
import { ElNotification } from 'element-plus'
import { alipayApi } from '@/api';
const form = ref({subject: '小米su8',outTradeNo: dayjs().format('YYYYMMDDHHmmss'),totalAmount: 188888,returnUrl: 'http://localhost:5000/paysuccess'
})const form2 = ref({outTradeNo: '20220422164101',refundAmount: 18888,
})
const onSubmit = () => {let returnUrl = encodeURIComponent(form.value.returnUrl)window.location.href = "http://localhost:8080/api/alipay/pay?subject=" + `${form.value.subject}` + "&outTradeNo=" + `${form.value.outTradeNo}`+ "&totalAmount=" + `${form.value.totalAmount}` + "&returnUrl=" + `${returnUrl}`
}
const onSubmit2 = () => {alipayApi.refund.call({outTradeNo: form2.value.outTradeNo,refundAmount: form2.value.refundAmount}).then(_res => {ElNotification({title: '提示',message: '退款成功',type: 'success',})})
}</script>
测试结果
一方面 : 前端返回我们设置的 returnUrl 界面
另一方: 后端执行 配置的 alipay.notifyUrl=http://xxxk.w1.luyouxia.net/api/alipay/notify
成功
3.7 退款

调用 refund 交易退款方法
@GetMapping("/refund")public String refund( String outTradeNo,Float refundAmount) {try {
com.alipay.easysdk.payment.common.models.AlipayTradeRefundResponse response = Factory.Payment.Common().refund(outTradeNo, String.valueOf(refundAmount));System.out.println(response);if (response.msg.equals("Success")){return "退款成功";}else {throw new BizException(777, "退款失败");}}catch (Exception e){e.printStackTrace();throw new BizException(777, "退款失败");}}
通用版
小程序文档 - 支付宝文档中心
通用版
导入依赖
<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.34.0.ALL</version></dependency>
配置
@Component
@ConfigurationProperties(prefix = "alipay2")
@Data
public class Alipay2Config extends com.alipay.api.AlipayConfig {// 网关地址private String serverUrl;// 应用Idprivate String appId;// 应用私钥private String appPrivateKey;//请求格式private String format;//字符集编码private String charset;//签名类型private String signType;// 支付宝公钥private String publiceKey;// 回调接口路径private String notifyUrl;}
支付
@GetMapping("/pay2")public void pay2(String subject, String outTradeNo, String totalAmount, String returnUrl, HttpServletResponse httpResponse) throws Exception {AlipayClient alipayClient = new DefaultAlipayClient(alipay2Config.getServerUrl(), alipay2Config.getAppId(),alipay2Config.getAppPrivateKey(), alipay2Config.getFormat(), alipay2Config.getCharset(), alipay2Config.getAlipayPublicKey(), alipay2Config.getSignType());AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();request.setNotifyUrl(alipay2Config.getNotifyUrl());request.setReturnUrl(returnUrl);JSONObject bizContent = new JSONObject();bizContent.put("out_trade_no", outTradeNo);bizContent.put("total_amount", totalAmount);bizContent.put("subject", subject);bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");request.setBizContent(bizContent.toString());String form = "";try {// 调用SDK生成表单form = alipayClient.pageExecute(request).getBody();} catch (AlipayApiException e) {e.printStackTrace();}httpResponse.setContentType("text/html;charset=UTF-8");// 直接将完整的表单html输出到页面httpResponse.getWriter().write(form);httpResponse.getWriter().flush();httpResponse.getWriter().close();}
退款
/*** 退款接口** @return*/@GetMapping("/refund2")public String refund2 (String outTradeNo, Float refundAmount){AlipayClient alipayClient = new DefaultAlipayClient("https://openapi-sandbox.dl.alipaydev.com/gateway.do",alipayConfig.getAppId(),alipayConfig.getAppPrivateKey(),"JSON","utf-8",alipayConfig.getPubliceKey(),"RSA2");AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();// 获取获取对应订单信息JSONObject bizContent = new JSONObject();bizContent.put("out_trade_no", outTradeNo);bizContent.put("refund_amount", refundAmount);bizContent.put("out_request_no", "HZ01RF002"); //退款标识,用于查询状态是操作request.setBizContent(bizContent.toString());// 使用支付宝支付页面接口进行支付try {AlipayTradeRefundResponse response = alipayClient.execute(request);System.out.println(response);if (response.isSuccess()) {System.out.println("退款成功");return "退款成功";} else {System.out.println("退款失败");throw new BizException(777, "退款失败");}} catch (Exception e) {e.printStackTrace();System.out.println("退款失败");throw new BizException(777, "退款失败");}}
相关文章:
支付宝沙箱环境 支付
一 什么是沙箱: 沙箱环境是支付宝开放平台为开发者提供的安全低门槛的测试环境 支付宝正式和沙箱环境的区别 : AI: 从沙箱到正式环境: 当应用程序开发完成后,需要将应用程序从沙箱环境迁移到正式环境。 这通常涉及…...
获取unity中prefab的中文文本内容以及和prefab有关的问题
背景1:经常会在开发中遇到策划需要改某个界面,但是我们不知道那是什么界面,只看到一些关键字比如圣诞活动,那这样我就可以轻易找到这个预设了。另外还可以扩展就是收集项目中的所有中文文本然后归集到多语言表中,然后接…...
Web自动化中常用XPath定位方式
在进行Web自动化测试时,元素定位是一个至关重要的环节。XPath(XML Path Language)是一种用于在XML文档中定位节点的语言。在Web自动化中,XPath广泛应用于定位HTML元素。本文将详细介绍几种常用的XPath定位方式,包括绝对…...
Unity3D播放GIF图片使用Animation来制作动画
系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、下载GIF动图,用PS制作导出帧动画图片👉二、使用Animation制作动画👉三、脚本控制动画播放👉壁纸分享👉总结👉前言 unity播放gif图片,本身是不支持的,但是可以使用其他方法来实现, 1.有一种使用System…...
redo log 和 bin log 的两阶段提交
两阶段提交的过程 当事务提交后,有一个两阶段提交策略。 在开启两阶段提交时,会开启一个 XA 事务(宏观上的事务), Prepare 阶段:将 redo log 的状态设置为 prepare,然后将 事务XID 写入 redo…...
Go基础学习07-map注意事项;多协程对map的资源竞争;sync.Mutex避免竟态条件
文章目录 Go中map使用以及注意事项map使用时的并发安全问题 Go中map使用以及注意事项 Go语言中map使用简单示例: func main() {var mp map[string]int// mp : map[string]int{}val, ok : mp["one"]if ok {fmt.Println(val)} else {fmt.Println(val)}mp[…...
远程服务器安装anaconda并创建虚拟环境
1、承接上文新用户zrcs,在服务器的zrcs文件夹下直接下载anaconda(很慢): wget https://repo.anaconda.com/archive/Anaconda3-2024.06-1-Linux-x86_64.sh 或者选择本地下载,清华大学开源软件镜像站:https:/…...
什么是IIC通信协议?
IIC(Inter-Integrated Circuit)通信协议,又称为I2C(Inter-Integrated Circuit 2)协议,是一种广泛使用的串行通信协议。它由飞利浦半导体公司(现NXP Semiconductors)开发,…...
P3131 [USACO16JAN] Subsequences Summing to Sevens S Python题解
[USACO16JAN] Subsequences Summing to Sevens S 题目描述 Farmer John’s N N N cows are standing in a row, as they have a tendency to do from time to time. Each cow is labeled with a distinct integer ID number so FJ can tell them apart. FJ would like to ta…...
鸿蒙NEXT开发-ArkUI(基于最新api12稳定版)
注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下 如果大家觉得博主文章写的好的话,可以点下关注,博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…...
Matplotlib 使用 LaTeX 渲染图表中的文本、标题和数学公式
Matplotlib 使用 LaTeX 渲染图表中的文本、标题和数学公式 Matplotlib 是一个功能强大的 Python 库,用于绘制各种高质量的图表和图形。在许多科研和技术文档中,数学公式是不可或缺的一部分,LaTeX 提供了精美的数学公式渲染能力。Matplotlib …...
Android 安卓内存安全漏洞数量大幅下降的原因
谷歌决定使用内存安全的编程语言 Rust 向 Android 代码库中写入新代码,尽管旧代码(用 C/C 编写)没有被重写,但内存安全漏洞却大幅减少。 Android 代码库中每年发现的内存安全漏洞数量(来源:谷歌)…...
c++primier第十二章类和动态内存
本章内容包括: 对类成员使用动态内存分配隐式和显式地复制构造函数隐式和显式地重载赋值操作符在构造函数中使用new所必须完成的工作使用静态类成员 将布局new操作符用于对象使用指向对象的指针实现队列抽象数据类型(ADT) 动态内存和类 复习范例和静态类成员 首…...
Ansible学习之ansible-pull命令
想要知道ansible-pull是用来做什么的,就需要了解Ansible的工作模,Ansible的工作模式有两种: push模式 push推送,这是Ansible的默认模式,在主控机上编排好playbook文件,push到远程主机上来执行。pull模式 p…...
Linux:磁盘管理
一、静态分区管理 静态的分区方法不可以动态的增加或减少分区的容量。 1、磁盘分区-fdisk 该命令是用于查看磁盘分区情况,和分区管理的命令 命令格式:fdisk [选项] 设备文件名常用命令: -h:查看分区信息 fdisk系统常用命令&…...
FP7209: 用于紫外线消毒灯的 升压LED恒流驱动芯片
现在社会对于居家消毒也越发重视起来。而居家消毒除了75%浓度酒精及各类消毒液外,利用紫外线灯给衣物表面、房间消毒也是一种很好的选择。FP7209 定位于低压线性恒流驱动,精度高、外围电路简单、使用方便且可靠性高,更可广泛应用于商业照明系…...
【华为HCIP实战课程二】OSPF基础介绍和OSPF RID NBMA配置详解
一、OSPF多区域 自治系统(Autonomous System) 一个自治系统是指使用同一种路由协议交换路由信息的一组路由器 1、Area0为骨干区域 2、ABR--关乎3类LSA后续详解 ABR用来连接骨干区域Area0和非骨干区域,它与骨干区域之间既可以是物理连接,也可以是逻辑上的连接。 3、AS…...
网络编程(13)——单例模式
十三、day13 今天学习如何单例模式实现逻辑层的设计。内容包括服务器如何能捕获信号使其安全退出、单例模标类 1. 什么是单例模式? 单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点&…...
基于定制开发与2+1链动模式的商城小程序搭建策略
摘要:本文探讨商城小程序的搭建策略,对比自主组建团队和第三方开发两种方式,强调以第三方开发模式为主的优势。阐述在第三方开发模式下,结合定制开发和21链动模式,如何搭建一款有助于企业商业模式创新与智能商业升级的…...
银河麒麟,apt 安装软件报错640Unknown Status
今天把银行麒麟的机器恢复出厂了,然后apt install 安装极其不稳定,故障现象如下图所示: 错误提示里面有: 640 Unknown Status [IP: 106.116.184.122 80] E: 无法下载 http://archive.kylinos.cn/kylin/KYLIN-ALL/pool/universe/f…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
