vue+node对接支付宝沙箱

目录

一、准备工作

二、后端node

1、添加支付宝配置文件

2、开始写支付提交接口

      3、前端部分(点击提交订单)

3.1、写axios请求

3.2、点击提交订单按钮后发送网络请求

3.3、付款成功跳转的页面的路径是下面这样的:

4、后端向支付宝发请求,拿到订单的状态

5、交易成功跳转后(前端部分)

在vue项目中,要对接支付宝完成支付功能,首先需要做如下准备:
一、准备工作
先登录到支付宝开发平台https://open.alipay.com/develop/sandbox/app
下载支付宝开发平台密钥工具https://opendocs.alipay.com/open/02kipk https://opendocs.alipay.com/open/291/106097/
打开支付宝开发平台密钥工具,生成密钥

这里需要注意:拿到的私钥需要转换格式,不然是用不了的

4.需要对刚才生成的私钥进行转换

5.配置完成后,需要返回开放平台,将公钥复制进去

二、后端node
需要安装的依赖:

npm i alipay-sdk -S

npm i express -S

1、添加支付宝配置文件

注意:下面的应用私钥是需要进行格式转换的(上面有说)

const AlipaySdk = require('alipay-sdk').default;
const alipaySdk = new AlipaySdk({// appIdappId: 'xxx',// 签名算法signType: 'RSA2',// 支付宝网关地址gateway: 'https://openapi.alipaydev.com/gateway.do',// 支付宝公钥alipayPublicKey: 'xxx',// 应用私钥privateKey: 'xxx'
})module.exports = alipaySdk;

2、开始写支付提交接口

// 引入支付宝配置信息
const alipaySdk = require('../zfb/zfb_config')
const AlipayFromData = require('alipay-sdk/lib/form').default;router.post('/pay', (req, res) => {// 前端给后端的数据(订单号,金额,商品描述等信息)let orderId = req.body.orderId;let orderMoney = req.body.orderMoney;let orderTitle = req.body.orderTitle;let orderInfo = req.body.orderInfo;// 对接支付宝const formData = new AlipayFromData()formData.setMethod('get')formData.addField('returnUrl', 'http://localhost:8080/#/paysuccess'); // 付款成功打开的链接formData.addField('bizContent', {// 传递的订单号outTradeNo: orderId,productCode: 'FAST_INSTANT_TRADE_PAY',// 金额total_amount: orderMoney,// 商品标题subject: orderTitle,// 商品描述body: orderInfo,});const result = alipaySdk.exec('alipay.trade.page.pay',{},{ formData: formData },);result.then((resp) => {res.send({success: '支付成功',code: 200,result: resp});});
})

3、前端部分(点击提交订单)
3.1、写axios请求
需要安装query-string,因为需要对请求中的对象转字符串

import querystring from 'query-string';
// 或者安装qs也行
export const reqZfbPay = (orderObj) => requset({url: '/pay', method: 'post', data: querystring.stringify(orderObj)})

3.2、点击提交订单按钮后发送网络请求

async PaySuccess() {/***  let orderId = req.body.orderId;let orderMoney = req.body.orderMoney;let orderTitle = req.body.orderTitle;let orderInfo = req.body.orderInfo;*/let orderTitle = [];let orderInfo = [];this.orderList.forEach((item) => {orderTitle.push(item.goods_name);orderInfo.push(item.goods_choose);});let orderObj = {orderId: this.order_code,orderMoney: this.total,orderTitle: orderTitle.toString(),orderInfo: orderInfo.toString(),};let res = await reqZfbPay(orderObj);// console.log(res)if (res.code === 200) {// 支付成功后,需要将购物车中的数据进行删除this.delAllGoods();Toast("正在支付,请稍等~");// 进行支付宝支付页面跳转window.location.href = res.result;}
}

控制台可以拿到返回的信息

返回的result数据就是需要跳转支付宝支付的页面

等输入支付密码支付完成后,就会跳转到之前node后端写的地址

3.3、付款成功跳转的页面的路径是下面这样的:
里面有需要的参数,可以通过$route.query拿到

跳转新页面后,并没有结束,还前端还需要向后端发送请求,获取订单数据

4、后端向支付宝发请求,拿到订单的状态
在后端安装axios

