支付宝支付流程

news2024/11/17 11:45:21

第一步前端:点击去结算,前端将商品的信息传递给后端,后端返回一个商品的订单号给到前端,前端将商品的订单号进行存储。

对应的前端代码:然后再跳转到支付页面

// 第一步 点击去结算 然后生成一个订单号
// 将选中的商品  商品的id 数量 名称 传递给后端
const payMoney = async () => {
    const res = await addOrderApi({ arr: [{ id: 1, name: '云南普洱', count: 10, price: 160 }] })
    const order = res.data.data
    console.log(order)
    // 将订单号存储到pinia中
    orderStore.setOrder(order)
    router.push('/order')
}

后端对应的代码:

// 生成订单号的接口
router.post('/addOrder',(req,res)=>{
  console.log(req.body.arr)
  // 生成订单号 年份+月份+日+分 + 6位的随机石
  // 将前端传递过来的数据存储到数据库中
  // 订单号的状态: 1 代表未支付  2代码等待支付 3代表成功 4代表失败
  res.send({status:200,message:'ok',data:'202405041050123456'})
})

第二步:点击提交订单: 这时候判断是否选择了收货地址。

01 前端将订单号发送给后端,后端修改订单号的状态,  

02 后端将购物车的商品进行删除,并提交到待支付的数据库中

03 接着将商品信息 订单号 价格 传递给后端,请求支付的接口 

04 后端这时候会返回跳转的链接,直接进行链接的跳转

05 支付宝链接支付是否成功都会跳转到传递跳转路由的界面

06 从跳转路由界面的url地址上面获取支付宝携带的参数订单号等,进行接口请求查询是否支付成功

前端代码如下:

const onSubmit = async () => {
    const order = orderStore.order
    console.log(order)
    console.log('提交订单')
    // 发送请求  修改订单的状态,  修改为待支付
    // 第二步将购物车该商品的数据进行清空,
    const res = await submitOrderApi({
        orderId: order
    })
    // 接着再调用支付的api,  参数包括订单号 总金额  买的商品的详情
    const res1 = await paymentApi(qs.stringify({
        orderId: order,
        name: '普洱茶叶300g',
        price: 100
    }))
    console.log(res1.data) // 返回的支付宝跳转的地址
    window.location.href = 'res1.data' // 跳转到支付宝支付的界面


}

后端代码如下:

01 修改订单的状态,以及将准备结算的商品,从购物车的数据表删除

// 修改订单号状态的接口   将订单号的状态修改为2    // 再将以及提交的订单的数据  从数据表中的购物车的表中删除
router.post('/submitOrder',(req,res)=>{
  // 这里通过mysql语句根据订单的条件 然后将状态进行修改
  res.send({success:true})
})

02 对接支付宝的沙箱环境将跳转的地址返回给后端。

配置沙箱的信息参数:

单独创建的allpay.js文件中进行配置

const AlipaySdk = require('alipay-sdk').default
const alipaySdk = new AlipaySdk({
    appId:'9021000136669436', // appid
    signType:'RSA2', // 签名算法
    gateway:'https://openapi-sandbox.dl.alipaydev.com/gateway.do', //支付宝网关
    alipayPublicKey:'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi5tQOLjk5pIFH40bOdglT5FS5QG/QrqsFG1VuJ3UH0Z18nqbOKm26G2zizwou2Ur6ycYcYWPg4NFgnSSoSGjobqLhr0WHqJ78rkmCUVDbhHYb+Co5qRKPPwCGfvQ1v0pgivq7SKVcBtf7SMdyDkufSWaAzZipSEr8fvn3tL+G/oIAA8hWUW5Rkb8rImvq/VjYHTusK0+YQFGrdgC5jIAAqm/YOyxJXGzDpUiFFc1DqquVrrZ0Sca+Fwtdos+HirMEjcm8K8Jv5FGUIzESTVqA+B9EDMn22KOio/bM0M09L+fCMix3BA/HcnTVkdzclfchrz2ZvvnLXzu81EIU3jz4QIDAQAB',// 支付宝公钥
    privateKey:'MIIEogIBAAKCAQEAgbOCYNKGGwQnjPOdTDZZ+fz6c6Gt66QK7/RzjWWxlXmUSP8Hc5MRFupwWJscM+2NjJOQmpI0hjeJcyo9M3h6rZXIkCqiWpeg+hDAj01TouO/woxQIZHvIpe1flAa1pgHzha0rBU7keyYLipkYda+nrbeKLDE5RJ3J8ANaHlCjKcisyFOs5JLd+CQ2gX7OZM2eTAwtL6G8BNHndZd9m9kV01WWkrAjl6KMNNLAgFzOBAMvcs4UuUjCW58RylkhhEpxEjpmhpga/9mXq7k1p5m9YJr/up5kpvLG7trqTZg6VSHutDnRypCdx2yNmLpQz7NEZo4aa2HUKQsCztLhu9zLwIDAQABAoIBAB3UCsf5op3T9sSTwjkkxsyXQYIWTMlEkL9emLSMDqsxqsie3jfWOrfqcqvuAC5xE3yg80CZHzs+yn2R2UFdE9mX+Ogu5eevt3XLJH3QasurVQ6I9mTCCx0JhtPl2EZB8ImU7zgkKe8FWnpDhZJ6sJwPskfpX17PQFgD8xFz0bpG4bVCgtRepsOpaRpba5yNtv61G0In0GviRcS4WD2shQMkPrSz0y0IZi/hkcBn8ZK2kF01Jl4OstMwD46d0iQgQM3L0xC7iQFPKYlpZTM9DKdgz/s8ncehtZH1AN7KFGB5aHARfKRVXTBzbI2F4oHaTr747LcnziBJ6Ecf4Y4zgwECgYEAxn9DL3zWFam1nzGzboBADhal8hglmp4j0I9ZB2JeXukscm/2C/KjlK0Aki8KxNFb+SiTtv561oDr5KN9GbzJBaQCN7+Svtbmlyq4VlGo8YrIOgcpzWz5dkFs9/SeaCJtdpqm/S+ii3jxvr7T5BW+mrLdDKI2VVeximMDbBNDc9MCgYEAp0ZGnOw/SD7yM1wm92Qa17t49EwagoqwHczBVJLmCYMrL5XFFMwt3Bm0QcI4r5Q4pOlelAbggCLScZ13jrGZCuKktbd/ColFvNlqn20BawPFwYZ8TpayJCUiG1F8eFNw+IGOy0ivXcGO7GKXccBOdEAr2fo1VsttUo6Iteeg1bUCgYB9NOsxOiJkWb9polUXX6iH+ntEgTy/Ef9vX+x9fuweHCDgMoVWNgA/GP1iOHAnhBPqz1CVvmHHilzBxOp1YKLAfxqzBZFP9YhQVC8gq7PQYIU6LSiOHq4gjNZqdY+yCf1YMechj3mNVoXOltpbZefr9uT+QhfZr04bB6ex9Vi35wKBgFQdpsyqkHgID0t8f6vQDx+FCqHu0zXp//48RMv+wubtqv3W1rBKrJUN5/NZc5/3bTSglgriGmrVF/ZCNSjwbgFnT2SBzcTCmusIefGJozjpQLy8oC304cgDVE9gfrMTYq/UlrXq6yS+fNyqB3YQOmODEYofpErtKSBmxKCUxfAxAoGANFkMzolsqKp6rRH6aCXnC0zpbdqr7yX2UVbhjRTBaRRKkbixIqik8J6qOAabDLc6bfOnnTfU7bSEh1yHWZgobpsQ3s/2tGRZU3hLYHjLo6IUBvZdj/mcwa/ZvQmjYBH5SCZdV0MwnMctBRZHctU2DYgDViD6yaGauDXB5xxDwu8='//应用私钥
})
module.exports = alipaySdk

03 路由文件中导入并使用

var alipaySdk = require('../db/allpay.js');

var AlipayFormData = require('alipay-sdk/lib/form.js').default

// 支付的接口 需要对接支付宝的砂箱环境
router.post('/payment',(req,res)=>{
  console.log(req.body) // 获取到订单号 商品名称 总金额
  let orderId = req.body.orderId
  let price = req.body.price
  let name = req.body.name
  // 开始对接支付宝API
  const formDate = new AlipayFormData()
  // 这里调用setMethod并传入get 会返回跳转到支付页面的url
  formDate.setMethod('get')
  // 支付信息
  formDate.addField('bizContent',{
    outTradeNo:orderId,
    productCode:'FAST_INSTANT_TRADE_PAY', //这里是固定写死的
    subject:name
  })
  // 支持成功或失败跳转的链接
  formDate.addField('returnUrl','http://localhost:4000/payment')
  // 返回promise
  const result = alipaySdk.exec(
    'alipay.trade.page.pay',
    {},
    {formData:formDate},
  );

    result.then(ress=>{
      res.send({
        code:200,
        data:ress // 这个就是支付宝返回的地址
      })
    })
})

