test 10 сар өмнө
parent
commit
773929c295

+ 0 - 10
src/modules/dj/controller/admin/bank.ts

@@ -1,10 +0,0 @@
-import { BankEntity } from '../../entity/bank';
-import { Inject, Post, Provide, Body } from '@midwayjs/decorator';
-import { CoolController, BaseController } from '@cool-midway/core';
-
-@Provide()
-@CoolController({
-  api: ['add', 'delete', 'list', 'update', 'info', 'page'],
-  entity: BankEntity,
-})
-export class BankController extends BaseController {}

+ 18 - 6
src/modules/dj/controller/admin/open.ts

@@ -78,7 +78,7 @@ export class PayOpenController extends BaseController {
   @Post('/SunCard/notifyOrder', { summary: '交易订单回调通知' })
   public async notifySunCardOrderGet(@Body(ALL) payload: any) {
     const headers = this.ctx.headers;
-    this.logger.error('SunCard收到交易订单回调数据', JSON.stringify(payload));
+    this.logger.error('SunCard收到交易订单回调数据', JSON.stringify(payload), headers);
     await this.orderService.handleNotify('SunCard', payload, headers);
     this.ctx.body = {   
       "is_success": "true",
@@ -87,11 +87,23 @@ export class PayOpenController extends BaseController {
   }
 
   @CoolTag(TagTypes.IGNORE_TOKEN)
-  @Post('/hambit/notifyOrder', { summary: '交易订单回调通知' })
-  public async hambitNotifyOrderGet(@Body(ALL) payload: any) {
-    const headers = this.ctx.req.headers;
-    this.logger.error('hambit收到交易订单回调数据', JSON.stringify(payload));
-    await this.orderService.handleNotify('HamBit', payload, headers);
+  @Post('/hambit/bra/notifyOrder', { summary: '巴西交易订单回调通知' })
+  public async hambitBraNotifyOrderGet(@Body(ALL) payload: any) {
+    const headers = this.ctx.headers;
+    this.logger.error('hambit收到交易订单回调数据', JSON.stringify(payload), headers);
+    await this.orderService.handleNotify('HamBitBra', payload, headers);
+    this.ctx.body = {   
+      "code": "200",
+      "success": "true"
+    };
+  }
+  
+  @CoolTag(TagTypes.IGNORE_TOKEN)
+  @Post('/hambit/ind/notifyOrder', { summary: '印度交易订单回调通知' })
+  public async hambitIndNotifyOrderGet(@Body(ALL) payload: any) {
+    const headers = this.ctx.headers;
+    this.logger.error('hambit收到交易订单回调数据', JSON.stringify(payload), headers);
+    await this.orderService.handleNotify('HamBitInd', payload, headers);
     this.ctx.body = {   
       "code": "200",
       "success": "true"

+ 0 - 24
src/modules/dj/entity/bank.ts

@@ -1,24 +0,0 @@
-import { BaseEntity } from '@cool-midway/core';
-import { Column, Entity, Index } from 'typeorm';
-
-/**
- * 字典信息
- */
-@Entity('dj_bank')
-export class BankEntity extends BaseEntity {
-  @Index({ unique: true })
-  @Column({ comment: '账户' })
-  accountNo: string;
-
-  @Column({ comment: '银行编码' })
-  bankCode: string;
-
-  @Column({ comment: '银行名称' })
-  bankName: string;
-
-  @Column({ comment: '账户名' })
-  accountName: string;
-
-  @Column({ comment: '备注', nullable: true })
-  remark: string;
-}

+ 1 - 1
src/modules/dj/entity/order.ts

@@ -67,6 +67,6 @@ export class OrderEntity extends BaseEntity {
   @Column({ comment: '备注', nullable: true })
   remark: string;
 
-  @Column({ comment: '支付地址', nullable: true })
+  @Column({ comment: '支付地址', nullable: true, length: 2000 })
   payUrl: string;
 }

+ 6 - 2
src/modules/dj/service/channels/dispatch.ts

@@ -2,7 +2,8 @@ import { Inject, Provide } from '@midwayjs/decorator';
 import { BaseService } from '@cool-midway/core';
 import { SunPayService } from './sunpay';
 import { ChannelService } from '../channel';
-import { HambitService } from './hambit';
+import { HambitBraService } from './hambitBra';
+import { HambitIndService } from './hambitInd';
 
 @Provide()
 export class DispatchService extends BaseService {
@@ -13,7 +14,10 @@ export class DispatchService extends BaseService {
   channelService: ChannelService;
   
   @Inject()
-  hambitService: HambitService;
+  hambitBraService: HambitBraService;
+
+  @Inject()
+  hambitIndService: HambitIndService;
 
 
   async order(order, channel) {

+ 161 - 0
src/modules/dj/service/channels/hambitBra.ts

@@ -0,0 +1,161 @@
+import { Inject, Logger, Provide } from '@midwayjs/decorator';
+import { BaseService } from '@cool-midway/core';
+import * as _ from 'lodash';
+import * as moment from 'moment';
+import { Utils } from '../../../../comm/utils';
+import { HttpService } from '@midwayjs/axios';
+import { ILogger } from '@midwayjs/logger';
+import { v4 as uuidv4 } from 'uuid';
+
+const HOST = "https://apis.hambit.co";
+const ACCESS_KEY = 'o1tbXAdd';
+const SECRET_KEY = 'cc2355c62627a1a437cf54d8b491aa6f82d30b31'
+const PAY_URL = '/api/v3/bra/createCollectingOrder';
+const QUERY_URL = '/api/v3/bra/query/collectingOrder'
+const BALANCE_URL = '/api/v3/bra/query/balance'
+
+const NOTIFY_HOST = `http://157.175.73.225/api/admin/dj/open/hambit/bra/notifyOrder`;
+
+const CHANNEL_TYPE = "PIX";
+
+@Provide()
+export class HambitBraService extends BaseService {
+  @Inject()
+  utils: Utils;
+  @Inject()
+  httpService: HttpService;
+  @Logger()
+  logger: ILogger;
+
+  async order(payload) {
+    const param = {
+      "amount": payload.amount.toFixed(2),
+      "channelType": CHANNEL_TYPE,
+      "externalOrderId": payload.orderNo,
+      "notifyUrl": NOTIFY_HOST,
+      "remark": "",
+      "returnUrl": payload.returnUrl || "",
+      "userIdentity": "",
+      "inputCpf": 0,
+    };
+    const timestamp = +moment();
+    const nonce = uuidv4();
+    const signStr = this.utils.signSort({
+      timestamp,
+      nonce,
+      access_key: ACCESS_KEY,
+      ...param
+    });
+    const sign = this.utils.signByHmacSha1(signStr, SECRET_KEY);
+    const res = await this.httpService.post(HOST + PAY_URL, param, {
+      headers: {
+        'access_key': ACCESS_KEY,
+        'timestamp': timestamp,
+        'nonce': nonce,
+        'sign': sign
+      }
+    });
+    this.logger.info('下单接口返回', param, JSON.stringify(res.data));
+    const { success, msg, data } = res.data;
+    if (success && data.cashierUrl) {
+      return {
+        payUrl: data.cashierUrl,
+        traceNo: data?.currencyOrderVo?.orderId
+      };
+    } else {
+      throw new Error(msg);
+    }
+  }
+
+  async query(payload) {
+    const param = {
+      externalOrderId: payload.orderNo
+    };
+    const timestamp = +moment();
+    const nonce = uuidv4();
+    const signStr = this.utils.signSort({
+      timestamp,
+      nonce,
+      access_key: ACCESS_KEY,
+      ...param
+    });
+    const sign = this.utils.signByHmacSha1(signStr, SECRET_KEY);
+    const res = await this.httpService.post(HOST + QUERY_URL, param, {
+      headers: {
+        'access_key': ACCESS_KEY,
+        'timestamp': timestamp,
+        'nonce': nonce,
+        'sign': sign
+      }
+    });
+    this.logger.info('查询接口返回', JSON.stringify(res.data));
+    const { success, msg, data = [] } = res.data;
+    const orderData = data.find(item => item.externalOrderId === payload.orderNo)
+    if (success && orderData && +orderData.orderStatus === 2) {
+      return {
+        status: 1,
+        traceNo: orderData.orderId,
+        date: new Date()
+      };
+    } else {
+      return {
+        status: 0,
+        msg,
+      };
+    }
+  }
+
+  async handleOrderNotify(payload, headers) {
+    const sign = headers['sign'];
+    const timestamp = headers['timestamp'];
+    const nonce = headers['nonce'];
+    const signStr = this.utils.signSort({
+      timestamp,
+      nonce,
+      access_key: ACCESS_KEY,
+      ...payload
+    });
+    const validSign = this.utils.signByHmacSha1(signStr, SECRET_KEY);
+    if (sign !== validSign) {
+      throw new Error('sign error');
+    }
+    if (+payload.orderStatusCode !== 2) {
+      throw new Error('order no success');
+    }
+    return {
+      date: new Date(1690429623000),
+      orderNo: payload.externalOrderId,
+      traceNo: payload.orderId,
+    };
+  }
+
+  async queryBalance() {
+    const param = {};
+    const timestamp = +moment();
+    const nonce = uuidv4();
+    const signStr = this.utils.signSort({
+      timestamp,
+      nonce,
+      access_key: ACCESS_KEY,
+      ...param
+    });
+    const sign = this.utils.signByHmacSha1(signStr, SECRET_KEY);
+    const res = await this.httpService.post(HOST + BALANCE_URL, param, {
+      headers: {
+        'access_key': ACCESS_KEY,
+        'timestamp': timestamp,
+        'nonce': nonce,
+        'sign': sign
+      }
+    });
+    this.logger.info('查询余额接口返回', param, JSON.stringify(res.data));
+    const { success, msg, data } = res.data;
+    if (success && data[0]) {
+      return {
+        balance: data[0]
+      }
+    } else {
+      throw new Error(msg);
+    }
+  }
+}

+ 159 - 0
src/modules/dj/service/channels/hambitInd.ts

@@ -0,0 +1,159 @@
+import { Inject, Logger, Provide } from '@midwayjs/decorator';
+import { BaseService } from '@cool-midway/core';
+import * as _ from 'lodash';
+import * as moment from 'moment';
+import { Utils } from '../../../../comm/utils';
+import { HttpService } from '@midwayjs/axios';
+import { ILogger } from '@midwayjs/logger';
+import { v4 as uuidv4 } from 'uuid';
+
+const HOST = "https://apis.hambit.co";
+const ACCESS_KEY = 'o1tbXAdd';
+const SECRET_KEY = 'cc2355c62627a1a437cf54d8b491aa6f82d30b31'
+const PAY_URL = '/api/v3/ind/createCollectingOrder';
+const QUERY_URL = '/api/v3/ind/query/collectingOrder'
+const BALANCE_URL = '/api/v3/ind/query/balance'
+
+const NOTIFY_HOST = `http://157.175.73.225/api/admin/dj/open/hambit/ind/notifyOrder`;
+
+const CHANNEL_TYPE = "BANK";
+
+@Provide()
+export class HambitIndService extends BaseService {
+  @Inject()
+  utils: Utils;
+  @Inject()
+  httpService: HttpService;
+  @Logger()
+  logger: ILogger;
+
+  async order(payload) {
+    const param = {
+      "amount": payload.amount.toFixed(2),
+      "channelType": CHANNEL_TYPE,
+      "externalOrderId": payload.orderNo,
+      "notifyUrl": NOTIFY_HOST,
+      "remark": "",
+      "returnUrl": payload.returnUrl || ""
+    };
+    const timestamp = +moment();
+    const nonce = uuidv4();
+    const signStr = this.utils.signSort({
+      timestamp,
+      nonce,
+      access_key: ACCESS_KEY,
+      ...param
+    });
+    const sign = this.utils.signByHmacSha1(signStr, SECRET_KEY);
+    const res = await this.httpService.post(HOST + PAY_URL, param, {
+      headers: {
+        'access_key': ACCESS_KEY,
+        'timestamp': timestamp,
+        'nonce': nonce,
+        'sign': sign
+      }
+    });
+    this.logger.info('下单接口返回', param, JSON.stringify(res.data));
+    const { success, msg, data } = res.data;
+    if (success && data.cashierUrl) {
+      return {
+        payUrl: data.cashierUrl,
+        traceNo: data?.currencyOrderVo?.orderId
+      };
+    } else {
+      throw new Error(msg);
+    }
+  }
+
+  async query(payload) {
+    const param = {
+      externalOrderId: payload.orderNo
+    };
+    const timestamp = +moment();
+    const nonce = uuidv4();
+    const signStr = this.utils.signSort({
+      timestamp,
+      nonce,
+      access_key: ACCESS_KEY,
+      ...param
+    });
+    const sign = this.utils.signByHmacSha1(signStr, SECRET_KEY);
+    const res = await this.httpService.post(HOST + QUERY_URL, param, {
+      headers: {
+        'access_key': ACCESS_KEY,
+        'timestamp': timestamp,
+        'nonce': nonce,
+        'sign': sign
+      }
+    });
+    this.logger.info('查询接口返回', JSON.stringify(res.data));
+    const { success, msg, data = [] } = res.data;
+    const orderData = data.find(item => item.externalOrderId === payload.orderNo)
+    if (success && orderData && +orderData.orderStatus === 2) {
+      return {
+        status: 1,
+        traceNo: orderData.orderId,
+        date: new Date()
+      };
+    } else {
+      return {
+        status: 0,
+        msg,
+      };
+    }
+  }
+
+  async handleOrderNotify(payload, headers) {
+    const sign = headers['sign'];
+    const timestamp = headers['timestamp'];
+    const nonce = headers['nonce'];
+    const signStr = this.utils.signSort({
+      timestamp,
+      nonce,
+      access_key: ACCESS_KEY,
+      ...payload
+    });
+    const validSign = this.utils.signByHmacSha1(signStr, SECRET_KEY);
+    if (sign !== validSign) {
+      throw new Error('sign error');
+    }
+    if (+payload.orderStatusCode !== 2) {
+      throw new Error('order no success');
+    }
+    return {
+      date: new Date(1690429623000),
+      orderNo: payload.externalOrderId,
+      traceNo: payload.orderId,
+    };
+  }
+
+  async queryBalance() {
+    const param = {};
+    const timestamp = +moment();
+    const nonce = uuidv4();
+    const signStr = this.utils.signSort({
+      timestamp,
+      nonce,
+      access_key: ACCESS_KEY,
+      ...param
+    });
+    const sign = this.utils.signByHmacSha1(signStr, SECRET_KEY);
+    const res = await this.httpService.post(HOST + BALANCE_URL, param, {
+      headers: {
+        'access_key': ACCESS_KEY,
+        'timestamp': timestamp,
+        'nonce': nonce,
+        'sign': sign
+      }
+    });
+    this.logger.info('查询余额接口返回', param, JSON.stringify(res.data));
+    const { success, msg, data } = res.data;
+    if (success && data[0]) {
+      return {
+        balance: data[0]
+      }
+    } else {
+      throw new Error(msg);
+    }
+  }
+}

+ 2 - 0
src/modules/dj/service/channels/sunpay.ts

@@ -226,6 +226,8 @@ export class SunPayService extends BaseService {
     if (is_success && res.data.data.order_status === 'SUCCESS') {
       return {
         status: 1,
+        traceNo: res.data.data.order_no,
+        date: new Date()
       };
     } else {
       return {