// 引入网络请求(向支付宝发请求)
const axios = require('axios')
router.post('/pay/orderStatu', (req, res) => {let out_trade_no = req.body.out_trade_no;let trade_no = req.body.trade_no;// 对接支付宝const formData = new AlipayFromData()formData.setMethod('get')formData.addField('bizContent', {out_trade_no,trade_no});const result = alipaySdk.exec(// 这个地方和前面的不同'alipay.trade.query',{},{ formData: formData },);result.then((resData) => {axios({url: resData,method: 'get'}).then(data => {// console.log(data);let r = data.data.alipay_trade_query_response;if (r.code === '10000') {switch (r.trade_status) {case 'WAIT_BUYER_PAY':res.send({success: true,code: 200,msg: '支付宝有交易记录,没付款'})break;case 'TRADE_FINISHED':res.send({success: true,code: 200,msg: '交易完成,不能退款'})break;case 'TRADE_SUCCESS':res.send({success: true,code: 200,msg: '刚交易完成,可以退款'})break;case 'TRADE_CLOSED':res.send({success: true,code: 200,msg: '交易关闭,没有支付成功'})break;}} else if (r.code === '40004') {res.json('交易不存在')}}).catch(err => {res.json({msg: '查询失败',err})})});
})

这里需要知道支付宝通知返回时的交易状态列表信息

WAIT_BUYER_PAY 支付宝有交易记录,但是没有付款
TRADE_FINISHED
交易完成,时间过了不能退款

TRADE_SUCCESS
刚交易完成,可以退款

TRADE_CLOSED
交易关闭,没有支付成功

5、交易成功跳转后(前端部分)

