[에러] 이미 사용된 주문번호입니다
안녕하세요 테스트 중인데
테스트 결제내약에서는 완료라고 뜨는데,
계속 아래와 같은 에러가 나옵니다.
code = FAILED_PAYMENT_INTERNAL_SYSTEM_PROCESSING
message = [S021] 이미 사용된 주문번호입니다. 새로운 주문번호로 결제를 시도해 주십시요.
어떤때는 PROVIDER 에러도 나오고요 (마찬가지로 결제내역에는 완료라고 나옵니다.)
20번정도 했는데 계속 이러네요. 확인 좀 부탁드립니다.
실제로 콘솔에 찍어보니, 인증요청시 보낸 주문번호와 인증후 리스판스로 받은 주문번호가 다릅니다.
주문번호 하나 말씀드리면 NrqAJ***입니다.
22 Replies
🫖 에러메세지를 찾아주세요 🧚
* code :
FAILED_PAYMENT_INTERNAL_SYSTEM_PROCESSING
* message : [0001] 거래제한카드
🧞 발생가능한 에러를 모두 알려드려요~
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 휴대폰
🔮 휴대폰
🔮 휴대폰
🔮 휴대폰
🔮 휴대폰
🔮 휴대폰
🔮 휴대폰
🔮 휴대폰
🔮 계좌이체
🔮 계좌이체
🔮 가상계좌
🔮 신용카드
🔮 신용카드
🔮 신용카드
```- 예상문제 : 복합 결제를 위한 계약몰 아이디가 없습니다.
- 해결방안 : 간편결제시에 복합결제(카드+포인트 또는 계좌사용등)계약이 되어 있지 않은 상점입니다. 복합결제 계약이 필요하시면 1 ......(생략)예상문제는 상점관리자에서 주문번호 별로도 확인가능해요!
⏳ 잠시만 기다려주세요! 곧 답변드리겠습니다
오류 문의일 경우 아래 정보를 미리 전달해주시면, 빠른 답변에 도움이 됩니다.
- 주문번호(orderId) :
- 문의 내용 :
(img를 함께 첨부해주시면 도움이됩니다)
* 계약관련 내용은 1544-7772로 문의주세요.
* 주말/공휴일에는 답변이 늦을 수 있어요.
테스트 결제내역에 완료로 뜨니 이미 사용된 주문번호입니다.
주문번호를 완전히 바꿔서 사용해보세요
nanoid() 를 써서 주문할 때 마다 계속 바뀌게 되어 있습니다. 콘솔에 찍어봐도 계속 바뀌어 있었고요. 그런데도 계속 같은 에러메세지가 나오고 있습니다.(reponse.ok 가 없으면 에러뜨게 해놓았습니다.)
그런데 개발 연동 체험 상점의 테스트 결제내역에는 결제상태가 완료라고 나옵니다. 주문번호는 계속 다른 주문번호로요.
신용카드로 결제하면 같은 주문번호라는 그런 메세지가 뜨고,
간편결제(토스페이)로 하면 항상 아래와 같은 에러메세지가 뜹니다.
code = PROVIDER_ERROR message = 죄송합니다. 잠시 후 다시 이용해 주시기 바랍니다.
그런데 이것도 마찬가지로 결제내역에의 결제상태는 완료로 되어 있고요.
그리고 결제내역에는 주문번호가 다 다르게 되어 있습니다.
좀 전에도 주문했는데 그렇습니다.
확인 좀 부탁드립니다.
(결제는 정상적으로 된건가요?)
🫖 에러메세지를 찾아주세요 🧚
* code :
PROVIDER_ERROR
* message : 토스 계좌는 최대 200만원까지 보유 가능합니다.
🧞 발생가능한 에러를 모두 알려드려요~
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 계좌이체
🔮 신용카드
🔮 신용카드
🔮 공통
🔮 신용카드
🔮 계좌이체
🔮 신용카드
🔮 계좌이체
🔮 계좌이체
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 계좌이체
🔮 계좌이체
🔮 계좌이체
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 신용카드
🔮 계좌이체
🔮 신용카드
🔮 신용카드
🔮 계좌이체
🔮 신용카드
🔮 신용카드
🔮 계좌이체
🔮 계좌이체
```- 예상문제 : [6000][427] 참가 은행 에러입니다., 기타 출금불가 계좌 (해당 지점 연락요망)
- 해결방안 : 출금불가 계좌로 ......(생략)예상문제는 상점관리자에서 주문번호 별로도 확인가능해요!
그리고 아까 알려드린 주문번호 NrqAJ**는 이미테스트한 후 같은 주문번호로 시도한 것이 아니라 처음시도했고 테스트 결제내역에도 처음 등록된 주문번호입니다. 그전 주문번호 알려드리면 pPuA** 도 마찬가지고요.
테스트 결제내역에 등록된 결제 내역 28건이 있는데 (제가 몇개 취소했음) 구매자명이 김토스로 되어 있는 것 들이 제가 로컬에서 테스트한 것인데 단 한번도 성공메세지가 나온적이 없었습니다. 그런데 결제내역에 결제 상태를 확인해보면 항상 완료라고 나왔습니다. 그리고 주문번호는 같았던 적이 없었습니다.
확인이 되셨나요?
주문번호를 정확히 알려주시기 바랍니다.
지금 테스트 결제내역을 보시는 페이지 링크를 보내주실수 있을까요?
@srvrvigsr 문의 정리 좀 하겠습니다.
1) 주문번호 전체를 전달주셔야 저희가 검색할 수 있습니다. 정확하게 알려주세요.
2) 결제완료라고 하는 부분, 저희가 직접 확인 하겠습니다. 정확한 주문번호 알려주시면, 해당되는 상점에 접속해서 보겠습니다. 주문번호 정확하게 알려주세요.
3) 신용카드 / 간편결제 둘다 상황이 다른것 같으니, 주문번호를 정확하게 알려주세요.
어제 전체 알려드렸었습니다만,
다시 말씀드리겠습니다. NrqAJiymlfhS-CDttFsoV, pPuAveiXWnXxd2VWEHd0q 빠른 확인 부탁드립니다.
혹시 라이브에서 테스트 해보실수 있으신가요?
저희 로그 확인결과 승인 API 가 0.01초 간격으로 2번 호출된것처럼 보입니다.
successURL 에서 승인 API 호출하는 코드 확인해 보실수 있을까요?
사업자로 가입은 아직 하지 않아서 테스트로만 가능합니다. 테스트먼저해보고 잘되면 하려고요.
모든 승인에 대해서 승인API가 계속해서 0.01초 간격으로 2번 호출되었다는 말씀인거죠? (제가 0.01초 간격으로 주문을 한적은 없으니까요)
그리고 항상 첫번째는 성공하고 두번째는 주문번호 중복에러 나와서 두번째 승인처리의 결과가 response되어서 그렇다는 말씀인거죠?
1) 결과적으로 결제승인은 성공한건가요?
2) 코드는 다음과 같습니다.
export function SuccessPage() {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
useEffect(() => {
const requestData = {
orderId: searchParams.get("orderId"),
amount: searchParams.get("amount"),
paymentKey: searchParams.get("paymentKey"),
};
const encryptedSecretKey =
return; } } confirm(); }, []);
Basic ${btoa(secretKey + ":")}
;
async function confirm() {
const response = await fetch("https://api.tosspayments.com/v1/payments/confirm", {
method: "POST",
headers: {
"Authorization": encryptedSecretKey,
"Content-Type": "application/json",
},
body: JSON.stringify(requestData),
})
const json = await response.json();
if (!response.ok) {
navigate(/fail?code=${json.code}&message=${json.message}
)return; } } confirm(); }, []);
1) 네, 결제승인 성공 했습니다.
2) 호출 부분 뿐 아니라, 페이지 로딩 부분에서 반복되는 부분 없을지도 확인 해보시면 좋을듯 합니다.
페이지 로딩은 승인처리 후 렌더링 되는 부분 말씀이신가요?
아뇨 successURL 자체가 브라우저에서 2번 로딩되면 보내주신코드가 2번 수행되면서 승인 API 요청이 2번 발생할수 있습니다.
해당 코드입니다.
export function CheckoutPage() {
......
useEffect(() => {
if (paymentWidget == null) {
return;
}
const paymentMethodsWidget = paymentWidget.renderPaymentMethods(selector, { value: price }, { variantKey: "DEFAULT" });
paymentWidget.renderAgreement("#agreement", { variantKey: "AGREEMENT" });
paymentMethodsWidgetRef.current = paymentMethodsWidget;
}, [paymentWidget]);
useEffect(() => {
const paymentMethodsWidget = paymentMethodsWidgetRef.current;
if (paymentMethodsWidget == null) {
return;
}
paymentMethodsWidget.updateAmount(price);
}, [price]);
return (
<div className="wrapper">
<div className="box_section">
<div id="payment-widget" />
.....
<div className="result wrapper">
<button
className="button"
style={{ marginTop: "30px" }}
onClick={async () => {
try {
await paymentWidget?.requestPayment({
orderId: nanoid(),
orderName: "토스 티셔츠 외 2건",
customerName: "김토스",
successUrl:
${window.location.origin}/success
,
failUrl: ${window.location.origin}/fail
,
});
} catch (error) {
console.error(error);
}
}}
>
결제하기
</button>
</div>
</div>
</div>
);
}
function usePaymentWidget(clientKey: string, customerKey: string) {
return useQuery({
queryKey: ["payment-widget", clientKey, customerKey],
queryFn: () => {
return loadPaymentWidget(clientKey, customerKey);
},
});
}우선 이부분에 로그를 심어서 실제로 해당 코드가 2번 실행이 되는지 확인해 보셔야 할것 같습니다.
const response = await fetch("https://api.tosspayments.com/v1/payments/confirm", {
method: "POST",
headers: {
"Authorization": encryptedSecretKey,
"Content-Type": "application/json",
},
body: JSON.stringify(requestData),
})
const json = await response.json();
지금 테스트를 해봤는데 (코드 앞뒤로 콘솔로그 붙여서 테스트),
두번 처리되는것 같습니다. (tqxZoKlRD5k56iDaFW5F_) - 이미지 첨부합니다.

