Spring Boot 完善订单【五】集成接入支付宝沙箱支付

1.1.什么是沙箱支付

支付宝沙箱支付(Alipay Sandbox Payment)是支付宝提供的一个模拟支付环境,用于开发和测试支付宝支付功能的开发者工具。在真实的支付宝环境中进行支付开发和测试可能涉及真实资金和真实用户账户,而沙箱环境则提供了一个安全、隔离的环境,使开发者能够模拟支付过程,测试支付功能,而不会使用真实资金。

使用支付宝沙箱支付环境,开发者可以模拟各种支付场景,包括交易创建、支付请求、支付回调等,以验证支付功能的正确性和稳定性。沙箱环境中的所有交易和数据都是虚拟的,不会产生真实的交易或资金流动。

支付宝沙箱支付提供了开发者工具和接口,使开发者能够在模拟环境下进行支付流程的调试和测试。开发者可以在沙箱环境中创建测试账户、配置模拟的交易金额和状态,使用沙箱环境中的接口进行支付操作,并模拟支付回调接口接收支付结果。

通过使用支付宝沙箱支付,开发者可以更安全、更有效地进行支付功能的开发和测试,避免了对真实环境的影响和风险。一旦支付功能在沙箱环境中验证通过,开发者可以将其部署到真实的支付宝生产环境中,与真实用户进行交互和支付。

步骤:

1.2接入支付宝开放平台

登陆支付宝:支付宝开放平台

登录成功之后,点击控制台跳转到控制台主页面,将浏览器进度条滚动到最下面,选择沙箱,最后点击沙箱选项即可,如下:

下载密钥生成工具:

小程序文档 - 支付宝文档中心

前端代码:

$(".pay").click(function () {//地址,手机号,收货人,支付方式,快递方式let el = $(".addres").find(".on")let person = el.find(".tit .fl").text()let address = el.find(".addCon p:first-child").text()let telephone = el.find(".addCon p:last-child").text()let pay = $(".way .on").attr('value')let mail = $(".dis .on").text()let ids = $(this).attr('data-ids')let order={person,telephone,address,pay,mail,ids}$.post('/order/add',order,resp=>{if(resp.code===200){//         进入支付let f = confirm("是否去结算?")if (f){console.log(resp.data)location.href="/order/pay?oid="+resp.data}else {location.href="/"}}},"json")
})

后端代码:

