UNPKG

wechatpay-axios-plugin

Version:

微信支付APIv2及v3 NodeJS SDK,支持CLI模式请求OpenAPI,支持v3证书下载,v2付款码支付、企业付款、退款,企业微信-企业支付-企业红包/向员工付款,v2&v3 Native支付、扫码支付、H5支付、JSAPI/小程序支付、合单支付...

143 lines (130 loc) 5.03 kB
/* eslint no-bitwise: ["error", { "allow": ["|"] }] */ const { randomFillSync } = require('crypto'); /** * Provides easy used methods using in this project. */ class Formatter { /** * Cast the `CSV` bill. * * @param {string|Buffer} buffer - CSV file content. * * @returns {object} - The casted source intputs as {rows, summary} Object */ static castCsvBill(buffer) { const data = Buffer.from(buffer).slice(3/* BOM(EFBBBF) */).toString().split(/\r?\n/); const list = data.slice(1, -3); const foot = data.slice(-3); const head = data.shift().split(','); const rows = list.map((row) => this.castCsvLine(row, head)); const caption = foot.shift().split(','); const summary = this.castCsvLine(foot.shift(), caption); return { rows, summary }; } /** * Cast the `CSV` line string by the keys named object. * * @param {string} row - CSV line. * @param {string[]} [keys] - CSV headers. * @param {boolean} [skipFirstChar = true] - Skip the first character of the CSV line, default is true. * @param {string} [separator = ',`'] - Split separator, default is ',`' (two chars). * * @returns {object} - The casted source line as Object */ static castCsvLine(row, keys = [], skipFirstChar = true, separator = ',`') { return (row || '').substring(skipFirstChar ? 1 : 0).split(separator).reduce( (pool, cell, idx) => Object.assign(pool, { [keys[idx] || idx]: cell }, pool), {}, ); } /** * Generate a Base62 random string aka `nonce`, similar as `crypto.randomBytes`. * * @param {number} [size = 32] - Nonce string length, default is 32 bytes. * * @returns {string} - Base62 random string. */ static nonce(size = 32) { return randomFillSync(Buffer.from(Array(size))).map((i) => '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'[i % 62].charCodeAt(0)).toString(); } /** * Retrieve the current `Unix` timestamp. * * @returns {number} Epoch timestamp. */ static timestamp() { return Date.now() / 1000 | 0; } /** * Formatting for the heading `Authorization` value. * * @param {string|number} mchid - The merchant ID. * @param {string} nonce - The Nonce string. * @param {string} signature - The base64-encoded `Rsa.sign` ciphertext. * @param {string|number} timestamp - The `Unix` timestamp. * @param {string} serial - The serial number of the merchant public certification. * * @returns {string} - The APIv3 Authorization `header` value */ static authorization(mchid, nonce, signature, timestamp, serial) { return `WECHATPAY2-SHA256-RSA2048 mchid="${mchid}",serial_no="${serial}",timestamp="${timestamp}",nonce_str="${nonce}",signature="${signature}"`; } /** * Formatting this `HTTP.request` for `Rsa.sign` input. * * @param {string} method - The HTTP verb, must be the uppercase sting. * @param {string} uri - Combined string with `URL.pathname` and `URL.search`. * @param {string|number} timestamp - The `Unix` timestamp, should be the one used in `authorization`. * @param {string} nonce - The `Nonce` string, should be the one used in `authorization`. * @param {string} body - The playload string, HTTP `GET` should be an empty string. * * @returns {string} - The content for `Rsa.sign` */ static request(method, uri, timestamp, nonce, body = '') { return this.joinedByLineFeed(method, uri, timestamp, nonce, body); } /** * Formatting this `HTTP.response` for `Rsa.verify` input. * * @param {string|number} timestamp - The `Unix` timestamp, should be the one from `response.headers[wechatpay-timestamp]`. * @param {string} nonce - The `Nonce` string, should be the one from `response.headers[wechatpay-nonce]`. * @param {string} body - The response payload string, HTTP status(`204`) should be an empty string. * * @returns {string} - The content for `Rsa.verify` */ static response(timestamp, nonce, body = '') { return this.joinedByLineFeed(timestamp, nonce, body); } /** * Joined this inputs by for `Line Feed`(LF) char. * * @param {string[]} pieces - The string(s) joined by line feed. * * @returns {string} - The joined string. */ static joinedByLineFeed(...pieces) { return [...pieces, ''].join('\n'); } /** * Sorts an Object by key. * * @param {object} thing - The input object. * * @returns {object} - The sorted object. */ static ksort(thing) { return Object.keys(thing).sort().reduce((des, key) => Object.assign(des, { [key]: thing[key] }), {}); } /** * Like `queryString` does but without the `sign` and `empty value` entities. * * @param {object} thing - The input object. * * @returns {string} - The sorted object. */ static queryStringLike(thing) { return Object.entries(thing).filter(([k, v]) => k !== 'sign' && v !== undefined && v !== '').map((i) => i.join('=')).join('&'); } static get default() { return this; } } module.exports = Formatter;