支付宝支付之收款码支付

文章目录

  • 收款码支付
    • 接入流程
    • 安全设计
    • 系统交互流程
    • 交易状态
    • 统一收单交易支付接口
      • 请求参数
      • 测试结果
      • 查询支付
      • 撤销支付
      • 退款支付
        • 退款结果
        • 退款说明

收款码支付

继:支付宝支付之入门支付

接入流程

在这里插入图片描述

安全设计

支付宝为了保证交易安全采取了一系列安全手段以保证交易安全。主要采用以下安全设计策略,详情可查看 应用安全开发指南。

  • 采用 HTTPS 协议传输交易数据,防止数据被截获、解密。
  • 采用 RSA/RSA2 非对称密钥,明确交易双方的身份,保证交易主体的正确性和唯一性。
  • 付款码定时刷新,防止被拍照。
  • 防止截屏 (截屏后二维码失效)

系统交互流程

在这里插入图片描述

  1. 买家出示钱包内付款码,商家通过扫码设备获取付款码信息,并将付款码上传到 alipay.trade.pay(统一收单交易支付接口)请求支付。
  2. 根据返回的结果,确定支付状态,从而进行相应处理(包括必要时关闭交易), 如图 opt 区块中所示根据付款码支付接口返回公共参数code,付款码支付存在以下四种状态:
结果码描述
请求成功(10000)只表示请求成功,若存在扣款异常可能发生回滚导致扣款失败,必须根据查询接口或者异步通知返回的交易状态进行判断,交易失败,建议关闭交易,更换订单号out_trade_no和买家支付渠道重新扣款。
等待用户付款(10003)由于余额不足、超额等原因导致订单创建但支付未成功,等待用户付款。付款码支付由于是线下面对面支付,需尽快确认交易情况,建议通过 轮询方式 判断交易状态,避免单边账。
未知异常(20000)未知异常,可能由于系统异常或者网络超时等问题导致接口报错,建议调用查询接口确认支付结果,详情可查看 异常处理 。
支付失败(40001- 40006)业务出现未知错误或者系统异常,需要重新检查参数,重新发起支付。详情可查看 异常处理 。

交易状态

在这里插入图片描述

随着订单支付成功、退款、关闭等操作,订单交易的每一个环节 trade_status(交易状态)不同。

  1. 交易创建成功后,用户支付成功,交易状态转为 TRADE_SUCCESS(交易成功)。
  2. 交易成功后,规定退款时间内没有退款,交易状态转为 TRADE_FINISHED(交易完成)。
  3. 交易支付成功后,交易部分退款,交易状态为 TRADE_SUCCESS(交易成功)。
  4. 交易成功后,交易全额退款,交易状态转为 TRADE_CLOSED(交易关闭)。
  5. 交易创建成功后,用户未付款交易超时关闭,交易状态转为 TRADE_CLOSED(交易关闭)。
  6. 交易创建成功后,用户支付成功后,若用户商品不支持退款,交易状态直接转为 TRADE_FINISHED(交易完成)。

注意:交易成功后部分退款,交易状态仍为 TRADE_SUCCESS(交易成功),如果一直部分退款退完所有交易金额则交易状态转为 TRADE_CLOSED(交易关闭),如果未退完所有交易金额,超过有效退款时间后交易状态转为 TRADE_FINISHED(交易完成)不可退款。
继:支付宝支付之入门支付

统一收单交易支付接口