04 在跳转之后的页面中也就是http://localhost:4000/payment的界面中获取url参数,请求接口查询支付的状态

const res = await submitOrderApi(qs.stringify({
    // 里面的参数是支付宝跳转之后会跳转的地址上面拼接的有
    out_trade_no: router.query.out_trade_no, //订单号
    trade_no: router.query.trade_no
}))

05 后端需要再向支付宝请求 获取订单最后的支付状态 返回给前端

router.post('/successpayment',(req,res)=>{
  //订单号
  let out_trade_no = req.body.out_trade_no
  let trade_no = req.body.trade_no

  // 后端要和支付宝进行比对和校验
  const formDate = new AlipayFormData()
  formDate.setMethod('get')

  formDate.addField('bizContent',{
    out_trade_no,
    trade_no
  })

  const result = alipaySdk.exec(
    'alipay.trade.query',
    {},
    {formData:formDate},
  );
  result.then(resData=>{
    axios({
      method:'GET',
      url:resData
    }).then(data=>{
      let responseCode = data.data.alipay_trade_query_response;
      if(responseCode.code==='10000'){
        switch(responseCode.trade_status){
          case 'WAIT_BUYER_PAY':
          res.send({
            data:{
              code:0,
              data:{
                msg:'支付有交易 没有付款'
              }
            }
          })
          break;
          case 'TRADE_CLOSED':
            res.send({
              data:{
                code:0,
                data:{
                  msg:'交易关闭'
                }
              }
            })
            break;
        }
      }
    })
  })


})

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

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

相关文章

计算机专业就业前景以及工资待遇水平怎么样

计算机专业毕业生的就业前景不错的,计算机专业人才的需求量大,各行各业都需要这类人才来进行软件开发、数据分析、网络安全管理、系统维护等工,工资待遇水平较高,以下是上大学网(www.sdaxue.com)整理的计算机专业就业前…

手把手教你在本机安装Stable Diffusion秋叶整合包(附安装包和大模型)

整合包对非技术出身的同学比较友好,因为秋叶大佬把相关的东西已经都整合好了,只需要点点点就行了。当然懂编程的同学就更没有问题了。 文末领取SD安装包和大模型! 准备 为了保证AI绘画的效率,建议在本机安装Nvidia独立显卡&…

转速(RPM)和角速度转换FC(CODESYS ST代码)

1、频率和转速转换功能块 频率和转速转换功能块(CODESYS ST源代码)-CSDN博客文章浏览阅读16次。1、转速和频率转换功能块转速和频率转换功能块(CODESYS ST源代码)-CSDN博客文章浏览阅读10次。1、转速/频率常用转换关系转速/频率/线速度/角速度计算FC_200 plc计算角速度-CSDN博…

EXCEL怎样把筛选后含有公式的数据,复制粘贴到同一行的其它列?

自excel2003版之后,常规情况下,复制筛选后的数据,会忽略隐藏行,仅复制其筛选后的数据,粘贴则是粘贴到连续单元格区域,不管行是在显示状态还是隐藏状态。 一、初始数据: 二、题主的复制粘贴问题…

Android仿微信公众号文章页面加载进度条

前言: 微信公众号文章详情页面加载的时候,WebView会在头部显示一个进度条,这样做的好处就是用户可以一边加载网页内容的同时也可浏览网页内容,不需要等完全加载完之后才全部显示出来。如何实现呢? 其实很简单&#xf…

【机器学习】BK- SDM与LCM的融合策略在文本到图像生成中的应用

突破边缘设备限制:BK-SDM与LCM的融合策略在文本到图像生成中的应用 一、引言二、稳定扩散算法的挑战与现状三、BK-SDM与LCM的融合策略利用高质量图像-文本对进行训练为LCM量身定制高级蒸馏过程 四、结论与展望 一、引言 随着人工智能技术的飞速发展,文本…

www.fastssh.com SSH over WebSockets with CDNs

https://www.fastssh.com/page/create-ssh-cdn-websocket/server/这其实不是标准的websocket报文(服务器响应报文无Sec-Websocket-Accept字段),所以无法使用github.com/gorilla/websocket包:GET / HTTP/1.1 Host: hostname:8080 User-Agent: Go-http-cli…

c#学习基础1

