一、参考支付宝api文档封装js
支付宝api文档参考:https://opendocs.alipay.com/apis/api_1
封装结果参考:https://blog.csdn.net/q3585914/article/details/72957548
对上面大佬的封装做了些许调整
(1) alipay.js
1 /** 2 * Created by ference on 2017/4/8. 3 */ 4 5 var fs = require('fs'); 6 var path = require('path'); 7 var utl = require('./utl'); 8 9 var alipay_gate_way = 'https://openapi.alipay.com/gateway.do'; 10 var alipay_gate_way_sandbox = 'https://openapi.alipaydev.com/gateway.do'; 11 12 module.exports = Alipay; 13 14 /** 15 * 16 * @param {Object} opts 17 * @param {String} opts.appId 支付宝的appId 18 * @param {String} opts.notifyUrl 支付宝服务器主动通知商户服务器里指定的页面http/https路径 19 * @param {String} opts.rsaPrivate 商户私钥pem文件路径 20 * @param {String} opts.rsaPublic 支付宝公钥pem文件路径 21 * @param {String} opts.signType 签名方式, 'RSA' or 'RSA2' 22 * @param {Boolean} [opts.sandbox] 是否是沙盒环境 23 * @constructor 24 */ 25 function Alipay(opts) { 26 this.appId = opts.appId; 27 this.sandbox = !!opts.sandbox; 28 this.notifyUrl = opts.notifyUrl; 29 this.signType = opts.signType; 30 31 this.rsaPrivate = fs.readFileSync(opts.rsaPrivate, 'utf-8'); 32 this.rsaPublic = fs.readFileSync(opts.rsaPublic, 'utf-8'); 33 } 34 35 var props = Alipay.prototype; 36 37 props.makeParams = function(method, biz_content) { 38 return { 39 app_id: this.appId, 40 method: method, 41 format: 'JSON', 42 charset: 'utf-8', 43 sign_type: this.signType, 44 timestamp: new Date().format('yyyy-MM-dd hh:mm:ss'), 45 version: '1.0', 46 biz_content: JSON.stringify(biz_content) 47 }; 48 }; 49 50 /** 51 * 生成支付参数供客户端使用 52 * @param {Object} opts 53 * @param {String} opts.subject 商品的标题/交易标题/订单标题/订单关键字等 54 * @param {String} [opts.body] 对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body 55 * @param {String} opts.outTradeId 商户网站唯一订单号 56 * @param {String} [opts.timeout] 设置未付款支付宝交易的超时时间,一旦超时,该笔交易就会自动被关闭。 57 当用户进入支付宝收银台页面(不包括登录页面),会触发即刻创建支付宝交易,此时开始计时。 58 取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 59 该参数数值不接受小数点, 如 1.5h,可转换为 90m。 60 * @param {String} opts.amount 订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000] 61 * @param {String} [opts.sellerId] 收款支付宝用户ID。 如果该值为空,则默认为商户签约账号对应的支付宝用户ID 62 * @param {String} opts.goodsType 商品主类型:0—虚拟类商品,1—实物类商品 注:虚拟类商品不支持使用花呗渠道 63 * @param {String} [opts.passbackParams] 公用回传参数,如果请求时传递了该参数,则返回给商户时会回传该参数。支付宝会在异步通知时将该参数原样返回。本参数必须进行UrlEncode之后才可以发送给支付宝 64 * @param {String} [opts.promoParams] 优惠参数(仅与支付宝协商后可用) 65 * @param {String} [opts.extendParams] 业务扩展参数 https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.3oJPAi&treeId=193&articleId=105465&docType=1#kzcs 66 * @param {String} [opts.enablePayChannels] 可用渠道,用户只能在指定渠道范围内支付。当有多个渠道时用“,”分隔。注:与disable_pay_channels互斥 67 * @param {String} [opts.disablePayChannels] 禁用渠道,用户不可用指定渠道支付。当有多个渠道时用“,”分隔。 注:与enable_pay_channels互斥 68 * @param {String} [opts.storeId] 商户门店编号 69 */ 70 props.pay = function (opts) { 71 72 var biz_content = { 73 body: opts.body, 74 subject: opts.subject, 75 out_trade_no: opts.outTradeId, 76 timeout_express: opts.timeout, 77 total_amount: opts.amount, 78 seller_id: opts.sellerId, 79 product_code: 'QUICK_MSECURITY_PAY', 80 goods_type: opts.goodsType, 81 passback_params: opts.passbackParams, 82 promo_params: opts.promoParams, 83 extend_params: opts.extendParams, 84 enable_pay_channels: opts.enablePayChannels, 85 disable_pay_channels: opts.disablePayChannels, 86 store_id: opts.storeId 87 }; 88 89 var params = this.makeParams('alipay.trade.app.pay', biz_content); 90 params.notify_url = this.notifyUrl; 91 92 return utl.processParams(params, this.rsaPrivate, this.signType); 93 }; 94 95 /** 96 * 生成支付参数供web端使用 97 * @param {Object} opts 98 * @param {String} opts.subject 商品的标题/交易标题/订单标题/订单关键字等 99 * @param {String} [opts.body] 对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body 100 * @param {String} opts.outTradeId 商户网站唯一订单号 101 * @param {String} [opts.timeout] 设置未付款支付宝交易的超时时间,一旦超时,该笔交易就会自动被关闭。 102 当用户进入支付宝收银台页面(不包括登录页面),会触发即刻创建支付宝交易,此时开始计时。 103 取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 104 该参数数值不接受小数点, 如 1.5h,可转换为 90m。 105 * @param {String} opts.amount 订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000] 106 * @param {String} [opts.sellerId] 收款支付宝用户ID。 如果该值为空,则默认为商户签约账号对应的支付宝用户ID 107 * @param {String} opts.goodsType 商品主类型:0—虚拟类商品,1—实物类商品 注:虚拟类商品不支持使用花呗渠道 108 * @param {String} [opts.passbackParams] 公用回传参数,如果请求时传递了该参数,则返回给商户时会回传该参数。支付宝会在异步通知时将该参数原样返回。本参数必须进行UrlEncode之后才可以发送给支付宝 109 * @param {String} [opts.promoParams] 优惠参数(仅与支付宝协商后可用) 110 * @param {String} [opts.extendParams] 业务扩展参数 https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.3oJPAi&treeId=193&articleId=105465&docType=1#kzcs 111 * @param {String} [opts.enablePayChannels] 可用渠道,用户只能在指定渠道范围内支付。当有多个渠道时用“,”分隔。注:与disable_pay_channels互斥 112 * @param {String} [opts.disablePayChannels] 禁用渠道,用户不可用指定渠道支付。当有多个渠道时用“,”分隔。 注:与enable_pay_channels互斥 113 * @param {String} [opts.storeId] 商户门店编号 114 */ 115 props.webPay = function (opts) { 116 117 var biz_content = { 118 body: opts.body, 119 subject: opts.subject, 120 out_trade_no: opts.outTradeId, 121 timeout_express: opts.timeout, 122 total_amount: opts.amount, 123 seller_id: opts.sellerId, 124 product_code: 'FAST_INSTANT_TRADE_PAY', 125 goods_type: opts.goodsType, 126 passback_params: opts.passbackParams, 127 promo_params: opts.promoParams, 128 extend_params: opts.extendParams, 129 enable_pay_channels: opts.enablePayChannels, 130 disable_pay_channels: opts.disablePayChannels, 131 store_id: opts.storeId 132 }; 133 134 // var params = this.makeParams('alipay.trade.page.pay', biz_content); // PC 135 var params = this.makeParams('alipay.trade.wap.pay', biz_content); // PHONE 136 params.notify_url = this.notifyUrl; 137 138 return utl.processParams(params, this.rsaPrivate, this.signType); 139 }; 140 141 /** 142 * 签名校验 143 * @param {Object} response 支付宝的响应报文 144 */ 145 props.signVerify = function (response) { 146 var ret = utl.copy(response); 147 var sign = ret['sign']; 148 ret.sign = undefined; 149 ret.sign_type = undefined; 150 151 var tmp = utl.encodeParams(ret); 152 return utl.signVerify(tmp.unencode, sign, this.rsaPublic, this.signType); 153 } 154 155 /** 156 * 查询交易状态 https://doc.open.alipay.com/doc2/apiDetail.htm?spm=a219a.7629065.0.0.PlTwKb&apiId=757&docType=4 157 * @param {Object} opts 158 * @param {String} [opts.outTradeId] 订单支付时传入的商户订单号,和支付宝交易号不能同时为空。 tradeId,outTradeId如果同时存在优先取tradeId 159 * @param {String} [opts.tradeId] 支付宝交易号,和商户订单号不能同时为空 160 * @param {String} [opts.appAuthToken] https://doc.open.alipay.com/doc2/detail.htm?treeId=216&articleId=105193&docType=1 161 */ 162 props.query = function (opts) { 163 164 var biz_content = { 165 out_trade_no: opts.outTradeId, 166 trade_no: opts.tradeId 167 }; 168 169 var params = { 170 app_id: this.appId, 171 method: 'alipay.trade.query', 172 format: 'JSON', 173 charset: 'utf-8', 174 sign_type: this.signType, 175 timestamp: new Date().format('yyyy-MM-dd hh:mm:ss'), 176 version: '1.0', 177 app_auth_token: opts.appAuthToken, 178 biz_content: JSON.stringify(biz_content) 179 }; 180 var params = this.makeParams('alipay.trade.query', biz_content); 181 if(this.appAuthToken) { 182 params.app_auth_token = this.appAuthToken; 183 } 184 185 var body = utl.processParams(params, this.rsaPrivate, this.signType); 186 187 return utl.request({ 188 method: 'GET', 189 url: (this.sandbox? alipay_gate_way_sandbox : alipay_gate_way) + '?' + body 190 }); 191 }; 192 193 194 /** 195 * 统一收单交易关闭接口 https://doc.open.alipay.com/doc2/apiDetail.htm?spm=a219a.7629065.0.0.6VzMcn&apiId=1058&docType=4 196 * @param {Object} opts 197 * @param {String} [opts.outTradeId] 订单支付时传入的商户订单号,和支付宝交易号不能同时为空。 tradeId,outTradeId如果同时存在优先取tradeId 198 * @param {String} [opts.tradeId] 支付宝交易号,和商户订单号不能同时为空 199 * @param {String} [opts.operatorId] 卖家端自定义的的操作员 ID 200 * @param {String} [opts.appAuthToken] https://doc.open.alipay.com/doc2/detail.htm?treeId=216&articleId=105193&docType=1 201 */ 202 props.close = function (opts) { 203 204 var biz_content = { 205 out_trade_no: opts.outTradeId, 206 trade_no: opts.tradeId, 207 operator_id: opts.operatorId 208 }; 209 210 var params = this.makeParams('alipay.trade.close', biz_content); 211 if(this.appAuthToken) { 212 params.app_auth_token = this.appAuthToken; 213 } 214 215 var body = utl.processParams(params, this.rsaPrivate, this.signType); 216 217 return utl.request({ 218 method: 'GET', 219 url: (this.sandbox? alipay_gate_way_sandbox : alipay_gate_way) + '?' + body 220 }); 221 }; 222 223 224 /** 225 * 统一收单交易退款接口 https://doc.open.alipay.com/doc2/apiDetail.htm?spm=a219a.7629065.0.0.PlTwKb&apiId=759&docType=4 226 * @param {Object} opts 227 * @param {String} [opts.outTradeId] 订单支付时传入的商户订单号,和支付宝交易号不能同时为空。 tradeId,outTradeId如果同时存在优先取tradeId 228 * @param {String} [opts.tradeId] 支付宝交易号,和商户订单号不能同时为空 229 * @param {String} [opts.operatorId] 卖家端自定义的的操作员 ID 230 * @param {String} [opts.appAuthToken] https://doc.open.alipay.com/doc2/detail.htm?treeId=216&articleId=105193&docType=1 231 * @param {String} opts.refundAmount 需要退款的金额,该金额不能大于订单金额,单位为元,支持两位小数 232 * @param {String} [opts.refundReason] 退款的原因说明 233 * @param {String} [opts.outRequestId] 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传。 234 * @param {String} [opts.storeId] 商户的门店编号 235 * @param {String} [opts.terminalId] 商户的终端编号 236 */ 237 props.refund = function (opts) { 238 239 // var biz_content = { 240 // out_trade_no: opts.outTradeId, 241 // trade_no: opts.tradeId, 242 // operator_id: opts.operatorId, 243 // refund_amount: opts.refundAmount, 244 // refund_reason: opts.refundReason, 245 // out_request_no: opts.outRequestId, 246 // store_id: opts.storeId, 247 // terminal_id: opts.terminalId 248 // }; 249 250 // var params = this.makeParams('alipay.trade.refund', biz_content); 251 // if(this.appAuthToken) { 252 // params.app_auth_token = this.appAuthToken; 253 // } 254 255 // var body = utl.processParams(params, this.rsaPrivate, this.signType); 256 257 // utl.request({ 258 // method: 'GET', 259 // url: body 260 // }).then(function (ret) { 261 // console.log("***** ret.body=" + body); 262 // }); 263 }; 264 265 266 /** 267 * 统一收单交易退款查询 https://doc.open.alipay.com/doc2/apiDetail.htm?docType=4&apiId=1049 268 * @param {Object} opts 269 * @param {String} [opts.outTradeId] 订单支付时传入的商户订单号,和支付宝交易号不能同时为空。 tradeId,outTradeId如果同时存在优先取tradeId 270 * @param {String} [opts.tradeId] 支付宝交易号,和商户订单号不能同时为空 271 * @param {String} [opts.outRequestId] 请求退款接口时,传入的退款请求号,如果在退款请求时未传入,则该值为创建交易时的外部交易号 272 * @param {String} [opts.appAuthToken] https://doc.open.alipay.com/doc2/detail.htm?treeId=216&articleId=105193&docType=1 273 */ 274 props.refundQuery = function (opts) { 275 276 var biz_content = { 277 out_trade_no: opts.outTradeId, 278 trade_no: opts.tradeId, 279 out_request_no: opts.outRequestId || opts.outTradeId 280 }; 281 282 var params = this.makeParams('alipay.trade.fastpay.refund.query', biz_content); 283 if(this.appAuthToken) { 284 params.app_auth_token = this.appAuthToken; 285 } 286 287 var body = utl.processParams(params, this.rsaPrivate, this.signType); 288 289 return utl.request({ 290 method: 'GET', 291 url: (this.sandbox? alipay_gate_way_sandbox : alipay_gate_way) + '?' + body 292 }); 293 }; 294 295 296 /** 297 * 查询对账单下载地址 https://doc.open.alipay.com/doc2/apiDetail.htm?spm=a219a.7629065.0.0.iX5mPA&apiId=1054&docType=4 298 * @param {Object} opts 299 * @param {String} [opts.billType] 账单类型,商户通过接口或商户经开放平台授权后其所属服务商通过接口可以获取以下账单类型: 300 trade、signcustomer;trade指商户基于支付宝交易收单的业务账单;signcustomer是指基于商户支付宝余额收入及支出等资金变动的帐务账单; 301 * @param {String} [opts.billDate] 账单时间:日账单格式为yyyy-MM-dd,月账单格式为yyyy-MM。 302 * @param {String} [opts.appAuthToken] https://doc.open.alipay.com/doc2/detail.htm?treeId=216&articleId=105193&docType=1 303 */ 304 props.billDownloadUrlQuery = function (opts) { 305 306 var biz_content = { 307 bill_type: opts.billType, 308 bill_date: opts.billDate 309 }; 310 311 var params = this.makeParams('alipay.data.dataservice.bill.downloadurl.query', biz_content); 312 if(this.appAuthToken) { 313 params.app_auth_token = this.appAuthToken; 314 } 315 316 var body = utl.processParams(params, this.rsaPrivate, this.signType); 317 318 return utl.request({ 319 method: 'GET', 320 url: (this.sandbox? alipay_gate_way_sandbox : alipay_gate_way) + '?' + body 321 }); 322 };