export const reqPaySuccess = (data) => requset({url: '/pay/orderStatu', method: 'post', data: querystring.stringify(data)})
import { reqPaySuccess } from "@/api";
export default {mounted() {let data = {// 跳转后的url里面的参数out_trade_no: this.$route.query.out_trade_no,trade_no: this.$route.query.trade_no,};this.paySuccess(data);},methods: {async paySuccess(data) {let res = await reqPaySuccess(data);console.log(res);}}
};

剩下业务逻辑自行填充吧😼

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

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

相关文章

Github上最值得学习的10个Android开源项目,安卓面试题

1.Java语言进阶与Android相关技术核 Android应用是由Java语言进行开发的,SDK也是由Java语言编写,对于Android来说,只要SDK没有用Kotlin重写,那么Java语言是都需要学习的。而且Android APK的后台服务器程序大概率是Java语言构建&a…

【计算机网络】应用层自定义协议

自定义协议 一、为什么需要自定义协议?二、网络版计算器1. 基本要求2. 序列化和反序列化3. 代码实现(1)封装 socket(2)定制协议和序列化反序列化(3)客户端(4)计算器服务端…

Javaweb之SpringBootWeb案例之自动配置以及常见方案的详细解析

3.2 自动配置 我们讲解了SpringBoot当中起步依赖的原理,就是Maven的依赖传递。接下来我们解析下自动配置的原理,我们要分析自动配置的原理,首先要知道什么是自动配置。 3.2.1 概述 SpringBoot的自动配置就是当Spring容器启动后&#xff0c…

OLLAMA 本地模型调用

Ollama 网址下载 再cmd,用 library 里面的库 英文对话: Gemma is available in both 2b and 7b parameter sizes: ollama run gemma:2bollama run gemma:7b (default) 中文对话 ollama run qwen:0.5bollama run qwen:1.8b 用vscode而不是cmd调用 …

【论文笔记】An Effective Adversarial Attack on Person Re-Identification ...

原文标题(文章标题处有字数限制): 《An Effective Adversarial Attack on Person Re-Identification in Video Surveillance via Dispersion Reduction》 Abstract 通过减少神经网络内部特征图的分散性攻击reid模型。 erbloo/Dispersion_r…

强化学习嵌入Transformer(代码实践)

这里写目录标题 ChatGPT的答案GPT4.0 ChatGPT的答案 # 定义Transformer模块 class Transformer(nn.Module):def __init__(self, input_dim, hidden_dim, num_heads, num_layers):super(Transformer, self).__init__()self.encoder_layer nn.TransformerEncoderLayer(d_modeli…

Vue3中组件通讯的方式

Vue3中组件通讯的方式 1 🤖GPT🤖: (答案有点问题混淆了vue2的内容) 父组件向子组件传递数据 props 子组件通过 props 属性从父组件接收数据。emit事件子组件通过emit 事件 子组件通过 emit事件子组件通过emit 发射事件向父组件发送消息。provide / in…

Java SpringCloud gateway面试题

Java SpringCloud gateway面试题 前言1、什么是网关Zuul(gateway)?2、服务网关的作用?3、Zuul网关(Gateway)如何搭建集群?4、ZuulFilter常用有那些方法?5、如何实现动态zuul网关路由转发?6、在Z…

kubeadm安装部署

目录 1.要求 2.环境准备 3.所有节点安装docker 4.所有节点安装kubeadm,kubelet和kubectl 5.部署K8S集群 6.测试 7.扩展3个副本 8.部署Dashboard master(2C/4G,cpu核心数要求大于2)192.168.27.10docker、kubeadm、kubelet、…

LightDB - ecpg 支持dml 中使用 return into 【24.1】

在之前的版本中ecpg 中只能使用returning into 来给c 变量赋值,如下: exec sql update t1 set c aa where id 2 returning c into :c_val;为了兼容oracle pro*c 中return into 的用法,从24.1 开始, LightDB 也支持通过return in…

Chrome插件 | WEB 网页数据采集和爬虫程序

无边无形的互联网遍地是数据,品类丰富、格式繁多,包罗万象。数据采集,或说抓取,就是把分散各处的内容,通过各种方式汇聚一堂,是个有讲究要思考的体力活。君子爱数,取之有道,得注意遵…

mobile app 安全扫描工具MobSF了解下

可以干啥: static 静态分析 dynamic 动态分析 可以用来渗透了 如何docker安装 docker image 下载地址https://hub.docker.com/r/opensecurity/mobile-security-framework-mobsf/ setup 两行即可 1 docker pull opensecurity/mobile-security-framework-mobsf…

关于VScode远程编写linux SHELL的报错处理

使用vscode远程编写linux保存shell时,提示报错: 未能保存“shell”: 无法写入文件"vscode-remote:.../tmp/shell"(NoPermissions (FileSystemError): Error: EACCES: permission denied, open /tmp/shell) 大体意思是说:权限被拒…

Python | 从子目录文件导入父目录模块的方法

问题描述 我有两级目录,第一级称为parent_dir,第二级称为child_dir。现在在child_dir下,有一个py,称为child.py,在parent_dir下,也有一个py,称为parent.py。 我想从child.py中导入parent.py中…

Go Slice的底层实现原理深度解析

文章目录 切片的诞生:数组的延伸切片的结构初始化切片 切片的内存管理扩容机制 实例分析:切片的动态特性切片与性能性能对比 切片的并发安全并发场景下的切片操作 切片与接口切片与空接口 切片的遍历与操作遍历切片切片的切片操作 切片的垃圾回收切片的生…

年轻人怎么搞钱?

年轻人想要搞钱,可以考虑以下几个方面: 1. 创业:年轻人可以通过自己的创意,找到一个市场的空缺,开创自己的业务。可以从比较小的项目开始,逐渐扩大范围,积累经验和财富。 2. 投资:…

成为大佬之路--linux软件安装使用第000000021篇--linux安装docker

简介 Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 [GitHub](https://github.co…

Hadoop之HDFS——【模块二】数据管理

一、Namespace的概述 1.1.集群与命名空间的关系 类似于大集群与小集群之间的关系,彼此之间独立又相互依存。每个namespace彼此独立,Namespace工作时只负责维护本区域的数据,同时所有的namespace维护的文件都可以共用DataNode节点,为了区分数据属于哪些Namespace,DataNode…

强大而灵活的python装饰器

装饰器(Decorators) 一、概述 在Python中,装饰器是一种特殊类型的函数,它允许我们修改或增强其他函数的功能,而无需修改其源代码。装饰器在函数定义之后立即调用,并以函数对象作为参数。装饰器返回一个新…

力扣151--反转字符串中的单词(优)

清晰易懂,简单高效! 大体思路: 每次截取到想要的单词,拼接到新的sb中,过程中伴随双指针进行空格位置指向控制, 其中如果start指针如果0的情况要放在第一个判断条件防止边界条件失效,并且这种…