【抖音小程序】通用交易系统-下单问题整理

在通用交易系统中,支付流程如下

1、服务端-预下单:生成参数与签名信息(此过程不需要与抖音平台对接)

参考 生成下单参数与签名_抖音开放平台

2、小程序用户端:根据返回的参数与签名,拉起抖音支付(tt.requestOrder、tt.getOrderPayment)  

参考  tt.requestOrder_抖音开放平台

3、服务端:接收抖音回调、或主动查询订单(此过程需要小程序正式发布

1、生成应用公私钥

抖音的密钥分为:应用、平台两种类型,注意区分。

进入抖音签名工具平台

生成好后,需要将公钥配置到抖音的控制台中。

每次修改应用公钥,都会变更keyVersion 值,后续签名过程需要匹配该值。注意

2、生成参数与签名

注意查看 官网文档中对 [生成下单参数与签名]  必传参数的要求。

抖音非必传参数的两种要求:

1)创建对象中,不允许出现该参数
2)该参数需要给定默认值,不能为 null 

待签名对象


import java.io.Serializable;
import java.util.List;/**** 抖音下单,签名对象* @author xuancg* @date 2025/6/6*/
public class DyOrderSignData implements Serializable {/**目前只支持传入一项*/private List<Sku> skuList;private String outOrderNo;/*** 订单总金额* 单位:分*/private Integer totalAmount;/**支付超时时间 秒、非必传*/private Integer payExpireSeconds = 300;private String payNotifyUrl;/**开发者自定义收款商户号、非必传*///private String merchantUid;private GoodsPage orderEntrySchema;/*** 屏蔽的支付方式,当开发者没有进件某个支付渠道,可在下单时屏蔽对应的支付方式。* 如:[1, 2]表示屏蔽微信和支付宝*/private Integer[] limitPayWayList = new Integer[0];public static class Sku implements Serializable{private String skuId;private Integer price;private Integer quantity;/**商品标题,长度 <= 256字节 */private String title;private List<String> imageList;/**商品类型,详见此处的商品类型枚举值*/private Integer type;/**交易规则标签组*/private String tagGroupId;/**非必传*///private IndustryOrderGoodsPage entrySchema;/**非必传*/private String skuAttr;}/*** 商品详情页*/public static  class GoodsPage {/*** 订单详情页跳转路径,没有前导的“/”,长度 <= 512byte*/private String path;/*** 订单详情页路径参数,自定义的 json 结构,* 序列化成字符串存入该字段,平台不限制* 但是写入的内容需要能够保证生成访问订单详情的schema能正确跳转到小程序内部的订单详情页* 长度 <= 512byte* 选填*/// private String params;}}

 

签名工具类

public class DecryptUtils {public static String getByteAuthorization(String privateKeyStr, String data, String appId, String nonceStr, long timestamp, String keyVersion) {String byteAuthorization = "";try {// 生成签名String signature = getSignature(privateKeyStr, "POST", "/requestOrder", timestamp, nonceStr, data);System.out.println(signature);// 构造byteAuthorizationStringBuilder sb = new StringBuilder();sb.append("SHA256-RSA2048 ").append("appid=").append(appId).append(",").append("nonce_str=").append(nonceStr).append(",").append("timestamp=").append(timestamp).append(",").append("key_version=").append(keyVersion).append(",").append("signature=").append(signature).append("");byteAuthorization = sb.toString();} catch (Exception ex) {ex.printStackTrace();return "";}return byteAuthorization;}public static String getSignature(String privateKeyStr, String method, String uri, long timestamp, String nonce, String data) throws Exception {data = data.replace("\\", "");System.out.println(data);String rawStr = method + "\n" +uri + "\n" +timestamp + "\n" +nonce + "\n" +data + "\n";privateKeyStr = privateKeyStr.replace("\n","");System.out.println(rawStr);System.out.println(privateKeyStr);Signature sign = Signature.getInstance("SHA256withRSA");sign.initSign(string2PrivateKey(privateKeyStr));sign.update(rawStr.getBytes(StandardCharsets.UTF_8));return Base64.getEncoder().encodeToString(sign.sign());}public static PrivateKey string2PrivateKey(String privateKeyStr) {PrivateKey prvKey = null;try {byte[] privateBytes = Base64.getDecoder().decode(privateKeyStr);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");prvKey = keyFactory.generatePrivate(keySpec);} catch (Exception ex) {ex.printStackTrace();}return prvKey;}}

调用签名方法

/*** 待签名串一共有五行(且必须严格按照以下顺序),每一行必须以 \n(换行符,ASCII 编码值为 0x0A)结束。* POST\n/requestOrder\n请求时间戳\n请求随机串\ndata\n*/public  String createByteSign(DyOrderSignData request){// 请求时间戳long timestamp = System.currentTimeMillis()/1000L;// 随机字符串String nonceStr = UUID.randomUUID().toString();String data = JSONUtil.toJsonStr(request);// 应用公钥版本,每次重新上传公钥后需要更新,可通过「开发管理-开发设置-密钥设置」处获取String keyVersion = "3";String appId = "";String appPrivateContent = "";return DecryptUtils.getByteAuthorization(appPrivateContent,data, appId, nonceStr, timestamp, keyVersion);}

获取应用私钥内容

/***
* classpath:app/rsa_private_key.pem
*/
public String loadKeyContent(String configPath)  {String path = configPath;if (configPath.startsWith("classpath:")) {path = configPath.replaceFirst("classpath:", "");}if (!path.startsWith("/")) {path = "/" + path;}try {ClassPathResource classPathResource = new ClassPathResource(path);String content =  FileUtils.readFileToString(classPathResource.getFile(), StandardCharsets.UTF_8);String[] repls = {"-----BEGIN PRIVATE KEY-----", "-----END PRIVATE KEY-----", "\n", "\r"};for (String repl : repls) {content = content.replace(repl, "");}return content;} catch (Exception e) {e.printStackTrace();}return null;}

 

返回前端内容

DyOrderSignData request
1、签名内容:String byteSign = createByteSign(request);
2、原始对象字符串(不建议传原始对象,官网的示例不合理):

String objStr = JSONUtil.toJsonStr(request);

 3、问题问题

先通过抖音签名工具,验证生成的签名内容是否一致。

签名不一致

1、检查是否使用应用私钥进行签名

2、私钥字符串内容不能用换行符、头部、尾部申明、其他隐藏符号等。

3、转化的参数对象是否一致。即在第五行,传入的JSON对象,可以在代码中打印内容。然后粘贴到签名工具中进行验证。

前端签名失败

1、如果是参数缺少、格式错误:请添加参数默认值,或者调整参数格式

2、下单errNo:11084 下单errMsg:requestOrder:fail 签名校验异常

由后端返回下单的参数对象 字符串,不能由前端将对象进行json转化。

如果在上一步签名不一致问题解决后,仍然出现签名校验异常

1)检查控制台的应用公钥与私钥是否匹配

2)检查keyVersion版本是否匹配

3)检查后端的下单对象封装JSON格式与返回前端字符串的JSON格式是否一致。

4)JSON对象中,不能有转义符\\ 、换行符 等特殊符号

没有收到抖音回调

小程序没有发布上线

 

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

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

相关文章

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…

EurekaServer 工作原理

一、核心工作流程 二、核心组件解析 1. 自动配置引擎 入口&#xff1a;EnableEurekaServer 引入 EurekaServerMarkerConfiguration&#xff0c;创建标记Bean Marker触发条件&#xff1a;EurekaServerAutoConfiguration 检测到 Marker 存在时激活关键Bean初始化&#xff1a; …

Playwright 与 Selenium:自动化测试的两大主流工具对比

《Playwright 与 Selenium&#xff1a;自动化测试的两大主流工具对比》 *Playwright 和 Selenium 是自动化测试领域的两大主流工具&#xff0c;二者在架构设计、功能特性和适用场景上存在显著差异&#xff0c;以下是核心对比&#xff1a; 一、架构与设计理念 维度Playwright…

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

R语言速释制剂QBD解决方案之二

影响含量均一性的显著因子&#xff08;%RSD&#xff09; 数据分析表明含量均一性的弯曲性不显著。如半正态图&#xff08;图12&#xff09;所示&#xff0c;影响含量均一性的显著因子为A&#xff08;原料药粒径&#xff09;和C&#xff08;MCC/Lactose&#xff09;。 mod2 <…

大模型原理、架构与落地

近年来&#xff0c;大模型&#xff08;Large Language Models&#xff0c;LLMs&#xff09;在人工智能领域迅猛发展&#xff0c;从GPT-3到GPT-4、Claude、Gemini、文心一言、GLM等模型相继发布&#xff0c;大模型已逐渐走出实验室&#xff0c;迈向产业落地。本文将从技术原理、…

WWDC 2025 macOS 26有哪些更新点

在2025年6月10日凌晨结束的WWDC 2025发布会中&#xff0c;苹果正式发布了全新的macOS 26&#xff0c;并给其命名为Tahoe。 以下为macOS相关的主要内容&#xff1a; 命名方式改变 苹果正式将各大系统的版本号改为对应年份&#xff0c;让命名方式更直观好记&#xff0c;macOS 2…

AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年6月10日第104弹

从今天开始&#xff0c;咱们还是暂时基于旧的模型进行预测&#xff0c;好了&#xff0c;废话不多说&#xff0c;按照老办法&#xff0c;重点8-9码定位&#xff0c;配合三胆下1或下2&#xff0c;杀1-2个和尾&#xff0c;再杀4-5个和值&#xff0c;可以做到100-300注左右。 (1)定…

.NET 8集成阿里云短信服务完全指南【短信接口】

文章目录 前言一、准备工作1.1 阿里云账号准备1.2 .NET 8项目创建 二、集成阿里云短信SDK2.1 安装NuGet包2.2 配置阿里云短信参数2.3 创建配置类 三、实现短信发送服务3.1 创建短信服务接口3.2 实现短信服务3.3 注册服务 四、创建控制器五、测试与优化5.1 单元测试5.2 性能优化…

解决HuggingFace不能git clone的问题

今天在从HuggingFace上clone项目的时候&#xff0c;一直出现超时问题&#xff0c;查了很多资料没有解决&#xff0c;后来向mentor请教了一下&#xff0c;可以通过镜像的方法解决这个问题&#xff0c;所以把方法放上来&#xff0c;希望对大家有帮助。 HuggingFace的服务器在国外…

Zookeeper 集群部署与故障转移

Zookeeper 介绍 Zookeeper 是一个开源的分布式协调服务&#xff0c;由Apache基金会维护&#xff0c;专为分布式应用提供高可用、强一致性的核心基础能力。它通过简单的树形命名空间&#xff08;称为ZNode树&#xff09;存储数据节点&#xff08;ZNode&#xff09;&#xff0c;…

简单聊下阿里云DNS劫持事件

阿里云域名被DNS劫持事件 事件总结 根据ICANN规则&#xff0c;域名注册商&#xff08;Verisign&#xff09;认定aliyuncs.com域名下的部分网站被用于非法活动&#xff08;如传播恶意软件&#xff09;&#xff1b;顶级域名DNS服务器将aliyuncs.com域名的DNS记录统一解析到shado…

服务器出现故障怎么办?快速排查与解决方法

服务器故障的常见原因分析 硬件故障&#xff1a;内存、硬盘、网络设备故障。 软件故障&#xff1a;操作系统、应用程序、数据库异常。 网络攻击&#xff08;如DDoS攻击&#xff09;造成资源耗尽。 快速排查故障的步骤 检查监控系统报警日志。 查看系统资源使用情况&#x…

Claude vs ChatGPT vs Gemini:功能对比、使用体验、适合人群

随着AI应用全面进入生产力场景&#xff0c;市面上的主流AI对话工具也进入“三国杀”时代&#xff1a; Claude&#xff08;Anthropic&#xff09;&#xff1a;新锐崛起&#xff0c;语言逻辑惊艳&#xff0c;Opus 模型被称为 GPT-4 杀手ChatGPT&#xff08;OpenAI&#xff09;&a…

Git 使用大全:从入门到精通

Git 是目前最流行的分布式版本控制系统&#xff0c;被广泛应用于软件开发中。本文将全面介绍 Git 的各种功能和使用方法&#xff0c;包含大量代码示例和实践建议。 文章目录 Git 基础概念版本控制系统Git 的特点Git 的三个区域Git 文件状态 Git 安装与配置安装 GitLinuxmacOSWi…

SpringBoot 框架第 1 次接口调用慢

文章目录 背景分析思路 1:DeepSeek 分析思路 2:日志分析思路 3:Arthas 分析下载 Arthas启动 Arthastrace 调用耗时分析Controller 调用耗时Service 调用分析ServiceImpl 耗时分析IService 耗时分析BaseMapper 耗时分析debug 执行链路MyBatisMapperProxy 解读解决思路 1:预热…

数据分析Agent构建

数据分析agent构建 代码资料来源于 Streamline-Analyst&#xff0c;旨在通过该仓库上的代码了解如何使用大语言模型构建数据分析工具&#xff1b; 个人仓库&#xff1a;Data-Analysis-Agent-Tutorial 不同的在于 Data-Analysis-Agent-Tutorial 是在 Streamline-Analyst 基础…

Java后端检查空条件查询

通过抛出运行异常&#xff1a;throw new RuntimeException("请输入查询条件&#xff01;");BranchWarehouseServiceImpl.java // 查询试剂交易&#xff08;入库/出库&#xff09;记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…

6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙

Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …