当前位置: 首页 > news >正文

支付宝沙箱环境 支付

一 什么是沙箱:

沙箱环境是支付宝开放平台为开发者提供的安全低门槛的测试环境

支付宝正式和沙箱环境的区别 :

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, "退款失败");}}

相关文章:

支付宝沙箱环境 支付

一 什么是沙箱&#xff1a; 沙箱环境是支付宝开放平台为开发者提供的安全低门槛的测试环境 支付宝正式和沙箱环境的区别 &#xff1a; AI&#xff1a; 从沙箱到正式环境&#xff1a; 当应用程序开发完成后&#xff0c;需要将应用程序从沙箱环境迁移到正式环境。 这通常涉及…...

获取unity中prefab的中文文本内容以及和prefab有关的问题

背景1&#xff1a;经常会在开发中遇到策划需要改某个界面&#xff0c;但是我们不知道那是什么界面&#xff0c;只看到一些关键字比如圣诞活动&#xff0c;那这样我就可以轻易找到这个预设了。另外还可以扩展就是收集项目中的所有中文文本然后归集到多语言表中&#xff0c;然后接…...

Web自动化中常用XPath定位方式

在进行Web自动化测试时&#xff0c;元素定位是一个至关重要的环节。XPath&#xff08;XML Path Language&#xff09;是一种用于在XML文档中定位节点的语言。在Web自动化中&#xff0c;XPath广泛应用于定位HTML元素。本文将详细介绍几种常用的XPath定位方式&#xff0c;包括绝对…...

Unity3D播放GIF图片使用Animation来制作动画

系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、下载GIF动图,用PS制作导出帧动画图片👉二、使用Animation制作动画👉三、脚本控制动画播放👉壁纸分享👉总结👉前言 unity播放gif图片,本身是不支持的,但是可以使用其他方法来实现, 1.有一种使用System…...

redo log 和 bin log 的两阶段提交

两阶段提交的过程 当事务提交后&#xff0c;有一个两阶段提交策略。 在开启两阶段提交时&#xff0c;会开启一个 XA 事务&#xff08;宏观上的事务&#xff09;&#xff0c; Prepare 阶段&#xff1a;将 redo log 的状态设置为 prepare&#xff0c;然后将 事务XID 写入 redo…...

Go基础学习07-map注意事项;多协程对map的资源竞争;sync.Mutex避免竟态条件

文章目录 Go中map使用以及注意事项map使用时的并发安全问题 Go中map使用以及注意事项 Go语言中map使用简单示例&#xff1a; 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&#xff0c;在服务器的zrcs文件夹下直接下载anaconda&#xff08;很慢&#xff09;&#xff1a; wget https://repo.anaconda.com/archive/Anaconda3-2024.06-1-Linux-x86_64.sh 或者选择本地下载&#xff0c;清华大学开源软件镜像站&#xff1a;https:/…...

什么是IIC通信协议?

IIC&#xff08;Inter-Integrated Circuit&#xff09;通信协议&#xff0c;又称为I2C&#xff08;Inter-Integrated Circuit 2&#xff09;协议&#xff0c;是一种广泛使用的串行通信协议。它由飞利浦半导体公司&#xff08;现NXP Semiconductors&#xff09;开发&#xff0c;…...

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稳定版)

注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章写的好的话&#xff0c;可以点下关注&#xff0c;博主会一直更新鸿蒙next相关知识 专栏地址: https://blog.csdn.net/qq_56760790/…...

Matplotlib 使用 LaTeX 渲染图表中的文本、标题和数学公式

Matplotlib 使用 LaTeX 渲染图表中的文本、标题和数学公式 Matplotlib 是一个功能强大的 Python 库&#xff0c;用于绘制各种高质量的图表和图形。在许多科研和技术文档中&#xff0c;数学公式是不可或缺的一部分&#xff0c;LaTeX 提供了精美的数学公式渲染能力。Matplotlib …...

Android 安卓内存安全漏洞数量大幅下降的原因

谷歌决定使用内存安全的编程语言 Rust 向 Android 代码库中写入新代码&#xff0c;尽管旧代码&#xff08;用 C/C 编写&#xff09;没有被重写&#xff0c;但内存安全漏洞却大幅减少。 Android 代码库中每年发现的内存安全漏洞数量&#xff08;来源&#xff1a;谷歌&#xff09…...

c++primier第十二章类和动态内存

本章内容包括&#xff1a; 对类成员使用动态内存分配隐式和显式地复制构造函数隐式和显式地重载赋值操作符在构造函数中使用new所必须完成的工作使用静态类成员 将布局new操作符用于对象使用指向对象的指针实现队列抽象数据类型(ADT) 动态内存和类 复习范例和静态类成员 首…...

Ansible学习之ansible-pull命令

想要知道ansible-pull是用来做什么的&#xff0c;就需要了解Ansible的工作模&#xff0c;Ansible的工作模式有两种&#xff1a; push模式 push推送&#xff0c;这是Ansible的默认模式&#xff0c;在主控机上编排好playbook文件&#xff0c;push到远程主机上来执行。pull模式 p…...

Linux:磁盘管理

一、静态分区管理 静态的分区方法不可以动态的增加或减少分区的容量。 1、磁盘分区-fdisk 该命令是用于查看磁盘分区情况&#xff0c;和分区管理的命令 命令格式&#xff1a;fdisk [选项] 设备文件名常用命令&#xff1a; -h&#xff1a;查看分区信息 fdisk系统常用命令&…...

FP7209: 用于紫外线消毒灯的 升压LED恒流驱动芯片

现在社会对于居家消毒也越发重视起来。而居家消毒除了75%浓度酒精及各类消毒液外&#xff0c;利用紫外线灯给衣物表面、房间消毒也是一种很好的选择。FP7209 定位于低压线性恒流驱动&#xff0c;精度高、外围电路简单、使用方便且可靠性高&#xff0c;更可广泛应用于商业照明系…...

【华为HCIP实战课程二】OSPF基础介绍和OSPF RID NBMA配置详解

一、OSPF多区域 自治系统(Autonomous System) 一个自治系统是指使用同一种路由协议交换路由信息的一组路由器 1、Area0为骨干区域 2、ABR--关乎3类LSA后续详解 ABR用来连接骨干区域Area0和非骨干区域,它与骨干区域之间既可以是物理连接,也可以是逻辑上的连接。 3、AS…...

网络编程(13)——单例模式

十三、day13 今天学习如何单例模式实现逻辑层的设计。内容包括服务器如何能捕获信号使其安全退出、单例模标类 1. 什么是单例模式&#xff1f; 单例模式&#xff08;Singleton&#xff09;&#xff0c;保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点&…...

基于定制开发与2+1链动模式的商城小程序搭建策略

摘要&#xff1a;本文探讨商城小程序的搭建策略&#xff0c;对比自主组建团队和第三方开发两种方式&#xff0c;强调以第三方开发模式为主的优势。阐述在第三方开发模式下&#xff0c;结合定制开发和21链动模式&#xff0c;如何搭建一款有助于企业商业模式创新与智能商业升级的…...

银河麒麟,apt 安装软件报错640Unknown Status

今天把银行麒麟的机器恢复出厂了&#xff0c;然后apt install 安装极其不稳定&#xff0c;故障现象如下图所示&#xff1a; 错误提示里面有&#xff1a; 640 Unknown Status [IP: 106.116.184.122 80] E: 无法下载 http://archive.kylinos.cn/kylin/KYLIN-ALL/pool/universe/f…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...