uniapp/手机APP使用支付宝支付(服务端)

news2024/10/7 10:25:27

博主介绍:✌全网粉丝4W+,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战、定制、远程,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验✌

博主作品:《Java项目案例》主要基于SpringBoot+MyBatis/MyBatis-plus+MySQL+Vue等前后端分离项目,可以在左边的分类专栏找到更多项目。《Uniapp项目案例》有几个有uniapp教程,企业实战开发。《微服务实战》专栏是本人的实战经验总结,《Spring家族及微服务系列》专注Spring、SpringMVC、SpringBoot、SpringCloud系列、Nacos等源码解读、热门面试题、架构设计等。除此之外还有不少文章等你来细细品味,更多惊喜等着你哦

🍅开源项目免费哦:点击这里克隆或者下载  ,已经发布Vue3版   🍅

🍅文末获取联系🍅精彩专栏推荐订阅👇🏻👇🏻 不然下次找不到哟

 Java项目案例《100套》

https://blog.csdn.net/qq_57756904/category_12173599.html

 uniapp小程序《100套》

https://blog.csdn.net/qq_57756904/category_12199600.html

目录

一、前言

二、获取APPID

三、设置应用

四、集成和开发

五、调用接口

六、调试应用

七、生产联调


一、前言

最近做了下接入支付宝支付,客户端使用uniapp,不过都是基于支付宝App支付那套规范约定去处理。之前想着接入其他第三方支付来着,但是不是很靠谱,而且可能存在一些其他隐患,还是直接些接入正规的支付宝·支付。下面就对接入做一些讲解:

二、获取APPID

要在您的应用中接入支付宝App支付能力,需要通过创建应用的方式接入蚂蚁相关接口并进行开发,基于对行业及业务场景痛点的理解,创造能够满足市场需要的解决方案,以应用的形式服务用户。

若还未成为开放平台的入驻服务商或者商户, 请完成。入驻完成后,您需要去蚂蚁金服开放平台(open.alipay.com),在开发者中心中创建您的应用,会为您生成应用唯一标识(APPID),并且可以申请开通开放产品使用权限,通过APPID您的应用才能调用开放产品的接口能力。需要详细了解开放平台创建应用步骤请参考《开放平台应用创建指南》。

在创建应用后即生成应用的标识APPID,使用支付宝账号登录开放平台后,在“我的应用”中查看APPID。

三、设置应用

应用创建完成后,需要给应用添加App支付功能,这样就可以在你的应用里使用App支付能力。此时该应用为开发中状态,只能在沙箱环境下进行调试。应用开发完成后,请开发者自行进行验收和安全性检查(安全性检查可参考《开放平台第三方应用安全开发指南》),验收检查完成后可申请上线。应用申请上线后,会同时申请此列表的功能,接口即生效,这个状态下的应用能够调用生产环境的接口。

签约

在使用这些能力的时候,需要在开放平台里进行签约,这时候约定的合同就生效了。也可以代替商户签约。

配置密钥

为了保证交易双方(商户和支付宝)的身份和数据安全,开发者在调用接口前,需要配置双方密钥,对交易数据进行双方校验。

1、了解下支付宝密钥处理体系:

2、密钥包含:

应用公钥:由商户自己生成的RSA公钥(与应用私钥必须匹配),商户需上传应用公钥到支付宝开放平台,以便支付宝使用该公钥验证该交易是否是商户发起的。

应用私钥:由商户自己生成的RSA私钥(与应用公钥必须匹配),商户开发者使用应用私钥对请求字符串进行加签。

支付宝公钥:支付宝的RSA公钥,商户使用该公钥验证该结果是否是支付宝返回的。

生成密钥后在开放平台开发者中心进行密钥配置,配置完成后可以获取支付宝公钥。具体方法流程请参见上传应用公钥并获取支付宝公钥。

3、配置生成的密钥等应用信息。配置的详细步骤请参考《配置应用环境》。

注:签名验签常见问题排查

支付宝开放平台SDK封装了签名和验签过程,只需配置账号及密钥参数,强烈建议使用。更多签名问题的自助排查流程,可以参考支付宝验签专区的未使用开放平台SDK的自助排查流程。关于同步通知和异步通知的验签规则,可参考验签教程。

更多关于签名教程和签名工具下载等问题,请参见签名专区。

四、集成和开发

服务端SDK需要商户集成在自己的服务端系统中,用于协助解析并验证客户端同步返回的支付结果和异步通知。

maven引入如下依赖

