README
微信支付 node.js
微信支付 SDK,支持刷卡支付、公众号支付、扫码支付、APP支付、H5支付,以及优惠券,红包,企业付款,微信代扣
- 微信支付 node.js
- 开始使用
- 接口
- microPay -- 提交刷卡支付
- reverse -- 撤销订单(仅限刷卡支付)
- shortUrl -- 转换短链接(仅限刷卡支付)
- authCodeToOpenId -- 授权码查询openid
- unifiedOrder -- 统一下单
- orderQuery -- 查询订单
- closeOrder -- 关闭订单
- refund -- 申请退款
- refundQuery -- 查询退款
- downloadBill -- 下载对账单
- downloadFundFlow -- 下载资金账单
- report -- 交易保障
- batchQueryComment -- 拉取订单评价数据
- sendCoupon -- 发放代金券
- queryCouponStock -- 查询代金券批次
- queryCouponsInfo -- 查询代金券信息
- sendRedPack -- 发放普通红包
- sendGroupRedPack -- 发放裂变红包
- getHbInfo -- 查询红包记录
- transfers -- 企业付款到零钱
- getTransferInfo -- 查询企业付款到零钱
- getPublicKey -- 获取RSA加密公钥
- queryBank -- 查询企业付款银行卡
- payBank -- 企业付款银行卡
- entrustWeb -- 公众号、APP纯签约
- minaEntrustWeb -- 小程序纯签约
- h5EntrustWeb -- H5纯签约
- contractorder -- 支付中签约
- queryContract -- 查询签约关系
- papPayApply -- 申请扣款
- deleteContract -- 申请解约
- papOrderQuery -- 查询代扣支付订单
- 帮助函数
- 错误处理
- 许可证
开始使用
var Pay = require('@sigodenh/wechatpay');
var pfxContent = fs.readFileSync("<location-of-your-apiclient-cert.p12>")
var pay = new Pay(appid, mch_id, key, pfxContent);
// Callback style
pay.unifiedOrder({
body: '腾讯充值中心-QQ会员充值',
out_trade_no: '1217752501201407033233368018',
total_fee: 888,
spbill_create_ip: '8.8.8.8',
notify_url: 'https://example.com/wechatpay/notify',
trade_type: 'JSAPI',
openid: 'oUpF8uMuAJO_M2pxb1Q9zNjWeS6o'
}, function(err, result) {
if (err) return callback(err);
console.log(pay.tidyOrderResult(result));
})
// Promise style
pay.unifiedOrder({
body: '腾讯充值中心-QQ会员充值',
out_trade_no: '1217752501201407033233368018',
total_fee: 888,
spbill_create_ip: '8.8.8.8',
notify_url: 'https://example.com/wechatpay/notify',
trade_type: 'JSAPI',
openid: 'oUpF8uMuAJO_M2pxb1Q9zNjWeS6o'
}).then(function(result) {
console.log(pay.tidyOrderResult(result));
})
接口
microPay -- 提交刷卡支付
pay.microPay({
device_info: '013467007045764',
body: '深圳腾大- QQ公仔',
out_trade_no: '1217752501201407033233368018',
total_fee: 888,
spbill_create_ip: '8.8.8.8',
auth_code: '120061098828009406'
}, function(err, result) {})
reverse -- 撤销订单(仅限刷卡支付)
pay.reverse({
out_trade_no: '1217752501201407033233368018'
}, function(err, result) {})
// 或者直接传 out_trade_no 字符串
pay.reverse('1217752501201407033233368018', function(err, result) {})
shortUrl -- 转换短链接(仅限刷卡支付)
pay.shortUrl({
long_url: 'weixin://wxpay/bizpayurl?sign=XX&appid=XX&mch_id=XX&product_id=XX&time_stamp=XX&nonce_str=XX'
}, function(err, result) {})
// 或者直接传递 long_url 字符串
pay.shortUrl('weixin://wxpay/bizpayurl?sign=XX&appid=XX&mch_id=XX&product_id=XX&time_stamp=XX&nonce_str=XX', function(err, result) {})
authCodeToOpenId -- 授权码查询openid
pay.authCodeToOpenid({
auth_code: '120061098828009406'
}, function(err, result) {})
// 或者直接传递 auth_code 字符串
pay.authCodeToOpenid('120061098828009406', function(err, result) {})
unifiedOrder -- 统一下单
tidyOrderResult 可以用来处理统一下单返回结果,根据接口交易类型 (trade_type) 会生成不同的数据。
pay.unifiedOrder({
body: '腾讯充值中心-QQ会员充值',
out_trade_no: '1217752501201407033233368018',
total_fee: 888,
spbill_create_ip: '8.8.8.8',
notify_url: 'https://example.com/wechatpay/notify',
trade_type: 'JSAPI',
openid: 'oUpF8uMuAJO_M2pxb1Q9zNjWeS6o'
}, function(err, result) {
if (err) return callback(err);
console.log(pay.tidyOrderResult(result));
})
{
appId: 'wxb80e5bddb2d804f3',
timeStamp: 1526470270,
nonceStr: '6LSB219WG129E3OLD9JOT1QA5RSOTBHA',
package: 'prepay_id=wx201411101639507cbf6ffd8b0779950874',
signType: 'MD5',
paySign: 'B8EE9BEF040D445275AE937CB93DAA8B'
}
pay.unifiedOrder({
body: '腾讯充值中心-QQ会员充值',
out_trade_no: '1217752501201407033233368018',
total_fee: 888,
spbill_create_ip: '8.8.8.8',
notify_url: 'https://example.com/wechatpay/notify',
product_id: '1324',
trade_type: 'NATIVE'
}, function(err, result) {
if (err) return callback(err);
console.log(pay.tidyOrderResult(result));
})
{ code_url: 'weixin://wxpay/s/An4baqw' }
pay.unifiedOrder({
body: '腾讯充值中心-QQ会员充值',
out_trade_no: '1217752501201407033233368018',
total_fee: 888,
spbill_create_ip: '8.8.8.8',
notify_url: 'https://example.com/wechatpay/notify',
trade_type: 'APP'
}, function(err, result) {
if (err) return callback(err);
console.log(pay.tidyOrderResult(result));
})
{
appid: 'wxb80e5bddb2d804f3',
partnerid: '1424712502',
prepayid: 'wx201411101639507cbf6ffd8b0779950874',
package: 'Sign=WXPay',
noncestr: '6LSB219WG129E3OLD9JOT1QA5RSOTBHA',
timestamp: 1526470270,
sign: '4B9580464280084A33C31546F65CAC9F'
}
pay.unifiedOrder({
body: '腾讯充值中心-QQ会员充值',
out_trade_no: '1217752501201407033233368018',
total_fee: 888,
spbill_create_ip: '8.8.8.8',
notify_url: 'https://example.com/wechatpay/notify',
trade_type: 'MWEB',
scene_info: '{"store_info":{"id":"SZTX001","name":"腾大餐厅","area_code":"440305","address":"科技园中一路腾讯大厦"}}'
}, function(err, result) {
if (err) return callback(err);
console.log(pay.tidyOrderResult(result));
})
{ mweb_url: 'https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx2016121516420242444321ca0631331346&package=1405458241' }
orderQuery -- 查询订单
pay.orderQuery({
out_trade_no: '120061098828009406'
}, function(err, result) {})
// 或者直接传递 out_trade_no 字符串
pay.orderQuery('120061098828009406', function(err, result) {})
closeOrder -- 关闭订单
pay.closeOrder({
out_trade_no: '120061098828009406'
}, function(err, result) {})
// 或者直接传递 out_trade_no 字符串
pay.closeOrder('120061098828009406', function(err, result) {})
refund -- 申请退款
pay.refund({
out_trade_no: '1217752501201407033233368018',
out_refund_no: '1217752501201407033233368019',
total_fee: 100,
refund_fee: 80
}, function(err, result) {})
refundQuery -- 查询退款
pay.refundQuery({
out_trade_no: '120061098828009406'
}, function(err, result) {})
// 或者直接传递 out_trade_no 字符串
pay.refundQuery('120061098828009406', function(err, result) {})
downloadBill -- 下载对账单
pay.downloadBill({
bill_date: '20140603',
bill_type: 'ALL'
}, function(err, result) {})
downloadFundFlow -- 下载资金账单
pay.downloadFundFlow({
bill_date: '20140603',
account_type: 'Basic',
}, function(err, result) {})
report -- 交易保障
pay.report({
interface_url: 'https://api.mch.weixin.qq.com/pay/unifiedorder',
execute_time: 1000,
return_code: 'SUCCESS',
result_code: 'SUCCESS',
user_ip: '8.8.8.8'
}, function(err, result) {})
batchQueryComment -- 拉取订单评价数据
pay.batchQueryComment({
begin_time: '20170724000000',
end_time: '20170725000000',
offset: 0,
}, function(err, result) {})
sendCoupon -- 发放代金券
pay.sendCoupon({
coupon_stock_id: '1757',
openid_count: 1,
partner_trade_no: '1000009820141203515766',
openid: 'onqOjjrXT-776SpHnfexGm1_P7iE'
}, function(err, result) {})
queryCouponStock -- 查询代金券批次
pay.queryCouponStock({
coupon_stock_id: '1757'
}, function(err, result) {})
// 或者直接传递 coupon_stock_id 字符串
pay.queryCouponStock('1757', function(err, result) {})
queryCouponsInfo -- 查询代金券信息
pay.queryCouponsInfo({
coupon_id: '1565',
openid: 'onqOjjrXT-776SpHnfexGm1_P7iE',
stock_id: '58818'
}, function(err, result) {})
sendRedPack -- 发放普通红包
pay.sendRedPack({
mch_billno: '10000098201411111234567890',
send_name: '天虹百货',
re_openid: 'oxTWIuGaIt6gTKsQRLau2M0yL16E',
total_amount: 1000,
total_num: 1,
wishing: '红包祝福语',
client_ip: '192.168.0.1',
act_name: '猜灯谜抢红包活动',
remark: '猜越多得越多,快来抢!'
}, function(err, result) {})
sendGroupRedPack -- 发放裂变红包
pay.sendGroupredPack({
mch_billno: '10000098201411111234567890',
send_name: '天虹百货',
re_openid: 'oxTWIuGaIt6gTKsQRLau2M0yL16E',
total_amount: 1000,
total_num: 1,
wishing: '红包祝福语',
client_ip: '192.168.0.1',
act_name: '猜灯谜抢红包活动',
remark: '猜越多得越多,快来抢!'
}, function(err, result) {})
getHbInfo -- 查询红包记录
pay.getHbInfo({
mch_billno: '10000098201411111234567890'
}, function(err, result) {})
// 或者直接传递 mch_billno 字符串
pay.getHbInfo('10000098201411111234567890', function(err, result) {})
transfers -- 企业付款到零钱
pay.transfers({
partner_trade_no: '10000098201411111234567890',
openid: 'oxTWIuGaIt6gTKsQRLau2M0yL16E',
check_name: 'FORCE_CHECK',
amount: 10099,
desc: '理赔',
spbill_create_ip: ' 192.168.0.1'
}, function(err, result) {})
getTransferInfo -- 查询企业付款到零钱
pay.getTransferInfo({
partner_trade_no: '10000098201411111234567890'
}, function(err, result) {})
// 或者直接传递 partner_trade_no 字符串
pay.getTransferInfo('10000098201411111234567890', function(err, result) {})
getPublicKey -- 获取RSA加密公钥
pay.getPublicKey(function(err, result) {})
queryBank -- 查询企业付款银行卡
pay.queryBank({
partner_trade_no: '1212121221227'
}, function(err, result) {})
// 或者直接传递 partner_trade_no 字符串
pay.queryBank('1212121221227', function(err, result) {})
payBank -- 企业付款银行卡
该接口使用前需要调用 pay.setBankRSA
设置 rsa 证书, 证书通过接口 pay.getpublickey
获得。
pay.setBankRSA(rsa);
pay.payBank({
partner_trade_no: '1212121221227',
enc_bank_no: '6225760017946512',
enc_true_name: '王小王',
bank_code: '1001',
amount: 100
}, function(err, result) {})
entrustWeb -- 公众号、APP纯签约
let url = pay.entrustWeb({
plan_id: '12535',
contract_code: '100000',
request_serial: 1000,
contract_display_account: '微信代扣',
notify_url: 'https://example.com/wechatpay/papcontract/notify'
});
console.log(url);
// https://api.mch.weixin.qq.com/papay/entrustweb?appid=wx426a3015555a46be&contract_code=122&contract_display_account=name1&mch_id=1223816102¬ify_url=www.qq.com%2Ftest%2Fpapay&plan_id=106&request_serial=123×tamp=1414488825&version=1.0&sign=FF1A406564EE701064450CA2149E2514
minaEntrustWeb -- 小程序纯签约
let extraData = pay.entrustWeb({
plan_id: '106',
contract_code: '122',
request_serial: 123,
contract_display_account: '张三',
notify_url: 'https://www.qq.com/test/papay'
});
console.log(extraData);
{
appid:'wx426a3015555a46be',
contract_code:'122',
contract_display_account:'张三',
mch_id:'1223816102',
notify_url:'https://www.qq.com/test/papay',
plan_id:'106',
request_serial:123,
timestamp:1414488825,
sign:'FF1A406564EE701064450CA2149E2514'
}
h5EntrustWeb -- H5纯签约
pay.h5EntrustWeb({
plan_id: '12535',
contract_code: '100000',
request_serial: 1000,
contract_display_account: '微信代扣',
notify_url: 'https://example.com/wechatpay/papcontract/notify',
clientip: '102.142.132.12'
}, function(err, result) {})
contractorder -- 支付中签约
pay.contractOrder({
trade_type: 'JSAPI', // 可选值 JSAPI,NATIVE,APP,MWEB
contract_mchid: '1223816102',
contract_appid: 'wx426a3015555a46be',
out_trade_no: '1217752501201407033233368018',
body: '腾讯充值中心-QQ会员充值',
notify_url: 'https://example.com/wechatpay/notify',
total_fee: 888,
spbill_create_ip: '8.8.8.8',
plan_id: 12535,
contract_code: '100000',
request_serial: 1000,
contract_display_account: '微信代扣',
contract_notify_url: 'https://example.com/wechatpay/pap/notify',
}, function(err, result) {
// 返回值的处理类似 unifiedOrder
});
queryContract -- 查询签约关系
// 通过 contract_id 查询
pay.queryContract('100005698', function(err, result) {})
pay.queryContract({
contract_id: '100005698'
}, function(err, result) {})
// 通过 plan_id + contract_code 查询
pay.queryContract({
plan_id: 123,
contract_code: '1023658866'
}, function(err, result) {})
papPayApply -- 申请扣款
pay.papPayApply({
body: '水电代扣',
out_trade_no: '1217752501201407033233368018',
total_fee: 888,
spbill_create_ip: '8.8.8.8',
notify_url: 'https://example.com/wechatpay/pap/notify',
contract_id: 'Wx15463511252015071056489715'
}, function(err, result) {})
deleteContract -- 申请解约
// 通过 contract_id 解约
pay.deleteContract({
contract_id: 'Wx15463511252015071056489715',
contract_termination_remark: '解约原因'
}, function(err, result) {})
// 通过 plan_id + contract_code 解约
pay.deleteContract({
plan_id: 123,
contract_code: '1023658866'
contract_termination_remark: '解约原因'
}, function(err, result) {})
papOrderQuery -- 查询代扣支付订单
// 通过 out_trade_no 查询
pay.papOrderQuery({
out_trade_no: '20150806125346'
}, function(err, result) {})
pay.papOrderQuery('20150806125346', function(err, result) {})
// 通过 transaction_id 查询
pay.papOrderQuery({
transaction_id: '1009660380201506130728806387'
}, function(err, result) {})
帮助函数
Pay.helper.nonceStr -- 生成随机字符串
Pay.helper.nonceStr() # KB29VVVPR2zJWPTqO7Kisr18CMOuCvu8
Pay.helper.nonceStr() # VLCoEJ70B68R3P8pRo82klegXSmavq3x
Pay.helper.toXML -- JS转XML
var obj = {
mch_id: '1900000109',
partner_trade_no: '1212121221227',
nonce_str: '5K8264ILTKCH16CQ2502SI8ZNMTM67Vs',
sign: 'C380BEC2BFD727A4B6845133519F3AD6'
}
var result = [
'<xml>',
' <mch_id>1900000109</mch_id>',
' <partner_trade_no>1212121221227</partner_trade_no>',
' <nonce_str>5K8264ILTKCH16CQ2502SI8ZNMTM67Vs</nonce_str>',
' <sign>C380BEC2BFD727A4B6845133519F3AD6</sign>',
'</xml>',
].join('\n');
Pay.helper.toXML(obj) === result;
Pay.helper.fromXML -- XML转JS
var xml = [
'<xml>',
' <mch_id>1900000109</mch_id>',
' <partner_trade_no>1212121221227</partner_trade_no>',
' <nonce_str>5K8264ILTKCH16CQ2502SI8ZNMTM67Vs</nonce_str>',
' <sign>C380BEC2BFD727A4B6845133519F3AD6</sign>',
'</xml>',
].join('\n');
var result = {
mch_id: '1900000109',
partner_trade_no: '1212121221227',
nonce_str: '5K8264ILTKCH16CQ2502SI8ZNMTM67Vs',
sign: 'C380BEC2BFD727A4B6845133519F3AD6'
};
Pay.helper.fromXML(xml, function(err, obj) {
equal(obj, result);
}) ;
Pay.helper.sign -- 签名
var obj = { a: 3, b: 4 };
Pay.helper.sign('MD5', obj, 'abc') === '85566166DABF8B84307C0AF0A7699366'
Pay.helper.sign('HMAC-SHA256', obj, 'abc') === 'AAF907CA1B2239E0187A4BD73331DCD840F84748C6905B7FD857688BED84ACF7'
Pay.helper.aes256Decode -- 用于退款通知数据 req_info 的解码
var data = '/Pe2X0sgRcndZWNJQQmcPw==';
var key = '6Q9VX4N3WTBM9G9XBL7H1L9PB9ANHLY8'
Pay.helper.aes256Decode(key, data) === '{"a":3}'
错误处理
在回调的Error上的以name做了区分,有需要可以拿来做判断
pay.unifiedOrder({
body: '腾讯充值中心-QQ会员充值',
out_trade_no: '1217752501201407033233368018',
total_fee: 888,
...
}, function(err, result) {
if (err) {
switch (err.name) {
case 'ArgumentError':
// 参数错误, 缺失参数或参数不合法
case 'RequestError':
//请求错误, 请求无法抛出
case 'XMLParseError':
// 响应XML解析错误,无法解析响应XML数据
case 'ProtocolError':
// 协议错误,return_code 为 FAIL 时抛出
case 'BusinessError':
// 业务错误,result_code 为 FAIL 时抛出
}
return result;
})