Release 4.14.0 [skip ci] 4.14.0 (2025-04-29)Features V3协议 Authorization 字段添加扩展支持 (#157) (04e75cf)
Release 4.14.0
[skip ci]
Alipay OpenAPI SDK for Node.js / 用于给 Node.js 服务器提供调用支付宝开放平台的能力。 包括向支付宝服务器发起 OpenAPI 请求、订单信息生成,以及配套的证书、加签和验签能力。
基于支付宝 API v3 接口规范实现。
同时支持 Commonjs 和 ESM 两种模块依赖方式引入,通过 TypeScript 实现,HTTP Client 使用 urllib。
安装依赖
npm install alipay-sdk --save
PKCS1
keyType: 'PKCS8'
appId
应用私钥
应用公钥证书文件
支付宝公钥证书文件
支付宝根证书文件
应用公钥
支付宝公钥
import { AlipaySdk } from 'alipay-sdk'; // 实例化客户端 const alipaySdk = new AlipaySdk({ // 设置应用 ID appId: 'your-APPID', // 设置应用私钥 privateKey: fs.readFileSync('/path/to/private-key.pem', 'ascii'), // 设置支付宝公钥 alipayPublicKey: fs.readFileSync('/path/to/alipay-public-key.pem', 'ascii'), // 密钥类型,请与生成的密钥格式保持一致,参考平台配置一节 // keyType: 'PKCS1', // 设置网关地址,默认是 https://openapi.alipay.com // endpoint: 'https://openapi.alipay.com', });
import { AlipaySdk } from 'alipay-sdk'; const alipaySdk = new AlipaySdk({ appId: '2016123456789012', privateKey: fs.readFileSync('/path/to/private-key.pem', 'ascii'), // 传入支付宝根证书、支付宝公钥证书和应用公钥证书。 alipayRootCertPath: '/path/to/alipayRootCert.crt', alipayPublicCertPath: '/path/to/alipayCertPublicKey_RSA2.crt', appCertPath: '/path/to/appCertPublicKey.crt', });
可以使用如下基础接口请求服务端,以验证配置正确。
// https://opendocs.alipay.com/open-v3/668cd27c_alipay.user.deloauth.detail.query?pathHash=3ab93168 const result = await alipaySdk.curl('POST', '/v3/alipay/user/deloauth/detail/query', { body: { date: '20230102', offset: 20, limit: 1, }, }); console.log(result);
只要接口调用返回 responseHttpStatus 200,即代表验证配置成功
{ data: {}, responseHttpStatus: 200, traceId: '06033316171731016275628924348' }
其余情况,如代码报错,则说明未配置成功。
用于向支付宝服务器发起请求,与具体接口相关的业务参数。 下面以 统一收单交易支付接口 为示例
const result = await alipaySdk.curl('POST', '/v3/alipay/trade/pay', { body: { notify_url: 'http://www.your-notify.com/notify', // 通知回调地址 out_trade_no: '商家的交易码,需保持唯一性', total_amount: '0.1', subject: '测试订单', // 更多参数请查看文档 https://opendocs.alipay.com/open-v3/08c7f9f8_alipay.trade.pay?scene=32&pathHash=8bf49b74 } }); console.log(result); // { // "trade_no":"2013112011001004330000121536", // "out_trade_no":"6823789339978248", // "buyer_logon_id":"159****5620", // "total_amount":"120.88", // ...
AlipayFormData
部分接口需要上传文件。 SDK 内部封装了一个 Form 对象,用以在发起 multipart/form-data 请求时使用。 以 支付宝文件上传接口 为例:
Form
multipart/form-data
import { AlipayFormData } from 'alipay-sdk'; const form = new AlipayFormData(); form.addFile('file_content', '图片.jpg', path.join(__dirname, './test.jpg')); const uploadResult = await alipaySdk.curl<{ file_id: string; }>('POST', '/v3/alipay/open/file/upload', { form, body: { biz_code: 'openpt_appstore', }, }); console.log(uploadResult); // { // data: { file_id: 'A*7Cr9T6IAAC4AAAAAAAAAAAAAATcnAA' }, // responseHttpStatus: 200, // traceId: '06033316171731110716358764348' // }
import fs from 'node:fs'; import { AlipayFormData } from 'alipay-sdk'; const form = new AlipayFormData(); form.addFile('file_content', '图片.jpg', fs.createReadStream('/path/to/test-file')); const uploadResult = await alipaySdk.curl<{ file_id: string; }>('POST', '/v3/alipay/open/file/upload', { form, body: { biz_code: 'openpt_appstore', }, }); console.log(uploadResult); // { // data: { file_id: 'A*7Cr9T6IAAC4AAAAAAAAAAAAAATcnAA' }, // responseHttpStatus: 200, // traceId: '06033316171731110716358764348' // }
import fs from 'node:fs'; import { AlipayFormData } from 'alipay-sdk'; const form = new AlipayFormData(); form.addFile('file_content', '图片.jpg', fs.readFileSync('/path/to/test-file')); const uploadResult = await alipaySdk.curl<{ file_id: string; }>('POST', '/v3/alipay/open/file/upload', { form, body: { biz_code: 'openpt_appstore', }, }); console.log(uploadResult); // { // data: { file_id: 'A*7Cr9T6IAAC4AAAAAAAAAAAAAATcnAA' }, // responseHttpStatus: 200, // traceId: '06033316171731110716358764348' // }
pageExecute 方法主要是用于网站支付接口请求链接生成,传入前台访问输入密码完成支付, 如电脑网站支付 alipay.trade.page.pay 等接口。
pageExecute
表单示例:
const bizContent = { out_trade_no: "ALIPfdf1211sdfsd12gfddsgs3", product_code: "FAST_INSTANT_TRADE_PAY", subject: "abc", body: "234", total_amount: "0.01" }; // 支付页面接口,返回 HTML 代码片段,内容为 Form 表单 const html = alipaySdk.pageExecute('alipay.trade.page.pay', 'POST', { bizContent, returnUrl: 'https://www.taobao.com' });
<form action="https://openapi.alipay.com/gateway.do?method=alipay.trade.app.pay&app_id=2021002182632749&charset=utf-8&version=1.0&sign_type=RSA2×tamp=2023-02-28%2011%3A48%3A28&app_auth_token=202302BBbcfad868001a4df3bbfa99e8a6913F10&sign=j9DjDGgxLt3jbOQZy7q7Qu8baKWTl4hZlxOHa%2B46hC1djmFx%2FIyBqzQntPMurzz3f8efXJsalZz3nqZ9ClowCCxBfBvqE0cdzCDAeQ1GMgjd7dbWgjfNNcqKgmJPsIkLaHnP5vTvj%2BA27SqkeZCMbeVfv%2B4nYurXaFB9dNBtA%3D%3D" method="post" name="alipaySDKSubmit1677556108819" id="alipaySDKSubmit1677556108819"> <input type="hidden" name="alipay_sdk" value="alipay-sdk-nodejs-3.3.0" /> <input type="hidden" name="biz_content" value="{"out_trade_no":"ziheng-test-eeee","product_code":"QUICK_MSECURITY_PAY","subject":"订单标题","total_amount":"0.01","body":"订单描述"}" /> </form> <script>document.forms["alipaySDKSubmit1677556108819"].submit();</script>
支付链接示例:
// 支付页面接口,返回支付链接,交由用户打开,会跳转至支付宝网站 const url = sdk.pageExecute('alipay.trade.page.pay', 'GET', { bizContent, returnUrl: 'https://www.taobao.com' }); // 返回示例:https://openapi.alipay.com/gateway.do?method=alipay.trade.app.pay&app_id=2021002182632749&charset=utf-8&version=1.0&sign_type=RSA2×tamp=2023-02-28%2011%3A46%3A35&app_auth_token=202302BBbcfaf3bbfa99e8a6913F10&sign=TPi33NcaKLRBLJDofon84D8itMoBkVAdJsfmIiQDScEw4NHAklXvcvn148A2t47YxDSK0urBnhS0%2BEV%2BVR6h6aKgp931%2FfFbG1I3SAguMjMbr23gnbS68d4spcQ%3D%3D&alipay_sdk=alipay-sdk-nodejs-3.3.0&biz_content=blabla
sdkExecute 方法主要是服务端生成请求字符串使用的,不会直接支付扣款,需传值到客户端进行调用收银台输入密码完成支付, 如 App 支付接口 alipay.trade.app.pay。
sdkExecute
// App 支付接口,生成请求字符串, const orderStr = sdk.sdkExecute('alipay.trade.app.pay', { bizContent: { out_trade_no: "ALIPfdf1211sdfsd12gfddsgs3", product_code: "FAST_INSTANT_TRADE_PAY", subject: "abc", body: "234", total_amount: "0.01" }, returnUrl: 'https://www.taobao.com' }); console.log(orderStr); // method=alipay.trade.app.pay&app_id=2021002182632749&charset=utf-8&version=1.0&sign_type=RSA2×tamp=2023-02-24%2016%3A20%3A28&app_auth_token=202302BBbcfad868001a4df3bbfa99e8a6913F10&sign=M%2B2sTNATtUk3i8cOhHGtqjVDHIHSpPReZgjfLfIgbQD4AvI%2Fh%2B%2FS2lkqfJVnI%2Bu0IQ2z7auE1AYQ0wd7yPC4%2B2m5WnN21Q6uQhCCHOsg30mXdnkdB3rgXIiFOSuURRwnaiBmKNKdhaXel51fxYZOTOApV47K6ZUsOlPxc%2FVJWUnC7Hrl64%2BAKqtbv%2BcaefzapYsJwGDzMAGccHGfxevSoZ2Ev7S0FsrDe4LBx4m%2BCWSIFASWFyWYxJq%2BJg7LH1HJqBdBk1jjh5JJ3bNlEqJk8MEFU7sNRae2ErdEPOwCchWkQOaVGOGpFlEHuTSvxnAKnjRkFerE14v%2BVm6weC1Tbw%3D%3D&alipay_sdk=alipay-sdk-nodejs-3.2.0&biz_content=%7B%22out_trade_no%22%3A%22ziheng-test-eeee%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22subject%22%3A%22%E8%AE%A2%E5%8D%95%E6%A0%87%E9%A2%98%22%2C%22total_amount%22%3A%220.01%22%2C%22body%22%3A%22%E8%AE%A2%E5%8D%95%E6%8F%8F%E8%BF%B0%22%7D // 返回支付宝客户端之后,在【小程序中】通过 my.tradePay 进行调用。 // 详见:https://opendocs.alipay.com/mini/api/openapi-pay my.tradePay({ // 服务端生成的字符串,即上面返回的 orderStr orderStr, success: (res) => { my.alert({ content: JSON.stringify(res), }); }, fail: (res) => { my.alert({ content: JSON.stringify(res), }); } });
用于向支付宝服务器发起请求。与具体接口相关的业务参数,需要放在 bizContent 中。
bizContent
const result = await alipay.exec('alipay.trade.pay', { notify_url: 'http://www.your-notify.com/notify', // 通知回调地址 bizContent: { out_trade_no: '商家的交易码,需保持唯一性', total_amount: '0.1', subject: '测试订单', } });
⚠️⚠️⚠️ 注意:部分接口的请求参数不在 bizContent 中, 如 alipay.system.oauth.token, 具体可参考官网各接口定义。
alipay.system.oauth.token
部分接口会设置回调地址,用于支付宝服务器向业务服务器通知业务情况(如交易成功)等。 此时业务服务应该验证该回调的来源安全性,确保其确实由支付宝官方发起。 SDK 提供了对应的通知验签能力。
// 获取 queryObj,如 ctx.query, router.query // 如服务器未将 queryString 转化为 object,需要手动转化 const queryObj = { sign_type: 'RSA2', sign: 'QfTb8tqE1BMhS5qAn.....', gmt_create: '2019-08-15 15:56:22', other_biz_field: '....', } // true | false const success = sdk.checkNotifySign(queryObj);
如果遇到验签失败,请尝试使用 checkNotifySignV2() 方法代替,它默认不会对 value 进行 decode 如 https://github.com/alipay/alipay-sdk-nodejs-all/issues/45 提到的常见问题。
checkNotifySignV2()
const postData = { sign_type: 'RSA2', sign: 'QfTb8tqE1BMhS5qAn.....', gmt_create: '2019-08-15 15:56:22', other_biz_field: '....', }; // true | false const success = sdk.checkNotifySignV2(postData);
例如需要对小程序拿到的加密手机号码进行解密
const plainText = alipaySdk.aesDecrypt(getPhoneNumberResponse);
参考 https://opendocs.alipay.com/common/02mse3#AES%20%E8%A7%A3%E5%AF%86%E5%87%BD%E6%95%B0 的算法
前端返回的内容
{ "response": "hvDOnibG0DPcOFPNubK3DEfLQGL4=", "sign": "OIwk7zfZMp5GX78Ow==", "sign_type": "RSA2", "encrypt_type": "AES", "charset": "UTF-8" }
通过 alipay-sdk 验签
// 注意,加密内容必须前后加上双引号 const signContent = '"hvDOnibG0DPcOFPNubK3DEfLQGL4="'; const sign = 'OIwk7zfZMp5GX78Ow=='; const signType = 'RSA2'; const signCheckPass = alipaySdk.rsaCheck(signContent, sign, signType); console.log(signCheckPass);
在需要固定 IP 白名单调用的场景下,可以通过配置 config.proxyAgent 来指定 HTTP 代理服务器调用。
config.proxyAgent
import { AlipaySdk, ProxyAgent } from 'alipay-sdk'; // 实例化客户端 const alipaySdk = new AlipaySdk({ // 其他配置不展示 // ... proxyAgent: new ProxyAgent('http(s)://your-http-proxy-address'), }); // 后续的所有 http 调用都会走此 HTTP 代理服务器 const result = await alipaySdk.curl('POST', '/v3/alipay/user/deloauth/detail/query', { body: { date: '20230102', offset: 20, limit: 1, }, }); console.log(result);
从 v3 到 v4 有以下不兼容变更,请参考示例代码进行更新
Node.js 需要升级到 >= 18.20.0 及以上版本,可以到 Node.js 官方网站下载更新
Commonjs 通过 require('alipay-sdk') 引入细微变化
require('alipay-sdk')
v3 是会直接导出到 module.exports 下
module.exports
const AlipaySdk = require('alipay-sdk');
v4 是导出到 exports.AlipaySdk 下
exports.AlipaySdk
const { AlipaySdk } = require('alipay-sdk');
exec() 方法如果传递 options.formData 不包含文件,会抛出 TypeError 异常 提示使用 pageExec() 方法代替
exec()
options.formData
TypeError
提示使用 pageExec()
通过 NODE_DEBUG 环境变量打印 alipay-sdk 相关的调试日志
NODE_DEBUG=alipay-sdk* node your-script.js
如您在使用 Alipay SDK for Node.js 过程中遇到问题, 欢迎前往 支付宝开放社区 发帖与支付宝工作人员和其他开发者一起交流, 或联系 支付宝开放平台客服 协助解决。
AlipaySdkConfig
string
"RSA2"
"RSA"
5000
number
foo_bar
fooBar
true
boolean
privateKey
"PKCS1"
"PKCS8"
Buffer
Promise<AlipayCommonResult<T>>
curl 方式调用支付宝 API v3 协议接口
Returns: Promise<AlipayCommonResult<T>> - 请求执行结果
GET, POST, PUT, DELETE
AlipayCURLOptions
Record<string, string | number>
Record<string, any>
AlipayFormData | AlipayFormStream
false
config.timeout
AlipayCommonResult<T>
响应结果
T
生成请求字符串,用于客户端进行调用
Returns: string - 请求字符串
IRequestParams
object
ISdkExecuteOptions
生成网站接口请求链接 URL 或 POST 表单 HTML
Returns: string - 请求链接 URL 或 POST 表单 HTML
deprecated
Promise<AlipaySdkCommonResult>
执行请求,调用支付宝 API v2 协议接口
注意:此方法是为了让 alipay-sdk@3 尽量平滑升级到 alipay-sdk@4 保留, 请尽快使用 alipaySdk.curl() 代替,走 API v3 协议。
alipay-sdk@3
alipay-sdk@4
alipaySdk.curl()
Returns: Promise<AlipaySdkCommonResult> - 请求执行结果
alipay.ebpp.bill.add
IRequestOption
Boolean
请求参数
通知验签,默认不会对 value 进行 decode
Returns: Boolean - 是否验签成功
JSON
通知验签
对加密内容进行 AES 解密
Returns: String - 解密后的明文字符串
String
MIT
Made with contrib.rocks.
版权所有:中国计算机学会技术支持:开源发展技术委员会 京ICP备13000930号-9 京公网安备 11010802032778号
Alipay OpenAPI SDK
简介
Alipay OpenAPI SDK for Node.js / 用于给 Node.js 服务器提供调用支付宝开放平台的能力。 包括向支付宝服务器发起 OpenAPI 请求、订单信息生成,以及配套的证书、加签和验签能力。
基于支付宝 API v3 接口规范实现。
同时支持 Commonjs 和 ESM 两种模块依赖方式引入,通过 TypeScript 实现,HTTP Client 使用 urllib。
环境要求
安装依赖
平台配置
PKCS1的格式解析密钥,与密钥工具的默认生成格式不一致。 请使用密钥工具【格式转换】功能转为PKCS1,或在本 SDK 初始化时显式指定keyType: 'PKCS8'。appId、应用私钥、应用公钥证书文件、支付宝公钥证书文件、支付宝根证书文件appId、应用私钥、应用公钥、支付宝公钥初始化 SDK
普通公钥模式
证书模式
验证配置
可以使用如下基础接口请求服务端,以验证配置正确。
只要接口调用返回 responseHttpStatus 200,即代表验证配置成功
其余情况,如代码报错,则说明未配置成功。
快速使用
curl 示例代码
用于向支付宝服务器发起请求,与具体接口相关的业务参数。 下面以 统一收单交易支付接口 为示例
使用
AlipayFormData表单上传文件部分接口需要上传文件。 SDK 内部封装了一个
Form对象,用以在发起multipart/form-data请求时使用。 以 支付宝文件上传接口 为例:上传文件流
上传文件内容
pageExecute 示例代码
pageExecute方法主要是用于网站支付接口请求链接生成,传入前台访问输入密码完成支付, 如电脑网站支付 alipay.trade.page.pay 等接口。表单示例:
支付链接示例:
sdkExecute 示例代码
sdkExecute方法主要是服务端生成请求字符串使用的,不会直接支付扣款,需传值到客户端进行调用收银台输入密码完成支付, 如 App 支付接口 alipay.trade.app.pay。exec 示例代码(已废弃,请使用 curl 代替)
用于向支付宝服务器发起请求。与具体接口相关的业务参数,需要放在
bizContent中。⚠️⚠️⚠️ 注意:部分接口的请求参数不在
bizContent中, 如alipay.system.oauth.token, 具体可参考官网各接口定义。通知验签
部分接口会设置回调地址,用于支付宝服务器向业务服务器通知业务情况(如交易成功)等。 此时业务服务应该验证该回调的来源安全性,确保其确实由支付宝官方发起。 SDK 提供了对应的通知验签能力。
如果遇到验签失败,请尝试使用
checkNotifySignV2()方法代替,它默认不会对 value 进行 decode 如 https://github.com/alipay/alipay-sdk-nodejs-all/issues/45 提到的常见问题。对加密内容进行解密
例如需要对小程序拿到的加密手机号码进行解密
对前端返回的报文进行验签
参考 https://opendocs.alipay.com/common/02mse3#AES%20%E8%A7%A3%E5%AF%86%E5%87%BD%E6%95%B0 的算法
前端返回的内容
通过 alipay-sdk 验签
通过 HTTP 代理服务器调用
在需要固定 IP 白名单调用的场景下,可以通过配置
config.proxyAgent来指定 HTTP 代理服务器调用。alipay-sdk v3 到 v4 的升级说明
从 v3 到 v4 有以下不兼容变更,请参考示例代码进行更新
Node.js 需要升级到 >= 18.20.0 及以上版本,可以到 Node.js 官方网站下载更新
Commonjs 通过
require('alipay-sdk')引入细微变化v3 是会直接导出到
module.exports下v4 是导出到
exports.AlipaySdk下exec()方法如果传递options.formData不包含文件,会抛出TypeError异常提示使用 pageExec()方法代替打印调试日志的方式
通过 NODE_DEBUG 环境变量打印 alipay-sdk 相关的调试日志
问题反馈
如您在使用 Alipay SDK for Node.js 过程中遇到问题, 欢迎前往 支付宝开放社区 发帖与支付宝工作人员和其他开发者一起交流, 或联系 支付宝开放平台客服 协助解决。
API
new AlipaySdk(config)
AlipaySdkConfigAlipaySdkConfig
stringstring"RSA2""RSA2"|"RSA"stringstring5000numberfoo_bar转换为驼峰写法fooBar,默认值是truebooleanprivateKey类型, 默认值是"PKCS1""PKCS1"|"PKCS8"stringstring|Bufferstringstringstring|Bufferstringstringstring|BufferstringstringstringalipaySdk.curl<T = any>(httpMethod, path, options?) ⇒
Promise<AlipayCommonResult<T>>curl 方式调用支付宝 API v3 协议接口
Returns:
Promise<AlipayCommonResult<T>>- 请求执行结果stringGET, POST, PUT, DELETE等stringAlipayCURLOptionsRecord<string, string | number>Record<string, any>AlipayFormData | AlipayFormStreamstringbooleanfalsestringnumberconfig.timeoutAlipayCommonResult<T>响应结果
TnumberstringalipaySdk.sdkExecute(method, bizParams, options?) ⇒
string生成请求字符串,用于客户端进行调用
Returns:
string- 请求字符串stringIRequestParamsobjectISdkExecuteOptionsbooleanbizContent做驼峰参数转为小写 + 下划线参数,如 outOrderNo => out_order_no,默认true,如果不需要自动转换,请设置为falsealipaySdk.pageExecute(method, httpMethod, bizParams) ⇒
string生成网站接口请求链接 URL 或 POST 表单 HTML
Returns:
string- 请求链接 URL 或 POST 表单 HTMLstringstringIRequestParamsobjectdeprecatedalipaySdk.exec(method, bizParams, options) ⇒Promise<AlipaySdkCommonResult>执行请求,调用支付宝 API v2 协议接口
注意:此方法是为了让
alipay-sdk@3尽量平滑升级到alipay-sdk@4保留, 请尽快使用alipaySdk.curl()代替,走 API v3 协议。Returns:
Promise<AlipaySdkCommonResult>- 请求执行结果stringalipay.ebpp.bill.addIRequestParamsobjectIRequestOptionBooleanobjectAlipaySdkCommonResult
响应结果
stringstringstringstringIRequestParams
请求参数
objectbooleanalipaySdk.checkNotifySignV2(postData)
通知验签,默认不会对 value 进行 decode
Returns:
Boolean- 是否验签成功JSONalipaySdk.checkNotifySign(postData, raw)
通知验签
Returns:
Boolean- 是否验签成功JSONBooleanalipaySdk.aesDecrypt(encryptedText)
对加密内容进行 AES 解密
Returns:
String- 解密后的明文字符串StringLicense
MIT
Contributors
Made with contrib.rocks.