두번 처리되는것 관련해서 전체코드를 chatGPT4 통해 확인을 해봤는데, 아래와 같습니다.
그리고 버튼 중복 클릭 관련한 부분은 코드에 반영해서 테스트 해봤는데 관련이 없었습니다.
==============================
이 코드에서 /success 부분이 두 번 실행되는 것처럼 보이는 문제의 원인은 직접적으로 코드 상에서 /success가 두 번 호출되거나 실행되는 부분이 존재하지 않습니다. 문제의 원인을 찾기 위해 코드의 전체적인 흐름과 React의 동작 방식을 고려해야 합니다.
useEffect와 상태 업데이트: 이 코드는 useEffect 훅을 사용하여 paymentWidget과 price 상태에 따라 사이드 이펙트를 실행합니다. useEffect는 의존성 배열([paymentWidget], [price])에 있는 값이 변경될 때마다 실행됩니다. 그러나 여기서 /success 경로가 직접적으로 관련된 로직은 보이지 않습니다.
onClick 이벤트 핸들러: 결제 요청을 처리하는 부분은 onClick 이벤트 핸들러 내부에 있으며, 이 핸들러는 사용자가 "결제하기" 버튼을 클릭할 때 실행됩니다. 이 함수 내부에서 paymentWidget?.requestPayment를 호출하고 있으며, 성공적인 결제 후에 사용자를 /success URL로 리디렉션하는 것으로 보입니다. 이 과정이 두 번 실행되는 것은 이 코드의 로직과는 직접적인 관련이 없을 수 있습니다.
원인을 명확히 파악하기 위해서는 다음과 같은 추가적인 정보가 필요합니다:
결제 요청의 중복 호출: 사용자가 실수로 또는 네트워크 지연 등의 이유로 "결제하기" 버튼을 빠르게 여러 번 클릭할 수 있습니다. 이러한 상황을 방지하기 위해 버튼 클릭 이벤트가 처리 중일 때 버튼을 비활성화하는 등의 조치를 취할 수 있습니다.
paymentWidget의 동작 방식: paymentWidget?.requestPayment 메소드의 내부 구현에 따라 결제 프로세스가 완료된 후 /success 페이지로의 이동이 중복으로 발생할 수 있습니다. 예를 들어, 결제 과정 중에 페이지를 리로드하거나 다른 방식으로 중복 호출이 발생할 수 있는 경우가 있습니다.
외부 요인: 브라우저의 특정 확장 프로그램, 네트워크 문제, 또는 paymentWidget SDK의 버그 등 외부 요인도 이 문제에 영향을 줄 수 있습니다.
문제를 해결하기 위한 첫 번째 단계로, "결제하기" 버튼을 클릭할 때 중복 클릭을 방지하는 로직을 추가하는 것을 고려할 수 있습니다. 예를 들어, 첫 클릭 시에 버튼을 비활성화하고, 결제 요청이 완료될 때까지 사용자가 다시 클릭할 수 없도록 합니다. 또한, paymentWidget의 문서나 커뮤니티에서 비슷한 문제를 경험한 다른 사용자의 사례를 찾아보는 것도 도움이 될 수 있습니다
==================================
이부분은 승인 API 코드가 2번 처리되는 것이어서 내부적으로 해당 코드가 2번 호출되는 이유를 찾아보셔야 할것 같습니다.
저희 widget 모듈은 결제창을 띄우는데만 관여 하기 때문에 승인 API 를 두번호출하는 것과는 관련이 없습니다.
토스페이먼츠 공식 깃헙 코드 그대로 따라서 했는것입니다만.....
https://github.com/tosspayments/payment-widget-sample/tree/main/react
GitHub
payment-widget-sample/react at main · tosspayments/payment-widget-s...
토스페이먼츠 결제위젯 샘플 프로젝트입니다. . Contribute to tosspayments/payment-widget-sample development by creating an account on GitHub.
그럼 저희 샘플에서 전혀 수정없이 한번 테스트 해보시기 바랍니다.
❤️ 기술문의 경험이 어떠셨나요?!
간단히 코멘트 남겨주세요! 제품 발전에 큰 힘이 됩니다.