0.0.4 • Published 4 years ago

cpay v0.0.4

Weekly downloads
3
License
ISC
Repository
github
Last release
4 years ago

Build Status GitHub license codecov NPM Version

微信/支付宝支付 For Typescript Express

使用Typescript语法开发基于Express框架的支付组件

功能微信(基于公众/商户号)微信(基于开放平台)支付宝
微信付款码支付 支付宝付款码支付微信开放平台不支持
微信扫码支付1 微信扫码支付2微信开放平台不支持
微信H5支付 支付宝H5支付微信开放平台不支持
微信JSAPI支付微信开放平台不支持
微信小程序支付微信开放平台不支持
微信APP支付微信开放平台不支持
刷脸支付微信开放平台不支持
微信支付结果通知微信开放平台不支持
微信查询订单微信开放平台不支持
微信撤销订单微信开放平台不支持
微信申请退款微信开放平台不支持
微信查询退款微信开放平台不支持
微信短链接生成微信开放平台不支持
微信网页授权
微信JSSDK
微信红包微信开放平台不支持
微信零钱转账微信开放平台不支持

安装

$ npm i cpay 

使用

import cPay from 'cpay';

Express简单架构

const Express = require('express'),
    bodyParser = require('body-parser'),
    app = new Express(),
    xmlparser = require('express-xml-bodyparser');

app.use(bodyParser.json({ limit: "500000kb" }));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(xmlparser());

配置

微信支付参数设置

// 微信支付配置对象
let weixin = new cPay.Model.WeixinConfig();
weixin.AppID = '微信公众号APPID';
weixin.AppSecret = '微信公众号AppSecret';
weixin.Key = '商户KEY';
weixin.MchID = '商户号';
weixin.Redirect_uri = '微信授权获取微信信息回调地址';
weixin.NotifyUrl = "微信支付回调通知结果地址";
weixin.SSlCertPath = `证书路径`;
weixin.SSlCertPassword = "证书密码";
weixin.Ip = "服务器IP";
weixin.Facid = "商户业务编号";
weixin.OpenAppid = "开放平台APPID";
weixin.OpenAppsecret = "开放平台密钥";
weixin.OpenAesKey = "开放平台消息加解密KEY";
// 启用配置对象,实例化即可启用
new cPay.Config.WeixinPayConfig(weixin);

支付宝支付参数设置

// 支付宝支付配置对象
let alipay = new cPay.Model.AlipayConfig();
alipay.AppID = "支付宝应用ID";
alipay.PrivateKey = "支付宝私钥";
alipay.AesKey = "支付宝AES密钥";
alipay.Notify_url = "支付宝通知地址";
new cPay.Config.AlipayPayConfig(alipay);

Redis配置

// 启用配置对象,实例化即可启用
new cPay.Config.RedisConfig("Redis地址", "端口", "库编号");

MySql配置

建库建表脚本

// 启用配置对象,实例化即可启用
new cPay.Config.MySqlConfig("数据库实例地址", "登录帐号","密码", "cPay");

API

支付宝支付

支付宝付款码支付

let microPay = new cPay.AliPay.MicroPay();
//条码支付,取值:bar_code
//声波支付,取值:wave_code
let data = await microPay.UnifiedOrder("订单号", "bar_code", "付款码", "备注");

支付宝H5支付

let h5pay = new cPay.AliPay.WapPay();
let data = await h5pay.UnifiedOrder("订单号", "应用回调地址", "订单总金额,单位:元", "标题", "销售产品码,商家和支付宝签约的产品码");

微信支付

付款码支付

// 使用付款码支付API实例
let microPay = new cPay.MicroPay();
// 创建商品信息
microPay.orderInfo = new cPay.Model.OrderInfo();
microPay.orderInfo.body = "商品描述";
microPay.orderInfo.total_fee = "总金额,数字类型,单位分";
microPay.orderInfo.attach = "附加数据";
microPay.orderInfo.detail = "商品详情";
microPay.orderInfo.goods_tag = "商品标记";
let data = await microPay.Scan("商户订单号", "用户付款码","其他可选参数,JSON对象");

扫码支付,模式1

// 使用扫码支付API
let nativepay = new cPay.NativePay();
nativepay.orderInfo = new cPay.Model.OrderInfo();
nativepay.orderInfo.body = "商品描述";
nativepay.orderInfo.total_fee = "总金额,数字类型,单位分";
nativepay.orderInfo.attach = "附加数据";
nativepay.orderInfo.detail = "商品详情";
nativepay.orderInfo.goods_tag = "商品标记";
// 扫码模式1 API
let url = await nativepay.GetPrePayUrl("商品ID");

扫码支付,模式2

// 使用扫码支付API
let nativepay = new cPay.NativePay();
nativepay.orderInfo = new cPay.Model.OrderInfo();
nativepay.orderInfo.body = "商品描述";
nativepay.orderInfo.total_fee = "总金额,数字类型,单位分";
nativepay.orderInfo.attach = "附加数据";
nativepay.orderInfo.detail = "商品详情";
nativepay.orderInfo.goods_tag = "商品标记";
// 扫码模式2 API
let url = await nativepay.GetPayUrl("商品ID","其他可选参数,JSON对象");

