Git Product home page Git Product logo

wechat-pay-v3-sdk's Introduction

npm package

微信支付 V3SDK

  • 🛠️ 极易扩展

  • 🛠️ typescript 编写且类型完备

  • 🛠️ 自动更新平台证书

  • 🛠️ 支持直连商户体系和服务商体系

  • 🛠️ hook 请求过程

安装

项目使用了 node 自身的 crypto,请确保运行的版本大于 15.6

npm install wechat-pay-v3

说明

sdk 公开工具函数,基础类和功能类。工具函数针对应用场景代码封装,基础类是 sdk 的核心,功能类为具体的功能实现。实现的功能类列表可在下方表格中查看。

base 类提供了验签方法resVerify,但并没有给功能方法添加自动验签。除了封装的 handleCallback 方法,其他情况下您可以通过 hook 的方式在 onResponse 中进行验签,下方有实例代码。

大多数情况下,提供的方法对于加密参数都是自动的,部分过于复杂的接口,在 JSDOC 提示中会有 notAutoEncrypt 标注。

使用

hook

请求流程:[onRequsetBefore] -> [sdkWork] -> [onRequsetAfter] -> [onResponse]

hook 方法传递的参数都是原始引用,请注意不要轻易修改,除非你知道你在做什么。

sdkWork:为请求的核心逻辑,在这个阶段会对参数进行加密,签名,更新证书等操作。

apiContainer(
  {
    /* config */
  },
  {
    onRequsetBefore(config, instance) {
      console.log(config)
    },
    onRequsetAfter(config, instance) {
      console.log(config)
    },
    onResponse(res, instance) {
      console.log(res)
      //如果需要验签
      const verifyResult = instance.resVerify(res.headers, res.data)

      //部分接口是不需要验签的,不要轻易直接抛错
      //您可以将验签结果加入 res.data 中,大多数方法返回res.data
      res.data.verifyResult = result
    },
  },
)

//or

const base = new WechatPayV3Base(
  {
    /* config */
  },
  {
    /* hooks */
  },
)

调用方式

调用方式有两种,一种通过封装的容器调用,一种通过类调用。容器实现默认单例(容器调用的类均单例)和自动的依赖注入。 容器函数为apiContainer

import { apiContainer, ContainerOptions, Applyment } from 'wechat-pay-v3'
const Config: ContainerOptions = {
  //证书
  apiclient_cret: readFileSync('/xx/apiclient_cret.pem'),
  //证书密钥
  apiclient_key: readFileSync('/xx/apiclient_key.pem'),
  //后台配置的key
  apiV3Key: 'APIv3密钥',
  //商户号
  mchid: '商户号',
  //默认单例模式,开启后同个商户号只会返回一个实例。
  singleton: true,
  //可选:默认系统的tmp目录
  downloadDir: './tmpDownlond',
  //可选: 默认true。开启后会缓存证书12小时,12小时后惰性更新证书
  autoUpdateCertificates: true,
  //可选,默认'wechatpay-sdk'
  userAgent: 'wechatpay-nodejs-sdk/1.0.0',
}
//1 容器获取示例
const applyment = apiContainer(Config).use(Applyment)
//2 类直接new就好,不过请自行管理实例避免重复创建造成性能浪费
const applyment = new Applyment(new WechatPayV3Base(Config))
//Applyment 为特约商户的功能类
//上方两种方式都可以拿到 applyment 实例
//例如调用提交特约商户申请接口
applyment.submitApplications()

已实现功能

功能 官方链接 库名 服务商 直连商户
核心类 加解密,管理证书,扩展功能使用的基础类 WechatPayV3Base
特约商户 link Applyment
基础支付 因除合单支付外,其余方式仅下单不同,BasePay 为支付基类 BasePay
JSAPI 支付 link JSPay
小程序支付 link MiniProgramPay
APP 支付 link AppPay
H5 支付 link H5Pay
Native 支付 link NativePay

sdk 满足大多数情况下的基本支付功能.扩展其余功能请参考扩展功能类

TODO

  • 国密支持

核心类

  • hook 事件 setEvents
  • 证书相关
    • 获取证书 getCertificates
    • 更新证书 updateCertificates
  • 请求相关
    • 请求实例 request
    • 下载文件 downloadFile
    • 上传图片 uploadImage
    • 上传视频 uploadVideo
  • 加解密
    • 公钥加密 publicEncrypt
    • 公钥加密(批量) publicEncryptObjectPaths
    • AESGCM 解密 aesGcmDecrypt
    • SHA256 签名 sha256WithRSA
    • SHA256 验签 sha256WithRsaVerify
  • 常用封装
    • 响应验签 resVerify
    • 回调处理 handleCallback

示例代码

下单接口示例

const router = Router()
const appId = '小程序appid'
const wxpay = router.post('/pay/order', async (req, res, next) => {
  try {
    const miniPay = apiContainer({
      /* xxx */
    }).use(MiniProgramPay)
    const { prepay_id } = await miniPay.order({
      /* xxx */
    })
    //获取小程序支付参数
    const payParams = miniPay.getPayParams({
      appId,
      prepay_id,
    })
    /* 小程序可以调起支付直接传入payParams即可 */
    res.send(payParams)
  } catch (e) {
    next(e)
  }
})

通知接收

base 实例上封装了通用的 handleCallback,他的功能是进行回调验签,通过后返回的 resource 对象会自动解密。

import { apiContainer } from 'wechat-pay-v3'

//假定这里是一个接口
router.post('/notify', async (req, res) => {
  try {
    const wxapi = apiContainer({
      /* xxx */
    })
    //handleCallback接收两个参数,第一个是请求头,第二个是请求体。
    //实际并不一定是这样的,请根据实际情况调整。
    const data = await wxapi.handleCallback(req.headers, req.body)
    res.status(204).send()
  } catch (e) {
    res.status(400).send({
      message: e.message,
      code: 'FAIL',
    })
  }
})

封装 sdk 的目的是解决现有项目的需求,所以优先保证的是架构的扩展性,而非接口完整。

当你遇到 sdk 未提供的接口时,可以注入 WechatPayV3Base 实例来完成。

import { WechatPayV3Base } from 'wechat-pay-v3'

class Others {
  //将WechatPayV3Base实例作为依赖
  constructor(public base: WechatPayV3Base) {}

  async test() {
    //调用base的request进行请求.自动签名满足大多数情况下的请求.
    //如果签名串并非data对象的内容,请自行计算
    //可以参照源码中_upload的实现
    return this.base.request({
      url: 'https://xxx.xxx.xxx/xxx', //需要为完整的url而非接口路径
      method: 'GET',
    })
  }
}

const baseIns = new WechatPayV3Base({
  /* xxx */
})
const others = new Others(baseIns)
//直接调用
others.test()
//或者通过容器调用
apiContainer({
  /* xxx */
})
  .use(Others)
  .test()

贡献须知

  • 类型和 JSDOC 完整

wechat-pay-v3-sdk's People

Contributors

wwog avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.