Key-In 결제 List,결제 신청, 결제신청결과 화면 추가

This commit is contained in:
HyeonJongKim
2025-09-12 14:45:51 +09:00
parent 188fe5b259
commit 044a0c56c3
11 changed files with 434 additions and 12 deletions

View File

@@ -17,7 +17,7 @@ export const extensionKeyinApply = (params: ExtensionKeyinApplyParams) => {
);
};
export const useExtensionKeyinListMutation = (options?: UseMutationOptions<ExtensionKeyinApplyResponse, CBDCAxiosError, ExtensionKeyinApplyParams>) => {
export const useExtensionKeyinApplyMutation = (options?: UseMutationOptions<ExtensionKeyinApplyResponse, CBDCAxiosError, ExtensionKeyinApplyParams>) => {
const mutation = useMutation<ExtensionKeyinApplyResponse, CBDCAxiosError, ExtensionKeyinApplyParams>({
...options,
mutationFn: (params: ExtensionKeyinApplyParams) => extensionKeyinApply(params),

View File

@@ -29,6 +29,8 @@ import { LinkPaymentApplyConfirmPage } from './link-payment/apply/link-payment-a
import { LinkPaymentApplySuccessPage } from './link-payment/apply/link-payment-apply-success-page';
import { LinkPaymentDetailPage } from './link-payment/link-payment-detail-page';
import { LinkPaymentPendingDetailPage } from './link-payment/link-payment-pending-detail-page';
import { KeyInPaymentRequestPage } from './key-in-payment/requeset-page';
import { KeyInPaymentRequestSuccessPage } from './key-in-payment/request-success-page';
export const AdditionalServicePages = () => {
return (
@@ -41,7 +43,11 @@ export const AdditionalServicePages = () => {
<Route path={ROUTE_NAMES.additionalService.arsCardPayment.request} element={<ArsCardPaymentRequestPage />} />
<Route path={ROUTE_NAMES.additionalService.arsCardPayment.requestSuccess} element={<ArsCardPaymentRequestSuccessPage />} />
</Route>
<Route path={ROUTE_NAMES.additionalService.keyInPayment} element={<KeyInPaymentPage />} />
<Route path={ROUTE_NAMES.additionalService.keyInPayment.base}>
<Route path={ROUTE_NAMES.additionalService.keyInPayment.list} element={<KeyInPaymentPage/>} />
<Route path={ROUTE_NAMES.additionalService.keyInPayment.request} element={<KeyInPaymentRequestPage/>} />
<Route path={ROUTE_NAMES.additionalService.keyInPayment.requestSuccess} element={<KeyInPaymentRequestSuccessPage/>} />
</Route>
<Route path={ROUTE_NAMES.additionalService.smsPaymentNotification} element={<SmsPaymentNotificationPage />} />
<Route path={ROUTE_NAMES.additionalService.accountHolderSearch} element={<AccountHolderSearchPage />} />
<Route path={ROUTE_NAMES.additionalService.accountHolderAuth} element={<AccountHolderAuthPage />} />

View File

@@ -31,7 +31,7 @@ export const IntroPage = () => {
},
{
className: 'list-wrap01', serviceName: 'KEY-IN 결제', serviceDesc: '상담 중 카드정보 입력으로 간편한 결제 지원',
icon: IMAGE_ROOT + '/icon_ing02.svg', path: PATHS.additionalService.keyInPayment
icon: IMAGE_ROOT + '/icon_ing02.svg', path: PATHS.additionalService.keyInPayment.list
},
{
className: 'list-wrap01', serviceName: '계좌성명조회', serviceDesc: '예금주 정보 입력으로 즉시 예금주 확인',

View File

@@ -1,18 +1,156 @@
import { useState } from 'react';
import { IMAGE_ROOT } from '@/shared/constants/common';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { HeaderType } from '@/entities/common/model/types';
import {
useSetHeaderTitle,
useSetHeaderType,
useSetFooterMode
import {
useSetHeaderTitle,
useSetHeaderType,
useSetFooterMode
} from '@/widgets/sub-layout/use-sub-layout';
import { PATHS } from '@/shared/constants/paths';
export const KeyInPaymentPage = () => {
const { navigate } = useNavigate();
useSetHeaderTitle('KEY-IN 결제');
useSetHeaderType(HeaderType.LeftArrow);
useSetFooterMode(true);
useSetFooterMode(false);
const onClickToNavigation = () => {
navigate(PATHS.additionalService.keyInPayment.request)
}
return (
<>
<main>
<div className="tab-content">
<div className="tab-pane sub active">
<section className="summary-section no-border">
<div className="credit-controls">
<div>
<input
className="credit-period"
type="text"
value="2025.06.01 ~ 2025.06.31"
readOnly={true}
/>
<button
className="filter-btn"
aria-label="필터"
>
<img
src={IMAGE_ROOT + '/ico_setting.svg'}
alt="검색옵션"
/>
</button>
</div>
<button
className="download-btn"
aria-label="다운로드"
>
<img
src={IMAGE_ROOT + '/ico_download.svg'}
alt="다운로드"
/>
</button>
</div>
</section>
<section className="filter-section">
<div className="sort-options">
<button className="sort-btn active"></button>
<span className="sort-divider">|</span>
<button className="sort-btn"></button>
</div>
<div className="excrow">
<div className="full-menu-keywords no-padding">
<span className="keyword-tag active"></span>
<span className="keyword-tag"></span>
<span className="keyword-tag"></span>
<span className="keyword-tag"></span>
</div>
</div>
</section>
<section className="transaction-list">
<div className="date-group">
<div className="date-header">2025.06.08()</div>
<div className="transaction-item approved">
<div className="transaction-status">
<div className="status-dot blue"></div>
</div>
<div className="transaction-content">
<div className="transaction-title">*(7000)</div>
<div className="transaction-details">
<span>20:00ㅣ승인</span>
</div>
</div>
<div className="transaction-amount">5,254,000</div>
</div>
<div className="transaction-item refund">
<div className="transaction-status">
<div className="status-dot gray"></div>
</div>
<div className="transaction-content">
<div className="transaction-title">*(7000)</div>
<div className="transaction-details">
<span>08:35ㅣ승인</span>
</div>
</div>
<div className="transaction-amount">23,845,000</div>
</div>
<div className="transaction-item approved">
<div className="transaction-status">
<div className="status-dot blue"></div>
</div>
<div className="transaction-content">
<div className="transaction-title">*(7000)</div>
<div className="transaction-details">
<span>20:00ㅣ승인</span>
</div>
</div>
<div className="transaction-amount">5,254,000</div>
</div>
<div className="transaction-item approved">
<div className="transaction-status">
<div className="status-dot blue"></div>
</div>
<div className="transaction-content">
<div className="transaction-title">*(7000)</div>
<div className="transaction-details">
<span>20:00ㅣ후취소</span>
</div>
</div>
<div className="transaction-amount">5,254,000</div>
</div>
<div className="transaction-item refund">
<div className="transaction-status">
<div className="status-dot gray"></div>
</div>
<div className="transaction-content">
<div className="transaction-title">*(7000)</div>
<div className="transaction-details">
<span>20:00ㅣ후취소</span>
</div>
</div>
<div className="transaction-amount">23,845,000</div>
</div>
</div>
</section>
<div className="apply-row">
<button
className="btn-50 btn-blue flex-1"
onClick={() => onClickToNavigation()}
> </button>
</div>
</div>
</div>
</main>
</>
);
};

View File

@@ -0,0 +1,210 @@
import { useState } from 'react';
import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { IMAGE_ROOT } from '@/shared/constants/common';
import { HeaderType } from '@/entities/common/model/types';
import { useExtensionKeyinApplyMutation } from '@/entities/additional-service/api/use-extension-keyin-apply-mutation';
import {
useSetHeaderTitle,
useSetHeaderType,
useSetFooterMode,
useSetOnBack
} from '@/widgets/sub-layout/use-sub-layout';
import { number } from 'framer-motion';
export const KeyInPaymentRequestPage = () => {
const { navigate } = useNavigate();
const { mutateAsync: keyInApply } = useExtensionKeyinApplyMutation();
useSetHeaderTitle('KEY-IN 결제');
useSetHeaderType(HeaderType.LeftArrow);
useSetFooterMode(false);
useSetOnBack(() => {
navigate(PATHS.additionalService.keyInPayment.list);
});
const callKeyInPaymentRequest = () => {
let keyInApplyParams = {
mid: 'string',
goodsName: 'string',
amount: 0,
buyerName: 'string',
email: 'string',
phoneNumber: 'string',
cardNo: 'string',
cardExpirationDate: 'string',
instmntMonth: 'string',
moid: 'SMS',
};
keyInApply(keyInApplyParams).then((rs) => {
navigate(PATHS.additionalService.arsCardPayment.requestSuccess);
console.log(rs)
}).catch(() => {
}).finally(() => {
});
};
const [formData, setFormData] = useState({
mid: 'nictest001m',
goodsName: '',
amount: 0
});
const handleInputChange = (field: string, value: string) => {
setFormData(prev => ({
...prev,
[field]: value
}));
};
const onClickToRequest = () => {
callKeyInPaymentRequest();
};
return (
<>
<main>
<div className="tab-content">
<div className="tab-pane sub active">
<div className="option-list">
<div className="billing-form gap-16">
<div className="billing-row">
<div className="billing-label"> <span>*</span></div>
<div className="billing-field">
<select
className="wid-100"
onChange={(e) => handleInputChange('merchant', e.target.value)}
>
<option>nictest001m</option>
</select>
</div>
</div>
<div className="billing-row">
<div className="billing-label"> <span>*</span></div>
<div className="billing-field">
<input
type="text"
value=""
/>
</div>
</div>
<div className="billing-row">
<div className="billing-label"> <span>*</span></div>
<div className="billing-field">
<input
type="text"
value=""
/>
</div>
</div>
<div className="billing-row">
<div className="billing-label"> <span>*</span></div>
<div className="billing-field">
<input
type="text"
value=""
/>
</div>
</div>
<div className="billing-row">
<div className="billing-label"> <span>*</span></div>
<div className="billing-field">
<select disabled>
<option selected></option>
<option></option>
</select>
</div>
</div>
<div className="billing-row">
<div className="billing-label"> <span>*</span></div>
<div className="billing-field">
<input
type="text"
value=""
placeholder=" '-' 제외하고 입력"
/>
</div>
</div>
<div className="billing-row">
<div className="billing-label"> <span>*</span></div>
<div className="billing-field">
<input
type="text"
value=""
/>
</div>
<div className="billing-field">
<input
type="text"
value=""
/>
</div>
<div className="billing-field">
<input
type="text"
value=""
/>
</div>
<div className="billing-field">
<input
type="text"
value=""
/>
</div>
</div>
<div className="billing-row">
<div className="billing-label">(/)<span>*</span></div>
<div className="billing-field">
<input
type="text"
value=""
placeholder='MM/YY'
/>
</div>
</div>
<div className="billing-row">
<div className="billing-label"> <span>*</span></div>
<div className="billing-field">
<select
className="wid-100"
onChange={(e) => handleInputChange('merchant', e.target.value)}
>
<option></option>
</select>
</div>
</div>
<div className="billing-row">
<div className="billing-label"></div>
<div className="billing-field">
<input
type="text"
value=""
/>
</div>
</div>
</div>
</div>
<div className="apply-row">
<button
className="btn-50 btn-blue flex-1"
onClick={() => onClickToRequest() }
> </button>
</div>
</div>
</div>
</main>
</>
)
}

View File

@@ -0,0 +1,43 @@
import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { HeaderType } from '@/entities/common/model/types';
import {
useSetHeaderType,
useSetFooterMode,
} from '@/widgets/sub-layout/use-sub-layout';
export const KeyInPaymentRequestSuccessPage = () => {
const { navigate } = useNavigate();
useSetHeaderType(HeaderType.NoHeader);
useSetFooterMode(false);
const onClickToNavigate = () => {
navigate(PATHS.additionalService.keyInPayment.list);
};
return (
<>
<div className="success-page" >
<div className="success-body">
<div
className="success-icon"
aria-hidden="true"
></div>
<h1 className="success-title">
<span>KEY-IN </span><br/>
<span> .</span>
</h1>
<div className="success-result">
<p className="result-text"> : [0000] ARS </p>
</div>
</div>
<div className="apply-row">
<button
className="btn-50 btn-blue flex-1"
onClick={ () => onClickToNavigate() }
></button>
</div>
</div>
</>
);
};

View File

@@ -13,6 +13,9 @@ import {
useSetOnBack
} from '@/widgets/sub-layout/use-sub-layout';
/**
* 발송내역 탭 화면
*/
export const LinkPaymentDispatchListPage = () => {
const { navigate } = useNavigate();

View File

@@ -14,6 +14,9 @@ import {
} from '@/widgets/sub-layout/use-sub-layout';
import { LinkPaymentFilter } from '@/entities/additional-service/ui/link-payment/link-payment-filter';
/**
* 발송대기 탭 화면
*/
export const LinkPaymentPendingSendPage = () => {
const { navigate } = useNavigate();

View File

@@ -157,7 +157,21 @@ export const PATHS: RouteNamesType = {
ROUTE_NAMES.additionalService.arsCardPayment.requestSuccess,
),
},
keyInPayment: generatePath(ROUTE_NAMES.additionalService.base, ROUTE_NAMES.additionalService.keyInPayment),
keyInPayment: {
base: generatePath(`${ROUTE_NAMES.additionalService.base}${ROUTE_NAMES.additionalService.keyInPayment.base}`),
list: generatePath(
`${ROUTE_NAMES.additionalService.base}${ROUTE_NAMES.additionalService.keyInPayment.base}`,
ROUTE_NAMES.additionalService.keyInPayment.list
),
request: generatePath(
`${ROUTE_NAMES.additionalService.base}${ROUTE_NAMES.additionalService.keyInPayment.base}`,
ROUTE_NAMES.additionalService.keyInPayment.request,
),
requestSuccess: generatePath(
`${ROUTE_NAMES.additionalService.base}${ROUTE_NAMES.additionalService.keyInPayment.base}`,
ROUTE_NAMES.additionalService.keyInPayment.requestSuccess,
),
},
smsPaymentNotification: generatePath(ROUTE_NAMES.additionalService.base, ROUTE_NAMES.additionalService.smsPaymentNotification),
accountHolderSearch: generatePath(ROUTE_NAMES.additionalService.base, ROUTE_NAMES.additionalService.accountHolderSearch),
accountHolderAuth: generatePath(ROUTE_NAMES.additionalService.base, ROUTE_NAMES.additionalService.accountHolderAuth),

View File

@@ -76,7 +76,12 @@ export const ROUTE_NAMES = {
request: 'request',
requestSuccess: 'request-success',
},
keyInPayment: 'key-in-payment',
keyInPayment: {
base: '/key-in-payment/*',
list: 'list',
request: 'request',
requestSuccess: 'request-success',
},
smsPaymentNotification: 'sms-payment-notification',
accountHolderSearch: 'account-holder-search',
accountHolderAuth: 'account-holder-auth',

View File

@@ -83,7 +83,7 @@ export const Menu = ({
items: [
{title: '부가서비스소개', path: PATHS.additionalService.intro},
{title: 'ARS 카드결제', path: PATHS.additionalService.arsCardPayment.list},
{title: 'KEY-IN 결제', path: PATHS.additionalService.keyInPayment},
{title: 'KEY-IN 결제', path: PATHS.additionalService.keyInPayment.list},
{title: 'SMS 결제 통보', path: PATHS.additionalService.smsPaymentNotification},
{title: '계좌성명조회', path: PATHS.additionalService.accountHolderSearch},
{title: '계좌점유인증', path: PATHS.additionalService.accountHolderAuth},