package com.sin.demo.controller;import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.response.AlipayTradePayResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** @createTime 2024/6/29 12:51* @createAuthor SIN* @use 付款码支付*/
@RestController
public class AliPayTradePayController {// 从配置文件中获取参数值@Value("${alipay.appId}")private String appId; // 支付宝应用ID@Value("${alipay.privateKey}")private String privateKey; // 商户应用私钥@Value("${alipay.publicKey}")private String publicKey; // 支付宝公钥@Value("${alipay.gatewayUrl}")private String gatewayUrl; // 支付宝网关URL/*** 创建订单* @param subject 交易订单标题* @param authCode 支付授权码* @param scene 支付场景* @param outTradeNo 商户订单号* @param totalAount  订单金额* @return* @throws AlipayApiException*/@GetMapping("/testAliPayTradePay")public String testAliPayTradePay(String subject,String authCode,String scene,String outTradeNo,String totalAount) throws AlipayApiException {// 创建支付宝客户端AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId, privateKey, "json", "UTF-8", publicKey, "RSA2");// 构造请求参数以调用接口AlipayTradePayRequest request = new AlipayTradePayRequest();// 用户在线下交易,创建交易信息并支付交易AlipayTradePayModel model = new AlipayTradePayModel();// 设置交易订单标题model.setSubject(subject);// 设置支付授权码model.setAuthCode(authCode);/*** 设置支付场景*  当面付条码支付场景: bar_code*  当面付刷脸支付场景,对应的auth_code为fp开头的刷脸标识串: security_code*/model.setScene(scene);// 设置商户订单号model.setOutTradeNo(outTradeNo);// 设置订单总金额model.setTotalAmount(totalAount);request.setBizModel(model);// 提交支付交易AlipayTradePayResponse response = alipayClient.execute(request);// 输出相应数据System.out.println(response.getBody());if (response.isSuccess()) {System.out.println("调用成功");} else {System.out.println("调用失败");}return response.getBody();}
}

将付款码数字传入到setAuthCode()方法中

在这里插入图片描述

如果有扫码设别的话,扫描付款码即可获取支付授权码

在这里插入图片描述

请求参数

参数参数值选项说明
out_trade_nostring(64)必选商户订单号。由商家自定义,64个字符以内,仅支持字母、数字、下划线且需保证在商户端不重复。
total_amountprice(11)必选订单总金额。单位为元,精确到小数点后两位,取值范围:[0.01,100000000]
subjectstring(256)必选订单标题。不可使用特殊字符,如 /,=,& 等
auth_codestring(64)必选支付授权码。当面付场景传买家的付款码(2530开头的长度为1624位的数字,实际字符串长度以开发者获取的付款码长度为准)或者刷脸标识串(fp开头的35位字符串)。
scenestring(32)必选支付场景。
bar_code:当面付条码支付场景;
security_code:当面付刷脸支付场景,对应的auth_code为fp开头的刷脸标识串;
默认值为bar_code。
product_codestring(64)可选产品码。
商家和支付宝签约的产品码。
当面付场景下,如果签约的是当面付快捷版,则传 OFFLINE_PAYMENT;
其它支付宝当面付产品传 FACE_TO_FACE_PAYMENT;
不传则默认使用FACE_TO_FACE_PAYMENT。
seller_idstring(28)可选卖家支付宝用户ID。
当需要指定收款账号时,通过该参数传入,如果该值为空,则默认为商户签约账号对应的支付宝用户ID。
收款账号优先级规则:门店绑定的收款账户>请求传入的seller_id>商户签约账号对应的支付宝用户ID;
注:直付通和机构间联场景下seller_id无需传入或者保持跟pid一致;如果传入的seller_id与pid不一致,需要联系支付宝小二配置收款关系;
goods_detailGoodsDetail[]可选订单包含的商品列表信息,json格式。
goods_id(string64)必选商品的编号
goods_name(string256)必选商品名称
quantity(number32)必选商品数量
price(price9)必选商品单价,单位为元
goods_category(string(24))可选商品类目
categories_tree(string128)可选商品类目树,从商品类目根节点到叶子节点的类目id组成,类目id值使用
show_url(string400)可选商品的展示地址
extend_paramsExtendParams可选业务扩展参数
sys_service_provider_id(string64)可选系统商编号。该参数作为系统商返佣数据提取的依据,请填写系统商签约协议的PID
specified_seller_name(string32)可选特殊场景下,允许商户指定交易展示的卖家名称
card_type(string64)可选卡类型
business_paramsBusinessParams可选商户传入业务信息,具体值要和支付宝约定,应用于安全,营销等参数直传场景,格式为json格式
mc_create_trade_ip(string128)可选商户端创建订单的 IP,须上传正确的用户端外网 IP,支持 ipv4/ipv6 格式;
mc_create_trade_ip和mcCreateTradeIp(旧)参数描述相同,首选mc_create_trade_ip入参,请勿重复入参;
如已入参mcCreateTradeIp(旧),无需新增入参mc_create_trade_ip。
promo_paramsPromoParam可选优惠明细参数,通过此属性补充营销参数。 注:仅与支付宝协商后可用。
actual_order_time(string32)可选存在延迟扣款这一类的场景,用这个时间表明用户发生交易的时间,比如说,在公交地铁场景,用户刷码出站的时间,和商户上送交易的时间是不一样的。
store_idstring(32)可选商户门店编号。
指商户创建门店时输入的门店编号。
operator_idstring(28)可选商户操作员编号。
terminal_idstring(32)可选商户机具终端编号。
query_optionsstring可选返回参数选项。
商户通过传递该参数来定制同步需要额外返回的信息字段,数组格式。如:[“fund_bill_list”,“voucher_detail_list”,“discount_goods_detail”]