<dependencies>    <dependency>        <groupId>com.alipay.sdk</groupId>        <artifactId>alipay-sdk-java</artifactId>        <version>4.8.10.ALL</version>    </dependency></dependencies>

五、调用接口

为了避免在线上生产环境联调过程中遇到问题,建议在沙箱环境中联调通过后再在线上生产环境进行联调,具体操作步骤见沙箱联调指南。如果需要在线上调用接口,需要参考下面第六步:应用上线后再进行接口调用,不然会报出“无权限错误”。

系统交互流程:

图中虚线标识商户链路,实线标识支付宝链路。

第4步:调用支付接口:此消息就是本接口所描述的支付宝客户端SDK提供的支付对象PayTask,将商户签名后的订单信息传进payv2方法唤起支付宝收银台,交易数据格式具体参见请求参数说明。

第5步:支付请求:支付宝客户端SDK将会按照商户客户端提供的请求参数发送支付请求。

第8步:接口返回支付结果:商户客户端在第4步中调用的支付接口,会返回最终的支付结果(即同步通知),参见客户端同步返回。

第13步:用户在支付宝APP或H5收银台完成支付后,会根据商户在手机网站支付API中传入的前台回跳地址return_url自动跳转回商户页面,同时在URL请求中附带上支付结果参数。同时,支付宝还会根据原始支付API中传入的异步通知地址notify_url,通过POST请求的形式将支付结果作为参数通知到商户系统,详情见支付结果异步通知。

除了正向支付流程外,支付宝也提供交易查询、关闭、退款、退款查询以及对账等配套API。

特别注意:

构造交易数据并签名必须在商户服务端完成,商户的应用私钥绝对不能保存在商户APP客户端中,也不能从服务端下发。

同步返回的数据,只是一个简单的结果通知,商户确定该笔交易付款是否成功需要依赖服务端收到支付宝异步通知的结果进行判断。

商户系统接收到通知以后,必须通过验签(验证通知中的sign参数)来确保支付通知是由支付宝发送的。建议使用支付宝提供的SDK来完成,详细验签规则参考异步通知验签。

使用SDK快速接入

App支付API必须通过支付宝提供的移动端SDK来调用。

交易操作

以下大致记录针对alipay.trade.app.pay接口的相关代码:

1.APP客户端调用应用服务端,应用服务端通过alipay.trade.app.pay接口传入订单参数,将alipay.trade.app.pay接口返回的AlipayTradeAppPayResponse返回给APP客户端,由APP唤起支付宝客户端。


 
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
 
import com.alibaba.fastjson.JSONObject;
import com.alipay.AliAppPayRequest;
import com.alipay.config.AlipayConfig;
import com.alipay.enums.AliAppPayResponseCode;
import com.alipay.enums.AliPayPublicCode;
import com.leopard.util.bean.Message;
import com.leopard.util.enums.SystemCodeAndMsg;
 
/**
 * ali支付
 */
@RestController
@RequestMapping(value = "/alipay")
public class AliPayAction {
 
  private static final Logger logger = LoggerFactory.getLogger(AliPayAction.class);
 
  /**
   * 请求生成订单签名信息
   * 
   * @param subject
   *            标题
   * @param body
   *            内容
   * @param totalAmount
   *            金额
   * @param passbackParams
   *            附加参数
   * @return
   */
  @RequestMapping(value = "/getModelOrderInfoSign", method = RequestMethod.POST)
  public Message getModelOrderInfoSign(@RequestParam(value = "subject") String subject,
      @RequestParam(value = "body") String body, @RequestParam(value = "totalAmount") String totalAmount,
      @RequestParam(value = "passbackParams") String passbackParams) {
 
    AliAppPayResponseCode appPayRequest = new AliAppPayRequest().appPayRequest(30, subject, body, totalAmount,
        "201910221548751212", passbackParams, "http://cwfpx6.natappfree.cc/verifyOrderInfoSign");
    // AliAppPayResponseCode appPayRequest = new
    // AliAppPayRequest().appPayRequest(30, "测试-model", "预约3天,详情如下。。。",
    // "0.01", "201910221548751212", "paramUrl;paramUrl2",
    // "http://cwfpx6.natappfree.cc/verifyOrderInfoSign");
    return new Message("200", "aa", appPayRequest.alias());
  }
 
  /**
   * 同步获取前端成功返回结果
   * 
   * @param result
   *            支付成功后的result的json串
   * @return
   */
  @RequestMapping(value = "/syncNotifyValidate", method = RequestMethod.POST)
  public Message syncNotifyValidate(@RequestParam(value = "result") String result) {
 
    JSONObject resultObject = JSONObject.parseObject(result);
    String alipayTradeAppPayResponse = resultObject.getString("alipay_trade_app_pay_response");
    if (StringUtils.isBlank(alipayTradeAppPayResponse)) {
      return new Message(SystemCodeAndMsg.FAIL.code(), "响应参数不存在");
    }
    String sign = resultObject.getString("sign");
    if (StringUtils.isBlank(sign)) {
      return new Message(SystemCodeAndMsg.FAIL.code(), "验签信息不能为空");
    }
    String signType = resultObject.getString("sign_type");
    if (!AlipayConfig.sign_type.equals(signType)) {
      return new Message(SystemCodeAndMsg.FAIL.code(), "签名类型不匹配");
    }
 
    JSONObject responseObject = JSONObject.parseObject(alipayTradeAppPayResponse);
    if (!AliPayPublicCode.Success.code().equals(responseObject.getString("code"))) {
      logger.info("---syncNotifyValidate-----responseObject:" + responseObject.toString());
      return new Message(responseObject.getString("code"), responseObject.getString("msg"));
    }
 
    // 以下验证业务逻辑需补充
    Message publicValidateBaseInfo = publicValidateBaseInfo(responseObject);
    if(!SystemCodeAndMsg.SUCCESS.code().equals(publicValidateBaseInfo.getCode())){
      //验证失败
      return publicValidateBaseInfo;
    }
 
    // 验证通过,买家付款成功,将信息记录到数据库
    // 业务代码
 
    // 反馈给前端
    return new Message(SystemCodeAndMsg.SUCCESS.code(), SystemCodeAndMsg.SUCCESS.msg());
  }
 
  /**
   * 异步获取支付宝POST通知。此地址是一开始生成订单传入的异步地址,请保留好路径
   * 
   * @param request
   * @return
   */
  @RequestMapping(value = "/asynNotifyValidate", method = RequestMethod.POST)
  public String asynNotifyValidate(HttpServletRequest request) {
 
    // 支付宝提供的验签方法,已经封装到依赖包,请求调用就行
    AliAppPayResponseCode verifyOrderInfoSign = new AliAppPayRequest().verifyOrderInfoSign(request);
    if (!AliAppPayResponseCode.SUCCESS.code().equals(verifyOrderInfoSign.code())) {
      return "failure";
    }
    
    // 以下验证业务逻辑需补充
    // 已经将验证过程中的订单信息和响应信息放入到alias内回传回来
    JSONObject verifyOrderInfoJson = JSONObject.parseObject(verifyOrderInfoSign.alias());
    Message publicValidateBaseInfo = publicValidateBaseInfo(verifyOrderInfoJson);
    if(!SystemCodeAndMsg.SUCCESS.code().equals(publicValidateBaseInfo.getCode())){
      //验证失败
      return "failure";
    }
    
    //验证通过,开始业务代码,并标记订单支付成功,该信息可覆盖同步回调信息,较为准确
    //最好将回调信息都保存在数据库做记录
    //verifyOrderInfoJson已经保存好回调数据,直接放入数据库用保存即可
 
    return "success";
  }
 
  /**
   * 支付宝公用回调信息验签
   * 
   * @param jsonObject
   * @return
   */
  private Message publicValidateBaseInfo(JSONObject jsonObject) {
    
    // 1、商户需要验证该通知数据中的 out_trade_no 是否为商户系统中创建的订单号;
    String outTradeNo = jsonObject.getString("out_trade_no");
    // 业务查找订单号对应的信息,并进行匹配验证
 
    // 2、判断 total_amount 是否确实为该订单的实际金额(即商户订单创建时的金额);
    String totalAmount = jsonObject.getString("total_amount");
    // 根据1获取到的信息,进行匹配验证
 
    // 3、校验通知中的 seller_id(或者 seller_email) 是否为 out_trade_no
    // 这笔单据对应的操作方(有的时候,一个商户可能有多个 seller_id/seller_email);
    String sellerId = jsonObject.getString("seller_id");
    if (!AliAppPayRequest.verifySellerId(sellerId)) {
      logger.info("---publicValidateBaseInfo-----verifySellerId:" + jsonObject.toString());
      return new Message(SystemCodeAndMsg.FAIL.code(), "验证信息有误");
    }
 
    // 4、验证 app_id
    // 是否为该商户本身。上述1、2、3、4有任何一个验证不通过,则表明同步校验结果是无效的,只有全部验证通过后,才可以认定买家付款成功。
    String appId = jsonObject.getString("app_id");
    if (!AliAppPayRequest.verifyAppId(appId)) {
      logger.info("---publicValidateBaseInfo-----verifyAppId:" + jsonObject.toString());
      return new Message(SystemCodeAndMsg.FAIL.code(), "验证信息有误");
    }
    
    return new Message(SystemCodeAndMsg.SUCCESS.code(), SystemCodeAndMsg.SUCCESS.msg());
  }
}

