|
@@ -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);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|