- 小程序 OpenAPI SDK 总览
- OpenAPI 简介
- 用户登录态签名
- 签名算法
- 联合授权
- 接口调用凭证
- 登录
- 小程序码与小程序链接
- Web 化接入
- 私信和群聊
- 解决方案
- 线索组件
- 隐私协议
- 视频能力
- 搜索能力
- 任务能力
- 电商
- 生活服务
- 短剧行业
- 用户信息
- 分享
- 客服
- 交易工具
- 小程序券
- 交易系统
- 素材库
- 内容安全
- 泛知识
- 担保支付
- 评价
- 其它
- 订阅消息
- 小程序推广计划
- 挂载
- 分发
- 数据分析
- 服务类目
- 直播间能力
- 抖音开放能力
- 能力申请
- 页面结构自定义
- 普通二维码绑定
- 抖音号绑定
- 流量主
- 抖店绑定
生成下单参数与签名收藏我的收藏
收藏
我的收藏接口说明
使用说明
- •开发者按照文档说明构造data,其结果为string类型,且必须符合json格式
- •开发者基于data生成签名,并按文档说明构造byteAuthorization,其结果为string类型
data
属性名 | 类型 | 默认值 | 必填 | 说明 |
skuList | SkuList[] SkuList说明见下文 | 无 | 是 | 下单商品信息 注意:目前只支持传入一项 |
outOrderNo | string | 无 | 是 | 外部订单号 |
totalAmount | number | 无 | 是 | 订单总金额 单位:分 |
payExpireSeconds | number | 无 | 否 | 支付超时时间,单位秒,例如 300 表示 300 秒后过期;不传或传 0 会使用默认值 300,不能超过48小时。 |
payNotifyUrl | string | 无 | 否 | 支付结果通知地址,必须是 HTTPS 类型,传入后该笔订单将通知到此地址。 |
merchantUid | string | 无 | 否 | 开发者自定义收款商户号 |
orderEntrySchema | Schema Schema说明见下文 | 无 | 是 | 订单详情页 |
limitPayWayList | number[] | 无 | 否 | 屏蔽的支付方式,当开发者没有进件某个支付渠道,可在下单时屏蔽对应的支付方式。如:[1, 2]表示屏蔽微信和支付宝 枚举说明: 1-微信 2-支付宝 |
SkuList
属性名 | 类型 | 默认值 | 必填 | 说明 |
skuId | string | 无 | 是 | 外部商品id,如:号卡商品id、会员充值套餐id、某类服务id、付费工具id等 |
price | number | 无 | 是 | 价格 单位:分 |
quantity | number | 无 | 是 | 购买数量 0 < quantity <= 100 |
title | string | 无 | 是 | 商品标题,长度 <= 256字节 |
imageList | string[] | 无 | 是 | 商品图片链接,长度 <= 512 字节 注意:目前只支持传入一项 |
type | number | 无 | 是 | 示例:
|
tagGroupId | string | 无 | 是 | 交易规则标签组 注意:根据接入规范,选择适合的标签组ID传入,该标签组对应标签将会在用户收银台展示。 |
entrySchema | Schema Schema说明见下文 | 无 | 否 | 商品详情页链接 |
skuAttr | Json Object | 无 | 否 | 号卡类商品必填,即当前商品类型 type in [101、102、103、104、105、106、107]的商品必填,内部结构请详见下文 ”skuAttr“ 小节说明。 示例:
|
skuAttr
号卡类
属性名 | 类型 | 默认值 | 必填 | 示例值 | 说明 |
package_cost | Json Object | 无 | 是 |
| 号卡商品套餐详情,具体字段说明详见下文”package_cost字段说明“小结 |
call_duration | number | 无 | 否,call_duration与traffic_bundle至少需要填一个 | 1000 | 套餐包含的通话时长,单位:分钟, |
traffic_bundle | number | 无 | 否 | 50 | 套餐包含的流量包大小,单位:G |
telecom_operator_type | string | 无 | 是 | official | 提供套餐的运营方性质,枚举值 official:官方 private:私营 |
package_cost字段说明
属性名 | 类型 | 默认值 | 必填 | 示例值 | 说明 |
amount | number | 无 | 是 | 1450 | 套餐售价,单位:分 |
time_len | number | 无 | 是 | 2 | 套餐时长 |
unit | string | 无 | 是 | month | 时长单位,枚举值 year:年 month:月 day:天 |
Schema:
名称 | 类型 | 是否必传 | 描述 | 正确示例 | 错误示例 |
path | string | 是 | 小程序xxx详情页跳转路径,没有前导的“/”,路径后不可携带query参数,路径中不可携带『?: & *』等特殊字符,路径只可以是『英文字符、数字、_、/ 』等组成,长度<=512byte | page/path/index | page/path/index?id=1234page/path:hello/index |
params | string | 否 | xx情页路径参数,自定义的json结构,内部为k-v结构,序列化成字符串存入该字段,平台不限制,但是写入的内容需要能够保证生成访问xx详情的schema能正确跳转到小程序内部的xx详情页,长度须<=512byte,params内key不可重复。 | '{"id":1234, "name":"hello"}' | {"id":1234,"id":2334,"name":hello} |
结果示例:
JSON复制{"skuList":[{"skuId":"657","price":1,"quantity":1,"title":"test_title","imageList":["https://xxxx.com/xxxxx.jpg"],"type":401,"tagGroupId":"tag_group_7272625659888041996"}],"outOrderNo":"test_out_order_no","totalAmount":1,"payExpireSeconds":300,"orderEntrySchema":{"path":"","params":""},"payNotifyUrl":"https://xxxxx/xxx"}
byteAuthorization
推荐开发者基于代码示例进行开发
第一步:构造待签名串
待签名串一共有五行(且必须严格按照以下顺序),每一行必须以
\n
(换行符,ASCII 编码值为 0x0A)结束Plain Text复制POST\n/requestOrder\n请求时间戳\n请求随机串\ndata\n
第二步:计算签名值
使用「应用私钥」对待签名串进行
SHA256-RSA2048
签名,并对签名结果进行Base64
编码得到签名值。第三步:生成 byteAuthorization
以下为具体格式:
Plain Text复制SHA256-RSA2048 应用appid,请求随机串nonce_str,请求时间戳timestamp,公钥版本key_version,签名值signature
示例:
Plain Text复制SHA256-RSA2048 appid=tt8629f0941xxxxxxxx,nonce_str=7CC7D26A52F05BA5CFD,timestamp=1698916641,key_version=1,signature=jz1+pplJX2IRcS24lsdsFFOF7+Wky3KiQhOMUz58u7n5VEDNr/axPLzm8+i232Aw4vxjoxavI77n8iUSaGcjHOXS1e4pkdJEHE1qQkQ1bNGsT1X2yXOMB5t8gceGiBJimwQkTSeq+KK/OzYTlCRaNuE784Mx7wtUdXCnBDKZDMxWBxu6R7L2eZ8mC5v67lV+oJcu7tRD10PePRXH1z+9zaX1CSwEg3K0IkLFxHqgrpsER7OeVBE8w9glsxjvuc2Gg==
代码示例
JAVA
GO
PHP
Java复制import java.security.PrivateKey;
import java.security.Signature;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.UUID;
public class DYSign {
public static void main(String []args) {
// 请求时间戳
long timestamp = System.currentTimeMillis()/1000L;
// 开发者填入自己的小程序app_id
String appId = "testAppId";
// 随机字符串
String nonceStr = UUID.randomUUID().toString();
// 应用公钥版本,每次重新上传公钥后需要更新,可通过「开发管理-开发设置-密钥设置」处获取
String keyVersion = "1";
// 应用私钥,用于加签 重要:1.测试时请修改为开发者自行生成的私钥;2.请勿将示例密钥用于生产环境;3.建议开发者不要将私钥文本写在代码中
String privateKeyStr = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCZSHNcFfthd/bV\nYexEJWOBVEjjDcXjfr1fYevuraNFfMmLPKV836BbvCiUSWHzJYEpkJ934e/j28NB\nEcEbPDLiGlLTd6AVwR22TkUwpLr41oQprz0HKFwhVPZ0HQCGIv0pVMA53TFSitIq\niqbNLmgm5yzSNqNy1t/0X/RfqEtA6Eoxw9u/Sx57i+pBFuLlZYanlm57+b7t1khg\n9JHvF0ulo7DScyJ4qgrD7oQf0RIQB0rqCFIeYuYO1cfvnxb9x4DPodEyVoAM4i9Y\ndFop9ZHt73W/icuLku/P8/G1+arzB5b7S1S3ky5/KdS8AEA9Ww5czZcdf9Jgm2S6\nRymjFGjzAgMBAAECggEBAIryGNgdePyWcSJmHHR9a+CdFWD0aDBa/7CJpAN8VKc1\ngcB8Xgp+7+6X9jTM/EQa+CVEWrmiDgF/gVPnkyNsAzff4rqcEnoFzzglZSS9/lp4\nod7jYa+uTy1LxgflDkeJSfEASStqrT4EZpR3kNInQfQZ1BBNxQXhb6smm+9mL6kK\nQJjAqBgEqtUAmNv0GnH89ZPPgZuIZeeL4cb4BhMEoa5MBnI+HDf07cN1nECQXRJl\nHU/iyhAPfP7RpO8O9KGDEDE36qebu0Cu4yUjWANXiqECFv93sQzONotkl3VPealv\nXM+jzGT7YdgHo/t3QKE8flMBo/XUzGTqi8j5AOXiaBkCgYEAylKVtjQMYgg4qMwd\n9Je+KZ9qL6QVHCsB2NPUt8N99oj70efsG4aGaEAadr8meNhIJ5lpoK+FXqSBIbbD\nS/xeOVI3XoMx/EdKLw/ZNi87G/EHYK9z7Fr3W7q8DFXe2hZ/ojFXC/aaBanjVVBK\n/6RfPzXfnx+vGX/t1FhcLC+yQD8CgYEAwfMtrXfH+3dW77dxXT/CTFJVs/o1K2qb\nepnQ6A33KMHPLBtPZZ6z5rzIO7OMSNItOTXTEoRXHmOKc5FtXGtbCvGSRByb6FgD\nWG3p2Bp2sZLuJBzXmLbSnEbHTNHM6uTgxNgWAh8pYpjPY8xF7BqYz2rGT47OPBmc\ntRzDjnzjak0CgYAqkM1mk/S2+zvQZ4E14GblouBYPZEjZ/jvgUGTl9F8eL1iIAUQ\nlXDZpgLrULPrYLVtf101rTfF/Z4dVbIo3mOEc8OqYre1d9onpJHyUGWDL2Z59O/S\nniDEb7j4b2h/QZSArxi9L5if8GofnNDqj85qIg92Dthr6PpEXoKl2TMLSQKBgFzQ\nBHHYukiqSV4ZyRQ4qMBhPkYMXFlUgObgqMoDtN06MewHfa1BjxHCEYgQWfeXLLEO\nAt3/mrkeJWk8lLr/XOgVxkr17d34EFHG93rE3zwG9hMuAjZAdvT2IfWvCIL32GAa\nkB2fz+ww+D3nySY9bBcGH7R+wE6eaxF4nFSZizKZAoGBAJzuaWCnVK0djfgvUsjm\nGUtyDvgyREcpAsXvES1pB2NLVeEUxm0uRtj6k4DhCv3rJfUwfMr0+sa9NUnXuaSR\nVqLYvAD8bNPKXwn7ymzQ7WioCqmZuUhLnQRppkjhfQGKLH0MnMw9Xh9FwJ9kzGNE\nUnTEhaaHsoaHMlLlRET32gyG".replace("\n","");
// 生成好的data
String data = "{\"skuList\":[{\"skuId\":\"1\",\"price\":9999,\"quantity\":1,\"title\":\"标题\",\"imageList\":[\"https://dummyimage.com/234x60\"],\"type\":401,\"tagGroupId\":\"idxxx\"}],\"outOrderNo\":\"1213\",\"totalAmount\":9999,\"limitPayWayList\":[],\"payExpireSeconds\":3000,\"orderEntrySchema\":{\"path\":\"page/index/index\",\"params\":\"{\\\"poi\\\":\\\"6601248937917548558\\\",\\\"aweme_useTemplate\\\":1}\"}}";
String byteAuthorization = getByteAuthorization(privateKeyStr, data, appId, nonceStr, timestamp, keyVersion);
System.out.println(byteAuthorization);
}
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);
// 构造byteAuthorization
StringBuilder 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);
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 {
String rawStr = method + "\n" +
uri + "\n" +
timestamp + "\n" +
nonce + "\n" +
data + "\n";
System.out.println(rawStr);
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;
}
}
密钥生成
适用于JAVA(PKCS8格式)
非JAVA适用(PKCS1格式)
PowerShell复制openssl
genrsa -out private_key.pem 2048
rsa -in private_key.pem -pubout -out public_key.pem
pkcs8 -topk8 -inform PEM -in private_key.pem -outform PEM -nocrypt -out rsa_private_key.pem
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
exit
// 注:生成出来的私钥文件为rsa_private_key.pem, 公钥文件为rsa_public_key.pem
// PKCS8格式,私钥以-----BEGIN PRIVATE KEY-----开头,-----END PRIVATE KEY-----结尾
应用公钥上传方式
点击纠错