六、调试应用

支付能力直接涉及到交易与资金,为了方便开放者调试支付能力,我们已经准备好沙箱环境,包括沙箱环境账号和沙箱版支付宝钱包,这样就可以在沙箱环境调试了。具体操作步骤见沙箱联调指南。

七、生产联调

小金额调试

1、

2、

更多细节可以加入知识星球向我提问。可以让你少走弯路哦!

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

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

相关文章

chatgpt赋能python:Python接口应用于SEO的指南

Python接口应用于SEO的指南 Python成为了web开发中最流行的语言之一&#xff0c;而且尤其在SEO领域中被广泛应用。一些Python库和框架可帮助SEO团队实现其目标&#xff0c;如排名跟踪&#xff0c;爬取数据&#xff0c;进行网站分析&#xff0c;等等。在本文中&#xff0c;我们…

基于Hexo和Butterfly创建个人技术博客,(9) 优化butterfly主题配置文章版本

Butterfly官方网站&#xff0c;请 点击进入 本章目标&#xff1a; 掌握butterfly主题对文章的配置&#xff0c;熟悉并可按需配置到个人的博客站点中&#xff0c;本章内容是一个必会章节&#xff0c;不仅包括文章的UI美化、SEO相关配置还包括其它增加的功能&#xff0c;内容不多…

英语不好能不能学编程?

入门教程、案例源码、学习资料、读者群 请访问&#xff1a; python666.cn 大家好&#xff0c;欢迎来到 Crossin的编程教室 &#xff01; 常有人问我&#xff1a;我英语不好&#xff0c;想学编程行不行&#xff1f; 这个问题需要分情况讨论。 1. 可以学 如果你因为担心自己英语不…

chatgpt赋能python:Python怎么用?Python编程的入门指南

Python怎么用&#xff1f;Python编程的入门指南 Python是一种流行的高级编程语言&#xff0c;它被广泛应用于数据分析、机器学习、Web开发、自动化测试等领域。Python语言非常容易学习和使用&#xff0c;因此非常适合初学者和有经验的开发人员。在这篇文章中&#xff0c;我们将…

手把手教你在CentOS7.9上使用docker 安装MySQL5.7

前言 大家好&#xff0c;又见面了&#xff0c;我是沐风晓月&#xff0c;本文主要讲解如何用docker在centos7.9系统上安装MySQL5.7&#xff0c;以及如何设置MySQL的远程登录。 文章收录到【容器管理】和【数据库入门到精通专栏】&#xff0c;此专栏是沐风晓月对linux云计算架构…

chatgpt赋能python:Python怎么清除动点轨迹?

Python怎么清除动点轨迹&#xff1f; 引言 在数据科学和可视化的领域中&#xff0c;动点轨迹是很有用的工具。动点轨迹可以轻松地显示数据点的时间序列&#xff0c;这可以帮助分析者发现有关数据集的有用信息。然而&#xff0c;当轨迹过于密集和复杂时&#xff0c;这种可视化…

Spring Cloud Alibaba - Sentinel源码分析(一)

目录 一、Sentinel核心源码分析 1、Sentinel核心概念 1.1、Node之间的关系 2、Sentinel源码入口 2.0、Sentinel源码启动 2.1、SlotChain解析 2.2、NodeSelectorSlot解析 2.3、ClusterBuilderSlot解析 2.4、StatisticSlot解析 2.5、FlowSlot解析 2.6、DegradeSlot解析…

白鲸优化算法优化VMD参数,最小包络熵为适应度函数,提取最小包络熵对应的IMF分量,采集最佳IMF分量的9种时域指标,提取特征向量。以西储大学数据为例,附MATLAB代码

大家看到这篇文章&#xff0c;肯定会有疑问&#xff0c;难道本篇文章和上一篇文章不是一个意思嘛&#xff0c;这是来凑数的嘛……其实不然&#xff0c;如果各位读者仔细看&#xff0c;就会发现本篇文章和上一篇文章大有不同&#xff0c;这篇文章也是我一直以来想在上一篇文章基…

chatgpt赋能python:Python断言:如何断言等于两个值其中一个?

