浏览代码

feat: api代理利润截流

max 5 月之前
父节点
当前提交
fa3ce6fec7

+ 1 - 0
src/modules/api/entity/open_payment_order.ts

@@ -75,4 +75,5 @@ export enum OrderType {
   PAYMENT = 'PAYMENT', // 付款
   TRANSFER = 'TRANSFER', // 转账
   DEPOSIT = 'DEPOSIT', // 入账
+  TRANSACTION_FEE_ORDER = 'TRANSACTION_FEE_ORDER', // 交易手续费订单
 }

+ 68 - 10
src/modules/api/service/open.ts

@@ -1,5 +1,5 @@
 import { BaseService, CoolTransaction } from '@cool-midway/core';
-import { ILogger, Inject, Provide } from '@midwayjs/core';
+import { ILogger, Init, Inject, Provide } from '@midwayjs/core';
 import { InjectEntityModel } from '@midwayjs/typeorm';
 import { OpenUserEntity } from '../entity/open_user';
 import * as crypto from 'crypto';
@@ -10,6 +10,7 @@ import {
 } from '../entity/open_payment_order';
 import { OpenPaymentAccountEntity } from '../entity/open_payment_account';
 import { EasyPayAdapter } from '../../payment/adapter/easypay.adapter';
+import * as md5 from 'md5';
 
 /**
  * 描述
@@ -31,10 +32,18 @@ export class EasyOpenService extends BaseService {
   @Inject()
   easyPayAdapter: EasyPayAdapter;
 
+
   @Inject()
   ctx;
 
-  /* 
+  @Init()
+  async init() {
+    // await super.init();
+    // this.setEntity(this.businessEntity);
+    this.easyPayAdapter.Init()
+  }
+
+  /*
     记录用户的数据来源
     */
   async save_user(userInfo, params) {
@@ -53,7 +62,7 @@ export class EasyOpenService extends BaseService {
     }
   }
 
-  /* 
+  /*
     记录用户的收款账户数据来源
     */
   async save_user_account(userInfo, params) {
@@ -73,52 +82,66 @@ export class EasyOpenService extends BaseService {
     }
   }
 
-  /* 
+  /*
     记录用户的订单数据来源
   */