测试结果

在这里插入图片描述

在这里插入图片描述

查询支付

商家可调用接口 [alipay.trade.query](统一收单交易查询接口),通过商家网站唯一订单号 out_trade_no 或支付宝交易号trade_no 查询对应订单支付情况。

/*** 查询订单* @param outTradeNode 商户订单号* @return 返回订单信息* @throws AlipayApiException*/
@GetMapping("/getQrCode/{outTradeNode}")
public String selectQrCode(@PathVariable("outTradeNode") String outTradeNode) throws AlipayApiException {// 创建支付宝客户端AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId, privateKey,"json", "UTF-8", publicKey, "RSA2");// 构造请求参数以调用接口AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();// 统一收单线下交易查询AlipayTradeQueryModel model = new AlipayTradeQueryModel();// 设置订单支付时传入的商户订单号model.setOutTradeNo(outTradeNode);// 设置查询选项List<String> queryOptions = new ArrayList<String>();queryOptions.add("trade_settle_info");model.setQueryOptions(queryOptions);// // 设置支付宝交易号// model.setTradeNo("2014112611001004680 073956707");request.setBizModel(model);AlipayTradeQueryResponse response = alipayClient.execute(request);System.out.println(response.getBody());if (response.isSuccess()) {System.out.println("调用成功");} else {System.out.println("调用失败");// sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接// String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);// System.out.println(diagnosisUrl);}return response.getBody();
}
参数名参数说明
out_trade_no支付时传入的商户订单号,与 trade_no 必填一个。
trade_no支付时返回的支付宝交易号,与 out_trade_no 必填一个。

在这里插入图片描述

撤销支付

支付交易返回失败或支付系统超时(交易状态不明确),商家可调用接口 [alipay.trade.cancel](统一收单交易撤销接口)通过商家网站唯一订单号 out_trade_no 或支付宝交易号trade_no 撤销交易。

重要说明:

  • 如果此订单用户支付失败,支付宝将关闭此订单,用户无法继续支付。
  • 如果此订单用户支付成功,支付宝将退还订单资金给用户,交易状态变为 trade_closed(交易关闭)。
  • 仅发生支付系统超时或者支付结果未知时可调用本接口撤销交易,其它正常支付的单如需实现相同功能请调用接口 [alipay.trade.refund](统一收单交易退款接口)。
    /*** 撤销订单编号* @param outTradeNode 商户订单号* @return* @throws AlipayApiException*/@GetMapping("/cancelQrCode/{outTradeNode}")public String cancelQrCode(@PathVariable("outTradeNode") String outTradeNode) throws AlipayApiException {// 创建支付宝客户端AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId, privateKey,"json", "UTF-8", publicKey, "RSA2");AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();JSONObject bizContent = new JSONObject();bizContent.put("out_trade_no", outTradeNode);request.setBizContent(bizContent.toString());AlipayTradeCancelResponse response = alipayClient.execute(request);if(response.isSuccess()){System.out.println("调用成功");} else {System.out.println("调用失败");}return response.getBody();}
}