Python断言&#xff1a;如何断言等于两个值其中一个&#xff1f; Python是一种广泛使用的编程语言&#xff0c;而断言是它的一个重要功能。在编程中&#xff0c;我们可以使用断言来验证代码是否按照预期工作。但是&#xff0c;在某些情况下&#xff0c;我们可能想要断言两个值…

快速上手kettle(四)壶中可以倒出些啥?

快速上手kettle&#xff08;四&#xff09;壶中可以倒出些啥 前言一 、kettle 这壶里能倒出啥&#xff1f;二 、Access输出2.1 Access输出设置2.2 启动转换&#xff0c;查看输出 三 、Excel输出3.1 选择excel扩展名3.2 1 将表中数据分别写入到excel中 四、JSON output4.1 JSON …

常见骨干网络介绍

骨干网络 骨干网络&#xff08;backbone network&#xff09;顾名思义&#xff0c;是深度学习中最核心的网络组成。本文按时间顺序&#xff0c;简要介绍几种影响重大的backbone设计思路&#xff0c;我们或许可以从窥探前人的设计思路中获得启发和灵感。 1.1 AlexNet, 2012 这…

10倍|中科院再传好消息:比英伟达还快,“新技术”实现弯道超车

中科院再传好消息&#xff1a;在光芯片上有了重大突破&#xff0c;李明-祝宁华团队研制出了一款超高集成度光学卷积处理器。 这种方案具有高算力密度、超高的线性扩展性&#xff01; 基于这种技术的&#xff0c;光芯片的性能将再次提升&#xff0c;光芯片是用于AI,如果能变成现…

每日算法(第二十四期)

先来回顾一下上期的问题及答案&#xff1a; 2023年6月15日 「电话号码的字母组合」&#xff08;Letter Combinations of a Phone Number&#xff09;。以下是题目的描述&#xff1a; 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。给出数字到字母的…

记录--前端如何优雅导出多表头xlsx

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言 xlsx导出是比较前后端开发过程中都比较常见的一个功能。但传统的二维表格可能很难能满足我们对业务的需求&#xff0c;因为当数据的维度和层次比较多时,二维表格很难以清晰和压缩的方式展现所有的…

macOS Ventura 13.5beta3(22G5048d)发布

系统介绍 黑果魏叔 6 月 16 日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS 13.5 开发者预览版 Beta 3 更新&#xff08;内部版本号&#xff1a;22G5048d&#xff09;&#xff0c;本次更新距离上次发布隔了 15 天。 macOS Ventura 带来了台前调度、连续互通相机、Fa…

【Axure 教程】中继器(进阶篇)

一、修改、删除指定行 首先我们还是在 Axure 页面中拖入一个【中继器】&#xff0c;并双击打开&#xff0c;在默认的【矩形】后面加上【修改】和【删除】按钮&#xff1a; 然后我们给修改按钮添加【中继器事件】&#xff0c;选择【更新行】&#xff1a; 可以看到&#xff0c;由…

Axure RP 9 基础教程 元件基础3

11、组合元件 Axure中可以将多个元件组合起来&#xff0c;组合可以被命名&#xff0c;也可以被当成一个元件来进行交互&#xff0c;调整位置和大小等。选中多个元件&#xff0c;在顶部菜单中点击组合图标即可。选中一个组合&#xff0c;点击取消组合&#xff0c;可以就地解散。…

多传感器融合分类及对比

1.多传感器融合的体系结构 在多传感器融合中&#xff0c;按照对原始数据处理方法的不同&#xff0c;多传感器融合系统的体系结构可以分为三种&#xff1a;集中式&#xff0c;分布式和混合式(混合式又分为有反馈结构和无反馈结构)。 集中式融合&#xff1a;将各传感器获得的原始…

软件设计的核心方法及实例解析

李连杰电影版《倚天屠龙记》里有个经典的名场面&#xff0c;祖师爷爷张三丰花了三分钟教张无忌太极拳&#xff0c;张无忌学成打败了对手。三丰爷爷的教学思路是这样的&#xff1a;爷爷演示太极拳让张无忌跟着练&#xff0c;边练边问张无忌记住了多少&#xff0c;等张无忌把所有…

网络系统安全——MS15_034漏洞利用与安全加固

Kali 192.168.124.162 Windows server 2008 192.168.124.169 检查2008服务器的IIS网站是否正常&#xff0c;进入2008服务器&#xff0c;使用ie浏览器访问本机地址 切换到kali&#xff0c;使用命令ping来测试他们的连通性 然后使用使用命令curl测试&#xff0c;测试&#x…