|
@@ -1,89 +1,23 @@
|
|
|
-import { Provide, Inject, Config, ALL } from '@midwayjs/decorator';
|
|
|
-
|
|
|
+import {
|
|
|
+ Provide,
|
|
|
+ Inject,
|
|
|
+ Config,
|
|
|
+ ALL,
|
|
|
+ InjectClient,
|
|
|
+} from '@midwayjs/decorator';
|
|
|
import { Repository } from 'typeorm';
|
|
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
|
|
import { PaymentChannelEntity } from '../entity/channel';
|
|
|
import axios from 'axios';
|
|
|
import { CustomerEntity } from '../entity/customer';
|
|
|
import qs = require('qs');
|
|
|
-import { ILogger } from '@midwayjs/core';
|
|
|
-
|
|
|
-class TokenManager {
|
|
|
- authUrl = ''; // 认证URL
|
|
|
- clientId = ''; // 客户端ID
|
|
|
- clientSecret = ''; // 客户端密钥
|
|
|
- refreshToken = null; // 刷新令牌
|
|
|
- accessToken = null; // 访问令牌
|
|
|
- expiresIn = 0; // 令牌过期时间
|
|
|
-
|
|
|
- constructor(authUrl, clientId, clientSecret) {
|
|
|
- this.authUrl = authUrl; // 初始化认证URL
|
|
|
- this.clientId = clientId; // 初始化客户端ID
|
|
|
- this.clientSecret = clientSecret; // 初始化客户端密钥
|
|
|
- this.accessToken = null; // 初始化访问令牌为空
|
|
|
- this.refreshToken = null; // 初始化刷新令牌为空
|
|
|
- this.expiresIn = 0; // 初始化过期时间为0
|
|
|
- }
|
|
|
-
|
|
|
- // 登录方法,用于获取访问令牌和刷新令牌
|
|
|
- async login() {
|
|
|
- try {
|
|
|
- const dataString = qs.stringify({
|
|
|
- client_id: this.clientId, // 传递客户端ID
|
|
|
- client_secret: this.clientSecret, // 传递客户端密钥
|
|
|
- grant_type: 'client_credentials', // 假设使用密码授权类型进行初始登录
|
|
|
- });
|
|
|
- const config = {
|
|
|
- method: 'post',
|
|
|
- url: this.authUrl,
|
|
|
- data: dataString,
|
|
|
- };
|
|
|
- const response = await axios(config);
|
|
|
-
|
|
|
- const data = response.data;
|
|
|
- this.accessToken = data.access_token; // 获取访问令牌
|
|
|
- this.refreshToken = data.refresh_token; // 获取刷新令牌
|
|
|
- this.expiresIn = Math.floor(Date.now() / 1000) + data.expires_in; // 计算令牌过期时间
|
|
|
-
|
|
|
- console.log('Login successful. Access Token acquired.'); // 登录成功日志
|
|
|
- } catch (error) {
|
|
|
- console.error('Login failed:', error); // 登录失败日志
|
|
|
- throw error; // 抛出错误
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 获取访问令牌的方法
|
|
|
- async getAccessToken() {
|
|
|
- const currentTime = Math.floor(Date.now() / 1000); // 获取当前时间戳
|
|
|
- if (this.accessToken && this.expiresIn > currentTime) {
|
|
|
- return this.accessToken; // 如果令牌有效,返回访问令牌
|
|
|
- }
|
|
|
-
|
|
|
- if (!this.refreshToken) {
|
|
|
- throw new Error('No refresh token available. Please login first.'); // 如果没有刷新令牌,抛出错误
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- const response = await axios.post(this.authUrl, {
|
|
|
- client_id: this.clientId, // 传递客户端ID
|
|
|
- client_secret: this.clientSecret, // 传递客户端密钥
|
|
|
- refresh_token: this.refreshToken, // 传递刷新令牌
|
|
|
- grant_type: 'refresh_token', // 使用刷新令牌授权类型
|
|
|
- });
|
|
|
-
|
|
|
- const data = response.data;
|
|
|
- this.accessToken = data.access_token; // 更新访问令牌
|
|
|
- this.expiresIn = currentTime + data.expires_in; // 更新过期时间
|
|
|
- return this.accessToken; // 返回新的访问令牌
|
|
|
- } catch (error) {
|
|
|
- console.error('Error fetching access token:', error); // 获取令牌错误日志
|
|
|
- throw error; // 抛出错误
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
+import { ILogger, Init } from '@midwayjs/core';
|
|
|
+import { CachingFactory, MidwayCache } from '@midwayjs/cache-manager';
|
|
|
+import { BaseService } from '@cool-midway/core';
|
|
|
+import { resolve } from 'path';
|
|
|
|
|
|
@Provide()
|
|
|
-export class EasyPayAdapter {
|
|
|
+export class EasyPayAdapter extends BaseService {
|
|
|
@InjectEntityModel(PaymentChannelEntity)
|
|
|
channelEntity: Repository<PaymentChannelEntity>;
|
|
|
@InjectEntityModel(CustomerEntity)
|
|
@@ -93,11 +27,12 @@ export class EasyPayAdapter {
|
|
|
@Inject()
|
|
|
ctx;
|
|
|
|
|
|
+ @InjectClient(CachingFactory, 'default')
|
|
|
+ midwayCache: MidwayCache;
|
|
|
+
|
|
|
@Inject()
|
|
|
logger: ILogger;
|
|
|
|
|
|
-
|
|
|
-
|
|
|
private config: {
|
|
|
apiKey: string;
|
|
|
apiSecret: string;
|
|
@@ -105,16 +40,15 @@ export class EasyPayAdapter {
|
|
|
chainApiKey: string;
|
|
|
chainApiSecret: string;
|
|
|
chainApiUrl: string;
|
|
|
- tokenManager: TokenManager;
|
|
|
};
|
|
|
|
|
|
baseInfo: {
|
|
|
- account_id?: string
|
|
|
- }
|
|
|
-
|
|
|
+ account_id?: string;
|
|
|
+ };
|
|
|
|
|
|
+ @Init()
|
|
|
Init() {
|
|
|
- this.initConfig()
|
|
|
+ this.initConfig();
|
|
|
}
|
|
|
/**
|
|
|
* 初始化渠道配置
|
|
@@ -127,12 +61,18 @@ export class EasyPayAdapter {
|
|
|
if (!channel) {
|
|
|
throw new Error('FusionPay channel not found or disabled');
|
|
|
}
|
|
|
- const tokenManager = new TokenManager(
|
|
|
+ await this.initTokenManager(
|
|
|
+ `${channel.apiUrl}/auth`,
|
|
|
+ channel.apiKey,
|
|
|
+ channel.apiSecret
|
|
|
+ );
|
|
|
+
|
|
|
+ this.initTokenManager(
|
|
|
`${channel.apiUrl}/auth`,
|
|
|
channel.apiKey,
|
|
|
channel.apiSecret
|
|
|
);
|
|
|
- await tokenManager.login();
|
|
|
+ // this.tokenManagerService.login();
|
|
|
this.config = {
|
|
|
apiKey: channel.apiKey,
|
|
|
apiSecret: channel.apiSecret,
|
|
@@ -140,9 +80,9 @@ export class EasyPayAdapter {
|
|
|
chainApiKey: channel.chainApiKey,
|
|
|
chainApiSecret: channel.chainApiSecret,
|
|
|
chainApiUrl: channel.chainApiUrl,
|
|
|
- tokenManager: tokenManager,
|
|
|
+ // tokenManager: tokenManager,
|
|
|
};
|
|
|
- this.baseInfo = channel.config
|
|
|
+ this.baseInfo = channel.config;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -151,11 +91,10 @@ export class EasyPayAdapter {
|
|
|
*/
|
|
|
async request(method: string, endpoint: string, data?: any) {
|
|
|
await this.initConfig();
|
|
|
- // return Promise.resolve(`https://api.easypayx.com${endpoint.replace('/api/open', '')}`);
|
|
|
let url = this.config.apiUrl;
|
|
|
try {
|
|
|
url = `${url}${endpoint.replace('/api/open', '')}`;
|
|
|
- const accessToken = await this.config.tokenManager.getAccessToken();
|
|
|
+ const accessToken = await this.getAccessToken();
|
|
|
const axiosParams = {
|
|
|
method,
|
|
|
url,
|
|
@@ -176,7 +115,6 @@ export class EasyPayAdapter {
|
|
|
// console.log('response', response.data);
|
|
|
return response.data;
|
|
|
} catch (error) {
|
|
|
-
|
|
|
// console.log(error.response.data);
|
|
|
if (axios.isAxiosError(error) && error.response) {
|
|
|
// console.log(error.response.data);
|
|
@@ -201,4 +139,86 @@ export class EasyPayAdapter {
|
|
|
});
|
|
|
return '';
|
|
|
}
|
|
|
+
|
|
|
+ async get_authUrl() {
|
|
|
+ return await this.midwayCache.get('easypay:adapter:authUrl'); // 初始化认证URL
|
|
|
+ }
|
|
|
+ async get_clientId() {
|
|
|
+ return await this.midwayCache.get('easypay:adapter:clientId'); // 初始化客户端ID
|
|
|
+ }
|
|
|
+ async get_clientSecret() {
|
|
|
+ return await this.midwayCache.get('easypay:adapter:clientSecret'); // 初始化客户端密钥
|
|
|
+ }
|
|
|
+ async get_accessToken() {
|
|
|
+ return await this.midwayCache.get('easypay:adapter:accessToken'); // 初始化访问令牌为空
|
|
|
+ }
|
|
|
+ async get_refreshToken() {
|
|
|
+ return await this.midwayCache.get('easypay:adapter:refreshToken'); // 初始化刷新令牌为空
|
|
|
+ }
|
|
|
+ async get_expiresIn() {
|
|
|
+ return await this.midwayCache.get('easypay:adapter:expiresIn'); // 初始化过期时间为0
|
|
|
+ }
|
|
|
+
|
|
|
+ async initTokenManager(authUrl, clientId, clientSecret) {
|
|
|
+ if (!(await this.get_authUrl())) {
|
|
|
+ await this.midwayCache.set('easypay:adapter:authUrl', authUrl); // 初始化认证URL
|
|
|
+ await this.midwayCache.set('easypay:adapter:clientId', clientId); // 初始化客户端ID
|
|
|
+ await this.midwayCache.set('easypay:adapter:clientSecret', clientSecret); // 初始化客户端密钥
|
|
|
+ await this.midwayCache.set('easypay:adapter:accessToken', ''); // 初始化访问令牌为空
|
|
|
+ await this.midwayCache.set('easypay:adapter:refreshToken', ''); // 初始化刷新令牌为空
|
|
|
+ await this.midwayCache.set('easypay:adapter:expiresIn', 0); // 初始化过期时间为0
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 获取访问令牌的方法
|
|
|
+ async getAccessToken() {
|
|
|
+ const currentTime = Math.floor(Date.now() / 1000); // 获取当前时间戳
|
|
|
+ const expiresIn = await this.get_expiresIn();
|
|
|
+ const accessToken = await this.get_accessToken();
|
|
|
+ if (accessToken && Number.parseInt(`${expiresIn}`) > currentTime) {
|
|
|
+ return accessToken; // 如果令牌有效,返回访问令牌
|
|
|
+ }
|
|
|
+ await this.login();
|
|
|
+ return await this.get_accessToken(); // 返回新的访问令牌
|
|
|
+ }
|
|
|
+ // 登录方法,用于获取访问令牌和刷新令牌
|
|
|
+ async login() {
|
|
|
+ return new Promise(async (resolve, reject) => {
|
|
|
+ const authUrl = await this.get_authUrl();
|
|
|
+ const clientId = await this.get_clientId();
|
|
|
+ const clientSecret = await this.get_clientSecret();
|
|
|
+ try {
|
|
|
+ const dataString = qs.stringify({
|
|
|
+ client_id: clientId, // 传递客户端ID
|
|
|
+ client_secret: clientSecret, // 传递客户端密钥
|
|
|
+ grant_type: 'client_credentials', // 假设使用密码授权类型进行初始登录
|
|
|
+ });
|
|
|
+ const config = {
|
|
|
+ method: 'post',
|
|
|
+ url: `${authUrl}`,
|
|
|
+ data: `${dataString}`,
|
|
|
+ };
|
|
|
+ // console.log(239, config);
|
|
|
+ const response = await axios(config);
|
|
|
+
|
|
|
+ const data = response.data;
|
|
|
+ await this.midwayCache.set(
|
|
|
+ 'easypay:adapter:accessToken',
|
|
|
+ data.access_token
|
|
|
+ ); // 初始化访问令牌为空
|
|
|
+ await this.midwayCache.set(
|
|
|
+ 'easypay:adapter:refreshToken',
|
|
|
+ data.refresh_token
|
|
|
+ ); // 初始化刷新令牌为空
|
|
|
+ await this.midwayCache.set(
|
|
|
+ 'easypay:adapter:expiresIn',
|
|
|
+ Math.floor(Date.now() / 1000) + data.expires_in - 10
|
|
|
+ ); // 初始化过期时间为0
|
|
|
+ console.log('Login successful. Access Token acquired. accessToken'); // 登录成功日志
|
|
|
+ resolve(data.access_token);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Login failed:', error); // 登录失败日志
|
|
|
+ reject(error); // 抛出错误
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|