在这里插入图片描述

在这里插入图片描述

重要入参说明

注意:请严格按照接口文档中的参数入参,传入非接口文档中的参数是无效的,并且可能会导致请求被拦截或其它异常。

参数名参数说明
out_trade_no支付时传入的商户订单号,与 trade_no 必填一个。
trade_no支付时返回的支付宝交易号,与 out_trade_no 必填一个。

重要出参说明

参数名参数说明
retry_flag是否需要重试,Y/N。
action本次撤销触发的交易动作。close:关闭交易,无退款 。refund:产生了退款。

退款支付

当交易发生之后一段时间内,由于业务原因(如金额错误,用户退款或者对账不平等等)需要退款时,商家可以调用接口 [alipay.trade.refund](统一收单交易退款接口)通过商家网站唯一订单号 out_trade_no 或支付宝交易号trade_no,将对应订单支付款退还给买家,支付宝将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家账号上。支持全额或部分退款。

在这里插入图片描述

退款结果
  • 退款成功:退款是否成功可以根据同步响应的 fund_change 参数来判断,返回值为 Y 则表示退款成功。

  • 退款失败:根据 [错误码]确认是否要重试,重试时注意 out_request_no 需保持一致。

  • 系统异常:无法确认退款结果。

    • 方案一:重试,重试时注意 out_request_no 需保持一致。
    • 方案二:先调用 [alipay.trade.fastpay.refund.query](统一收单交易退款查询接口)确认退款结果,如失败,再发起重试。
退款说明
  • **退款周期:**以签约协议为准,默认12个月,即交易发生后12个月内可发起退款,超期不可退款。
  • **退款方式:**资金原路返回用户账号。
  • **退款退费:**默认退款时手续费退回。
  • 退款时效:支付渠道为花呗、余额等退款即时到账。银行卡的退款时间以银行退款时间为准,一般情况下 2 小时内可到账(若退款到卡失败,退款金额会退回用户支付宝账户余额)。
  • 商家可以在 商家平台 > 对账中心 > 交易订单 中退款。
  • 退款接口会根据外部请求号 out_request_no 幂等返回,因此同一笔交易需要多次部分退款时,必须使用不同的 out_request_no
/*** 退款* @param outTradeNode 退款账单* @param refundAmount 退款金额* @return* @throws AlipayApiException*/
@GetMapping("/refundQrCode/{outTradeNode}/{refundAmount}")
public String refundQrCode(@PathVariable("outTradeNode") String outTradeNode,@PathVariable("refundAmount")Double refundAmount) throws AlipayApiException {AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId, privateKey,"json", "UTF-8", publicKey, "RSA2");AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();JSONObject bizContent = new JSONObject();// bizContent.put("trade_no", "2021081722001419121412730660");bizContent.put("refund_amount", refundAmount);bizContent.put("out_trade_no", outTradeNode); 返回参数选项,按需传入//JSONArray queryOptions = new JSONArray();//queryOptions.add("refund_detail_item_list");//bizContent.put("query_options", queryOptions);request.setBizContent(bizContent.toString());AlipayTradeRefundResponse response = alipayClient.execute(request);if(response.isSuccess()){System.out.println("调用成功");} else {System.out.println("调用失败");}return response.getBody();
}

在这里插入图片描述

重要入参说明

注意:请严格按照接口文档中的参数入参,传入非接口文档中的参数是无效的,并且可能会导致请求被拦截或其它异常。

参数名参数说明
out_trade_no支付时传入的商户订单号,与 trade_no 必填一个。
trade_no支付时返回的支付宝交易号,与 out_trade_no 必填一个。
out_request_no本次退款请求流水号,部分退款时必传。
refund_amount本次退款金额。

重要出参说明

参数名参数说明
refund_fee该笔交易已退款的总金额。

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

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

相关文章

