Yet Another Alipay OpenAPI Smart Development Kit
Axios
aes-128-cbc
)加/解密功能sha1WithRSAEncryption
)及RSA2(sha256WithRSAEncryption
)签名、验签功能method({请求参数}[, {公共请求参数}[, {特殊头参数}]])
作为HTTP接口驱动,释义如下:
公共请求参数
的 method
,即作为本SDK标准方法链,弹性扩容,示例使用方法如下,详细审查见文末请求参数
,以 Object
对象作为第一个入参公共请求参数
,以 Object
对象作为第二个入参multipart/form-data
头信息,以 Object
对象作为第三个入参,见如下示例Formatter.page
,返回结果可直接作为页面/接口输出,说明用法见如下示例headers[x-alipay-verified]
为验签结果,值可能为 ok
, undefined
headers[x-alipay-signature]
为源返回数据签名值,值可能为 undefined
headers[x-alipay-responder]
为源返回值字段名转译,值可能为 undefined
, error
或者实际请求的 method
值以命令行的形式,与OpenAPI网关交互,play the OpenAPI requests over command line.
此命令行工具,主要是用来计算并获取 公钥证书模式 所需的 应用公钥证书SN(app_cert_sn)及 支付宝公钥证书SN(alipay_root_cert_sn)。
./bin/cert.js SN -f /path/your/app_cert.crt
./bin/cert.js SN -f /path/your/alipay_root_cert.crt -p RSAEncryption
而SN
命令是 Helpers.SN
的语法糖,可从如下API文档查看更详细用法
const {readFileSync} = require('fs')
const {Alipay} = require('whats-alipay')
//应用app_id
const app_id = '2014072300007148'
//商户私钥证书,须完整格式,同时支持 `PKCS#1` `PKCS#8` 格式
const privateKey = readFileSync('/your/openapi/private_key.pem')
//支付宝公钥证书,须完整格式,同时支持 `PKCS#1` `PKCS#8` 格式
const publicCert = readFileSync('/the/alipay/public_cert.pem')
const whats = new Alipay({ privateKey, publicCert, params: { app_id, } })
证书完整格式 是指: 包含
-----BEGIN
及-----END
,内容是列宽64的base64-encoded
字符串,可直接用openssl
命令行工具进行验证格式。
whats
.alipay.trade.query({out_trade_no})
.then(({headers,data}) => ({headers,data}))
.catch(({response: {data}}) => data)
.then(console.log)
whats
.alipay.trade.pay({
out_trade_no,
scene,
auth_code,
product_code,
subject,
total_amount,
})
.then(({data}) => data)
.catch(({response: {data}}) => data)
.then(console.log)
whats
.alipay.trade.precreate({
out_trade_no,
subject,
total_amount,
})
.then(({data}) => data)
.catch(({response: {data}}) => data)
.then(console.log)
whats
.alipay.trade.wap.pay({
out_trade_no,
subject,
total_amount,
product_code,
quit_url,
}, {}, Formatter.page)
.then(res => res)
.then(console.log)
res
结构做了优化,直接支持 literal
(独立服务模式: ${res}
) 或者 JSON.stringify
(二次接口模式: JSON.stringify(res)
)whats
.alipay.trade.page.pay({
out_trade_no,
subject,
total_amount,
product_code,
}, {return_url}, Formatter.page)
.then(res => res)
.then(console.log)
res
结构做了优化,直接支持 literal
(独立服务模式: ${res}
) 或者 JSON.stringify
(二次接口模式: JSON.stringify(res)
)whats
.alipay.trade.advance.consult({/*文档上的参数就好*/})
.then(({data}) => data)
.catch(({response: {data}}) => data)
.then(console.log)
whats
.koubei.marketing.campaign.activity.batchquery(/*文档上的参数就好*/})
.then(({data}) => data)
.catch(({response: {data}}) => data)
.then(console.log)
const {Form} = require('whats-alipay')
const payload = new Form()
payload.append('image_content', require('fs').readFileSync('/path/for/uploading.jpg'), 'uploading.jpg')
whats
.ant.merchant.expand.indirect.image.upload(
payload.getBuffer(),
{image_type: 'jpg'},
{...payload.getHeaders()}
)
.then(({data}) => data)
.catch(({response: {data}}) => data)
.then(console.log)
const {Form} = require('whats-alipay')
const payload = new Form()
payload.append('image_content', require('fs').readFileSync('/path/for/uploading.jpg'), 'uploading.jpg')
whats
.alipay.offline.material.image.upload(
payload.getBuffer(),
{image_type: 'jpg', image_name: 'uploading.jpg'},
{...payload.getHeaders()}
)
.then(({data}) => data)
.catch(({response: {data}}) => data)
.then(console.log)
whats
.zhima.auth.info.authquery(/*文档上的参数就好*/})
.then(({data}) => data)
.catch(({response: {data}}) => data)
.then(console.log)
whats
.alipay.eco.mycar.parking.enterinfo.sync(/*文档上的参数就好*/})
.then(({data}) => data)
.catch(({response: {data}}) => data)
.then(console.log)
whats
.alipay.fund.trans.uni.transfer(/*文档上的参数就好*/})
.then(({data}) => data)
.catch(({response: {data}}) => data)
.then(console.log)
whats
上绑定多少 method
,即扩容至多少,以上示例打印如下:
Alipay
类实例链如下:
通知消息验签,依赖相关 webserver
提供的 POST
数据解析能力,以下函数在 http.createServer
上做过验证,仅供参考。
function notificationValidator(things, publicCert, withoutSignType = true) {
const {groups: {sign}} = (typeof things === 'string' ? things : '').match(/\bsign=(?<sign>[^&]+)/) || {groups: {}}
const source = [...new URLSearchParams(things)].reduce((des, [key, value]) => (des[key] = value, des), {})
const signType = source['sign_type']
const signature = (source.sign || '').replace(/ /g, '+').replace(/_/g, '/')
// The signature with `sign_type` is only for the notifications whose come from `alipay.open.public.*` APIs.
if (withoutSignType) {
delete source['sign_type']
}
return Rsa.verify(Formatter.queryStringLike(Formatter.ksort(source)), sign || signature, publicCert, signType)
}
Manually generated by for f in lib/*.js; do ./node_modules/.bin/jsdoc2md -d 3 $f; done
Aes - Advanced Encryption Standard
Kind: global class
To prevent new
operation, works only as static class.
Kind: static property of Aes
Properties
Name | Type | Description |
---|---|---|
hex | string |
Alias of hex string |
Kind: static property of Aes
Properties
Name | Type | Description |
---|---|---|
utf8 | string |
Alias of utf8 string |
Kind: static property of Aes
Properties
Name | Type | Description |
---|---|---|
base64 | string |
Alias of base64 string |
Kind: static property of Aes
Properties
Name | Type | Description |
---|---|---|
BLOCK_SIZE | integer |
The aes block size |
Kind: static property of Aes
Properties
Name | Type | Description |
---|---|---|
MODE_CBC | string |
The cbc mode string |
array
Detect the algo with given cipherkey
length and mode
.
Kind: static method of Aes
Returns: array
- - [algorithm, key]
pairs
Param | Type | Description |
---|---|---|
cipherkey | string |
Based64 encoded key string. |
[mode] | string |
The mode string, default is this.MODE_CBC . |
AesCbc
Kind: global class
string
string
string
Encrypts plaintext.
Kind: static method of AesCbc
Returns: string
- Base64-encoded ciphertext.
Param | Type | Description |
---|---|---|
plaintext | string |
Text to encode. |
cipherkey | string |
The secret key, base64 encoded string. |
[iv] | string | buffer |
The initialization vector, 16 bytes string or buffer, default is 0{16} buffer. |
string
Decrypts ciphertext.
Kind: static method of AesCbc
Returns: string
- Utf-8 plaintext.
Param | Type | Description |
---|---|---|
ciphertext | string |
Base64-encoded ciphertext. |
cipherkey | string |
The secret key, base64 encoded string. |
[iv] | string | buffer |
The initialization vector, 16 bytes string or buffer, default is 0{16} buffer. |
Whats Alipay Core
object
Whats Alipay Core
Kind: global class
Proxy
function
To compose the method chain
.
Param | Type | Description |
---|---|---|
config | object |
The configuration passed in Decorator . |
config.privateKey | string | Buffer |
The merchant’s RSA’s private key. |
config.publicCert | string | Buffer |
The alipay’s RSA’s pubkey or certificate(recommend). |
[config.params] | object |
The general parameters. |
[config.params.app_id] | string | number |
The merchant’s application id. |
[config.params.app_auth_token] | string |
The merchant’s authorization token. |
[config.params.app_cert_sn] | string |
The merchant’s RSA’s certificate SN. |
[config.params.alipay_root_cert_sn] | string |
The alipay’s RSA’s certificate SN. |
Kind: static property of Alipay
Properties
Name | Type | Description |
---|---|---|
handler | object |
A Getter handler object |
Proxy
Compose a named function with prefix
and suffix
whose joined by a dot(.)
Kind: static method of Alipay
Returns: Proxy
- - With a special Getter
Function.
Param | Type | Description |
---|---|---|
[prefix] | string |
The prefix string. |
[suffix] | string |
The suffix string. |
function
Chain the input method
Kind: static method of Alipay
Returns: function
- - Named as given method
function
Param | Type | Description |
---|---|---|
method | string |
The naming string. |
object
Kind: global function
Returns: object
- - An object or object’s property
Param | Type | Description |
---|---|---|
target | object |
The object |
property | string |
The property |
Properties
Name | Type | Description |
---|---|---|
get | function |
Object’s getter handler |
Decorate the Axios
instance
Kind: global class
Decorate factory
Param | Type | Description |
---|---|---|
config | object |
The configuration. |
config.privateKey | string | Buffer |
The merchant’s RSA’s private key. |
config.publicCert | string | Buffer |
The alipay’s RSA’s pubkey or certificate(recommend). |
[config.params] | object |
The general parameters. |
[config.params.app_id] | string | number |
The merchant’s application id. |
[config.params.app_auth_token] | string |
The merchant’s authorization token. |
[config.params.app_cert_sn] | string |
The merchant’s RSA’s certificate SN. |
[config.params.alipay_root_cert_sn] | string |
The alipay’s RSA’s certificate SN. |
Kind: static property of Decorator
Properties
Name | Type | Description |
---|---|---|
client | AxiosInstance |
The Axios instance. |
Kind: static property of Decorator
Properties
Name | Type | Description |
---|---|---|
privateKey | buffer |
Buffer of the private key certificate. |
Kind: static property of Decorator
Properties
Name | Type | Description |
---|---|---|
publicCert | buffer |
Buffer of the alipay public certificate. |
Kind: static property of Decorator
Properties
Name | Type | Description |
---|---|---|
requestInterceptor | function |
Named as signer function. |
Kind: static property of Decorator
Properties
Name | Type | Description |
---|---|---|
responseVerifier | function |
Named as verifier function. |
Kind: static property of Decorator
Properties
Name | Type | Description |
---|---|---|
defaults | object |
The defaults configuration whose pased in Axios . |
PromiseLike
Portable of the axios.request
with defaults {method, params, headers}
compatible since Axios >= 0.19.0
function
of config.headers
is available since v0.0.9Kind: static method of Decorator
Returns: PromiseLike
- - The AxiosPromise
instance.
Param | Type | Description |
---|---|---|
config | object |
The configuration. |
config.data | object | Buffer | undefined |
The post data |
config.params | object | undefined |
The search parameters |
config.headers | object | function | undefined |
The request’s headers object or a callback function for sign-only requests |
object
Deep merge the input with the defaults
Kind: static method of Decorator
Returns: object
- - With the built-in configuration.
Param | Type | Description |
---|---|---|
config | object |
The configuration. |
Simple and lite of multipart/form-data
implementation, most similar to form-data
(new Form)
.append('a', 1)
.append('b', '2')
.append('c', Buffer.from('31'))
.append('d', JSON.stringify({}), 'any.json')
.append('e', require('fs').readFileSync('/path/your/file.jpg'), 'file.jpg')
.getBuffer()
Object.<string, string>
built-in mime-type mapping
Buffer
Buffer
Buffer
array.<Buffer>
The Form's data storage
Object.<string, number>
The entities' value indices whose were in this.data
Simple and lite of multipart/form-data
implementation, most similar to form-data
(new Form)
.append('a', 1)
.append('b', '2')
.append('c', Buffer.from('31'))
.append('d', JSON.stringify({}), 'any.json')
.append('e', require('fs').readFileSync('/path/your/file.jpg'), 'file.jpg')
.getBuffer()
Kind: global class
Buffer
Object.<string, string>
Form
Form
Create a multipart/form-data
buffer container for the file uploading.
Buffer
To retrieve the data
buffer
Kind: instance method of Form
Returns: Buffer
- - The payload buffer
Object.<string, string>
To retrieve the Content-Type
multipart/form-data header
Kind: instance method of Form
Returns: Object.<string, string>
- - The Content-Type
header With this.boundary
Form
Append a customized mime-type(s)
Kind: instance method of Form
Returns: Form
- - The Form
class instance self
Param | Type | Description |
---|---|---|
things | Object.<string, string> |
The mime-type |
Form
Append data wrapped by boundary
Kind: instance method of Form
Returns: Form
- - The Form
class instance self
Param | Type | Description |
---|---|---|
field | string |
The field |
value | string | Buffer |
The value |
[filename] | String |
Optional filename, when provided, then append the Content-Type after of the Content-Disposition |
Object.<string, string>
built-in mime-type mapping
Buffer
Buffer
Buffer
array.<Buffer>
The Form’s data storage
Object.<string, number>
The entities’ value indices whose were in this.data
Provides easy used methods using in this project.
Kind: global class
object
string
string
object
boolean
object
To prevent new
operation, works only as static class.
object
Sorts an Object by key.
Kind: static method of Formatter
Returns: object
- - The sorted object.
Param | Type | Description |
---|---|---|
thing | object | URLSearchParams |
The input plain or URLSearchParams object. |
string
Like queryString
does but without the sign
and empty value
entities.
Kind: static method of Formatter
Returns: string
- - The sorted object.
Param | Type | Description |
---|---|---|
thing | object |
The input object. |
string
Retrieve the current yyyy-MM-dd HH:mm:ss
date time based on given timeZone
.
Notes: NodeJS v10.15.3,v12.18.0,v14.5.0 had strange behavior on Intl.DateTimeFormat
, see hourCycle:h23
comments below:
Kind: static method of Formatter
Returns: string
- - yyyy-MM-dd HH:mm:ss
date time string
Param | Type | Default | Description |
---|---|---|---|
[when] | string | number | Date |
Any available inputs refer to the Date() constructor , default Date.now() . |
|
[timeZone] | string |
"Asia/Shanghai" |
Any available inputs refer to the options in Intl.DateTimeFormat , default Asia/Shanghai . |
object
Parse the source
with given placeholder
.
Kind: static method of Formatter
Returns: object
- - {ident, payload, sign}
object
Param | Type | Default | Description |
---|---|---|---|
source | string |
The inputs string. | |
[placeholder] | string |
(?<ident>[a-z](?:[a-z_])+)_response |
The payload pattern. |
boolean
Check the given numeric
input whether or nor the leap year.
Kind: static method of Formatter
Returns: boolean
- - True
means is leap year, otherwise NOT.
Param | Type | Description |
---|---|---|
numeric | number |
The inputs number. |
object
Translate the inputs for the page service, such as alipay.trade.page.pay
, alipay.trade.wap.pay
OpenAPI methods.
Kind: static method of Formatter
Returns: object
- - Minimal following the AxiosResponse
specification, returns {data, toJSON(), toString()}
object
Param | Type | Description |
---|---|---|
options | object |
The inputs |
options.baseURL | string |
The OpenAPI gateway URL |
options.method | string |
The HTTP method, should be get or post , default is post |
options.params | object |
The gernal paramters object, including method , version , charset , sign_type , format etc. |
options.params.method | string |
The OpenAPI’s method , should be alipay.trade.page.pay etc. |
options.params.version | string |
The OpenAPI’s version , default is 1.0 |
options.params.charset | string |
The OpenAPI’s charset , default is utf-8 |
options.params.format | string |
The OpenAPI’s format , default is JSON |
options.params.sign_type | string |
The OpenAPI’s sign_type , default is RSA2 |
options.data | URLSearchParams |
The biz_content and sign contents |
options.data.biz_content | string |
The OpenAPI’s biz_content , json string |
options.data.sign | string |
The OpenAPI’s sign , base64 encoded string dependent on the options.params.sign_type |
Provide some useful functions for the catificate(s)
Kind: global class
string
string
array.<Certificate>
string
string
To prevent new
operation, works only as static class.
Kind: static property of Helpers
Propertiy: LF - The line feed character
Kind: static property of Helpers
Propertiy: OIDs - Built-in ASN.1 OIDs
string
MD5 hash function
Kind: static method of Helpers
Returns: string
- - The digest string
Param | Type | Description |
---|---|---|
…things | string | Buffer | BufferView |
To caculating things |
string
Similar to require(‘wordwrap’) function for formatting the PEM certificate
Kind: static method of Helpers
Returns: string
- - The wrapped string
Param | Type | Default | Description |
---|---|---|---|
str | string |
The input string | |
[width] | number |
64 |
The wrapping width, default is 64 |
[char] | string |
The wrapping character, default is this.LF |
array.<Certificate>
Mapping to @fidm/x509
.Certificate.fromPEMs
Kind: static method of Helpers
Returns: array.<Certificate>
- - Array of the @fidm/x509
.Certificate instance
Param | Type | Default | Description |
---|---|---|---|
thing | string | Buffer |
The certificatie(s) file path or Buffer | |
[pattern] | string |
"." |
The signatureAlgorithm matching pattern, default is dot(. ) for all |
string
Extract a certificate from given thing
Kind: static method of Helpers
Returns: string
- - The pem format certificate(s)
Param | Type | Default | Description |
---|---|---|---|
thing | string | Buffer |
The certificatie(s) file path or Buffer | |
[pattern] | string |
"sha256" |
The algo prefix or suffix, default is sha256 prefix |
string
Calculate the given certificate(s) SN
value string
Note: The primitive BigInt
was shipped since nodejs v10.8.0, we’re >= 10.15.0 on safety.
Kind: static method of Helpers
Returns: string
- - The SN value string
Param | Type | Default | Description |
---|---|---|---|
thing | string | Buffer |
The certificatie(s) file path or Buffer | |
[pattern] | string |
"sha256" |
The algo prefix or suffix, default is sha256 prefix |
Provides sign/verify for the RSA sha1WithRSAEncryption
RSA2 sha256WithRSAEncryption
cryptos.
Kind: global class
To prevent new
operation, works only as static class.
Kind: static property of Rsa
Properties
Name | Type | Description |
---|---|---|
base64 | string |
Alias of base64 string |
Kind: static property of Rsa
Properties
Name | Type | Description |
---|---|---|
ALGO_TYPE_RSA | string |
Alias of sha1WithRSAEncryption string |
Kind: static property of Rsa
Properties
Name | Type | Description |
---|---|---|
ALGO_TYPE_RSA2 | string |
Alias of sha256WithRSAEncryption string |
string
Creates and returns a Sign
string that uses given type=RSA|RSA2
.
Kind: static method of Rsa
Returns: string
- Base64-encoded signature.
Param | Type | Description |
---|---|---|
message | string |
Content will be crypto.Sign . |
privateKeyCertificate | string | Buffer |
A PEM encoded private key certificate. |
[type] | string |
one of the algo alias RSA/RSA2, default is RSA2 . |
boolean
Verifying the message
with given signature
string that uses given type=RSA|RSA2
.
Kind: static method of Rsa
Returns: boolean
- True is passed, false is failed.
Param | Type | Description |
---|---|---|
message | string |
Content will be crypto.Verify . |
signature | string |
The base64-encoded ciphertext. |
publicCertificate | string | Buffer |
A PEM encoded public certificate. |
[type] | string |
one of the algo alias RSA/RSA2, default is RSA2 . |
npm test
To disable nock
and request with the real gateway, just NOCK_OFF=true npm test
Helpers
为本模块基础类之一;Helpers.SN
方法,兼容多DN
属性情况;Formatter.localeDateTime
方法,使用 String.padStart
计算 h23
小时;同步应答验签
逻辑,遵从本SDK约定,只要能从应答返回中解析出有效负载,即仅返回负载;异步通知消息
验签文档示例函数;ts
,相关问题 #4;npm install --no-optional
(>5.8.0)不起作用,不再可选依赖 form-data
,以内置 Form
类为主;v0.0.11 新增 whatsCli
cli.js
命令行交互工具
v0.0.10 优化 Formatter.page().data.html
, 重点兼容utf8
v0.0.9 新增 Formatter.page
函数,支持page
类接口调用(以第三入参回调)
v0.0.8 完善 API
文档 by jsdoc2md
v0.0.7 新增 Helpers
类及 certHelper
命令行工具集
v0.0.6 新增 Form
类,缩减并兼容 form-data
v0.0.5 向下兼容 NodeJS
>= 10.15.0
v0.0.4 向下兼容 Axios
>= 0.19.0
v0.0.3 增加测试用例及BUG修复
v0.0.2 重新发布版本
The MIT License (MIT)
Copyright (c) 2020 James ZHANG(TheNorthMemory)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.