-  async save_user_order(orderInfo, params, type: OrderType) {
+  async save_user_order(orderInfo, params, type: OrderType, baseOrderInfo) {
     try {
       let openOrderObj: any = {
         mch_id: this.ctx.admin.merchant.mchId,
         account_id: params.account_id,
-        request_id: params.payment.request_id,
+        request_id: params?.payment?.request_id,
         order_type: type,
         additional_info: {
           orderInfo,
           params,
           type,
+          baseOrderInfo // 当发生流水交易时,记录原始订单,做后续的退款操作
         },
       };
 
       // 收单支付订单
       if (OrderType.ACQUIRING_PAYMENT === type) {
-        openOrderObj.amount = params.payment.amount;
+        openOrderObj.request_id = params?.request_id;
+        openOrderObj.amount = params.payment.amount - this.getTotransfersAmount(params.payment.amount);
         openOrderObj.currency = params.payment.currency;
       }
 
       // 收单退款订单
       if (OrderType.ACQUIRING_REFUND === type) {
+        openOrderObj.request_id = params?.request_id;
         openOrderObj.amount = params.refund.amount;
         openOrderObj.currency = params.refund.currency;
       }
 
       // 换汇
       if (OrderType.CURRENCY_EXCHANGE === type) {
-        openOrderObj.amount = params.sell_amount; // 卖出金额
+        openOrderObj.request_id = params?.request_id;
+        openOrderObj.amount = params.sell_amount - this.getTotransfersAmount(params.sell_amount); // 卖出金额
         openOrderObj.currency = params.sell_currency; // 卖出币种
-
         openOrderObj.target_amount = params.buy_amount; // 买入金额
         openOrderObj.target_currency = params.buy_currency; // 买入币种
       }
 
       // 付款
       if (OrderType.PAYMENT === type) {
-        openOrderObj.amount = params.amount;
+        openOrderObj.amount = params.amount - this.getTotransfersAmount(params.amount);
         openOrderObj.currency = params.currency;
+        openOrderObj.request_id = params?.request_id;
       }
 
       // 转账
       if (OrderType.TRANSFER === type) {
+        openOrderObj.amount = params.amount - this.getTotransfersAmount(params.amount);
+        openOrderObj.currency = params.currency;
+        openOrderObj.from_account_id = params.from_account_id;
+        openOrderObj.to_account_id = params.to_account_id;
+        openOrderObj.request_id = params?.request_id;
+      }
+
+      // 流水的转账
+      if (OrderType.TRANSACTION_FEE_ORDER === type) {
+        openOrderObj.request_id = params?.request_id;
         openOrderObj.amount = params.amount;
         openOrderObj.currency = params.currency;
         openOrderObj.from_account_id = params.from_account_id;
@@ -132,6 +155,10 @@ export class EasyOpenService extends BaseService {
       // }
 
       await this.openPaymentOrderEntity.insert(openOrderObj);
+      // 如果不是流水交易和退款交易的话,进行费率扣除
+      if(type !== OrderType.TRANSACTION_FEE_ORDER && OrderType.ACQUIRING_REFUND !== type) {
+        await this.capturedTransferStream(openOrderObj, type)
+      }
 
       /* 更新相关订单信息 */
 
@@ -148,6 +175,7 @@ export class EasyOpenService extends BaseService {
         await this.openPaymentOrderEntity.update(paymentOrder, {
           status: 'REFUNDED',
         });
+        // TODO 取消流水利润 退回原帐户
       }
       this.logger.info(
         `save_user_order 商户: ${this.ctx.admin.merchant.mchId}; userInfo${JSON.stringify(orderInfo)} params${JSON.stringify(params)}`
@@ -156,6 +184,36 @@ export class EasyOpenService extends BaseService {
       this.logger.error('save_user_order:error: ', error);
     }
   }
+  createRequest_id(openOrderObj) {
+    md5(JSON.stringify({
+        mch_id: openOrderObj.mchId,
+        account_id: openOrderObj.account_id,
+        request_id: openOrderObj.request_id,
+    }))
+  }
+  getTotransfersAmount(amount) {
+    const rate = this.ctx.admin.merchant.baseRate / 100;
+    const result = Math.round(amount * rate * 100) / 100;
+    return result;
+  }
+  // 截取流水的转账
+  async capturedTransferStream(openOrderObj, type) {
+    // /v1/transfers
+    const params = {
+      // ...openOrderObj,
+      request_id: this.createRequest_id(openOrderObj),
+      from_account_id: openOrderObj.account_id,
+      to_account_id: this.easyPayAdapter.baseInfo.account_id,
+      currency: openOrderObj.currency,
+      amount: this.getTotransfersAmount(openOrderObj.amount),
+      purpose: "收取手续费用"
+    }
+    // 截取流水的转账
+    const res = await this.easyPayAdapter.request("POST", "/v1/transfers", params);
+    // 记录流水
+    await this.save_user_order(res, params, OrderType.TRANSACTION_FEE_ORDER, openOrderObj);
+  }
+
 
   createSign(params, timestamp, nonce, secret) {
     // 2. 生成签名

+ 12 - 1
src/modules/payment/adapter/easypay.adapter.ts

@@ -96,6 +96,8 @@ export class EasyPayAdapter {
   @Inject()
   logger: ILogger;
 
+
+
   private config: {
     apiKey: string;
     apiSecret: string;
@@ -106,6 +108,14 @@ export class EasyPayAdapter {
     tokenManager: TokenManager;
   };
 
+  baseInfo: {
+    account_id?: string
+  }
+
+
+  Init() {
+    this.initConfig()
+  }
   /**
    * 初始化渠道配置
    */
@@ -132,6 +142,7 @@ export class EasyPayAdapter {
         chainApiUrl: channel.chainApiUrl,
         tokenManager: tokenManager,
       };
+      this.baseInfo = channel.config
     }
   }
 
@@ -165,7 +176,7 @@ export class EasyPayAdapter {
       // console.log('response', response.data.data);
       return response.data.data;
     } catch (error) {
-      
+
       // console.log(error.response.data);
       if (axios.isAxiosError(error) && error.response) {
         // console.log(error.response.data);

+ 4 - 1
src/modules/payment/entity/merchant.ts

@@ -21,9 +21,12 @@ export class MerchantEntity extends BaseEntity {
   @Column({ comment: '邮箱' })
   email: string;
 
+  @Column({ comment: '基础费率' })
+  baseRate: number;
+
   @Column({ comment: 'API Secret', default: '' , nullable: true})
   apikey!: string;
-  
+
   @Column({ comment: 'API Secret', default: '' , nullable: true})
   apiSecret!: string;