账号和权限的管理1

文章目录 修改用户账号的属性usermod格式常用选项 用户账号的初始化配置文件文件来源主要的用户初始配置文件 组账号文件添加组账号groupadd格式常用选项其他选项 删除组账号groupdel格式 查询账号信息groups格式 id格式 finger格式 W、who、users格式 文件/目录的权限和归属访…

emptyDir + initContainer实现ConfigMap的动态更新(K8s相关)

1. 絮絮叨叨 K8s部署服务时&#xff0c;一般都需要使用ConfigMap定义一些配置文件例如&#xff0c;部署分布式SQL引擎Presto&#xff0c;会在ConfigMap中定义coordinator、worker所需的配置文件以node.properties为例&#xff0c;node.environment和node.data-dir的值将由Helm…

android 通过gradle去除aar的重复资源图片

背景&#xff1a;项目中引入了aar包&#xff0c;结果导致资源出问题了&#xff0c;于是需要对下面aar包进行重复资源去除操作 操作具体如下&#xff1a; 目录&#xff1a;app/build.gradle 末尾配置 apply from: "${project.rootDir}/scripts/excludewidgetAar.gradle&qu…

【web】2、集成插件

1、element-plus 官网地址:设计 | Element Plus 安装 plus 及 icon 图标库 1.1 官网提供plus安装方法&#xff1a; 1.2 官网提供 icon 安装方法 1.3 安装 pnpm install element-plus element-plus/icons-vue main.ts全局安装element-plus,element-plus默认支持语言英语设…

matlab编辑稀疏单位方阵

创建 10001000 稀疏单位方阵&#xff0c;并查看稀疏模式。 &#xff08;1&#xff09; I speye(1000); spy(I)&#xff08;2&#xff09; S speye(400,800); spy(S)此命令等同于 speye([400 800])。

Nginx中封装的数据结构

Nginx中封装的数据结构 Nginx中封装的数据结构整型ngx_str_t【字符串】ngx_list_t【链表】ngx_table_elt_t【key/value】ngx_buf_tngx_chain_t Nginx中封装的数据结构 整型 typedef intptr_t ngx_int_t; typedef uintptr_t ngx_uint_t;ngx_str_t【字符串】 typ…

qt6开发环境配置杂记

很多同学不重视环境配置问题&#xff0c;这是工程问题&#xff0c;实际工作中&#xff0c;如果不真正搞懂环境配置&#xff0c;后期可能会遇到各种坑。 QT是一套开发框架&#xff0c;最终要翻译成c去执行。总体而言&#xff0c;就是下面三张框图&#xff1a; &#xff08;工程…

Spring底层原理之bean的加载方式一 用XML方式声明bean 自定义bean及加载第三方bean 2024详解

目录 用XML方式声明bean 首先我们创建一个空的java工程 我们要导入一个spring的依赖 注意在maven工程里瞅一眼 我们创建一个业务层接口 还有四个实现类 我们最初的spingboot生命bean的方式是通过xml声明 我们在resources文件夹下创建一个配置文件 我们书写代码 首先初…

AI Agent:技术原理与未来趋势

在人工智能的快速发展中&#xff0c;AI Agent作为一项创新技术&#xff0c;正逐渐成为研究和应用的热点。AI Agent不仅仅是执行命令的程序&#xff0c;它们能够感知环境、做出决策并采取行动&#xff0c;展现出类似人类的群体协作能力。本文将探讨AI Agent的技术原理、开源框架…

使用vite官网和vue3官网分别都可以创建vue3项目

问: npm init vitelatest 和 npm create vuelatest创建的vue3项目有什么区别? 回答: npm init vitelatest 和 npm create vuelatest 分别是使用 Vite 和 Vue CLI 工具创建 Vue 项目的两种方式&#xff0c;它们之间有几个主要区别&#xff1a; 1. **构建工具&#xff1a;** …

忍法:声音克隆之术