H5支付

// 使用H5支付API
let h5pay = new cPay.H5Pay(),
scene = new cPay.Model.SceneInfo("场景类型", "WAP网站URL地址", "WAP 网站名");
h5pay.orderInfo = new cPay.Model.OrderInfo();
h5pay.orderInfo.body = "商品描述";
h5pay.orderInfo.total_fee = "总金额,数字类型,单位分";
h5pay.orderInfo.attach = "附加数据";
h5pay.orderInfo.detail = "商品详情";
h5pay.orderInfo.goods_tag = "商品标记";
// H5支付统一下单API
let res_order = await h5pay.UnifiedOrder("商户订单号", scene, "应用回调地址","其他可选参数,JSON对象");

JSAPI支付

// 服务端
app.post('/jspay', async function (req: any, res: any, next: any) {
    // 使用JSAPI 支付
    let ojsapipay = new cPay.JsApiPay(req, res, next);
    ojsapipay.orderInfo = new cPay.Model.OrderInfo("商品描述", "商品描述", "附加数据", "商品标记", "总金额,数字类型,单位分");
    // JSAPI统一下单API
    let res_order = await ojsapipay.UnifiedOrder("微信用户openid","其他可选参数,JSON对象");
    // 获取前端支付参数
    let paramter = ojsapipay.GetJsApiPayParameters();
    res.send(paramter);

});


// 客户端
function onBridgeReady(){
   WeixinJSBridge.invoke(
      'getBrandWCPayRequest', paramter,
      function(res){
      if(res.err_msg == "get_brand_wcpay_request:ok" ){
        //使用以上方式判断前端返回,微信团队郑重提示:
        //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
      } 
   }); 
}
if (typeof WeixinJSBridge == "undefined"){
   if( document.addEventListener ){
       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
   }else if (document.attachEvent){
       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
   }
}else{
   onBridgeReady();
}

小程序支付

// 服务端
app.post('/wxapay', async function (req: any, res: any, next: any) {
    // 使用小程序支付API
    let wxaPay = new cPay.WxaPay();
    wxaPay.orderInfo = new cPay.Model.OrderInfo();
    wxaPay.orderInfo.body = "商品描述";
    wxaPay.orderInfo.total_fee = "总金额,数字类型,单位分";
    wxaPay.orderInfo.attach = "附加数据";
    wxaPay.orderInfo.detail = "商品详情";
    wxaPay.orderInfo.goods_tag = "商品标记";
    let data = await wxaPay.UnifiedOrder("商户订单号", "微信用户openid","其他可选参数,JSON对象");
    let parameters = wxaPay.GetWxaApiPayParameters();
    res.send(parameters);
});

// 客户端
wx.requestPayment(
{
    ...parameters,
    'success':function(res){},
    'fail':function(res){},
    'complete':function(res){}
})

APP支付

// 服务端
app.post('/wxapay', async function (req: any, res: any, next: any) {
    // 使用APP支付API
    let appPay = new cPay.AppPay();
    appPay.orderInfo = new cPay.Model.OrderInfo();
    appPay.orderInfo.body = "商品描述";
    appPay.orderInfo.total_fee = "总金额,数字类型,单位分";
    appPay.orderInfo.attach = "附加数据";
    appPay.orderInfo.detail = "商品详情";
    appPay.orderInfo.goods_tag = "商品标记";
    let data = await appPay.UnifiedOrder("商户订单号","其他可选参数,JSON对象"),
        parameters = appPay.GetAppApiPayParameters();
    res.send(parameters);
});

微信现金红包

app.get('/sendredpack', async function (req: any, res: any, next: any) {
    let redpack = new cPay.SendRedpack(), 
        redinfo = new cPay.Model.RedPackInfo();
    redinfo.act_name = "活动名称";
    redinfo.openid = "微信OPENID";
    redinfo.remark = "备注";
    redinfo.send_name = "商户名称";
    redinfo.total_amount = "金额,单位:分";
    redinfo.scene_id = "场景类型,举例:cPay.Model.RedPackSceneEnum.Draw";
    redinfo.wishing = "祝福语,如:感谢您参加猜灯谜活动,祝您元宵节快乐!";
    let data = await redpack.Send(redinfo);
});

微信零钱转账

app.get('/transfer', async function (req: any, res: any, next: any) {
    let redpack = new cPay.SendRedpack();
    let data = await redpack.Transfer("微信用户OPENID","金额,单位:分","描述");
});

微信支付结果通知

通用支付结果推送地址

app.post('/notice', async function (req: any, res: any, next: any) {
    let notify = new cPay.Notify.CommonlyNotify(req, res, next);
    await notify.ProcessNotify();
});

