{"_id":"@afyercu/nest-wechat","name":"@afyercu/nest-wechat","dist-tags":{"latest":"0.2.51"},"versions":{"0.2.51":{"name":"@afyercu/nest-wechat","version":"0.2.51","description":"nestjs module for wechat server-side api.","scripts":{"build":"rimraf -rf dist && tsc -p tsconfig.json","format":"prettier --write \"{lib,test}/**/*.ts\"","lint":"eslint lib/**/*.ts --fix","test":"jest","test:e2e":"jest --config ./tests/jest-e2e.json --runInBand","serve:docs":"docsify serve docs","cpdocs":"cp README.md CHANGELOG.md ./docs/","postversion":"git push --follow-tags","release:dry":"release-it patch --dry-run","release":"release-it patch","prepare":"husky install"},"repository":{"type":"git","url":"git+https://github.com/baaxl9vh/nest-wechat.git"},"keywords":["nest","nestjs","wechat"],"author":{"name":"jay"},"license":"MIT","bugs":{"url":"https://github.com/baaxl9vh/nest-wechat/issues"},"homepage":"https://baaxl9vh.github.io/nest-wechat","devDependencies":{"@commitlint/cli":"^16.0.1","@commitlint/config-conventional":"^16.0.0","@nestjs/common":"^8.2.4","@nestjs/config":"^1.1.6","@nestjs/core":"^8.2.4","@nestjs/platform-express":"^8.2.4","@nestjs/testing":"^8.2.4","@release-it/conventional-changelog":"^3.3.0","@types/cache-manager-redis-store":"^2.0.1","@types/express":"^4.17.13","@types/jest":"^27.0.3","@types/node-forge":"^1.0.2","@typescript-eslint/eslint-plugin":"^5.8.0","@typescript-eslint/parser":"^5.8.0","cache-manager":"^3.6.0","cache-manager-redis-store":"^2.0.0","cross-env":"^7.0.3","dayjs":"^1.11.9","docsify-cli":"^4.4.3","dotenv":"^10.0.0","eslint":"^8.5.0","husky":"^7.0.0","jest":"^29.4.3","prettier":"^2.5.1","reflect-metadata":"^0.1.13","release-it":"^14.11.8","rimraf":"^3.0.2","rxjs":"^7.4.0","ts-jest":"^29.0.5","typescript":"^4.5.4"},"dependencies":{"axios":"^1.3.4","fast-xml-parser":"^4.0.7","node-forge":"^1.3.1","raw-body":"^2.5.1"},"engines":{"node":">=10.0.0"},"_id":"@afyercu/nest-wechat@0.2.51","gitHead":"384bb5a5721c9d6120016b93af95dc2733187be1","types":"./index.d.ts","_nodeVersion":"18.20.2","_npmVersion":"10.5.0","dist":{"integrity":"sha512-WDjfuqFMcSSMrVkpY1j8g/pKN15jpcFrcJyu2aE8eBIa/Aq2HO2xOk4AVrNM+tl61OHfsGyyIirO68AodYqC0Q==","shasum":"21d2940e274d08f2f3596c56c753a980c9d9d860","tarball":"https://registry.npmjs.org/@afyercu/nest-wechat/-/nest-wechat-0.2.51.tgz","fileCount":54,"unpackedSize":362711,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDkErMFZcy/DZ9gKM0OwjI3vsE1nWRG8eZtzNdcw0erRgIgYXg8B9pMj7TXwvrjBoIEgGWXYio2dcBPpbGG1beR9X8="}]},"_npmUser":{"name":"afyercu","email":"20569838@qq.com"},"directories":{},"maintainers":[{"name":"afyercu","email":"20569838@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nest-wechat_0.2.51_1731829412260_0.47790618809070873"},"_hasShrinkwrap":false}},"time":{"created":"2024-11-17T07:43:32.166Z","0.2.51":"2024-11-17T07:43:32.460Z","modified":"2024-11-17T07:43:32.707Z"},"maintainers":[{"name":"afyercu","email":"20569838@qq.com"}],"description":"nestjs module for wechat server-side api.","homepage":"https://baaxl9vh.github.io/nest-wechat","keywords":["nest","nestjs","wechat"],"repository":{"type":"git","url":"git+https://github.com/baaxl9vh/nest-wechat.git"},"author":{"name":"jay"},"bugs":{"url":"https://github.com/baaxl9vh/nest-wechat/issues"},"license":"MIT","readme":"<div>\r\n  <div align='center'>\r\n    <h1>nest-wechat</h1>\r\n  </div>\r\n  <div>\r\n    <p>微信公众号、微信程序开、微信小游戏、微信支付以及企业微信等服务端API nestjs 模块封装。也可以直接当工具类使用。</p>\r\n    <p>nest-wechat是自用业务的封装，如果你需要用到的api还没有，可以提 <a href='https://github.com/baaxl9vh/nest-wechat/issues'>issues</a> 给我，我会尽快补上。</p>\r\n    <div align='center'>\r\n      <br />\r\n      <sub><a href='https://baaxl9vh.github.io/nest-wechat/'>中文文档<a/></sub>\r\n    </div>\r\n  </div>\r\n  <br />\r\n</div>\r\n\r\n## 快速开始\r\n\r\n### 安装\r\n\r\n```shell\r\nnpm i --save nest-wechat\r\n```\r\n\r\n### nestjs 模块引入\r\n\r\n+ register方法注册\r\n\r\n```javascript\r\nimport { Module } from '@nestjs/common';\r\n\r\nimport { WeChatModule } from 'nest-wechat';\r\n\r\n@Module({\r\n  imports: [WeChatModule.register({appId: 'your app id', secret: 'your secret'})],\r\n})\r\nexport class AppModule {\r\n}\r\n```\r\n\r\n+ forRoot配置注册\r\n\r\n```javascript\r\nimport { CACHE_MANAGER, Module } from '@nestjs/common';\r\nimport { ConfigModule, ConfigService } from '@nestjs/config';\r\nimport { Cache } from 'cache-manager';\r\nimport { RedisCache, WeChatModule } from 'nest-wechat';\r\n\r\n@Module({\r\n  imports: [\r\n    ConfigModule.forRoot({\r\n      envFilePath: '.env.test.local',\r\n    }),\r\n    WeChatModule.forRootAsync({\r\n      imports: [ConfigModule],\r\n      inject: [ConfigService, CACHE_MANAGER],\r\n      useFactory: (configService: ConfigService, cache: Cache) => ({\r\n        appId: configService.get('WX_APPID'),\r\n        secret: configService.get('WX_SECRET'),\r\n        token: configService.get('WX_TOKEN'),\r\n        encodingAESKey: configService.get('WX_AESKEY'),\r\n        cacheAdapter: new RedisCache(cache),\r\n        debug: true,\r\n      }),\r\n    }),\r\n  ]\r\n})\r\nexport class AppModule {\r\n}\r\n```\r\n\r\n### 工具类引入\r\n\r\n```javascript\r\nimport { WeChatService } from 'nest-wechat';\r\nconst service = new WeChatService({ appId: 'your app id', secret: 'your secret'});\r\n```\r\n\r\n## 全局接口\r\n\r\n### ICache\r\n\r\n```javascript\r\n/**\r\n * 缓存接口，需要自定义缓存，请实现该接口\r\n * \r\n * cache interface, please implement this interface if you need.\r\n * \r\n */\r\nexport interface ICache {\r\n  get<T> (key: string): Promise<T>;\r\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n  set (key: string, value: any): void;\r\n  remove (key: string): boolean;\r\n  close (): void;\r\n}\r\n```\r\n\r\n## WeChatService 属性与方法\r\n\r\n### config: WeChatModuleOptions\r\n\r\n配置读写属性，类型：WeChatModuleOptions\r\n\r\n### cacheAdapter: ICache\r\n\r\n缓存适配器读写属性，类型：ICache，默认是一个Map实现的缓存\r\n\r\n## 微信公众号API\r\n\r\n### 网页授权\r\n\r\n#### getAccessTokenByCode\r\n\r\n```typescript\r\npublic async getAccessTokenByCode (code: string, _appId?: string, _secret?: string): Promise<UserAccessTokenResult>;\r\n```\r\n\r\n正确返回\r\n\r\n```json\r\n{\r\n  \"access_token\":\"ACCESS_TOKEN\",\r\n  \"expires_in\":7200,\r\n  \"refresh_token\":\"REFRESH_TOKEN\",\r\n  \"openid\":\"OPENID\",\r\n  \"scope\":\"SCOPE\" \r\n}\r\n```\r\n\r\n错误返回\r\n\r\n```json\r\n{\r\n    \"errcode\": 40029,\r\n    \"errmsg\": \"invalid code\"\r\n}\r\n```\r\n\r\n> [参考文档](https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html)\r\n\r\n#### getUserInfo\r\n\r\n公众号拉取用户信息\r\n\r\n```typescript\r\npublic async getUserInfo (accessToken: string, openid: string, lang: 'zh_CN' | 'zh_TW' | 'en' = 'zh_CN'): Promise<UserInfoResult>;\r\n```\r\n\r\n正确返回\r\n\r\n```json\r\n{   \r\n  \"openid\": \"OPENID\",\r\n  \"nickname\": NICKNAME,\r\n  \"sex\": 1,\r\n  \"province\":\"PROVINCE\",\r\n  \"city\":\"CITY\",\r\n  \"country\":\"COUNTRY\",\r\n  \"headimgurl\":\"https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46\",\r\n  \"privilege\":[ \"PRIVILEGE1\" \"PRIVILEGE2\"     ],\r\n  \"unionid\": \"o6_bmasdasdsad6_2sgVt7hMZOPfL\"\r\n}\r\n```\r\n\r\n错误返回\r\n\r\n```json\r\n{\r\n  \"errcode\":40003,\r\n  \"errmsg\":\" invalid openid \"\r\n}\r\n```\r\n\r\n### 获取Access token\r\n\r\n#### getAccountAccessToken\r\n\r\n```typescript\r\npublic async getAccountAccessToken (_appId?: string, _secret?: string): Promise<AccountAccessTokenResult>;\r\n```\r\n\r\n正确返回\r\n\r\n```json\r\n{\r\n  \"access_token\": \"52_s0Mcl3E3DBKs12rthjxG8_DOvsIC4puV9A34WQR6Bhb_30TW9W9BjhUxDRkyph-hY9Ab2QS03Q8wZBe5UkA1k0q0hc17eUDZ7vAWItl4iahnhq_57dCoKc1dQ3AfiHUKGCCMJ2NcQ0BmbBRIKBEgAAAPGJ\",\r\n  \"expires_in\": 7200\r\n}\r\n```\r\n\r\n错误返回\r\n\r\n```json\r\n{\r\n  \"errcode\": 40013,\r\n  \"errmsg\": \"invalid appid\"\r\n}\r\n```\r\n\r\n> [参考文档](https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html)\r\n\r\n### 获取稳定版接口调用凭据\r\n\r\n#### getStableAccessToken\r\n\r\n```typescript\r\npublic async getStableAccessToken (_appId?: string, _secret?: string, force = false): Promise<AccountAccessTokenResult>;\r\n```\r\n\r\n> [参考文档](https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/getStableAccessToken.html)\r\n\r\n### 获取jsapi_ticket\r\n\r\n#### getJSApiTicket\r\n\r\n```typescript\r\npublic async getJSApiTicket (_appId?: string, _secret?: string): Promise<TicketResult>;\r\n```\r\n\r\n返回数据\r\n\r\n```json\r\n{\r\n  \"errcode\": 0,\r\n  \"errmsg\": \"ok\",\r\n  \"ticket\": \"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA\",\r\n  \"expires_in\": 7200\r\n}\r\n```\r\n\r\n> [参考文档](https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62)\r\n\r\n### JS-SDK使用权限签名\r\n\r\n#### jssdkSignature\r\n\r\n```typescript\r\npublic async jssdkSignature (url: string): Promise<SignatureResult>;\r\npublic async jssdkSignature (url: string, appId: string, secret:string): Promise<SignatureResult>;\r\n```\r\n\r\n> [参考文档](https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#65)\r\n\r\n### 发送模板消息\r\n\r\n#### sendTemplateMessage\r\n\r\n```typescript\r\npublic async sendTemplateMessage (message: TemplateMessage, appId?: string, secret?: string): Promise<DefaultRequestResult & { msgid: string }>;\r\n```\r\n\r\n> [参考文档](https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html#5)\r\n\r\n### 生成带参数的二维码\r\n\r\n#### createQRCode\r\n\r\n```typescript\r\npublic async createQRCode (data: AccountCreateQRCode, appId?: string, secret?: string): Promise<AccountCreateQRCodeResult>;\r\n```\r\n\r\n> [参考文档](https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html)\r\n\r\n### 通过ticket换取二维码\r\n\r\n#### showQRCode\r\n\r\n```typescript\r\npublic showQRCode (ticket: string): Promis<Buffer>;\r\n```\r\n\r\n> [参考文档](https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html)\r\n\r\n### 填写服务器配置\r\n\r\n#### checkSignatureExpress\r\n\r\n```typescript\r\nWeChatService.checkSignatureExpress (req: Request, res: Response);\r\n```\r\n\r\nUsage:\r\n\r\n```typescript\r\n@Get('push')\r\nasync pushTest (@Req() req: Request, @Res() res: Response) {\r\n  this.service.checkSignatureExpress(req, res);\r\n}\r\n```\r\n\r\n> [参考文档](https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html)\r\n\r\n### 接收事件推送\r\n\r\n#### messagePushExpressHandler\r\n\r\n```typescript\r\n// 加密模式\r\nWeChatService.messagePushExpressHandler (req: Request, res?: Response, resText?: string);\r\n// 明文模式\r\nWeChatService.plainMessagePushExpressHandler (req: Request, res?: Response, resText?: string);\r\n```\r\n\r\nUsage:\r\n\r\n```typescript\r\n@Post('push')\r\nasync officialPushTest (@Req() req: Request, @Res() res: Response) {\r\n  const decrypt = await this.service.messagePushExpressHandler(req, res);\r\n}\r\n```\r\n\r\n> [参考文档](https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html)\r\n\r\n## 微信小程序\r\n\r\n### 获取接口调用凭据\r\n\r\n```typescript\r\npublic getAccessToken (appId?: string, secret?: string): Promise<AccessTokenResult>;\r\n```\r\n\r\n```typescript\r\nconst service = new WeChatService({ appId: 'your app id', secret: 'your secret'});\r\nconst res = await service.mp.getAccessToken();\r\nconsole.log(res.data.access_token);\r\n```\r\n\r\n### 查询rid信息\r\n\r\n```typescript\r\npublic async getRid (rid: string, accessToken: string): Promise<RidInfo>;\r\n```\r\n\r\n### 获取插件用户openpid\r\n\r\n```typescript\r\npublic async getPluginOpenPId (code: string, accessToken: string): Promise<DefaultRequestResult & { openpid: string }>;\r\n```\r\n\r\n### 登录code2Session\r\n\r\n```typescript\r\npublic async code2Session (code: string, appId?: string, secret?: string): Promise<SessionResult>;\r\n```\r\n\r\n返回数据\r\n\r\n```json\r\n{\r\n  \"openid\": \"openid\",\r\n  \"session_key\": \"key\",\r\n  \"unionid\": \"unionid\",\r\n  \"errcode\": 0,\r\n  \"errmsg\": \"ok\",\r\n}\r\n```\r\n\r\n> [参考文档](https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html)\r\n\r\n### 获取手机号码\r\n\r\n```javascript\r\npublic async getPhoneNumber (code: string, accessToken: string);\r\n```\r\n\r\n> [参考文档](https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-info/phone-number/getPhoneNumber.html)\r\n\r\n### 获取小程序码\r\n\r\n```typescript\r\npublic async getQRCode (params: QRCode, accessToken: string): Promise<DefaultRequestResult & { contentType: string, buffer: Buffer }>;\r\n```\r\n\r\n### 获取不限制的小程序码\r\n\r\n```typescript\r\npublic getUnlimitedQRCode (params: GetUnlimitedQRCode, accessToken: string): Promise<DefaultRequestResult & { buffer: Buffer }>;\r\n```\r\n\r\n### 获取小程序二维码\r\n\r\n```typescript\r\npublic async createQRCode (params: CreateQRCode, accessToken: string): Promise<DefaultRequestResult & { contentType: string, buffer: Buffer }>;\r\n```\r\n\r\n### 查询scheme码\r\n\r\n```typescript\r\npublic async queryScheme (scheme: string, accessToken: string): Promise<DefaultRequestResult & { scheme_info: SchemeInfo, scheme_quota: SchemeQuota }>;\r\n```\r\n\r\n### 获取scheme码\r\n\r\n```typescript\r\npublic generateScheme (params: GenerateScheme, accessToken: string): Promise<DefaultRequestResult & { openlink: string >;\r\n```\r\n\r\n### 获取NFC的小程序scheme\r\n\r\n```typescript\r\npublic generateNFCScheme (params: GenerateNFCScheme, accessToken: string): Promise<DefaultRequestResult & { openlink: string }>;\r\n```\r\n\r\n### 获取URLLink\r\n\r\n```typescript\r\npublic generateUrlLink (params: GenerateUrlLink, accessToken: string): Promise<DefaultRequestResult & { url_link: string }>;\r\n```\r\n\r\n### 查询URLLink\r\n\r\n```typescript\r\npublic queryUrlLink (urlLink: string, accessToken: string): Promise<UrlLinkResult>;\r\n```\r\n\r\n### 获取ShortLink\r\n\r\n```typescript\r\npublic generateShortLink (params: GenerateShortLink, accessToken: string): Promise<DefaultRequestResult & { link: string }>;\r\n```\r\n\r\n### 下发统一消息\r\n\r\n```typescript\r\npublic sendUniformMessage (params: SendUniformMessage, accessToken: string): Promise<DefaultRequestResult>;\r\n```\r\n\r\n### 创建activity_id\r\n\r\n```typescript\r\npublic createActivityId (params: CreateActivityId, accessToken: string): Promise<ActivityIdResult>;\r\n```\r\n\r\n### 修改动态消息\r\n\r\n```typescript\r\npublic setUpdatableMsg (params: UpdatableMsg, accessToken: string): Promise<DefaultRequestResult>;\r\n```\r\n\r\n### 删除模板\r\n\r\n```typescript\r\npublic deleteMessageTemplate (priTmplId: string, accessToken: string): Promise<DefaultRequestResult>;\r\n```\r\n\r\n### 获取类目\r\n\r\n```typescript\r\npublic getCategory (accessToken: string): Promise<DefaultRequestResult & { data: {id: number, name: string}[] }>;\r\n```\r\n\r\n### 获取关键词列表\r\n\r\n```typescript\r\npublic getPubTemplateKeyWordsById (tid: number, accessToken: string): Promise<PubTemplateKeyWords>;\r\n```\r\n\r\n### 获取所属类目下的公共模板\r\n\r\n```typescript\r\npublic getPubTemplateTitleList (params: PubTemplateTitleList, accessToken: string): Promise<PubTemplateTitleListResult>;\r\n```\r\n\r\n### 获取个人模板列表\r\n\r\n```typescript\r\npublic getMessageTemplateList (accessToken: string): Promise<MessageTemplateListResult>;\r\n```\r\n\r\n### 发送订阅消息\r\n\r\n```typescript\r\npublic sendMessage (params: SendMessage, accessToken: string): Promise<DefaultRequestResult>;\r\n```\r\n\r\n### 添加模板\r\n\r\n```typescript\r\npublic addMessageTemplate (params: MessageTemplate, accessToken: string): Promise<DefaultRequestResult & { priTmplId: string }>;\r\n```\r\n\r\n## 移动应用\r\n\r\nModule导入\r\n\r\n```typescript\r\nimport { Module } from '@nestjs/common';\r\n\r\nimport { WeChatMobileModule } from 'nest-wechat';\r\n\r\n@Module({\r\n  imports: [WeChatMobileModule.register()],\r\n})\r\nexport class AppModule {\r\n}\r\n```\r\n\r\n工具类引入\r\n\r\n```typescript\r\nimport { MobileService } from 'nest-wechat';\r\nconst service = new MobileService();\r\n```\r\n\r\n### 通过code获取access_token\r\n\r\n```typescript\r\npublic getAccessToken (code: string, appId: string, secret: string): Promise<AxiosResponse<MobileAppAccessTokenResult, any>>;\r\n```\r\n\r\n### 刷新或续期access_token\r\n\r\n```typescript\r\npublic refreshAccessToken (appId: string, refreshToken: string): Promise<AxiosResponse<MobileAppAccessTokenResult, any>>;\r\n```\r\n\r\n### 检验access_token\r\n\r\n```typescript\r\npublic checkAccessToken (openId: string, accessToken: string): Promise<AxiosResponse<DefaultRequestResult, any>>;\r\n```\r\n\r\n## 微信支付\r\n\r\n### 小程序\r\n\r\n#### JSAPI下单\r\n\r\n```javascript\r\npay.jsapi (order: TransactionOrder, serialNo: string, privateKey: Buffer | string): Promise<{prepay_id: string}>;\r\n```\r\n\r\n#### 商户订单号查询订单\r\n\r\n```javascript\r\npay.getTransactionById (id: string, mchId: string, serialNo: string, privateKey: Buffer | string): Promise<Trade>;\r\n```\r\n\r\n#### 微信支付订单号查询订单\r\n\r\n```javascript\r\npay.getTransactionByOutTradeNo (outTradeNo: string, mchId: string, serialNo: string, privateKey: Buffer | string): Promise<Trade>;\r\n```\r\n\r\n#### 关闭订单\r\n\r\n```javascript\r\npay.close (outTradeNo: string, mchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n#### 申请请退\r\n\r\n```javascript\r\npay.refund (refund: RequireOnlyOne<RefundParameters, 'transaction_id' | 'out_trade_no'>, mchId: string, serialNo: string, privateKey: Buffer | string): Promise<RefundResult>;\r\n```\r\n\r\n#### 查询单笔退款\r\n\r\n```javascript\r\npay.getRefund (outRefundNo: string, mchId: string, serialNo: string, privateKey: Buffer | string): Promise<RefundResult>;\r\n```\r\n\r\n#### 构造小程序调起支付参数\r\n\r\n```javascript\r\npay.buildMiniProgramPayment (appId: string, prepayId: string, privateKey: Buffer | string): MiniProgramPaymentParameters;\r\n```\r\n\r\n#### 支付通知处理程序\r\n\r\n```javascript\r\npay.paidCallback (publicKey: Buffer | string, apiKey: string, req: Request, res: Response): Promise<Trade>;\r\n```\r\n\r\n#### 退款通知处理程序\r\n\r\n```javascript\r\npay.refundedCallback (certs: Map<string, string>, apiKey: string, req: Request, res: Response): Promise<RefundNotifyResult>;\r\n```\r\n\r\n### 电子发票\r\n\r\n#### 配置开发选项\r\n\r\n```javascript\r\npay.fapiaoDevConfig (data: DevelopmentConfigRequest, mchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n#### 查询商户配置的开发选项\r\n\r\n```javascript\r\npay.getFapiaoDevConfig (mchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n#### 创建电子发票卡券模板\r\n\r\n```javascript\r\npay.createCardTemplate (data: CreateCardTemplateRequest, mchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n#### 微信发票通知\r\n\r\n```javascript\r\npay.fapiaoCallback (certs: Map<string, string>, apiKey: string, req: Request, res: Response): Promise<FapiaoNotifyResult>;\r\n```\r\n\r\n#### 获取用户填写的抬头\r\n\r\n```javascript\r\npay.getUserTitle (params: GetUserTitleParams, mchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n#### 开具电子发票\r\n\r\n```javascript\r\npay.issueFapiao (data: IssueFapiaoRequest, mchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n#### 查询电子发票\r\n\r\n```javascript\r\npay.getIssueFapiao (fapiaoApplyId: string, fapiaoId: string, mchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n#### 冲红电子发票\r\n\r\n```javascript\r\npay.reverseFapiao (fapiaoApplyId: string, data: ReverseFapiaoRequest, mchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n### 敏感信息加解密\r\n\r\n#### 加密\r\n\r\n```javascript\r\npay.rsaEncryptOAEP (text: string, publicKey: Buffer | string);\r\n```\r\n\r\n#### 解密\r\n\r\n```javascript\r\npay.rsaDecryptOAEP (cipherText: string, privateKey: Buffer | string);\r\n```\r\n\r\n### 现金红包\r\n\r\n没有可用测试商户，未做成功测试，请自行测试，有问题请提issue。\r\n\r\n测试可自行执行单元测试（需要修改配置）\r\n\r\n```bash\r\nnpm run test lib/wepay.hb.spec.ts\r\n```\r\n\r\n#### 发放红包\r\n\r\n```javascript\r\npay.sendRedPack(redPack: RedPackData, appId: string, mchId: string, apiKey: string, publicKey: Buffer | string, privateKey: Buffer | string, group = false): Promise<AxiosResponse<string, any>>;\r\n```\r\n\r\n#### 发放裂变红包\r\n\r\n```javascript\r\npay.sendGroupRedPack(redPack: GroupRedPackData, appId: string, mchId: string, apiKey: string, publicKey: Buffer | string, privateKey: Buffer | string): Promise<AxiosResponse<string, any>>;\r\n```\r\n\r\n#### 查询红包记录\r\n\r\n```javascript\r\npay.getHbInfo(billNO: string, appId: string, mchId: string, apiKey: string, publicKey: Buffer | string, privateKey: Buffer | string): Promise<AxiosResponse<string, any>>;\r\n```\r\n\r\n### 微信支付服务商\r\n\r\n#### 服务商JSAPI下单\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/partner-jsapi-payment/partner-jsons/partner-jsapi-prepay.html)\r\n\r\n```javascript\r\njsapiOfPartner (order: TransactionOrderOfPartner, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n#### 服务商JSAPI调起支付\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/partner-jsapi-payment/jsapi-transfer-payment.html)\r\n\r\n构建调起微信支付参数接口\r\n\r\n```javascript\r\nbuildJSAPIParameters (appId: string, prepayId: string, privateKey: Buffer | string): MiniProgramPaymentParameters;\r\n```\r\n\r\n#### 服务商支付通知\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/partner-jsapi-payment/payment-notice.html)\r\n\r\n```javascript\r\npaidCallbackOfPartner (certs: Map<string, string>, apiKey: string, req: Request, res: Response): Promise<TradeOfPartner>;\r\n```\r\n\r\n#### 服务商关闭订单\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/partner-jsapi-payment/close-order.html)\r\n\r\n```javascript\r\ncloseOfPartner (outTradeNo: string, spMchId: string, subMchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n#### 服务商微信支付订单号查询订单\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/partner-jsapi-payment/query-by-wx-trade-no.html)\r\n\r\n```javascript\r\ngetTransactionByIdOfPartner (id: string, spMchId: string, subMchid: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n#### 服务商商户订单号查询订单\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/partner-jsapi-payment/query-by-out-trade-no.html)\r\n\r\n```javascript\r\ngetTransactionByOutTradeNoOfPartner (outTradeNo: string, spMchId: string, subMchid: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n#### 服务商退款申请\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/partner-jsapi-payment/create.html)\r\n\r\n```javascript\r\nrefundOfPartner (refund: RequireOnlyOne<RefundParametersOfPartner, 'transaction_id' | 'out_trade_no'>, spMchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n#### 服务商查询单笔退款\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/partner-jsapi-payment/query-by-out-refund-no.html)\r\n\r\n```javascript\r\ngetRefundOfPartner (outRefundNo: string, spMchId: string, subMchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n#### 服务商退款结果通知\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/partner-jsapi-payment/refund-result-notice.html)\r\n\r\n```javascript\r\nrefundedCallbackOfPartner (certs: Map<string, string>, apiKey: string, req: Request, res: Response): Promise<RefundNotifyResultOfPartner>;\r\n```\r\n\r\n#### 服务商电子发票\r\n\r\n##### 服务商创建电子发票卡券模板\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/fapiao/fapiao-card-template/create-fapiao-card-template.html)\r\n\r\n```javascript\r\ncreateCardTemplateOfPartner (data: CreateCardTemplateRequestOfPartner, spMchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n##### 服务商配置开发选项\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/fapiao/fapiao-merchant/update-development-config.html)\r\n\r\n```javascript\r\nfapiaoDevConfigOfPartner (data: DevelopmentConfigRequestOfPartner, spMchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n##### 服务商查询商户配置的开发选项\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/fapiao/fapiao-merchant/query-development-config.html)\r\n\r\n```javascript\r\ngetFapiaoDevConfigOfPartner (spMchId: string, subMchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n##### 服务商微信发票通知\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/fapiao/fapiao-card-template/user-invoice-rise-write-notice.html)\r\n\r\n```javascript\r\nfapiaoCallbackOfPartner (certs: Map<string, string>, apiKey: string, req: Request, res: Response): Promise<FapiaoNotifyResultOfPartner>;\r\n```\r\n\r\n##### 服务商获取用户填写的抬头\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/fapiao/user-title/get-user-title.html)\r\n\r\n```javascript\r\ngetUserTitleOfPartner (params: GetUserTitleParams, spMchId: string, subMchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n##### 服务商开具电子发票\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/fapiao/fapiao-applications/issue-fapiao-applications.html)\r\n\r\n```javascript\r\nissueFapiaoOfPartner (data: IssueFapiaoRequestOfPartner, spMchId: string, serialNo: string, privateKey: Buffer | string, platformSerial: string);\r\n```\r\n\r\n##### 服务商查询电子发票\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/fapiao/fapiao-applications/get-fapiao-applications.html)\r\n\r\n```javascript\r\ngetIssueFapiaoOfPartner (fapiaoApplyId: string, fapiaoId: string | null | undefined, spMchId: string, subMchid: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n##### 服务商冲红电子发票\r\n\r\n> [参考文档](https://pay.weixin.qq.com/docs/partner/apis/fapiao/fapiao-applications/reverse-fapiao-applications.html)\r\n\r\n```javascript\r\nreverseFapiaoOfPartner (fapiaoApplyId: string, data: ReverseFapiaoRequestOfPartner, spMchId: string, serialNo: string, privateKey: Buffer | string);\r\n```\r\n\r\n### 微信支付工具函数\r\n\r\n#### 报文解密\r\n\r\ndecryptCipherText\r\n\r\n```javascript\r\ndecryptCipherText<T> (apiKey: string, cipher: string, associatedData: string, nonce: string): T | string;\r\n```\r\n\r\n> [参考文档](https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_2.shtml)\r\n\r\n## 微信消息加解密签名工具类\r\n\r\n```typescript\r\nimport { MessageCrypto } from 'nest-wechat';\r\nconst sha1 = MessageCrypto.sha1('string to hash');\r\n```\r\n\r\n静态方法：\r\n\r\n+ sha1 (...args: string[]): string;\r\n+ md5 (text: string): string;\r\n+ getAESKey (encodingAESKey: string): Buffer;\r\n+ getAESKeyIV (aesKey: Buffer): Buffer;\r\n+ PKCS7Encoder (buff: Buffer): Buffer;\r\n+ PKCS7Decoder (buff: Buffer): Buffer;\r\n+ decrypt (aesKey: Buffer, iv: Buffer, str: string): string;\r\n+ encrypt (aesKey: Buffer, iv: Buffer, msg: string, appId: string): string;\r\n+ createNonceStr (length = 16): string;\r\n+ encryptMessage (appId: string, token: string, encodingAESKey: string, message: string, timestamp: string, nonce: string): string;\r\n+ decryptMessage (token: string, encodingAESKey: string, signature: string, timestamp: string, nonce: string, encryptXml: string);\r\n+ decryptMessage (token: string, encodingAESKey: string, signature: string, timestamp: string, nonce: string, encryptXml: string);\r\n+ checkSignature (signature: string, timestamp: string, nonce: string, token: string);\r\n\r\n## Run Test\r\n\r\nCreate .env.test.local file, and save your test appid and secret in the file.\r\n\r\n```config\r\nTEST_APPID=your/test/appid\r\nTEST_SECRET=your/test/secret\r\nTEST_JSSDK_URL=https://your/website/url\r\nTEST_TOKEN=your/token\r\nTEST_AESKEY=your/aeskey\r\n\r\nREDIS_HOST=your/redis/host\r\nREDIS_PORT=6379\r\nREDIS_PASSWORD=\r\nREDIS_DB=0\r\nREDIS_TTL=600\r\n```\r\n\r\nRun e2e test.\r\n\r\n```shell\r\nnpm run test:e2e\r\n```\r\n\r\nRun unit test.\r\n\r\n```shell\r\nnpm run test wechat.service.userinfo.spec.ts\r\n```\r\n\r\n### 消息推送测试\r\n\r\n+ 开启服务测试\r\n\r\n```bash\r\nnpx ts-node -T tests/e2e/wechat-app.main.ts\r\n```\r\n\r\n+ 公众号消息推送配置（微信公众测试平台），开启上面服务测试后，可以通过配置验证\r\n\r\n+ URL: http://your/url/wechat/push，如：http://113.22.11.2:3001/wechat/push\r\n+ Token: pamtest\r\n\r\n+ 在[微信公众平台接口调试工具](https://mp.weixin.qq.com/debug/)获得access_token\r\n\r\nbody\r\n\r\n```json\r\n{\r\n  \"grant_type\": \"client_credential\", \r\n  \"appid\": \"your/appid\", \r\n  \"secret\": \"your/secret\", \r\n  \"force_refresh\": false\r\n}\r\n```\r\n\r\n+ 在[微信开放平台调试工具-消息推送测试](https://developers.weixin.qq.com/apiExplorer?type=messagePush)的调试工具测试推送\r\n","readmeFilename":"README.md"}