前言&#xff1a; 最近因为一直在给肚子里面的宝宝做故事胎教&#xff0c;每天&#xff08;其实是看自己心情抽空讲下故事&#xff09;都要给宝宝讲故事&#xff0c;心想反正宝宝也看不见我&#xff0c;只听我的声音&#xff0c;干脆偷个懒&#xff0c;克隆自己的声音&#xf…

Linux CentOS 宝塔 Suhosin禁用php5.6版本eval函数详细图文教程

方法一&#xff1a;PHP_diseval_extension禁用 Linux CentOS 禁用php的eval函数详细图文教程_centos php 禁用 eval-CSDN博客 这个方法make报错&#xff0c;懒得费时间处理&#xff0c;直接用第二种 方法二&#xff1a;suhosin禁用 不支持PHP8&#xff0c;官方只支持PHP7以下…

【电源专题】为什么带电量计芯片的电池MOS保护要放在高侧

在实际的电量计电池开发中,发现一个很奇怪的现象。传统电池保护IC往往都是将充电保护和放电保护的两个MOS管放在低侧的。如下所示是文章:【电源专题】读一读单节锂电池保护IC规格书 可以看到M1和M2两个MOS管是放在PB-(也就是电池的负端),我们叫做低端。 而BQ28Z610电…

目标检测常用涨点方法:注意力机制小结(空间注意力、通道注意力、CBAM等)

1.通道注意力 通道注意力&#xff08;Channel Attention&#xff09;是在通道维度上对输入数据进行学习&#xff0c;再对不同的通道分配相应的权重表示重要性&#xff0c;从而达到“分配注意力”的效果。SENet&#xff08;Squeeze and Excitation networks) 是一个典型的使用通…

Swift宏的实现

上篇介绍了Swift宏的定义与生声明&#xff0c;本篇主要看看是Swift宏的具体实现。结合Swift中Codable协议&#xff0c;封装一个工具让类或者结构体自动实现Codable协议&#xff0c;并且添加一些协议中没有的功能。 关于Codable协议 Codable很好&#xff0c;但是有一些缺陷&…

yaklang window安装 vscode运行得到“hello world”

资源来源&#xff1a;旅程伊始&#xff1a;Yak 语言环境安装与搭建环境 | Yak Program Language 安装yak语言非常简单&#xff0c;管理员权限打开命令行运行以下命令&#xff1a; powershell (new-object System.Net.WebClient).DownloadFile(https://yaklang.oss-cn-beijing…

1085 PAT单位排行(测试点5)

solution 测试点5&#xff1a;总分是在每个学生加权后再取整&#xff0c;所以用来存学生分数的变量要用浮点型学校排序&#xff1a; 若成绩不同&#xff0c;则按成绩降序若成绩相同&#xff0c;人数不同&#xff0c;则按成绩升序若成绩和人数都相同&#xff0c;则按单位名升序…

理解GPT2:无监督学习的多任务语言模型

目录 一、背景与动机 二、卖点与创新 三、几个问题 四、具体是如何做的 1、更多、优质的数据&#xff0c;更大的模型 2、大数据量&#xff0c;大模型使得zero-shot成为可能 3、使用prompt做下游任务 五、一些资料 一、背景与动机 基于 Transformer 解码器的 GPT-1 证明…

NAS教程丨铁威马如何登录 SSH终端?

适用型号&#xff1a; 所有TNAS 型号 如您有特殊操作需要通过 SSH 终端登录 TNAS&#xff0c;请参照以下指引&#xff1a; (注意: 关于以下操作步骤中的"cd /"的指令,其作用是使当前 SSH/Telnet 连接的位置切换到根目录,以免造成对卷的占用.请不要遗漏它.) Windows…

数据分析的线上云端数据库搭建及Excel和Tableau连接

数据分析的线上云端数据库搭建及Excel和Tableau连接 SQL基础知识 线上SQL训练&#xff1a; SQlZOO: https://www.sqlzoo.net/wiki/SQL_Tutorial 牛客网SQL真题&#xff1a;https://www.nowcoder.com/ta/sql select,from,where, order by, limit, group by, having, substr(),…