|
|
@@ -1,11 +1,28 @@
|
|
|
import { Inject, Injectable } from '@nestjs/common'
|
|
|
import weixinConfig from './weixin.config'
|
|
|
import { ConfigType } from '@nestjs/config'
|
|
|
-import { ApiConfig, ApiConfigKit, AccessTokenApi } from 'tnwx'
|
|
|
+import {
|
|
|
+ ApiConfig,
|
|
|
+ ApiConfigKit,
|
|
|
+ AccessTokenApi,
|
|
|
+ SnsAccessTokenApi,
|
|
|
+ ScopeEnum,
|
|
|
+ PayKit,
|
|
|
+ WX_DOMAIN,
|
|
|
+ WX_API_TYPE,
|
|
|
+ Kits,
|
|
|
+ WX_TRADE_TYPE,
|
|
|
+ SIGN_TYPE,
|
|
|
+ HttpKit,
|
|
|
+ WxPayApiConifgKit,
|
|
|
+ WxPayApiConfig
|
|
|
+} from 'tnwx'
|
|
|
import { InjectRepository } from '@nestjs/typeorm'
|
|
|
import { AccessToken } from './entities/accessToken.entity'
|
|
|
import { LessThan, Not, Repository } from 'typeorm'
|
|
|
import { addSeconds } from 'date-fns'
|
|
|
+import * as fs from 'node:fs'
|
|
|
+const { Wechatpay } = require('wechatpay-axios-plugin');
|
|
|
|
|
|
@Injectable()
|
|
|
export class WeixinService {
|
|
|
@@ -21,6 +38,26 @@ export class WeixinService {
|
|
|
ApiConfigKit.devMode = true
|
|
|
// 设置当前应用
|
|
|
ApiConfigKit.setCurrentAppId(apiConfig.getAppId)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ const wxpay = new Wechatpay({
|
|
|
+ mchid: weixinConfiguration.mchId,
|
|
|
+ serial: merchantCertificateSerial,
|
|
|
+ privateKey: merchantPrivateKeyInstance,
|
|
|
+ certs: { [platformCertificateSerial]: platformCertificateInstance, },
|
|
|
+ // 使用APIv2时,需要至少设置 `secret`字段,示例代码未开启
|
|
|
+ // APIv2密钥(32字节)
|
|
|
+ // secret: 'your_merchant_secret_key_string',
|
|
|
+ // // 接口不要求证书情形,例如仅收款merchant对象参数可选
|
|
|
+ // merchant: {
|
|
|
+ // cert: readFileSync('/path/to/merchant/apiclient_cert.pem'),
|
|
|
+ // key: merchantPrivateKeyInstance,
|
|
|
+ // // or
|
|
|
+ // // passphrase: 'your_merchant_id',
|
|
|
+ // // pfx: fs.readFileSync('/your/merchant/cert/apiclient_cert.p12'),
|
|
|
+ // },
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
async getAccessToken() {
|
|
|
@@ -44,4 +81,91 @@ export class WeixinService {
|
|
|
await this.accessTokenRepository.delete({ id: Not(newToken.id) })
|
|
|
return newToken.accessToken
|
|
|
}
|
|
|
+
|
|
|
+ getRedirectUrl() {
|
|
|
+ return SnsAccessTokenApi.getAuthorizeUrl(
|
|
|
+ 'https://chillgpt.raexmeta.com/ui/#/home',
|
|
|
+ ScopeEnum.SNSAPI_BASE,
|
|
|
+ 'pay'
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ async code2oenId(code: string) {
|
|
|
+ const res = await SnsAccessTokenApi.getSnsAccessToken(code)
|
|
|
+ return res.getOpenid
|
|
|
+ }
|
|
|
+
|
|
|
+ async pay() {
|
|
|
+ let reqObj = {
|
|
|
+ appid: this.weixinConfiguration.appId,
|
|
|
+ mch_id: this.weixinConfiguration.mchId,
|
|
|
+ nonce_str: Kits.generateStr(), //生成随机字符串
|
|
|
+ body: 'IJPay 让支付触手可及',
|
|
|
+ attach: 'TNWX 微信系开发脚手架',
|
|
|
+ out_trade_no: Kits.generateStr(),
|
|
|
+ total_fee: 666,
|
|
|
+ spbill_create_ip: '110.172.10.1',
|
|
|
+ notify_url: 'https://chillgpt.raexmeta.com/api/weixin/notify',
|
|
|
+ trade_type: WX_TRADE_TYPE.JSAPI,
|
|
|
+ sign_type: SIGN_TYPE.SIGN_TYPE_MD5
|
|
|
+ }
|
|
|
+ let xml = await Kits.generateSignedXml(reqObj, this.weixinConfiguration.mchKey, SIGN_TYPE.SIGN_TYPE_MD5)
|
|
|
+ PayKit.buildRepSignMessage
|
|
|
+ let result = await PayKit.exePost(
|
|
|
+ WX_DOMAIN.CHINA, //
|
|
|
+ WX_API_TYPE.UNIFIED_ORDER,
|
|
|
+ this.weixinConfiguration.mchId,
|
|
|
+ this.weixinConfiguration.certSerial,
|
|
|
+ fs.readFileSync('/Users/drew/Downloads/1642294106_20230418_cert 2/apiclient_key.pem'),
|
|
|
+ xml
|
|
|
+ )
|
|
|
+ console.log(result)
|
|
|
+ }
|
|
|
+
|
|
|
+ async pay1() {
|
|
|
+ try {
|
|
|
+ let result = await PayKit.exeGet(
|
|
|
+ WX_DOMAIN.CHINA, //
|
|
|
+ WX_API_TYPE.GET_CERTIFICATES,
|
|
|
+ this.weixinConfiguration.mchId,
|
|
|
+ this.weixinConfiguration.certSerial,
|
|
|
+ fs.readFileSync('/Users/drew/Downloads/1642294106_20230418_cert 2/apiclient_key.pem')
|
|
|
+ )
|
|
|
+ console.log(`result.data:${result.data}`)
|
|
|
+
|
|
|
+ // 应答报文主体
|
|
|
+ let data = JSON.stringify(result.data)
|
|
|
+ // 应答状态码
|
|
|
+ console.log(`status:${result.status}`)
|
|
|
+ console.log(`data:${data}`)
|
|
|
+ // http 请求头
|
|
|
+ let headers = result.headers
|
|
|
+ // 证书序列号
|
|
|
+ let serial = headers['wechatpay-serial']
|
|
|
+ // 应答时间戳
|
|
|
+ let timestamp = headers['wechatpay-timestamp']
|
|
|
+ // 应答随机串
|
|
|
+ let nonce = headers['wechatpay-nonce']
|
|
|
+ // 应答签名
|
|
|
+ let signature = headers['wechatpay-signature']
|
|
|
+
|
|
|
+ console.log(`serial:\n${serial}`)
|
|
|
+ console.log(`timestamp:\n${timestamp}`)
|
|
|
+ console.log(`nonce:\n${nonce}`)
|
|
|
+ console.log(`signature:\n${signature}`)
|
|
|
+
|
|
|
+ // 根据序列号查证书 验证签名
|
|
|
+ // let verifySignature: boolean = PayKit.verifySignature(signature, data, nonce, timestamp, wxPublicKey)
|
|
|
+ let verifySignature: boolean = PayKit.verifySign(
|
|
|
+ headers,
|
|
|
+ data,
|
|
|
+ fs.readFileSync('/Users/drew/Downloads/1642294106_20230418_cert 2/apiclient_cert.pem')
|
|
|
+ )
|
|
|
+ console.log(`verifySignature:${verifySignature}`)
|
|
|
+
|
|
|
+ return data
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|