- 부가서비스 소개 List, 권한 검증 추가

- 각 API 오류 수정
This commit is contained in:
HyeonJongKim
2025-10-24 20:45:24 +09:00
parent 2f13c29d1b
commit b10376e171
33 changed files with 657 additions and 284 deletions

View File

@@ -0,0 +1,31 @@
import axios from 'axios';
import { API_URL_ADDITIONAL_SERVICE } from '@/shared/api/api-url-additional-service';
import { resultify } from '@/shared/lib/resultify';
import { CBDCAxiosError } from '@/shared/@types/error';
import {
ExtensionCheckParams,
ExtensionCheckResponse,
ExtensionListParams,
ExtensionListResponse
} from '../model/types';
import {
useMutation,
UseMutationOptions
} from '@tanstack/react-query';
export const extensionCheck = (params: ExtensionCheckParams) => {
return resultify(
axios.post<ExtensionCheckResponse>(API_URL_ADDITIONAL_SERVICE.extensionCheck(), params),
);
};
export const useExtensionCheckMutation = (options?: UseMutationOptions<ExtensionCheckResponse, CBDCAxiosError, ExtensionCheckParams>) => {
const mutation = useMutation<ExtensionCheckResponse, CBDCAxiosError, ExtensionCheckParams>({
...options,
mutationFn: (params: ExtensionCheckParams) => extensionCheck(params),
});
return {
...mutation,
};
};

View File

