123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- import { Inject, Logger, Provide } from '@midwayjs/decorator';
- import { BaseService, CoolCommException } from '@cool-midway/core';
- import { InjectEntityModel } from '@midwayjs/typeorm';
- import { Repository } from 'typeorm';
- import * as _ from 'lodash';
- import { KycEntity } from '../entity/kyc';
- import { SunPayService } from './channels/sunpay';
- import { ILogger } from '@midwayjs/logger';
- import { PayService } from './pay';
- import * as moment from 'moment';
- import * as md5 from 'md5';
- @Provide()
- export class KycOpenService extends BaseService {
- @InjectEntityModel(KycEntity)
- kycEntity: Repository<KycEntity>;
- @Inject()
- sunPayService: SunPayService
- @Inject()
- payService: PayService
- @Logger()
- logger: ILogger;
- async validGetCustomer(payload) {
- if (_.isEmpty(payload.mchId)) {
- throw new Error('商户编号【mchId】不能为空');
- }
- if (_.isEmpty(payload.userId)) {
- throw new Error('商户平台用户ID【userId】不能为空');
- }
- }
- async getCustomer(payload) {
- try {
- this.logger.info('获取客户信息', JSON.stringify(payload));
- await this.validGetCustomer(payload);
- const merchant = await this.payService.validMerchant(payload.mchId);
- await this.payService.validSign(payload, merchant);
- let kyc = await this.kycEntity.findOneBy({
- mchId: payload.mchId,
- userId: payload.userId,
- code: 'SUN_CARD',
- })
- if (kyc && kyc.customerId) {
- return {
- mchId: kyc.mchId,
- userId: kyc.mchId,
- kycUserId: kyc.userId,
- country: kyc.country,
- level: kyc.level,
- email: kyc.email
- }
- }
- const outUserId = md5(payload.mchId + '_' + payload.userId + 'v2');
- const data = await this.sunPayService.queryKyc(outUserId);
- const newKyc = {
- userId: payload.userId,
- mchId: payload.mchId,
- code: 'SUN_CARD',
- kycUserId: data.kycUserId,
- customerId: data.customerId,
- level: '1',
- country: data.countryCode,
- email: data.customerEmail
- }
- await this.kycEntity.insert(kyc)
- return {
- mchId: newKyc.mchId,
- userId: newKyc.mchId,
- kycUserId: newKyc.userId,
- country: newKyc.country,
- email: newKyc.email,
- level: newKyc.level
- }
- } catch (err) {
- this.logger.error('获取客户信息', JSON.stringify(payload), err.message);
- throw new CoolCommException(err.message);
- }
- }
- async validPremiumParam(payload, files) {
- if (_.isEmpty(payload.mchId)) {
- throw new Error('商户编号【mchId】不能为空');
- }
- if (_.isEmpty(payload.kycUserId)) {
- throw new Error('KYC用户ID【kycUserId】不能为空');
- }
- if (!files.residentialAddress) {
- throw new Error('居住地址证明文件【residentialAddress】不能为空');
- }
- if (!files.income) {
- throw new Error('收入证明文件【income】不能为空');
- }
- if (_.isEmpty(payload.sign)) {
- throw new Error('签名【sign】不能为空');
- }
- }
- async createOpenPremium(payload, files) {
- try {
- this.logger.info('KYC高级认证', JSON.stringify(payload));
- if (!files) {
- throw new Error('参数错误,请提交正确参数');
- }
- const fileObj = {};
- files.forEach(item => {
- fileObj[item.fieldName] = item
- })
- await this.validPremiumParam(payload, fileObj);
- const merchant = await this.payService.validMerchant(payload.mchId);
- await this.payService.validSign(payload, merchant);
- const kyc = await this.kycEntity.findOneBy({ kycUserId: payload.kycUserId });
- if (!kyc || !kyc.customerId) {
- throw new CoolCommException('KYC用户不存在');
- }
- const data = await this.sunPayService.createPremium({
- customerId: kyc.customerId,
- }, fileObj);
- await this.kycEntity.update(kyc.id, { level: '3' });
- return { kycUserId: payload.kycUserId }
- } catch (err) {
- this.logger.error('KYC高级认证提交失败', JSON.stringify(payload), err.message);
- throw new CoolCommException(err.message);
- }
- }
- async validAdvanced(payload, files) {
- if (_.isEmpty(payload.mchId)) {
- throw new Error('商户编号【mchId】不能为空');
- }
- if (_.isEmpty(payload.kycUserId)) {
- throw new Error('KYC用户ID【kycUserId】不能为空');
- }
- if (_.isEmpty(payload.documentType)) {
- throw new Error('证件类型【documentType】不能为空');
- }
- if (+payload.documentType < 0 || +payload.documentType > 2) {
- throw new Error('证件类型【documentType】取值错误');
- }
- if (_.isEmpty(payload.documentNumber)) {
- throw new Error('证件号码【documentNumber】不能为空');
- }
- if (!files.frontSideDocument) {
- throw new Error('证件正面图片【frontSideDocument】不能为空');
- }
- if (!files.backSideDocument) {
- throw new Error('证件背面图片【backSideDocument】不能为空');
- }
- if (!files.customerPhoto) {
- throw new Error('客户人像图片【customerPhoto】不能为空');
- }
- if (_.isEmpty(payload.sign)) {
- throw new Error('签名【sign】不能为空');
- }
- }
- async createOpenAdvanced(payload, files) {
- try {
- this.logger.info('KYC进阶认证', JSON.stringify(payload));
- if (!files) {
- throw new Error('参数错误,请提交正确参数');
- }
- const fileObj = {};
- files.forEach(item => {
- fileObj[item.fieldName] = item
- })
- await this.validAdvanced(payload, fileObj);
- const merchant = await this.payService.validMerchant(payload.mchId);
- await this.payService.validSign(payload, merchant);
- const kyc = await this.kycEntity.findOneBy({ kycUserId: payload.kycUserId });
- if (!kyc || !kyc.customerId) {
- throw new CoolCommException('KYC用户不存在');
- }
- const data = await this.sunPayService.createAdvanced({
- customerId: kyc.customerId,
- documentType: payload.documentType,
- documentNumber: payload.documentNumber
- }, fileObj);
- await this.kycEntity.update(kyc.id, { level: '2' });
- return { kycUserId: payload.kycUserId }
- } catch (err) {
- this.logger.error('KYC进阶认证提交失败', JSON.stringify(payload), err.message);
- throw new CoolCommException(err.message);
- }
- }
- async validBasicParam(payload) {
- if (_.isEmpty(payload.mchId)) {
- throw new Error('商户编号【mchId】不能为空');
- }
- if (_.isEmpty(payload.userId)) {
- throw new Error('商户平台用户ID【userId】不能为空');
- }
- if (_.isEmpty(payload.customerName)) {
- throw new Error('客户姓名【customerName】不能为空');
- }
- if (_.isEmpty(payload.customerEmail)) {
- throw new Error('客户邮箱地址【customerEmail】不能为空');
- }
- if (_.isEmpty(payload.countryCode)) {
- throw new Error('国家编码【countryCode】不能为空');
- }
- if (_.isEmpty(payload.residenceCountry)) {
- throw new Error('国家编码【residenceCountry】不能为空');
- }
- if (_.isEmpty(payload.birthDate)) {
- throw new Error('出生日期【birthDate】不能为空');
- }
- if (!moment(payload.birthDate).isValid()) {
- throw new Error('出生日期【birthDate】非正确日期格式');
- }
- if (_.isEmpty(payload.sign)) {
- throw new Error('签名【sign】不能为空');
- }
- }
- async createOpenBasic(payload) {
- try {
- this.logger.info('KYC基础认证', JSON.stringify(payload));
- await this.validBasicParam(payload);
- const merchant = await this.payService.validMerchant(payload.mchId);
- await this.payService.validSign(payload, merchant);
- const kyc = await this.kycEntity.findOneBy({
- mchId: payload.mchId,
- userId: payload.userId,
- code: 'SUN_CARD',
- })
- if (kyc) {
- throw new Error('当前客户ID已存在,请勿重复提交');
- }
- const emailKyc = await this.kycEntity.findOneBy({ email: payload.customerEmail });
- if (emailKyc) {
- throw new CoolCommException('邮箱已被使用');
- }
- const outUserId = md5(payload.mchId + '_' + payload.userId + 'v2');
- const { customerId } = await this.sunPayService.createBasic({
- outUserId,
- customerName: payload.customerName,
- customerEmail: payload.customerEmail,
- countryCode: payload.countryCode,
- residenceCountry: payload.residenceCountry,
- birthDate: payload.birthDate,
- });
- if (customerId) {
- await this.kycEntity.insert({
- userId: payload.userId,
- mchId: payload.mchId,
- code: 'SUN_CARD',
- kycUserId: outUserId,
- customerId: customerId,
- email: payload.customerEmail,
- level: '1',
- country: payload.countryCode
- })
- return { kycUserId: outUserId }
- } else {
- throw new CoolCommException('Network exception, please try again later');
- }
- } catch (err) {
- this.logger.error('KYC基础认证提交失败', JSON.stringify(payload), err.message);
- throw new CoolCommException(err.message);
- }
- }
- }
|