一、复杂数据类型 1)概述 2)枚举 1.基本概念 枚举是一个比较特别的存在,它是一个被命名的整形常量的集合,一般用它来表示状态,类型等 1.1申明枚举和申明枚举变量 1.2申明枚举语法 2.在哪里申明枚举 3.枚举的使用 4…

Unity技术学习:RenderMesh、RenderMeshInstanced

叠甲:本人比较菜,如果哪里不对或者有认知不到的地方,欢迎锐评(不玻璃心)! 导师留了个任务,渲染大量的、移动的物体。 当时找了几个解决方案: 静态批处理: 这东西只对静…

从0开始linux(1)——文件操作

欢迎来到博主的专栏——从0开始linux 博主ID:代码小豪 博主使用的linux发行版是:CentOS 7.6 不同版本下的操作可能存在差异 文章目录 命令文件操作命令文件树和文件路径文件树绝对路径相对路径 文件属性tree指令删除文件复制文件 大家还记得在小学第一次…

java下乡扶贫志愿者招募管理系统springboot-vue

计算机技术在现代管理中的应用,使计算机成为人们应用现代技术的重要工具。能够有效的解决获取信息便捷化、全面化的问题,提高效率。 技术栈 前端:vue.jsElementUI 开发工具:IDEA 或者eclipse都支持 编程语言: java 框架&#xff1…

SQL 基础 | AVG 函数的用法

在SQL中,AVG()是一个聚合函数,用来计算某个列中所有值的平均值。 它通常与GROUP BY子句一起使用,以便对分组后的数据进行平均值计算。 AVG()函数在需要了解数据集中某个数值列的中心趋势时非常有用。 以下是AVG()函数的一些常见用法&#xff…

猿人学第七题-动态字体-随风漂移

前言:该题主要是考对fontTools.ttLib.TTFont的操作,另外就是对字典互相映射的操作 一、woff文件存储 from fontTools.ttLib import TTFont #pip install fontTools def save_woff(response):woff response[woff]woff_file base64.b64decode(woff.enc…

第11章 软件工程

这里写目录标题 1.软件过程1.1能力成熟度模型(CMM)1.2能力成熟度模型集成(CMMI)1.3瀑布模型(线性顺序)1.4增量模型1.5演化模型1.5.1原型模型1.5.2螺旋模型 1.6喷泉模型1.7统一过程(UP)模型 2.敏捷方法3.系统设计4.系统测试4.1单元测试(模块测试)4.2集成测试4.3黑盒测试(功能测试…

噪声嵌入提升语言模型微调性能

在自然语言处理(NLP)的快速发展中,大模型(LLMs)的微调技术一直是研究的热点。最近,一篇名为《NEFTUNE: NOISY EMBEDDINGS IMPROVE INSTRUCTION FINETUNING》的论文提出了一种新颖的方法,通过在训…

每日一题2:获取DataFrame的大小

在Python中,pandas库是一个非常流行的数据处理库,它提供了DataFrame这一数据结构来高效地处理表格化的数据。如果想查看一个DataFrame的行数和列数,可以使用.shape来实现。 一、基本用法 当你有一个名为df的DataFrame时,只需调用…

rust使用Atomic创建全局变量和使用

Mutex用起来简单,但是无法并发读,RwLock可以并发读,但是使用场景较为受限且性能不够,那么有没有一种全能性选手呢? 欢迎我们的Atomic闪亮登场。 从 Rust1.34 版本后,就正式支持原子类型。原子指的是一系列…

USP技术提升大语言模型的零样本学习能力

大语言模型(LLMs)在零样本和少样本学习能力上取得了显著进展,这通常通过上下文学习(in-context learning, ICL)和提示(prompting)来实现。然而,零样本性能通常较弱,因为缺…

c#Excel:2.写入Excel表 3.读取Excel表

--写入Excel表-- 该例首先从数据库aq中读取学生信息表staq(参考数据库章节),然后将学生信息表中的数据写入Excel表格中 (1)在OfficeOperator类库项目的ExcelOperator类中定义索引器,用于获取Excel表格中的单元格,代码…

QT:QT窗口(一)

文章目录 菜单栏创建菜单栏在菜单栏中添加菜单创建菜单项添加分割线 工具栏创建工具栏设置停靠位置创建工具栏的同时指定停靠位置使用QToolBar类提供的setAllowedAreas函数来设置停靠位置 设置浮动属性设置移动属性 状态栏状态栏的创建在状态栏中显示实时消息在状态栏中显示永久…