KEY-IN 결제 페이지 다국어 지원 추가
KEY-IN 결제 관련 모든 페이지에 대한 다국어 지원을 추가했습니다. 변경사항: - 목록 페이지: 페이지 타이틀 다국어화 - 결제 신청 페이지: 모든 폼 레이블, 버튼, 에러 메시지 다국어화 - 성공 페이지: 성공 메시지, 버튼 다국어화 번역 키 추가: - 폼 레이블: merchant, productName, productPrice, buyerName, buyerEmail, buyerPhoneNumber, cardNumber, expiryDate, installmentPeriod, lumpSum, orderNumber - 성공/실패 메시지: requestSuccess, requestFailed, requestError - 성공 페이지: paymentRequestComplete, resultLabel, arsRequestComplete, confirm - 기타: phoneNumberPlaceholder, fullCancel, postCancel 중복 keyIn 섹션 제거 및 통합 완료 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -890,6 +890,31 @@
|
|||||||
"paymentMethod": "Payment Method",
|
"paymentMethod": "Payment Method",
|
||||||
"requestFailed": "Request failed."
|
"requestFailed": "Request failed."
|
||||||
},
|
},
|
||||||
|
"keyIn": {
|
||||||
|
"title": "KEY-IN Payment",
|
||||||
|
"paymentRequest": "Payment Request",
|
||||||
|
"merchant": "Merchant",
|
||||||
|
"productName": "Product Name",
|
||||||
|
"productPrice": "Product Price",
|
||||||
|
"buyerName": "Buyer Name",
|
||||||
|
"buyerEmail": "Buyer Email",
|
||||||
|
"buyerPhoneNumber": "Buyer Phone Number",
|
||||||
|
"phoneNumberPlaceholder": "Enter without -",
|
||||||
|
"cardNumber": "Card Number",
|
||||||
|
"expiryDate": "Expiry Date (MM/YY)",
|
||||||
|
"installmentPeriod": "Installment Period",
|
||||||
|
"lumpSum": "Lump Sum",
|
||||||
|
"orderNumber": "Order Number",
|
||||||
|
"requestSuccess": "KEY-IN payment request successful.",
|
||||||
|
"requestFailed": "Payment request failed.",
|
||||||
|
"requestError": "An error occurred during payment request",
|
||||||
|
"paymentRequestComplete": "Payment request completed.",
|
||||||
|
"resultLabel": "Result",
|
||||||
|
"arsRequestComplete": "ARS request processing complete",
|
||||||
|
"confirm": "Confirm",
|
||||||
|
"fullCancel": "Full Cancel",
|
||||||
|
"postCancel": "Post Cancel"
|
||||||
|
},
|
||||||
"sms": {
|
"sms": {
|
||||||
"title": "SMS Payment Notification",
|
"title": "SMS Payment Notification",
|
||||||
"virtualAccountRequest": "Virtual Account Request",
|
"virtualAccountRequest": "Virtual Account Request",
|
||||||
@@ -1155,11 +1180,6 @@
|
|||||||
"sendCancel": "Send Cancel",
|
"sendCancel": "Send Cancel",
|
||||||
"progressStatus": "Progress Status"
|
"progressStatus": "Progress Status"
|
||||||
},
|
},
|
||||||
"keyIn": {
|
|
||||||
"fullCancel": "Pre-cancel",
|
|
||||||
"partialCancel": "Post-cancel",
|
|
||||||
"productPrice": "Product Price"
|
|
||||||
},
|
|
||||||
"infoWrap": {
|
"infoWrap": {
|
||||||
"paymentInfo": "Payment Information",
|
"paymentInfo": "Payment Information",
|
||||||
"buyerName": "Buyer Name",
|
"buyerName": "Buyer Name",
|
||||||
|
|||||||
@@ -890,6 +890,31 @@
|
|||||||
"paymentMethod": "결제 방식",
|
"paymentMethod": "결제 방식",
|
||||||
"requestFailed": "신청을 실패하였습니다."
|
"requestFailed": "신청을 실패하였습니다."
|
||||||
},
|
},
|
||||||
|
"keyIn": {
|
||||||
|
"title": "KEY-IN 결제",
|
||||||
|
"paymentRequest": "결제 신청",
|
||||||
|
"merchant": "가맹점",
|
||||||
|
"productName": "상품명",
|
||||||
|
"productPrice": "상품가격",
|
||||||
|
"buyerName": "구매자명",
|
||||||
|
"buyerEmail": "구매자 이메일",
|
||||||
|
"buyerPhoneNumber": "구매자 전화번호",
|
||||||
|
"phoneNumberPlaceholder": "- 제외하고 입력",
|
||||||
|
"cardNumber": "카드번호",
|
||||||
|
"expiryDate": "유효기간(월/년)",
|
||||||
|
"installmentPeriod": "할부 기간",
|
||||||
|
"lumpSum": "일시불",
|
||||||
|
"orderNumber": "주문번호",
|
||||||
|
"requestSuccess": "KEY-IN 결제 신청을 성공하였습니다.",
|
||||||
|
"requestFailed": "결제 신청에 실패했습니다.",
|
||||||
|
"requestError": "결제 요청 중 오류가 발생했습니다",
|
||||||
|
"paymentRequestComplete": "결제 신청이 완료되었습니다.",
|
||||||
|
"resultLabel": "결과",
|
||||||
|
"arsRequestComplete": "ARS 요청 처리 완료",
|
||||||
|
"confirm": "확인",
|
||||||
|
"fullCancel": "전취소",
|
||||||
|
"postCancel": "후취소"
|
||||||
|
},
|
||||||
"sms": {
|
"sms": {
|
||||||
"title": "SMS 결제 통보",
|
"title": "SMS 결제 통보",
|
||||||
"virtualAccountRequest": "가상계좌 요청",
|
"virtualAccountRequest": "가상계좌 요청",
|
||||||
@@ -1155,11 +1180,6 @@
|
|||||||
"sendCancel": "발송취소",
|
"sendCancel": "발송취소",
|
||||||
"progressStatus": "진행상태"
|
"progressStatus": "진행상태"
|
||||||
},
|
},
|
||||||
"keyIn": {
|
|
||||||
"fullCancel":"전취소",
|
|
||||||
"postCancel": "후취소",
|
|
||||||
"productPrice": "상품가격"
|
|
||||||
},
|
|
||||||
"infoWrap": {
|
"infoWrap": {
|
||||||
"paymentInfo": "결제 정보",
|
"paymentInfo": "결제 정보",
|
||||||
"buyerName": "구매자명",
|
"buyerName": "구매자명",
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export const KeyInPaymentPage = () => {
|
|||||||
const [maxAmount, setMaxAmount] = useState<number>();
|
const [maxAmount, setMaxAmount] = useState<number>();
|
||||||
const [emailBottomSheetOn, setEmailBottomSheetOn] = useState<boolean>(false);
|
const [emailBottomSheetOn, setEmailBottomSheetOn] = useState<boolean>(false);
|
||||||
|
|
||||||
useSetHeaderTitle('KEY-IN 결제');
|
useSetHeaderTitle(t('additionalService.keyIn.title'));
|
||||||
useSetHeaderType(HeaderType.LeftArrow);
|
useSetHeaderType(HeaderType.LeftArrow);
|
||||||
useSetFooterMode(false);
|
useSetFooterMode(false);
|
||||||
useSetOnBack(() => {
|
useSetOnBack(() => {
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ import { Dialog } from '@/shared/ui/dialogs/dialog';
|
|||||||
import { useStore } from '@/shared/model/store';
|
import { useStore } from '@/shared/model/store';
|
||||||
import { snackBar } from '@/shared/lib';
|
import { snackBar } from '@/shared/lib';
|
||||||
import { NumericFormat, PatternFormat } from 'react-number-format';
|
import { NumericFormat, PatternFormat } from 'react-number-format';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const KeyInPaymentRequestPage = () => {
|
export const KeyInPaymentRequestPage = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { navigate } = useNavigate();
|
const { navigate } = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
@@ -41,7 +43,7 @@ export const KeyInPaymentRequestPage = () => {
|
|||||||
|
|
||||||
const { mutateAsync: keyInApply } = useExtensionKeyinApplyMutation();
|
const { mutateAsync: keyInApply } = useExtensionKeyinApplyMutation();
|
||||||
|
|
||||||
useSetHeaderTitle('KEY-IN 결제');
|
useSetHeaderTitle(t('additionalService.keyIn.title'));
|
||||||
useSetHeaderType(HeaderType.LeftArrow);
|
useSetHeaderType(HeaderType.LeftArrow);
|
||||||
useSetFooterMode(false);
|
useSetFooterMode(false);
|
||||||
useSetOnBack(() => {
|
useSetOnBack(() => {
|
||||||
@@ -87,25 +89,25 @@ export const KeyInPaymentRequestPage = () => {
|
|||||||
|
|
||||||
if (rs.status && rs.data?.success) {
|
if (rs.status && rs.data?.success) {
|
||||||
// 성공: 화면 유지 & 입력 내용 초기화
|
// 성공: 화면 유지 & 입력 내용 초기화
|
||||||
snackBar("KEY-IN 결제 신청을 성공하였습니다.")
|
snackBar(t('additionalService.keyIn.requestSuccess'))
|
||||||
resetForm();
|
resetForm();
|
||||||
} else {
|
} else {
|
||||||
// 실패: 화면 유지 & 입력 내용 유지
|
// 실패: 화면 유지 & 입력 내용 유지
|
||||||
const errorMessage = rs.data?.resultMessage ||
|
const errorMessage = rs.data?.resultMessage ||
|
||||||
rs.error?.message ||
|
rs.error?.message ||
|
||||||
'결제 신청에 실패했습니다.';
|
t('additionalService.keyIn.requestFailed');
|
||||||
console.log('최종 errorMessage:', errorMessage);
|
console.log('최종 errorMessage:', errorMessage);
|
||||||
// HTML 태그 제거
|
// HTML 태그 제거
|
||||||
const cleanMessage = errorMessage.replace(/<br\s*\/?>/gi, ' ').trim();
|
const cleanMessage = errorMessage.replace(/<br\s*\/?>/gi, ' ').trim();
|
||||||
snackBar(`[실패] ${cleanMessage}`);
|
snackBar(`[${t('common.failed')}] ${cleanMessage}`);
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.error('결제 실패:', error);
|
console.error('결제 실패:', error);
|
||||||
const errorMessage = error?.response?.data?.data?.resultMessage ||
|
const errorMessage = error?.response?.data?.data?.resultMessage ||
|
||||||
error?.response?.data?.error?.message ||
|
error?.response?.data?.error?.message ||
|
||||||
error?.message ||
|
error?.message ||
|
||||||
'결제 요청 중 오류가 발생했습니다';
|
t('additionalService.keyIn.requestError');
|
||||||
snackBar(`[실패] ${errorMessage}`);
|
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -152,7 +154,7 @@ export const KeyInPaymentRequestPage = () => {
|
|||||||
<div className="option-list">
|
<div className="option-list">
|
||||||
<div className="billing-form gap-16">
|
<div className="billing-form gap-16">
|
||||||
<div className="billing-row">
|
<div className="billing-row">
|
||||||
<div className="billing-label">가맹점 <span>*</span></div>
|
<div className="billing-label">{t('additionalService.keyIn.merchant')} <span>*</span></div>
|
||||||
<div className="billing-field">
|
<div className="billing-field">
|
||||||
<select
|
<select
|
||||||
value={mid}
|
value={mid}
|
||||||
@@ -171,7 +173,7 @@ export const KeyInPaymentRequestPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="billing-row">
|
<div className="billing-row">
|
||||||
<div className="billing-label">상품명 <span>*</span></div>
|
<div className="billing-label">{t('additionalService.keyIn.productName')} <span>*</span></div>
|
||||||
<div className="billing-field">
|
<div className="billing-field">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -182,7 +184,7 @@ export const KeyInPaymentRequestPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="billing-row">
|
<div className="billing-row">
|
||||||
<div className="billing-label">상품가격 <span>*</span></div>
|
<div className="billing-label">{t('additionalService.keyIn.productPrice')} <span>*</span></div>
|
||||||
<div className="billing-field">
|
<div className="billing-field">
|
||||||
<NumericFormat
|
<NumericFormat
|
||||||
value={amount}
|
value={amount}
|
||||||
@@ -198,7 +200,7 @@ export const KeyInPaymentRequestPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="billing-row">
|
<div className="billing-row">
|
||||||
<div className="billing-label">구매자명 <span>*</span></div>
|
<div className="billing-label">{t('additionalService.keyIn.buyerName')} <span>*</span></div>
|
||||||
<div className="billing-field">
|
<div className="billing-field">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -209,7 +211,7 @@ export const KeyInPaymentRequestPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="billing-row">
|
<div className="billing-row">
|
||||||
<div className="billing-label">구매자 이메일 <span>*</span></div>
|
<div className="billing-label">{t('additionalService.keyIn.buyerEmail')} <span>*</span></div>
|
||||||
<div className="billing-field">
|
<div className="billing-field">
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
@@ -221,12 +223,12 @@ export const KeyInPaymentRequestPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="billing-row">
|
<div className="billing-row">
|
||||||
<div className="billing-label">구매자 전화번호 <span>*</span></div>
|
<div className="billing-label">{t('additionalService.keyIn.buyerPhoneNumber')} <span>*</span></div>
|
||||||
<div className="billing-field">
|
<div className="billing-field">
|
||||||
<input
|
<input
|
||||||
type="tel"
|
type="tel"
|
||||||
value={phoneNumber}
|
value={phoneNumber}
|
||||||
placeholder='- 제외하고 입력'
|
placeholder={t('additionalService.keyIn.phoneNumberPlaceholder')}
|
||||||
onChange={(e: ChangeEvent<HTMLInputElement>) => {
|
onChange={(e: ChangeEvent<HTMLInputElement>) => {
|
||||||
const onlyNumbers = e.target.value.replace(/[^0-9]/g, '');
|
const onlyNumbers = e.target.value.replace(/[^0-9]/g, '');
|
||||||
setPhoneNumber(onlyNumbers);
|
setPhoneNumber(onlyNumbers);
|
||||||
@@ -240,7 +242,7 @@ export const KeyInPaymentRequestPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="billing-row">
|
<div className="billing-row">
|
||||||
<div className="billing-label">카드번호 <span>*</span></div>
|
<div className="billing-label">{t('additionalService.keyIn.cardNumber')} <span>*</span></div>
|
||||||
<div className="billing-field">
|
<div className="billing-field">
|
||||||
<PatternFormat
|
<PatternFormat
|
||||||
value={cardNo1}
|
value={cardNo1}
|
||||||
@@ -284,7 +286,7 @@ export const KeyInPaymentRequestPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="billing-row">
|
<div className="billing-row">
|
||||||
<div className="billing-label">유효기간(월/년)<span>*</span></div>
|
<div className="billing-label">{t('additionalService.keyIn.expiryDate')}<span>*</span></div>
|
||||||
<div className="billing-field" style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
|
<div className="billing-field" style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
|
||||||
<PatternFormat
|
<PatternFormat
|
||||||
placeholder='MM'
|
placeholder='MM'
|
||||||
@@ -326,14 +328,14 @@ export const KeyInPaymentRequestPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="billing-row">
|
<div className="billing-row">
|
||||||
<div className="billing-label">할부 기간<span>*</span></div>
|
<div className="billing-label">{t('additionalService.keyIn.installmentPeriod')}<span>*</span></div>
|
||||||
<div className="billing-field">
|
<div className="billing-field">
|
||||||
<select
|
<select
|
||||||
disabled={amount < 50000}
|
disabled={amount < 50000}
|
||||||
value={instmnt}
|
value={instmnt}
|
||||||
onChange={(e: ChangeEvent<HTMLSelectElement>) => setInstmnt(e.target.value)}
|
onChange={(e: ChangeEvent<HTMLSelectElement>) => setInstmnt(e.target.value)}
|
||||||
>
|
>
|
||||||
<option value="00">일시불</option>
|
<option value="00">{t('additionalService.keyIn.lumpSum')}</option>
|
||||||
{/* {amount >= 50000 && (
|
{/* {amount >= 50000 && (
|
||||||
<>
|
<>
|
||||||
<option value="02">2개월</option>
|
<option value="02">2개월</option>
|
||||||
@@ -354,7 +356,7 @@ export const KeyInPaymentRequestPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="billing-row">
|
<div className="billing-row">
|
||||||
<div className="billing-label">주문번호<span>*</span></div>
|
<div className="billing-label">{t('additionalService.keyIn.orderNumber')}<span>*</span></div>
|
||||||
<div className="billing-field">
|
<div className="billing-field">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -370,7 +372,7 @@ export const KeyInPaymentRequestPage = () => {
|
|||||||
className="btn-50 btn-blue flex-1"
|
className="btn-50 btn-blue flex-1"
|
||||||
onClick={() => onClickToRequest()}
|
onClick={() => onClickToRequest()}
|
||||||
disabled={!isFormValid()}
|
disabled={!isFormValid()}
|
||||||
>결제 신청</button>
|
>{t('additionalService.keyIn.paymentRequest')}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import { PATHS } from '@/shared/constants/paths';
|
import { PATHS } from '@/shared/constants/paths';
|
||||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import { HeaderType } from '@/entities/common/model/types';
|
import { HeaderType } from '@/entities/common/model/types';
|
||||||
import {
|
import {
|
||||||
useSetHeaderType,
|
useSetHeaderType,
|
||||||
useSetFooterMode,
|
useSetFooterMode,
|
||||||
} from '@/widgets/sub-layout/use-sub-layout';
|
} from '@/widgets/sub-layout/use-sub-layout';
|
||||||
export const KeyInPaymentRequestSuccessPage = () => {
|
export const KeyInPaymentRequestSuccessPage = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { navigate } = useNavigate();
|
const { navigate } = useNavigate();
|
||||||
|
|
||||||
useSetHeaderType(HeaderType.NoHeader);
|
useSetHeaderType(HeaderType.NoHeader);
|
||||||
@@ -24,18 +26,18 @@ export const KeyInPaymentRequestSuccessPage = () => {
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></div>
|
></div>
|
||||||
<h1 className="success-title">
|
<h1 className="success-title">
|
||||||
<span>KEY-IN 결제</span><br/>
|
<span>{t('additionalService.keyIn.title')}</span><br/>
|
||||||
<span>결제 신청이 완료되었습니다.</span>
|
<span>{t('additionalService.keyIn.paymentRequestComplete')}</span>
|
||||||
</h1>
|
</h1>
|
||||||
<div className="success-result">
|
<div className="success-result">
|
||||||
<p className="result-text">결과 : [0000] ARS 요청 처리 완료</p>
|
<p className="result-text">{t('additionalService.keyIn.resultLabel')} : [0000] {t('additionalService.keyIn.arsRequestComplete')}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="apply-row">
|
<div className="apply-row">
|
||||||
<button
|
<button
|
||||||
className="btn-50 btn-blue flex-1"
|
className="btn-50 btn-blue flex-1"
|
||||||
onClick={ () => onClickToNavigate() }
|
onClick={ () => onClickToNavigate() }
|
||||||
>확인</button>
|
>{t('additionalService.keyIn.confirm')}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user