扫码支付模式1支付结果推送地址

app.post('/notice/native', async function (req: any, res: any, next: any) {
    let notify = new cPay.Notify.NativeNotify(req, res, next);
    await notify.ProcessNotify();
});

微信支付基础API

查询订单

let paydata = new cPay.Model.WxPayData(), orderinfo;
paydata.SetValue("out_trade_no", "商户订单号");
orderinfo = await cPay.BaseApi.OrderQuery(paydata);

撤销订单

let paydata = new cPay.Model.WxPayData(), orderinfo;
paydata.SetValue("out_trade_no", "商户订单号");
orderinfo = await cPay.BaseApi.CloseOrder(paydata);

申请退款

let paydata = new cPay.Model.WxPayData(), orderinfo;
paydata.SetValue("out_refund_no", "商户退款单号");
paydata.SetValue("out_trade_no", "商户订单号");
paydata.SetValue("refund_fee", "退款金额:订单总金额,单位为分,只能为整数");
paydata.SetValue("op_user_id", "操作员");
paydata.SetValue("total_fee", "订单金额:订单总金额,单位为分,只能为整数");
orderinfo = await cPay.BaseApi.Refund(paydata);

查询退款

let paydata = new cPay.Model.WxPayData(), orderinfo;
paydata.SetValue("out_refund_no", "商户退款单号");
orderinfo = await cPay.BaseApi.RefundQuery(paydata);

短链接生成

let paydata = new cPay.Model.WxPayData(), orderinfo;
paydata.SetValue("long_url", "需要转换的URL,传输需URL encode");
orderinfo = await cPay.BaseApi.ShortUrl(paydata);

公众号发起网页授权

app.get('/auth', async function (req: any, res: any, next: any) {
    let ojsapipay = new cPay.JsApiPay(req, res, next);
    await ojsapipay.GetWeixinUserInfo('网页应用回调地址', "是否是静默授权,Boolean类型");
    // 打印微信用户信息
    console.log(ojsapipay.WeixinUserInfo);
});

微信开放平台

开放平台代替公众号发起网页授权

  • 方式一:回调地址如果为当前路由地址
weixin.Redirect_uri="http://开放平台设置的域名/open/getwxinfo";
app.get('/open/getwxinfo', async function (req: any, res: any, next: any) {
    let ojsapipay = new cPay.AccountWebsiteAuth(req, res, next);
    let wxinfo = await ojsapipay.GetWeixinUserInfo("wx97e377b7691b236a");
    console.log(wxinfo);
    console.log(ojsapipay.WeixinUserInfo);
});
  • 方式二:回调地址和发起请求地址不一样
weixin.Redirect_uri="http://开放平台设置的域名/wechat/authorize-code";
app.get('/open/getwxinfo', async function (req: any, res: any, next: any) {
    let ojsapipay = new cPay.AccountWebsiteAuth(req, res, next);
    let wxinfo = await ojsapipay.GetWeixinUserInfo("wx97e377b7691b236a");
});

app.get('/wechat/authorize-code', async function (req: any, res: any, next: any) {
   let ojsapipay = new cPay.AccountWebsiteAuth(req, res, next);
    let wxinfo = await ojsapipay.GetWeixinUserInfoFromCode("wx97e377b7691b236a");
    console.log(wxinfo);
    console.log(ojsapipay.WeixinUserInfo);
});

开放平台代替公众号使用JSSDK

在申请第三方平台时填写的网页开发域名,将作为旗下授权公众号的 JS SDK 安全域名(详情见“接入前必读”-“申请资料说明”) 最多可设置三个,用“;”隔开

// 服务端
app.get('/jssdk', async function (req: any, res: any, next: any) {
    let jssdk = new cPay.JssdkSign();
    let data = await jssdk.GetJSSDK('公众号APPID','当前需要使用JSSDK的页面地址');
    // 输出参数到模版jssdk
    res.render('jssdk', { data: data });
});

关于JSSDK基于Jquery常用方法封装组件,请到NPM包微信JSSDK查看。注意!此组件不在维护,如有需要自行下载修改源码!

// 客户端
<script src="http://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

<script>
    wx.config({
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: '<%= data.appid%>', // 必填,公众号的唯一标识
        timestamp: '<%= data.timestamp %>', // 必填,生成签名的时间戳
        nonceStr: '<%= data.noncestr%>', // 必填,生成签名的随机串
        signature: '<%= data.signature%>',// 必填,签名
        jsApiList: ["scanQRCode"] // 必填,需要使用的JS接口列表
    });

    wx.ready(function () {
        // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
        console.log('OK');
    });
    wx.error(function (res) {
        // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
        console.log('error');
    });

    function Scan() {
        wx.scanQRCode({
            needResult: 0, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
            scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
            success: function (res) {
                var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
                console.log(result);
            }
        });
    }
</script>

<button onclick="Scan()" style="width: 150px; height: 40px; background-color: beige;">
    扫一扫
</button>

作者

打赏