package com.lya.lyaspshop.controller;import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.yitter.idgen.YitIdHelper;
import com.lya.lyaspshop.config.AlipayConfig;
import com.lya.lyaspshop.pojo.Goods;
import com.lya.lyaspshop.pojo.Order;
import com.lya.lyaspshop.pojo.OrderItem;
import com.lya.lyaspshop.pojo.User;
import com.lya.lyaspshop.resp.JsonResponseBody;
import com.lya.lyaspshop.service.IOrderItemService;
import com.lya.lyaspshop.service.IOrderService;
import com.lya.lyaspshop.service.impl.GoodsServiceImpl;
import com.lya.lyaspshop.service.impl.RedisServiceImpl;
import com.lya.lyaspshop.vo.CartItemVo;
import com.lya.lyaspshop.vo.OrderVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;@RestController
@RequestMapping("/order")
public class OrderController {@Autowiredprivate RedisServiceImpl redisService;@Autowiredprivate GoodsServiceImpl goodsService;@Autowiredprivate IOrderItemService iOrderItemService;@Autowiredprivate IOrderService iOrderService;@RequestMapping("/add")public JsonResponseBody<?> toOrder(User user, OrderVo orderVo){String ids = orderVo.getIds();List<CartItemVo> cartItems = redisService.loadCart(user, ids);//所有的购物车中商品的id集合List<Long> gds = cartItems.stream().map(CartItemVo::getGid).collect(Collectors.toList());//根据集合查询所有对应的商品List<Goods> goods = goodsService.listByIds(gds);//遍历集合 赋值给对应的对象for (Goods g : goods) {//找到对应id相同的元素CartItemVo vo = cartItems.stream().filter(v -> Objects.equals(v.getGid(), g.getGid())).findFirst().get();//将商品g的属性赋值给voBeanUtils.copyProperties(g,vo);}long oid = YitIdHelper.nextId();//增加订单项BigDecimal total=new BigDecimal(0);List<OrderItem> orderItems=new ArrayList<>();for (CartItemVo item : cartItems) {//生成订单项OrderItem orderItem = new OrderItem();//赋值属性BeanUtils.copyProperties(item,orderItem);orderItem.setQuantity(item.getNum());orderItem.setOoid(YitIdHelper.nextId());orderItem.setOid(oid);//放到一个集合中 批量增加 只会有一次数据库新增orderItems.add(orderItem);//计算总价 + 当前的小计total = total.add(item.cartprice());}iOrderItemService.saveBatch(orderItems,5);//增加订单Order order = new Order();BeanUtils.copyProperties(orderVo,order);order.setOid(oid);order.setTotal(total);order.setUserId(user.getId());order.setStatus(0);order.setCreateDate(new Date());//订单插入数据库iOrderService.save(order);//删除缓存元素
//        redisService.removeCart(user,orderVo.getIds());return JsonResponseBody.success(oid);}@RequestMapping("/pay")public String pay(User user, String oid){
//        得到结算的订单Order order = iOrderService.getById(oid);
//        调用支付页面
//        传来的是表单String body = new AlipayConfig().goAlipay(order);return body;}
//    这里传递来的数据:@RequestMapping("/payDone")public String payDone(Map<String,String> stringMap){
//        更具成功支付了id来修改状态:String oid = stringMap.get("out_trade_no");iOrderService.update(new UpdateWrapper<Order>().eq("oid",oid).set("status",1).set("pay_date",new Date()));
//        html语句可以解析,json数据只能响应return "<script>\n" +"    alert(\"支付成功\")\n" +"    location.href=\"/\"\n" +"< /script>";}}

这里我们要添加一条代码:(异步通知验签)

//      安全验证:Boolean b = Factory.Payment.Common().verifyNotify(stringMap);if (!b){throw   new BusinessException(JsonResponseStatus.UN_KNOWN);}

支付宝接口:(根据自己数据的来)

package com.lya.lyaspshop.config;import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.lya.lyaspshop.pojo.Order;
import org.springframework.stereotype.Component;@Component
public class AlipayConfig {private Config aliconfig() {Config config = new Config();//沙箱支付宝地址config.gatewayHost = "openapi-sandbox.dl.alipaydev.com";//协议httpsconfig.protocol = "https";//应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号config.appId = "9021000132623583";//支付宝公钥config.alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmexyLYPEgC4GHxHtCYEhThPEIOjOoMpr8w+bmOtAPpmLg3wrYt4xMFbTP4Wg8wBSWiLHgXtBl32BekY5PD0pOPRZ5VW8rL84uDt+wnCdS9PjXscFmDdzGvp4c1o4vgjQovylrfEf1AlLINYUsXaTp1Nk5IZGRxERLOoTKVI/COY/qyIvhSueS+gIadpgSXNn1R0K73zorJaKVhJS4WKtHfr1246sslQRptinaFiU5PAvQXzt5iaBLdqc3C0UGz1jTHgemaJOIW/SlhsR3CkKif0MX25IoCrwgpzYbv0JDoGG74pzAIOf2LuNaZbQRwQldYokTLVXIlWis1H0UqiYzQIDAQAB";//签名方式config.signType = "RSA2";//商户私钥(应用私钥),您的PKCS8格式RSA2私钥config.merchantPrivateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC+y08ssgZZsO0y1Xr4dTTD3/Vh9rfpCJ79B5YLJlWhWDZ/+yfGBdyoMtMnPjvuqZNvyloNrxJFAlOc17A6JLEypnJw7G1W7BYIRur0cQx7bVjqqN/lCO9V1dsyOOKhFd+10lbkIgr1DY0FwY4z9bZuniPCRERvKu6M/485Iq68C8vQnBzlXPYSP9STmzLoNtkSDhC/4t5EQus5FEcpNkmXuDM9fGw1J2d4e3SKMZIj4h2+1qByhktEsc5HhKF4RCZK+MR0fhBStF8rRVd2hvDhjcgg3TVoYjvn0fLN2wMX03/lLsIA7+G4ORVxO9RS5PmhCLQab5lqa9YPFpqyoCB7AgMBAAECggEAAUE3CRU2o3pdZPswbtfee/dKFtXXicnLueBF5VbgM0pwOVE+hrfdJqIG73giTsSAurh69SIUna2RPTPR7d/15l5f3ExBv9OXpYBJ5UelDF7AufJYXpo7cLYSVfc3zlVlfj2e4qsypT/skIAgXkkcZQfXNlzaklyW6wh3Oan3ujbau1IQVE/jQBvTdUbAWapFcGJ5RH07MvuBJhz4rG2eAMANxT6JIp8+3rU1Pi//enhb5qTWa5xg+HFtqeNs5T+E0JPzR8ezWYkbCDiXL5iYE1jvoTeyaBfz7iKxRuN1bpgClg/DNB5j3JXo3Ke4SRtLf80WnCQFwV5paeWXUbdsuQKBgQDs7DiGoa1YD3yhXdkXJQONDp2EZb2679d3rC5m5qJsAZi+W+qWe4V7vqqmfJrFjAUe+eNWSaoaUXO9Z5Ps3dcNpFXBnOW0ODpBGcYnT8bu5qqWjRbYFMOAAznh895v/2uNtljWvYTHUrnYEP2ZNkiEzCg9IYgH1L5GWJ8hoPC+jQKBgQDOKDkHfSwELOOIFidOAJqV3qpeo4AzPW5X3GsNKg1fcnN9nRTgUqZhW+woGetXTbbCxuM24uQpVZqpVhZA+TcCBc+kj7yDwkyjhFtO7UQQRSBiyQm0w6qZY+1aKIwf1Z578Nsbcf07FEJjpfxV8YAuF6Vq9PcS1lI4N1rVi5m9JwKBgE6zYUuHpVddPZ8014pSp01SD40NZusUBNUiAv/3mPibxytkyRZXzc1/VpybQ6ZfjsvtYlElgzXe3L2MDJ1gS7GiZ0I7ZippiyBY+XPRklmFkiEUmQQKUa7SY4XlRnyZshaO/g/HQLYditJ1QmiEma5TSwKTguZnCxW/Fo1LMu15AoGBALEc/WHhuB8eMZyI69unySdY1SXZchqTfGkfhRkaN8L4oSAaBAV0/FxIjOsm2Xl32rwcArj01PBuCyHQQ+4uLYQfWfUXR+4qz4zr+UYlsYQI33n/HcefEsIVh6UdkMUI0c/JbXR2yggnr6HMyK1NfcIbrpHlQx974cdKR0+PT9WhAoGBANC3h8Y4FBaKOLcxwHCVDSUrCszCyE+NGvDJI2I5Q7Pjxb5hfHkYR0/cVG5aUJPElWWizaf+7wNCL9XtVCfoUYWZ3DffNs526DL3btN9zby2Tcq7q3NhvRc3ZezSd/XZkGpr7LhWK0wppi5TuvNlhl1VyoGtbMiNUPOrSNWepror";return config;}public String goAlipay(Order order) {try {// 1. 设置参数(全局只需设置一次)Factory.setOptions(aliconfig());// 2. 发起API调用(subject商品标题、outTradeNo订单编号、totalAmount总金额、returnUrl异步通知地址)AlipayTradePagePayResponse response = Factory.Payment.Page().pay("商城项目收款",order.getOid().toString(),order.getTotal().toString(),//支付成功之后的异步通知(跳出到自己系统的哪个位置)"http://localhost:8080/order/payDone");
//            支付宝支付页面return response.body;} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);}}}

注意:

这里的支付宝公钥,应用私钥要填好:失败了多生成几次:

接入成功:

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

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

相关文章

快速搭建知识付费平台?明理信息科技,为你提供一站式解决方案

明理信息科技知识付费saas租户平台 在当今数字化时代&#xff0c;知识付费已经成为一种趋势&#xff0c;越来越多的人愿意为有价值的知识付费。然而&#xff0c;公共知识付费平台虽然内容丰富&#xff0c;但难以满足个人或企业个性化的需求和品牌打造。同时&#xff0c;开发和…

Time-series forecasting with deep learning: a survey

人们开发了许多深度学习架构来适应不同领域的时间序列数据集的多样性。在本文中&#xff0c;我们调查了一步前进和多水平时间序列预测中使用的常见编码器和解码器设计&#xff0c;描述了如何将时间信息纳入每个模型的预测中。接下来&#xff0c;我们重点介绍混合深度学习模型的…

计算机组成原理-输入输出系统和IO控制方式

文章目录 总览现代计算机的结构常见的IO设备主机如何与IO设备交互IO控制方式简介程序查询方式程序中断方式DMA控制方式通道控制方式 IO系统基本组成小结 总览 现代计算机的结构 常见的IO设备 主机如何与IO设备交互 IO控制方式简介 数据寄存器&#xff1a;存放主机要输出到外设…

输出回文数-第11届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第23讲。 输出回文数&#…

openwrt使用docker部署adguard home

docker创建macvlan&#xff0c;目的使adguard home具备宿主机同网段IP docker network create -d macvlan --subnet192.168.88.0/24 --gateway192.168.88.254 -o parentbr-lan bridge-host&#xff08;虚拟网卡名字)拉取adguard home镜像 docker pull adguard/adguardhome:la…

为何Selenium这么火?

今天给大家带来的主题是自动化测试框架Selenium&#xff0c;话不多说&#xff0c;直接开始&#xff01; 1.什么是 Selenium 自动化测试 Jason Huggins 于 2004 年创建了一个 JavaScript 框架&#xff0c;旨在将其从重复的手动测试中解放出来。 最初命名为 JavaScriptTestRunn…

【数据结构—二叉树的链式结构实现】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言 一、二叉树的存储结构 二、二叉树链式结构的实现 2.1手动构建一课树 2.2二叉树的遍历 三、二叉树链式结构的实现 3.1前序遍历(递归) 3.2中序遍历(递归) 3.3后序…

第三方软件测试机构可提供哪些服务类型?如何收费?

随着高新技术的快速发展&#xff0c;软件企业将测试工作交由第三方软件测试机构进行已经成为了行业趋势&#xff0c;因为企业自身的大多精力都投入在产品开发上&#xff0c;第三方软件测试机构的存在也就极大的提供了便利。 第三方软件测试机构是区别于软件企业与软件需求方的…

Spark内核解析-节点启动4(六)

1、Master节点启动 Master作为Endpoint的具体实例&#xff0c;下面我们介绍一下Master启动以及OnStart指令后的相关工作 1.1脚本概览 下面是一个举例&#xff1a; /opt/jdk1.7.0_79/bin/java -cp /opt/spark-2.1.0/conf/:/opt/spark-2.1.0/jars/*:/opt/hadoop-2.6.4/etc/ha…

科研+临床观摩|牙科医生公派美国从事访问学者交流

很多临床医学专业的访问学者希望在访学从事科研的同时&#xff0c;能到医院进行临床观摩。对于这些申请者的要求&#xff0c;我们会尽量满足。本案例中的T医生&#xff0c;口语较弱&#xff0c;担心英语面试&#xff0c;最终我们为其取得了田纳西大学健康科学中心的邀请函&…

记模型训练损失为NAN

前段时间想把我模型的输入由DWT子带改为分块的图像块&#xff0c;一顿魔改后&#xff0c;模型跑着跑着损失就朝着奇怪的方向跑去了&#xff1a;要么突然增大&#xff0c;要么变为NAN。 为什么训练损失会突然变为NAN呢&#xff1f;这个作者将模型训练过程中loss为NAN或INF的原因…

SoapUI参数传递操作详解

SoapUI 传递参数 本文章主要是通过例子&#xff0c;给大家讲解一下 SoapUI 发送请求时&#xff0c;如何带上参数~ 我们可以先了解下&#xff1a;SoapUI简介&#xff1a;了解这个流行的API测试工具 新建工程 首先新建一个工程&#xff0c;然后在里面进行后续的操作。 填写工程…

【python入门】day12:bug及其处理思路

bug的常见类型 粗心 / 没有好习惯 思路不清 lst[{rating:[9.7,2062397],id:1292052,type:[犯罪,剧情],title:肖申克的救赎,actors:[蒂姆罗宾斯,摩根弗里曼]},{rating:[9.6,1528760],id:1291546,type:[剧情,爱情,同性],title:霸王别姬,actors:[张国荣 ,张丰毅 , 巩俐 ,葛优]},{r…

redis重启后数据丢失问题解决(亲测好用)

redis修改密码重启后发现redis中的数据丢失了 解决办法&#xff1a; 首先在redis的安装目录下查找重启之前的dump.rdb文件&#xff0c;发现只有当天的一个dump.rdb文件&#xff0c;确认不是重启备份的文件 然后我就全盘找一下dump.rdb的备份文件&#xff0c;找到前一天的备份…

喜讯丨上海和今信息科技有限公司入选2023年上海市专精特新中小企业名单

近日&#xff0c;上海市经济和信息化委员会公示了 2023 年上海市专精特新中小企业名单&#xff0c;上海和今信息科技有限公司凭借多年专注数据智能领域、领先的产品技术实力、专业的创新研发能力以及卓越的行业影响力&#xff0c;顺利通过专家评审和综合评估&#xff0c;荣获上…

MO 2023 年度回顾

PART-ONE 行业态势 随着供需关系的变化&#xff0c;数据库的竞争在经历了 3 年 “百花齐放” 般的发展后&#xff0c;终于在 2023 年进入到了一个相对收拢的阶段。 2023 年&#xff0c;各个数据库厂商间很有默契地在两个方面达成了一致&#xff1a; HTAP 已经成为新一代数据…

源码安全静态扫描工具对比

Checkmarx CxSuite 介绍参见&#xff1a;https://cloud.tencent.com/developer/article/2249914 这家报价接近90W人民币/ 一年&#xff0c;据我们联系的人说 这家销售觉得我们预算不够&#xff0c;高高在上。。。。 sonarqube 参见&#xff1a;GitHub - SonarSource/sonarqu…

【Storm实战】1.2 图解Storm的架构及其组件

文章目录 0. 前言1. 图解架构及其组件2. Storm的主要架构组件 0. 前言 上一章节&#xff0c;我们为了好理解&#xff0c;将storm中的抽象概念 通过画了一个水力发电系统的工作模式&#xff0c;相信大家一定可以直观地理解Storm中的流 (Stream) 、拓扑 (Topology)、Spout、Bolt…

How to understand DataArts Insight in Huawei Cloud

How to understand DataArts Insight in Huawei Cloud 概述什么是DataArts Insight为什么选择华为云DataArts Insight多业务场景全覆盖&#xff0c;实现企业智能分析产品架构产品功能数据接入数据加工仪表板数据大屏交互式分析嵌入式分析智能分析助手智能洞察BI内存引擎企业级数…

Vue中的计算属性与监听器

聚沙成塔每天进步一点点 ⭐ 专栏简介 Vue学习之旅的奇妙世界 欢迎大家来到 Vue 技能树参考资料专栏!创建这个专栏的初衷是为了帮助大家更好地应对 Vue.js 技能树的学习。每篇文章都致力于提供清晰、深入的参考资料,让你能够更轻松、更自信地理解和掌握 Vue.js 的核心概念和技…