@@ -81,10 +81,10 @@ export const getAlimtalkServiceCodeText = (status?: string): string => {
if (!status) return '';
const serviceCodeMap: Record<string, string> = {
'01': '카드',
'02': '신용카드',
'03': '가상계좌',
'05': '휴대폰'
'CARD': '신용카드',
'BANK': '계좌이체',
'VBANK': '가상계좌',
'PHONE': '휴대폰'
}
return serviceCodeMap[status] || status;

View File

@@ -126,14 +126,14 @@ export interface ExtensionAlimtalkDetailParams {
export interface ExtensionAlimtalkDetailResponse {
receiverName: string;
merchantName: string;
companyName: string;
sendDate: string;
mid: string;
tid: string;
extensionServiceName: string;
sendType: AlimtalkSendType;
senderName: string;
paymentMethod: string;
serviceCode: string;
alimCl: AlimtalkAlimCl;
sendCl: AlimTalkSendCl;
};

View File

@@ -9,4 +9,16 @@ export const PayoutDisbursementStatusBtnGroup = [
{name: '요청', value: PayoutDisbursementStatus.REQUEST},
{name: '성공', value: PayoutDisbursementStatus.SUCCESS},
{name: '실패', value: PayoutDisbursementStatus.FAIL},
];
];
export const getPayoutStatusText = (status?: string): string => {
if (!status) return '';
const statusMap: Record<string, string> = {
"REQUEST" : "요청",
"SUCCESS" : "성공",
"FAIL" : "실패"
}
return statusMap[status] || status;
}

View File

@@ -6,7 +6,9 @@ export interface ExtensionPayoutRequestParams {
disbursementAmount: number;
settlementDate: string;
};
export interface ExtensionPayoutRequestResponse {};
export interface ExtensionPayoutRequestResponse {
status: boolean;
};
export enum PayoutSearchDateType {
REQUEST_DATE = 'REQUEST_DATE',
SETTLEMENT_DATE = 'SETTLEMENT_DATE',
@@ -36,10 +38,15 @@ export interface PayoutContent {
requestDate?: string;
settlementDate?: string;
companyName?: string;
disbursementStatus?: PayoutDisbursementStatus;
disbursementAmount?: number;
status?: PayoutDisbursementStatus;
amount?: number;
};
export interface ExtensionPayoutExcelParams {
mid: string;
email: string;
fromDate: string;
toDate: string;
};
export interface ExtensionPayoutExcelParams extends ExtensionPayoutListParams {};
export interface ExtensionPayoutExcelResponse {}

View File

@@ -117,6 +117,7 @@ export interface ExtensionSmsDownloadExcelParams extends ExtensionRequestParams
fromDate: string;
toDate: string;
smsCl: string;
}
export interface ExtensionSmsDownloadExcelResponse {

View File

@@ -10,6 +10,8 @@ import { AccountHolderSearchListItem } from './account-holder-search/types';
import { KeyInPaymentListItem } from './key-in/types';
import { AccountHolderAuthListItem, AccountHolderAuthStatus } from './account-holder-auth/types';
import { LinkContentType, LinkPaymentHistoryListItem, LinkPaymentSendMethod, LinkPaymentWaitListItem } from './link-pay/types';
import { IMAGE_ROOT } from '@/shared/constants/common';
import { PATHS } from '@/shared/constants/paths';
// ========================================
// 공통 Enums 및 타입들
@@ -47,6 +49,20 @@ export enum Language {
EN = "EN"
}
export const SERVICE_MAP = [
{ code: 'SMS', serviceName: 'SMS 결제 통보', serviceDesc: '입금 요청부터 완료까지 SMS 자동 전송', icon: IMAGE_ROOT + '/icon_ing03.svg', path: PATHS.additionalService.smsPaymentNotification },
{ code: 'ARS', serviceName: '신용카드 ARS 결제', serviceDesc: '전화 한 통으로 결제 성공 편리하고 안전한 서비스', icon: IMAGE_ROOT + '/icon_ing01.svg', path: PATHS.additionalService.ars.list },
{ code: 'KEYIN', serviceName: 'KEY-IN 결제', serviceDesc: '상담 중 카드정보 입력으로 간편한 결제 지원', icon: IMAGE_ROOT + '/icon_ing02.svg', path: PATHS.additionalService.keyInPayment.list },
{ code: 'SEARCH_ACCOUNT_NAME', serviceName: '계좌성명조회', serviceDesc: '예금주 정보 입력으로 즉시 예금주 확인', icon: IMAGE_ROOT + '/icon_ing04.svg', path: PATHS.additionalService.accountHolderSearch.list },
{ code: 'PAYOUT', serviceName: '지급대행', serviceDesc: '하위 가맹점에 빠른 정산금 지급 지급대행 서비스', icon: IMAGE_ROOT + '/icon_ing05.svg', path: PATHS.additionalService.payout.list },
{ code: 'SETTLEMENT', serviceName: '정산대행', serviceDesc: '하위 가맹점 정산금 계산부터 지급까지 자동 해결 서비스', icon: IMAGE_ROOT + '/icon_ing06.svg', path: PATHS.additionalService.settlementAgency.manage },
{ code: 'LINKPAY', serviceName: '링크 결제', serviceDesc: '결제 링크 전송만으로 어디서든 결제 가능 서비스', icon: IMAGE_ROOT + '/icon_ing07.svg', path: PATHS.additionalService.linkPayment.shippingHistory },
{ code: 'FUND_ACCOUNT', serviceName: '자금이체', serviceDesc: '예치금으로 즉시 송금, 파일 등록만으로 다중 송금 가능', icon: IMAGE_ROOT + '/icon_ing08.svg', path: PATHS.additionalService.fundAccount.transferList },
{ code: 'ACCOUNT_AUTH', serviceName: '계좌점유인증', serviceDesc: '1원 송금으로 실제 계좌 점유 확인 여부', icon: IMAGE_ROOT + '/icon_ing09.svg', path: PATHS.additionalService.accountHolderAuth.list },
{ code: 'ALIMTALK', serviceName: '알림톡 결제통보', serviceDesc: '결제 상태를 알림톡으로 쉽고 빠른 안내', icon: IMAGE_ROOT + '/icon_ing10.svg', path: PATHS.additionalService.alimtalk.list },
{ code: 'FACE_AUTH', serviceName: '얼굴인증', serviceDesc: '얼굴 인식으로 간편 본인확인과 결제 가능한 안전 결제 서비스', icon: IMAGE_ROOT + '/icon_ing11.svg', path: PATHS.additionalService.faceAuth.list },
];
// ========================================
// 상세정보 Interface
// ========================================
@@ -223,8 +239,17 @@ export interface ExtensionListItemProps {
availableExtensionList: Array<availableExtensionListItem>;
}
export interface ExtensionListResponse extends DefaulResponsePagination {
content: Array<ExtensionListItemProps>
export interface ExtensionListResponse {
activeExtensionList: string[];
availableExtensionList: string[];
}
export interface ExtensionCheckParams {
extensionCode: string;
}
export interface ExtensionCheckResponse {
checkResult: boolean;
}
// ========================================

View File

@@ -1,7 +1,7 @@
import moment from 'moment';
import { IMAGE_ROOT } from '@/shared/constants/common';
import { motion } from 'framer-motion';
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { FilterSelect } from '@/shared/ui/filter/select';
import { FilterCalendar } from '@/shared/ui/filter/calendar';
import { FilterButtonGroups } from '@/shared/ui/filter/button-groups';
@@ -42,6 +42,9 @@ export const AccountHolderAuthFilter = ({
onClickToClose();
};
useEffect(() => {
setFilterAuthStatus(authStatus);
}, [authStatus]);
return (
<>
<motion.div

View File

@@ -49,8 +49,7 @@ export const ListDateGroup = ({
submallId={ items[i]?.submallId }
settlementDate={ items[i]?.settlementDate }
companyName={ items[i]?. companyName }
disbursementStatus={ items[i]?.disbursementStatus }
disbursementAmount={ items[i]?.disbursementAmount }
status={ items[i]?.status }
orderStatus={ items[i]?.orderStatus }
arsPaymentMethod={ items[i]?.arsPaymentMethod }

View File

@@ -12,30 +12,31 @@ import { getArsPaymentStatusName, getArsOrderStatusName } from '../model/ars/con
import { ServiceCode } from '../model/alimtalk/types';
import { getAlimtalkAlimClText, getAlimtalkSendClTypeText, getAlimtalkSendTypeText, getAlimtalkServiceCodeText } from '../model/alimtalk/constant';
import { getAuthResultStatusText, getTransTypeText } from '../model/face-auth/constant';
import { getPayoutStatusText } from '../model/payout/constant';
export const ListItem = ({
additionalServiceCategory,
mid, tid, paymentDate, paymentStatus,
applicationDate, requestDate, bankName, accountNo, resultStatus, resultMessage,
amount, sendMethod, processStatus,registDate,
amount, sendMethod, processStatus, registDate,
accountName,
submallId, settlementDate, companyName,
disbursementStatus, disbursementAmount,
status: disbursementStatus, amount: disbursementAmount,
orderStatus, arsPaymentMethod,
alimCl, sendType, sendCl,
paymentMethod, receiverName,
requestId,subReqId,
buyerName,receiverInfo,
seq,serviceCode,sendDate,
authStatus,
requestId, subReqId,
buyerName, receiverInfo,
seq, serviceCode, sendDate,
authStatus, status,
smsCl,groupId,userMallId,transType,
authResult,failReason,requestTime,
smsCl, groupId, userMallId, transType,
authResult, failReason, requestTime,
onResendClick
}: ListItemProps) => {
const { navigate } = useNavigate();
@@ -89,7 +90,7 @@ export const ListItem = ({
}
}
else if (additionalServiceCategory === AdditionalServiceCategory.Alimtalk) {
if (sendCl === "SUCCESS" || "REQUEST") {
if (sendCl === "SUCCESS" || sendCl === "REQUEST") {
rs = 'blue';
} else {
rs = 'gray';
@@ -104,20 +105,13 @@ export const ListItem = ({
}
}
else if (additionalServiceCategory === AdditionalServiceCategory.LinkPaymentHistory) {
if (paymentStatus === "PAYMENT_COMPLETE") {
if (paymentStatus === "0" || paymentStatus === "1" || paymentStatus === "2") {
rs = 'blue';
}
else if (paymentStatus === "ACTIVE") {
rs = 'blue';
else if (paymentStatus === "3") {
rs = 'gray';
}
else if (paymentStatus === "DEPOSIT_REQUEST") {
rs = 'blue';
}
else if (paymentStatus === "PAYMENT_FAIL") {
rs = 'blue';
}
else if (paymentStatus === "INACTIVE") {
else if (paymentStatus === '4') {
rs = 'gray';
}
} else if (additionalServiceCategory === AdditionalServiceCategory.LinkPaymentWait) {
@@ -144,6 +138,12 @@ export const ListItem = ({
} else if (resultStatus === "FAIL") {
rs = 'gray';
}
} else if (additionalServiceCategory === AdditionalServiceCategory.Payout) {
if (status === "SUCCESS" || status === "REQUEST") {
rs = 'blue';
} else if (status === "FAIL") {
rs = 'gray';
}
}
return rs;
@@ -286,7 +286,7 @@ export const ListItem = ({
if (applicationDate && applicationDate.length >= 12) {
timeStr = applicationDate.substring(8, 10) + ':' + applicationDate.substring(10, 12);
} else {
timeStr = requestDate?.substring(8,10) + ':' + requestDate?.substring(10, 12);
timeStr = requestDate?.substring(8, 10) + ':' + requestDate?.substring(10, 12);
}
}
else if (additionalServiceCategory === AdditionalServiceCategory.Ars) {
@@ -349,9 +349,10 @@ export const ListItem = ({
else if (additionalServiceCategory === AdditionalServiceCategory.FaceAuth) {
str = `${userMallId}(${mid})`;
}
else if (additionalServiceCategory === AdditionalServiceCategory.LinkPaymentHistory ||
additionalServiceCategory === AdditionalServiceCategory.LinkPaymentWait
else if (additionalServiceCategory === AdditionalServiceCategory.LinkPaymentHistory
) {
str = `${buyerName}`;
} else if (additionalServiceCategory === AdditionalServiceCategory.LinkPaymentWait) {
str = `${buyerName}(${receiverInfo})`;
}
else if (additionalServiceCategory === AdditionalServiceCategory.Payout) {
@@ -451,7 +452,7 @@ export const ListItem = ({
else if (additionalServiceCategory === AdditionalServiceCategory.Payout) {
rs.push(
<div className="transaction-details">
<span>{disbursementStatus}</span>
<span>{getPayoutStatusText(disbursementStatus)}</span>
<span className="separator">|</span>
<span>{submallId}</span>
</div>
@@ -498,7 +499,7 @@ export const ListItem = ({
);
}
else if (additionalServiceCategory === AdditionalServiceCategory.Alimtalk) {
console.log(serviceCode)
console.log(serviceCode)
rs.push(
<div className="transaction-details">
<span>{getTime()}</span>

View File

@@ -0,0 +1,90 @@
import { BottomSheetMotionDuration, BottomSheetMotionVaiants } from '@/entities/common/model/constant';
import { IMAGE_ROOT } from '@/shared/constants/common';
import { motion } from 'framer-motion';
export interface DownloadTypeBottomSheetProps {
bottomSheetOn: boolean;
setBottomSheetOn: (bottomSheetOn: boolean) => void;
onSelectType: (type: 'IMAGE' | 'EMAIL') => void;
}
export const DownloadTypeBottomSheet = ({
bottomSheetOn,
setBottomSheetOn,
onSelectType
}: DownloadTypeBottomSheetProps) => {
const onClickToClose = () => {
setBottomSheetOn(false);
};
const handleSelectType = (type: 'IMAGE' | 'EMAIL') => {
onSelectType(type);
setBottomSheetOn(false);
};
return (
<>
{ (bottomSheetOn) &&
<div className="bg-dim"></div>
}
<motion.div
className="bottomsheet"
initial="hidden"
animate={ (bottomSheetOn)? 'visible': 'hidden' }
variants={ BottomSheetMotionVaiants }
transition={ BottomSheetMotionDuration }
>
<div className="bottomsheet-header">
<div className="bottomsheet-title">
<h2> </h2>
<button
className="close-btn"
type="button"
>
<img
src={ IMAGE_ROOT + '/ico_close.svg' }
alt="닫기"
onClick={ () => onClickToClose() }
/>
</button>
</div>
</div>
<div className="bottomsheet-content">
<div className="email-section">
<div
className="email-label mb-10"
onClick={() => handleSelectType('IMAGE')}
style={{ cursor: 'pointer' }}
>
<div className="mail-icon">
<div className="mail-icon-bg"></div>
<img
src={ IMAGE_ROOT + '/ico_pic.svg' }
alt="이미지"
/>
</div>
<span className="label-text"> </span>
</div>
<div
className="email-label"
onClick={() => handleSelectType('EMAIL')}
style={{ cursor: 'pointer' }}
>
<div className="mail-icon">
<div className="mail-icon-bg"></div>
<img
src={ IMAGE_ROOT + '/ico_email.svg' }
alt='메일'
/>
</div>
<span className="label-text"> </span>
</div>
</div>
</div>
</motion.div>
</>
);
};