{"version":3,"sources":["jsdelivr-header.js","/npm/zhifubao-pay@1.0.7/lib/index.js"],"names":[],"mappings":"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","file":"/npm/zhifubao-pay@1.0.7/lib/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/zhifubao-pay@1.0.7/lib/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","\"use strict\";\r\n\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nconst fs = require(\"fs\");\r\nconst is = require(\"is\");\r\nconst crypto = require(\"crypto\");\r\nconst urllib = require(\"urllib\");\r\nconst request = require(\"request\");\r\nconst decamelize = require(\"decamelize\");\r\nconst camelcaseKeys = require(\"camelcase-keys\");\r\nconst snakeCaseKeys = require(\"snakecase-keys\");\r\nconst util_1 = require(\"./util\");\r\nconst pkg = require('../package.json');\r\nconst dateformat = require(\"dateformat\");\r\nconst form_1 = require(\"./form\");\r\n\r\nclass AlipaySdk {\r\n    constructor(config) {\r\n        if (!config.appId) {\r\n            throw Error('config.appId is required');\r\n        }\r\n        if (!config.privateKey) {\r\n            throw Error('config.privateKey is required');\r\n        }\r\n        const privateKeyType = config.keyType === 'PKCS8' ? 'PRIVATE KEY' : 'RSA PRIVATE KEY';\r\n        config.privateKey = this.formatKey(config.privateKey, privateKeyType);\r\n        if (config.alipayPublicKey) {\r\n            config.alipayPublicKey = this.formatKey(config.alipayPublicKey, 'PUBLIC KEY');\r\n        }\r\n        this.config = Object.assign({\r\n            urllib,\r\n            gateway: 'https://openapi.alipay.com/gateway.do',\r\n            timeout: 5000,\r\n            camelcase: true,\r\n            signType: 'RSA2',\r\n            charset: 'utf-8',\r\n            version: '1.0',\r\n        }, camelcaseKeys(config, { deep: true }));\r\n        this.sdkVersion = `AlipaySdk-${pkg.version}`;\r\n    }\r\n\r\n    // 格式化 key\r\n    formatKey(key, type) {\r\n        const item = key.split('\\n').map(val => val.trim());\r\n        // 删除包含 `RSA PRIVATE KEY / PUBLIC KEY` 等字样的第一行\r\n        if (item[0].includes(type)) {\r\n            item.shift();\r\n        }\r\n        // 删除包含 `RSA PRIVATE KEY / PUBLIC KEY` 等字样的最后一行\r\n        if (item[item.length - 1].includes(type)) {\r\n            item.pop();\r\n        }\r\n        return `-----BEGIN ${type}-----\\n${item.join('')}\\n-----END ${type}-----`;\r\n    }\r\n\r\n    // 格式化请求 url（按规范把某些固定的参数放入 url）\r\n    formatUrl(url, params) {\r\n        let requestUrl = url;\r\n        // 需要放在 url 中的参数列表\r\n        const urlArgs = [\r\n            'app_id', 'method', 'format', 'charset',\r\n            'sign_type', 'sign', 'timestamp', 'version',\r\n            'notify_url', 'return_url', 'auth_token', 'app_auth_token',\r\n        ];\r\n        for (const key in params) {\r\n            if (urlArgs.indexOf(key) > -1) {\r\n                const val = encodeURIComponent(params[key]);\r\n                requestUrl = `${requestUrl}${requestUrl.includes('?') ? '&' : '?'}${key}=${val}`;\r\n                // 删除 postData 中对应的数据\r\n                delete params[key];\r\n            }\r\n        }\r\n        return { execParams: params, url: requestUrl };\r\n    }\r\n\r\n    // 文件上传\r\n    multipartExec(method, option = {}) {\r\n        const config = this.config;\r\n        let signParams = {};\r\n        let formData = {};\r\n        const infoLog = (option.log && is.fn(option.log.info)) ? option.log.info : null;\r\n        const errorLog = (option.log && is.fn(option.log.error)) ? option.log.error : null;\r\n        option.formData.getFields().forEach((field) => {\r\n            // 字段加入签名参数（文件不需要签名）\r\n            signParams[field.name] = field.value;\r\n            formData[field.name] = field.value;\r\n        });\r\n        // 签名方法中使用的 key 是驼峰\r\n        signParams = camelcaseKeys(signParams, { deep: true });\r\n        formData = snakeCaseKeys(formData);\r\n        option.formData.getFiles().forEach((file) => {\r\n            // 文件名需要转换驼峰为下划线\r\n            const fileKey = decamelize(file.fieldName);\r\n            // 单独处理文件类型\r\n            formData[fileKey] = fs.createReadStream(file.path);\r\n        });\r\n        // 计算签名\r\n        const signData = util_1.sign(method, signParams, config);\r\n        // 格式化 url\r\n        const { url } = this.formatUrl(config.gateway, signData);\r\n        infoLog && infoLog('[AlipaySdk]start exec url: %s, method: %s, params: %s', url, method, JSON.stringify(signParams));\r\n        return new Promise((resolve, reject) => {\r\n            request.post({\r\n                url,\r\n                formData,\r\n                json: false,\r\n                timeout: config.timeout,\r\n                headers: { 'user-agent': this.sdkVersion },\r\n            }, (err, { }, body) => {\r\n                if (err) {\r\n                    err.message = '[AlipaySdk]exec error';\r\n                    errorLog && errorLog(err);\r\n                    reject(err);\r\n                }\r\n                infoLog && infoLog('[AlipaySdk]exec response: %s', body);\r\n                const result = JSON.parse(body);\r\n                const responseKey = `${method.replace(/\\./g, '_')}_response`;\r\n                const data = result[responseKey];\r\n                // 开放平台返回错误时，`${responseKey}` 对应的值不存在\r\n                if (data) {\r\n                    // 验签\r\n                    const validateSuccess = option.validateSign ? this.checkResponseSign(body, responseKey) : true;\r\n                    if (validateSuccess) {\r\n                        resolve(config.camelcase ? camelcaseKeys(data, { deep: true }) : data);\r\n                    }\r\n                    else {\r\n                        reject({ serverResult: body, errorMessage: '[AlipaySdk]验签失败' });\r\n                    }\r\n                }\r\n                reject({ serverResult: body, errorMessage: '[AlipaySdk]HTTP 请求错误' });\r\n            });\r\n        });\r\n    }\r\n\r\n    // page 类接口\r\n    pageExec(method, option = {}) {\r\n        let signParams = { alipaySdk: this.sdkVersion };\r\n        const config = this.config;\r\n        const infoLog = (option.log && is.fn(option.log.info)) ? option.log.info : null;\r\n        option.formData.getFields().forEach((field) => {\r\n            signParams[field.name] = field.value;\r\n        });\r\n        // 签名方法中使用的 key 是驼峰\r\n        signParams = camelcaseKeys(signParams, { deep: true });\r\n        // 计算签名\r\n        const signData = util_1.sign(method, signParams, config);\r\n        // 格式化 url\r\n        const { url, execParams } = this.formatUrl(config.gateway, signData);\r\n        infoLog && infoLog(`[AlipaySdk]start exec url: ${url}, method: ${method}, params: ${JSON.stringify(signParams)}`);\r\n        if (option.formData.getMethod() === 'get') {\r\n            return new Promise((resolve) => {\r\n                const query = Object.keys(execParams).map((key) => {\r\n                    return `${key}=${encodeURIComponent(execParams[key])}`;\r\n                });\r\n                resolve(`${url}&${query.join('&')}`);\r\n            });\r\n        }\r\n        return new Promise((resolve) => {\r\n            // 生成表单\r\n            const formName = `alipaySDKSubmit${Date.now()}`;\r\n            resolve(`\r\n        <form action=\"${url}\" method=\"post\" name=\"${formName}\" id=\"${formName}\">\r\n          ${Object.keys(execParams).map((key) => {\r\n                const value = String(execParams[key]).replace(/\\\"/g, '&quot;');\r\n                return `<input type=\"hidden\" name=\"${key}\" value=\"${value}\" />`;\r\n            }).join('')}\r\n        </form>\r\n        <script>document.forms[\"${formName}\"].submit();</script>\r\n      `);\r\n        });\r\n    }\r\n\r\n    /**\r\n     *\r\n     * @param originStr 开放平台返回的原始字符串\r\n     * @param responseKey xx_response 方法名 key\r\n     */\r\n    getSignStr(originStr, responseKey) {\r\n        // 待签名的字符串\r\n        let validateStr = originStr.trim();\r\n        // 找到 xxx_response 开始的位置\r\n        const startIndex = originStr.indexOf(`${responseKey}\"`);\r\n        // 找到最后一个 “\"sign\"” 字符串的位置（避免）\r\n        const lastIndex = originStr.lastIndexOf('\"sign\"');\r\n        /**\r\n         * 删除 xxx_response 及之前的字符串\r\n         * 假设原始字符串为\r\n         *  {\"xxx_response\":{\"code\":\"10000\"},\"sign\":\"jumSvxTKwn24G5sAIN\"}\r\n         * 删除后变为\r\n         *  :{\"code\":\"10000\"},\"sign\":\"jumSvxTKwn24G5sAIN\"}\r\n         */\r\n        validateStr = validateStr.substr(startIndex + responseKey.length + 1);\r\n        /**\r\n         * 删除最后一个 \"sign\" 及之后的字符串\r\n         * 删除后变为\r\n         *  :{\"code\":\"10000\"},\r\n         * {} 之间就是待验签的字符串\r\n         */\r\n        validateStr = validateStr.substr(0, lastIndex);\r\n        // 删除第一个 { 之前的任何字符\r\n        validateStr = validateStr.replace(/^[^{]*{/g, '{');\r\n        // 删除最后一个 } 之后的任何字符\r\n        validateStr = validateStr.replace(/\\}([^}]*)$/g, '}');\r\n        return validateStr;\r\n    }\r\n\r\n    /**\r\n     * @description 执行请求\r\n     * @param {string} method 调用接口方法名，比如 alipay.ebpp.bill.add\r\n     * @param {object} params 请求参数\r\n     * @param {object} params.bizContent 业务请求参数\r\n     * @param {Boolean} option 选项\r\n     * @param {Boolean} option.validateSign 是否验签\r\n     * @param {object} args.log 可选日志记录对象\r\n     * @return {Promise} 请求执行结果\r\n     */\r\n    exec(method, params = {}, option = {}) {\r\n        if (option.formData) {\r\n            if (option.formData.getFiles().length > 0) {\r\n                return this.multipartExec(method, option);\r\n            }\r\n            /**\r\n             * fromData 中不包含文件时，认为是 page 类接口（返回 form 表单）\r\n             * 比如 PC 端支付接口 alipay.trade.page.pay\r\n             */\r\n            return this.pageExec(method, option);\r\n        }\r\n        const config = this.config;\r\n        // 计算签名\r\n        const signData = util_1.sign(method, params, config);\r\n        const { url, execParams } = this.formatUrl(config.gateway, signData);\r\n        const infoLog = (option.log && is.fn(option.log.info)) ? option.log.info : null;\r\n        const errorLog = (option.log && is.fn(option.log.error)) ? option.log.error : null;\r\n        infoLog && infoLog(`[AlipaySdk]start exec, url: ${url}, method: ${method}, params:${JSON.stringify(execParams)}`);\r\n        return new Promise((resolve, reject) => {\r\n            config.urllib.request(url, {\r\n                method: 'POST',\r\n                data: execParams,\r\n                // 按 text 返回（为了验签）\r\n                dataType: 'text',\r\n                timeout: config.timeout,\r\n                headers: { 'user-agent': this.sdkVersion },\r\n            })\r\n                .then((ret) => {\r\n                    infoLog && infoLog(`[AlipaySdk]exec response: ${JSON.stringify(ret.data)}`, ret);\r\n                    if (ret.status === 200) {\r\n                        /**\r\n                         * 示例响应格式\r\n                         * {\"alipay_trade_precreate_response\":\r\n                         *  {\"code\": \"10000\",\"msg\": \"Success\",\"out_trade_no\": \"111111\",\"qr_code\": \"https:\\/\\/\"},\r\n                         *  \"sign\": \"abcde=\"\r\n                         * }\r\n                         * 或者\r\n                         * {\"error_response\":\r\n                         *  {\"code\":\"40002\",\"msg\":\"Invalid Arguments\",\"sub_code\":\"isv.code-invalid\",\"sub_msg\":\"授权码code无效\"},\r\n                         * }\r\n                         */\r\n                        const result = JSON.parse(ret.data);\r\n                        const responseKey = `${method.replace(/\\./g, '_')}_response`;\r\n                        const data = result[responseKey];\r\n                        if (data) {\r\n                            // 按字符串验签\r\n                            const validateSuccess = option.validateSign ? this.checkResponseSign(ret.data, responseKey) : true;\r\n                            if (validateSuccess) {\r\n                                resolve(config.camelcase ? camelcaseKeys(data, { deep: true }) : data);\r\n                            }\r\n                            else {\r\n                                reject({ serverResult: ret, errorMessage: '[AlipaySdk]验签失败' });\r\n                            }\r\n                        }\r\n                        reject({ serverResult: ret, errorMessage: '[AlipaySdk]HTTP 请求错误' });\r\n                    }\r\n                    reject({ serverResult: ret, errorMessage: '[AlipaySdk]HTTP 请求错误' });\r\n                })\r\n                .catch((err) => {\r\n                    err.message = '[AlipaySdk]exec error';\r\n                    errorLog && errorLog(err);\r\n                    reject(err);\r\n                });\r\n        });\r\n    }\r\n\r\n    /**\r\n     * @description 获取18位按日期和随机数拼接生成的订单号\r\n     * @return {string}\r\n     */\r\n    getOutTradeNo() {\r\n        return `${dateformat(new Date(), \"yyyymmddHHMMss\")}${Math.floor(Math.random() * (8999) + 1000)}`;\r\n    }\r\n\r\n    /**\r\n     * @description 订单预创建生成支付二维码\r\n     * @param {object} param 请求参数 \r\n     * @param {string} param.outTradeNo 商户订单号\r\n     * @param {string} param.subject 订单标题\r\n     * @param {number} param.totalAmount 订单金额\r\n     * @param {object} args.log 可选日志记录对象\r\n     * @return {Promise}\r\n     */\r\n    tradePrecreate(param, log) {\r\n        const method = 'alipay.trade.precreate';\r\n        let params = {};\r\n        let option = {};\r\n        param = camelcaseKeys(param, { deep: true });\r\n        if (param.notifyUrl) {\r\n            params.notifyUrl = param.notifyUrl;\r\n            delete param.notifyUrl;\r\n        }\r\n        params.bizContent = Object.assign(param);\r\n        option.validateSign = this.config.alipayPublicKey ? true : false;\r\n        option.log = log ? log : null;\r\n        return this.exec(method, params, option);\r\n    }\r\n\r\n    /**\r\n     * @description 手机网站支付\r\n     * @param {object} param 请求参数 \r\n     * @param {string} param.outTradeNo 商户订单号\r\n     * @param {string} param.subject 订单标题\r\n     * @param {number} param.totalAmount 订单金额\r\n     * @param {object} args.log 可选日志记录对象\r\n     * @return {Promise} 返回form表单,唤起支付宝\r\n     */\r\n    wapPay(param, log) {\r\n        const method = 'alipay.trade.wap.pay';\r\n        let option = {};\r\n        let bizContent = { productCode: 'QUICK_WAP_WAY' }\r\n        const formData = new form_1.default();\r\n        param = camelcaseKeys(param, { deep: true });\r\n        if (param.notifyUrl) {\r\n            formData.addField('notifyUrl', param.notifyUrl);\r\n            delete param.notifyUrl\r\n        }\r\n        if (param.returnUrl) {\r\n            formData.addField('returnUrl', param.returnUrl);\r\n            delete param.returnUrl\r\n        }\r\n        bizContent = Object.assign(param);\r\n        formData.addField('bizContent', bizContent);\r\n        option.log = log ? log : null\r\n        option.formData = formData\r\n        return this.exec(method, {}, option)\r\n    }\r\n\r\n    /**\r\n     * @description 订单查询 \r\n     * @param {string} outTradeNo 商户订单号\r\n     * @param {object} args.log 可选日志记录对象\r\n     * @return {Promise}\r\n     */\r\n    tradeQuery(outTradeNo, log) {\r\n        const method = 'alipay.trade.query';\r\n        let params = { bizContent: {} };\r\n        let option = {};\r\n        params.bizContent.outTradeNo = outTradeNo;\r\n        option.validateSign = this.config.alipayPublicKey ? true : false;\r\n        option.log = log ? log : null;\r\n        return this.exec(method, params, option);\r\n    }\r\n\r\n    /**\r\n     * @description 订单撤销\r\n     * @param {string} outTradeNo 商户订单号\r\n     * @param {object} args.log 可选日志记录对象\r\n     * @return {Promise}\r\n     */\r\n    tradeCancel(outTradeNo, log) {\r\n        const method = 'alipay.trade.cancel';\r\n        let params = { bizContent: {} };\r\n        let option = {};\r\n        params.bizContent.outTradeNo = outTradeNo;\r\n        option.validateSign = this.config.alipayPublicKey ? true : false;\r\n        option.log = log ? log : null;\r\n        return this.exec(method, params, option);\r\n    }\r\n\r\n    /**\r\n     * @description 订单关闭\r\n     * @param {string} outTradeNo 商户订单号\r\n     * @param {object} args.log 可选日志记录对象\r\n     * @return {Promise}\r\n     */\r\n    tradeClose(outTradeNo, log) {\r\n        const method = 'alipay.trade.close';\r\n        let params = { bizContent: {} };\r\n        let option = {};\r\n        params.bizContent.outTradeNo = outTradeNo;\r\n        option.validateSign = this.config.alipayPublicKey ? true : false;\r\n        option.log = log ? log : null;\r\n        return this.exec(method, params, option);\r\n    }\r\n\r\n    /**\r\n     * @description 订单退款\r\n     * @param {object} param 请求参数 \r\n     * @param {string} param.outTradeNo 商户订单号\r\n     * @param {string} param.outRequestNo 退款请求号,同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传。\r\n     * @param {number} param.refundAmount 退款金额\r\n     * @param {object} args.log 可选日志记录对象\r\n     * @return {Promise}\r\n     */\r\n    tradeRefund(param, log) {\r\n        const method = 'alipay.trade.refund';\r\n        let params = {};\r\n        let option = {};\r\n        param = camelcaseKeys(param, { deep: true });\r\n        param.outRequestNo = param.outRequestNo ? param.outRequestNo : param.outTradeNo;\r\n        params.bizContent = Object.assign(param);\r\n        option.validateSign = this.config.alipayPublicKey ? true : false;\r\n        option.log = log ? log : null;\r\n        return this.exec(method, params, option);\r\n    }\r\n\r\n    /**\r\n     * @description 订单退款查询\r\n     * @param {object} param 请求参数 \r\n     * @param {string} param.outTradeNo 商户订单号\r\n     * @param {string} param.outRequestNo 退款请求号,请求退款接口时，传入的退款请求号，如果在退款请求时未传入，则该值为创建交易时的外部交易号\r\n     * @param {object} args.log 可选日志记录对象\r\n     * @return {Promise}\r\n     */\r\n    tradeRefundQuery(param, log) {\r\n        const method = 'alipay.trade.fastpay.refund.query';\r\n        let params = {};\r\n        let option = {};\r\n        params.bizContent = Object.assign(param);\r\n        option.validateSign = this.config.alipayPublicKey ? true : false;\r\n        option.log = log ? log : null;\r\n        return this.exec(method, params, option);\r\n    }\r\n\r\n    /**\r\n     * @description 查询对账单下载地址\r\n     * @param {object} param 请求参数 \r\n     * @param {string} param.billType 账单类型(trade、signcustomer),trade指商户基于支付宝交易收单的业务账单,signcustomer是指基于商户支付宝余额收入及支出等    资金变动的帐务账单\r\n     * @param {string} param.billDate 账单时间：日账单格式为yyyy-MM-dd，月账单格式为yyyy-MM。\r\n     * @param {object} args.log 可选日志记录对象\r\n     * @return {Promise}\r\n     */\r\n    billDownloadUrl(param, log) {\r\n        const method = 'alipay.data.dataservice.bill.downloadurl.query';\r\n        let params = {};\r\n        let option = {};\r\n        params.bizContent = Object.assign(param);\r\n        option.validateSign = this.config.alipayPublicKey ? true : false;\r\n        option.log = log ? log : null;\r\n        return this.exec(method, params, option);\r\n    }\r\n\r\n    // 结果验签\r\n    checkResponseSign(signStr, responseKey) {\r\n        if (!this.config.alipayPublicKey || this.config.alipayPublicKey === '') {\r\n            console.warn('config.alipayPublicKey is empty');\r\n            // 支付宝公钥不存在时不做验签\r\n            return true;\r\n        }\r\n        // 带验签的参数不存在时返回失败\r\n        if (!signStr) {\r\n            return false;\r\n        }\r\n        // 根据服务端返回的结果截取需要验签的目标字符串\r\n        const validateStr = this.getSignStr(signStr, responseKey);\r\n        // 服务端返回的签名\r\n        const serverSign = JSON.parse(signStr).sign;\r\n        // 参数存在，并且是正常的结果（不包含 sub_code）时才验签\r\n        const verifier = crypto.createVerify(util_1.ALIPAY_ALGORITHM_MAPPING[this.config.signType]);\r\n        verifier.update(validateStr, 'utf8');\r\n        return verifier.verify(this.config.alipayPublicKey, serverSign, 'base64');\r\n    }\r\n\r\n    /**\r\n     * @description 通知验签\r\n     * @param postData {JSON} 服务端的消息内容\r\n     */\r\n    checkNotifySign(postData) {\r\n        const signStr = postData.sign;\r\n        const signType = postData.sign_type || 'RSA2';\r\n        if (!this.config.alipayPublicKey || !signStr) {\r\n            return false;\r\n        }\r\n        const signArgs = Object.assign({}, postData);\r\n        // 除去sign、sign_type 皆是待验签的参数。\r\n        delete signArgs.sign;\r\n        delete signArgs.sign_type;\r\n        const decodeSign = Object.keys(signArgs).sort().filter(val => val).map((key) => {\r\n            let value = signArgs[key];\r\n            if (Array.prototype.toString.call(value) !== '[object String]') {\r\n                value = JSON.stringify(value);\r\n            }\r\n            return `${key}=${decodeURIComponent(value)}`;\r\n        }).join('&');\r\n        const verifier = crypto.createVerify(util_1.ALIPAY_ALGORITHM_MAPPING[signType]);\r\n        verifier.update(decodeSign, 'utf8');\r\n        return verifier.verify(this.config.alipayPublicKey, signStr, 'base64');\r\n    }\r\n}\r\nexports.default = AlipaySdk;"]}