디플롯
디플롯12mo ago

특정 카드사 결제 오류 문의드립니다.

신용카드 > 우리은행 > 우리카드앱 결제 시도시 결제가 정상적으로 진행되지 않고 있어 문의드립니다. 저희는 결제창 Javascript SDK 를 사용하고 있고, RN 으로 구현된 앱에 웹뷰 환경에서 결제 프로세스를 사용하고 있습니다. IOS, AOS 모두에서 재현되는 이슈이고, 재현 도움을 위해 동영상 첨부해 드립니다. 위 이슈와 관련은 없지만 질문 한가지가 더 있습니다. 토스페이먼츠 가이드 문서에는 저희가 사용하는 '결제창 Javascript SDK' 가 없고 검색을 통해서 웹 문서가 노출되고 있더라구요. 공식 가이드에는 '결제위젯 Javascript SDK' 만 노출되는데, 저희가 쓰고있는 SDK는 구 버전으로 지원 종료가 되는 SDK 일까요?
57 Replies
디플롯
디플롯OP12mo ago
추가적인 정보를 더 작성하자면 requestPayment 호출 코드는 아래와 같습니다.
tossPayments.requestPayment('카드', {
amount: 2500,
orderId: '20240306000101',
orderName: '상품명',
customerName: '주문자명',
successUrl: 'https://stg-m.dplot.co.kr/order-tossPaymentSucc',
failUrl: 'https://stg-m.dplot.co.kr/order-tossPaymentFail',
})
tossPayments.requestPayment('카드', {
amount: 2500,
orderId: '20240306000101',
orderName: '상품명',
customerName: '주문자명',
successUrl: 'https://stg-m.dplot.co.kr/order-tossPaymentSucc',
failUrl: 'https://stg-m.dplot.co.kr/order-tossPaymentFail',
})
successUrl 안내에 오리진이 포함되어야 한다고 되어있는데 동일한 도메인 내에서 콜백을 받도록 처리되어있습니다. 개발자 도구를 연결해서 결제창 이동하는 도메인들을 살펴보니 아래와 같은 순서로 이동하고 있더라구요. 1. https://dacs.wooricard.com:8886/wcrpay/VPQ140001A.wcdo 2. https://dacs.wooricard.com:8886/werpay/COM300001A.wedo 3. https://wpay.wooricard.com/wpay/ap/order/paycode/acs 4. https://dacs.wooricard.com:8886/wcrpay/SMP300010A.wcdo 5. https://payment-gateway.tosspayments.com/mobile/auth/card/KMPI/result
김차장
김차장12mo ago
결제하려면 다음버튼.. 이 화면은 successUrl 로 접속을 못할때 재시도를 하기위해 제공해드리는 기능입니다. successUrl 로 설정하신 페이지가 접속가능한지 확인해보시겠어요? successUrl 페이지가 접속가능한 상태일경우에는 저 페이지가 없이 바로 successUrl 로 리다이렉트 됩니다
디플롯
디플롯OP12mo ago
@삼부장 넵 접속가능한 상태입니다. 위의 결체장 웹뷰에서 이동하는 도큐먼트 동작을 보면 저희 사이트로 들어오지 않고 있습니다.
김차장
김차장12mo ago
successUrl 변경이 자유로우 시다면 successUrl을 임의로 https://google.com 이나 https://naver.com 등으로 변경가능하실까요? 변경후에 어떻게 이동하는지 확인을 해보면 도움이 될거같습니다.
Google
Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for.
네이버
네이버 메인에서 다양한 정보와 유용한 컨텐츠를 만나 보세요
디플롯
디플롯OP12mo ago
@삼부장 요청 주신대로 네이버 도메인으로 바꿔서 테스트해봤지만 동일합니다. 그런데 네이버 도메인을 사용할경우 토스페이먼츠 가이드에 있는 아래 스크린샷 내용에 부합되어 어차피 안되는것 아닌가요?
No description
김차장
김차장12mo ago
오리진 내용은 CORS 관련이라서 적어도..
https://www.google.com/?orderId=sample-1709787749057&paymentKey=4qjZblEopLBa5PzR0ArnElLzez5LvXVvmYnNeDMyW2G1OgwK&amount=1000
https://www.google.com/?orderId=sample-1709787749057&paymentKey=4qjZblEopLBa5PzR0ArnElLzez5LvXVvmYnNeDMyW2G1OgwK&amount=1000
이런식으로 호출은 되어야합니다 사용하시는 브라우저가 있는 PC가 외부인터넷은 접속이 가능한 곳인가요?
김차장
김차장12mo ago
김차장
김차장12mo ago
저는 successUrl 을 http://naver.com 으로 설정했구요
네이버
네이버 메인에서 다양한 정보와 유용한 컨텐츠를 만나 보세요
김차장
김차장12mo ago
영상보시면 반짝하고 리다이렉트 되는 것을 확인하실 수 있습니다.
No description
김차장
김차장12mo ago
공식 가이드에는 '결제위젯 Javascript SDK' 만 노출되는데, 저희가 쓰고있는 SDK는 구 버전으로 지원 종료가 되는 SDK 일까요?
이 내용 답변드립니다. 구버전은 맞긴한데요 종료되지는 않습니다.
디플롯
디플롯OP12mo ago
@삼부장 질문 내용을 보시면 PC 환경 아니고 모바일 환경입니다. 모바일 웹이나 PC에서는 정상 결제가 이루어지는데 모바일 앱 환경에서만 발생하고 있습니다.
김차장
김차장12mo ago
인증결과를 수신하지 못하고 계신거같네요
디플롯
디플롯OP12mo ago
동영상 보시면 실제 결제는 다 잘되는데, 성공이던 실패던 콜백을 받아서 저희쪽으로 넘어와야 하는데 어딘가에서 유실되는것 같습니다.
김차장
김차장12mo ago
모바일웹은 잘 되시는것인가요?
디플롯
디플롯OP12mo ago
김차장
김차장12mo ago
모바일웹에서의 successUrl 세팅과 모바일앱에서의 successUrl 세팅은 동일한가요? 문제의 범위를 좁혀가면서 보는게 좋겠습니다.
디플롯
디플롯OP12mo ago
동일한 코드로 운영되고 있어 파라메터의 이슈는 아닙니다.
김차장
김차장12mo ago
어딘가에서 유실 -- 이 부분은 앱의 successUrl 에서 못받는 현상입니다
디플롯
디플롯OP12mo ago
위에 naver.com 으로 성공,실패 콜백을 넣어둔 상태로 모웹은 네이버로 잘이동합니다.
김차장
김차장12mo ago
앱은요?
디플롯
디플롯OP12mo ago
@삼부장 앱에서 못받는 현상이라는게, 저희는 앱 SDK를 쓰는게 아니라 웹뷰로 모웹과 동일한 상황인데 왜 앱에서만 동작안하는지가 궁금합니다. 앱은 계속해서 동작하지 않는다고 이야기 드렸습니다.
김차장
김차장12mo ago
그렇군요 잠시만요, 비슷한 케이스가 있었던거같아요
디플롯
디플롯OP12mo ago
저희쪽에서 디버깅을 해드려야 하는 케이스가 있는경우 안내 주시면 해당 상태를 디버깅하고 원인을 같이 찾아주시면 좋을것 같습니다. Javascript SDK 설명을 통해서 결제를 진행하고, 모바일 웹과 앱이 모두 동일한 코드인데 결과 동작이 다른상황입니다.
유부장
유부장12mo ago
지금 설명 주신 내용을 보면, 웹에서 해당 사이트로 접속 하여, 결제 인증 진행 후 successUrl 로의 이동에 문제 없다고 설명 주셨는데 앱 내 웹뷰 상에서 동일한 URL을 띄워서, 결제 진행 할때, 인증 완료 된 이후에 successUrl 로의 이동이 안되는 상황으로 이해 되는것 같습니다. 맞나요? 결제창 띄우는 사이트 URL 공유 가능 하실까요? 앱내 웹뷰에서의 리다이렉션 관련해서, 웹뷰상에 보안 설정 관련 해두신 것 있으신 지도 궁금 합니다.
디플롯
디플롯OP12mo ago
@유부장 결체창을 띄우는 사이트 URL이 tossPayments.requestPayment 함수를 호출하는 URL을 물으시는것일까요?
유부장
유부장12mo ago
네 맞습니다. 앱내 웹뷰로 진행 한다고 하셨으니, 웹 이나 앱내웹뷰나 동일한 URL 에서 진행 한다고 이해 됩니다.
이실장
이실장12mo ago
@디플롯 안녕하세요. 우선 지난주에 카카오뱅크 / ISP 등 문의주셨던 것과 유사할 수 있을 것 같은데. 당시에는 해결이 되셨었나요? 추가로 이동을 안했으면 디버깅 툴이나 콘솔 창에 에러메세지는 없는지 확인 바랍니다. 저희쪽 로그에서는 리다이렉트 시키기 위해 요청이 나갔습니다. 웹뷰 내에서 설정 때문에 문제가 발생하는 것 같아요 추가로 우리카드 외 다른 카드는 redirect가 잘되나요?
디플롯
디플롯OP12mo ago
@이실장 넵 어제 카카오뱅크 ISP 관련해서 문의를 했었구요. RN에 originWhitelist 에 모두 허용(["*"]) 처리를 해도 증상은 동일합니다. 해결이 안된 상황입니다. 카카오뱅크/ISP의 경우 외부 앱이 실행도 안되는 이슈이고, 우리카드의 경우 외부 앱은 실행이 되고 결제도 잘 처리되고 성공 또는 실패 콜백 페이지로 이동이 안되는 이슈입니다. 우리카드이외에 삼성, 현대, 롯데 경우 잘 이동하고 있습니다.
이실장
이실장12mo ago
웹뷰 안에 별도로 iframe을 사용하시거나, 웹뷰가 중첩되거나 하는 경우가 있을까요? 저희가 계속 질문을 드리는 사유는 현재 동일한 현상이 보고된 내용이 없어 그렇습니다. 말씀하신 것처럼 모바일웹에서는 정상동작하니 웹서비스는 정상 구현되었을 것으로 예상되고요. 웹뷰의 경우 저희가 확인하기가 어려워 계속 질문드리는 점 양해바랍니다.
디플롯
디플롯OP12mo ago
@이실장 위의 링크로 드린 페이지는 div 만 존재하는 더미 페이지입니다. 웹뷰 안에 별도의 iframe 는 사용하고 있지 않습니다.
이실장
이실장12mo ago
위 링크를 저희 테스트 앱에 띄워서 결제해봐도 괜찮을까요?
디플롯
디플롯OP12mo ago
@이실장 넵 괜찮을것 같습니다. 최종 결제 처리는 안될거라서요
이실장
이실장12mo ago
안드로이드 /ios 양쪽 동일할까요?
디플롯
디플롯OP12mo ago
넵 동일합니다.
이실장
이실장12mo ago
카카오뱅크 이슈도요 네 알겠습니다.
디플롯
디플롯OP12mo ago
넵 @이실장 모바일 웹이나 앱에서 tossPayments.requestPayment 호출하는 코드가 아래와 같은데요. 해당 코드가 혹시 웹뷰 환경에서 이슈가 있을수 있나요?
tossPayments.requestPayment(payType, tossInfo).catch((error) => {
console.log(error)
});
tossPayments.requestPayment(payType, tossInfo).catch((error) => {
console.log(error)
});
이실장
이실장12mo ago
혹시 모르니 catch문만 뺴고 한번 실행해보시겠어요? tossPayments.requestPayment(payType, tossInfo) 여기까지요
디플롯
디플롯OP12mo ago
네. @이실장 질문드린 이유도.. 코드가이드는 catch 문이 있는데, 하단 내용에 보면 모바일 환경에서는 promise 사용하면 결제가 안될수도 있다고 되어있어서요.
이실장
이실장12mo ago
네 우선 requestPayment 자체는 이슈가 없습니다. 이미 수많은 가맹점에서 앱으로 이상없이 사용 중이서요. 확인 후 말씀주세요
디플롯
디플롯OP12mo ago
@이실장 넵 일단 저희도 requestPayment 이슈 보다는 RN 이슈가 있을수도 있을것 같아서 그부분 적용을 먼저 해보았는데요. 웹뷰 적용 관련 pdf 주신 코드가이드 적용해도 이슈가 동일하게 발생하고 있더라구요. @이실장 호출하는 코드는 이슈없는것 같네요. 동일합니다.
이실장
이실장12mo ago
이실장
이실장12mo ago
이상없이 잘되네요
import React from 'react';
import { Linking, Platform } from 'react-native';
import { WebView } from 'react-native-webview';
import { ShouldStartLoadRequest } from "react-native-webview/lib/WebViewTypes";
import SendIntentAndroid from "react-native-send-intent";

const App: React.FC = (): React.ReactElement => {
const onShouldStartLoadWithRequest = (event: ShouldStartLoadRequest): boolean => {
if (event.url.startsWith("http://") || event.url.startsWith("https://") || event.url.startsWith("about:blank")) {
return true; // 허용된 URL은 로드합니다.
}
if (Platform.OS === "android") {
SendIntentAndroid.openAppWithUri(event.url).catch(err => console.log(err));
} else if (Platform.OS === "ios") {
Linking.openURL(event.url).catch(err => console.error(err));
}
return false; // WebView에서는 URL 로드를 막습니다.
};

return (
<WebView
useWebkit
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
style={{ flex: 1 }}
javaScriptEnabled={true}
originWhitelist={["*"]}
source={{ uri: 'https://stg-www.dplot.co.kr/common/tossPayment?payType=%EC%B9%B4%EB%93%9C&tossInfo=%7B%22amount%22%3A2500,%22orderId%22%3A%2220240306000101%22,%22orderName%22%3A%22%ED%85%8C%EC%8A%A4%ED%8A%B8%20%EC%83%81%ED%92%88%EC%9E%85%EB%8B%88%EB%8B%A4.%20%28%EB%AF%B8%EC%A0%84%EC%8B%9C%29%22,%22customerName%22%3A%22%EC%A0%84%EC%84%9D%ED%99%98%22,%22successUrl%22%3A%22https%3A%2F%2Fstg-m.dplot.co.kr%2Forder-tossPaymentSucc%22,%22failUrl%22%3A%22https%3A%2F%2Fstg-m.dplot.co.kr%2Forder-tossPaymentFail%22%7D' }}
/>
);
};

export default App;
import React from 'react';
import { Linking, Platform } from 'react-native';
import { WebView } from 'react-native-webview';
import { ShouldStartLoadRequest } from "react-native-webview/lib/WebViewTypes";
import SendIntentAndroid from "react-native-send-intent";

const App: React.FC = (): React.ReactElement => {
const onShouldStartLoadWithRequest = (event: ShouldStartLoadRequest): boolean => {
if (event.url.startsWith("http://") || event.url.startsWith("https://") || event.url.startsWith("about:blank")) {
return true; // 허용된 URL은 로드합니다.
}
if (Platform.OS === "android") {
SendIntentAndroid.openAppWithUri(event.url).catch(err => console.log(err));
} else if (Platform.OS === "ios") {
Linking.openURL(event.url).catch(err => console.error(err));
}
return false; // WebView에서는 URL 로드를 막습니다.
};

return (
<WebView
useWebkit
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
style={{ flex: 1 }}
javaScriptEnabled={true}
originWhitelist={["*"]}
source={{ uri: 'https://stg-www.dplot.co.kr/common/tossPayment?payType=%EC%B9%B4%EB%93%9C&tossInfo=%7B%22amount%22%3A2500,%22orderId%22%3A%2220240306000101%22,%22orderName%22%3A%22%ED%85%8C%EC%8A%A4%ED%8A%B8%20%EC%83%81%ED%92%88%EC%9E%85%EB%8B%88%EB%8B%A4.%20%28%EB%AF%B8%EC%A0%84%EC%8B%9C%29%22,%22customerName%22%3A%22%EC%A0%84%EC%84%9D%ED%99%98%22,%22successUrl%22%3A%22https%3A%2F%2Fstg-m.dplot.co.kr%2Forder-tossPaymentSucc%22,%22failUrl%22%3A%22https%3A%2F%2Fstg-m.dplot.co.kr%2Forder-tossPaymentFail%22%7D' }}
/>
);
};

export default App;
AndroidManifest.xml 추가
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<queries>
<!-- -->
<package android:name="com.shcard.smartpay" />
<package android:name="com.shinhancard.smartshinhan" />
<package android:name="com.hyundaicard.appcard" />
<package android:name="com.lumensoft.touchenappfree" />
<package android:name="kr.co.samsungcard.mpocket" />
<package android:name="nh.smart.nhallonepay" />
<package android:name="com.kbcard.cxh.appcard" />
<package android:name="com.kbstar.liivbank" />
<package android:name="com.kbstar.kbbank" />
<package android:name="com.kbstar.reboot" />
<package android:name="kvp.jjy.MispAndroid320" />
<package android:name="com.lcacApp" />
<package android:name="com.hanaskcard.paycla" />
<package android:name="kr.co.hanamembers.hmscustomer" />
<package android:name="kr.co.citibank.citimobile" />
<package android:name="com.wooricard.wpay" />
<package android:name="com.wooricard.smartapp" />
<package android:name="com.wooribank.smart.npib" />
<package android:name="viva.republica.toss" />
<!-- -->
<package android:name="com.nhnent.payapp" />
<package android:name="com.ssg.serviceapp.android.egiftcertificate" />
<package android:name="com.kakao.talk" />
<package android:name="com.nhn.android.search" />
<package android:name="com.lotte.lpay" />
<package android:name="com.lottemembers.android" />
<package android:name="com.samsung.android.spay" />
<package android:name="com.samsung.android.spaylite" />
<package android:name="com.lge.lgpay" />
<!-- -->
<package android:name="com.TouchEn.mVaccine.webs" /> <package android:name="kr.co.shiftworks.vguardweb" /> <package android:name="com.ahnlab.v3mobileplus" />
</queries>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<queries>
<!-- -->
<package android:name="com.shcard.smartpay" />
<package android:name="com.shinhancard.smartshinhan" />
<package android:name="com.hyundaicard.appcard" />
<package android:name="com.lumensoft.touchenappfree" />
<package android:name="kr.co.samsungcard.mpocket" />
<package android:name="nh.smart.nhallonepay" />
<package android:name="com.kbcard.cxh.appcard" />
<package android:name="com.kbstar.liivbank" />
<package android:name="com.kbstar.kbbank" />
<package android:name="com.kbstar.reboot" />
<package android:name="kvp.jjy.MispAndroid320" />
<package android:name="com.lcacApp" />
<package android:name="com.hanaskcard.paycla" />
<package android:name="kr.co.hanamembers.hmscustomer" />
<package android:name="kr.co.citibank.citimobile" />
<package android:name="com.wooricard.wpay" />
<package android:name="com.wooricard.smartapp" />
<package android:name="com.wooribank.smart.npib" />
<package android:name="viva.republica.toss" />
<!-- -->
<package android:name="com.nhnent.payapp" />
<package android:name="com.ssg.serviceapp.android.egiftcertificate" />
<package android:name="com.kakao.talk" />
<package android:name="com.nhn.android.search" />
<package android:name="com.lotte.lpay" />
<package android:name="com.lottemembers.android" />
<package android:name="com.samsung.android.spay" />
<package android:name="com.samsung.android.spaylite" />
<package android:name="com.lge.lgpay" />
<!-- -->
<package android:name="com.TouchEn.mVaccine.webs" /> <package android:name="kr.co.shiftworks.vguardweb" /> <package android:name="com.ahnlab.v3mobileplus" />
</queries>
디플롯
디플롯OP12mo ago
@이실장 영상으로 보내주신 코드 환경에서 카카오뱅크 ISP도 정상적으로 노출되나요?
이실장
이실장12mo ago
2번째 영상이 카카오라고 생각햇는데 잘못보냇내요 잘됩니다.
이실장
이실장12mo ago
\
이실장
이실장12mo ago
여기서 웹뷰가 어디서부터 어딘가요
No description
디플롯
디플롯OP12mo ago
상단 X 헤더가 RN이고 하단 헤더 영역부터가 웹뷰입니다.
이실장
이실장12mo ago
우선 웹뷰 쪽 한번 살펴보셔야할 것 같습니다.
디플롯
디플롯OP12mo ago
@이실장 그럼 RN 영역에 웹뷰 세팅이나 RN 세팅의 문제라고 보시는것이죠? 혹시 영상으로 보내주신 앱은 RN 버전이 어떻게 되나요?
이실장
이실장12mo ago
{
"name": "ReactNativeSample",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint .",
"start": "react-native start",
"test": "jest"
},
"dependencies": {
"react": "18.2.0",
"react-native": "0.72.7",
"react-native-send-intent": "^1.3.0",
"react-native-webview": "^13.6.3"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/eslint-config": "^0.72.2",
"@react-native/metro-config": "^0.72.11",
"@tsconfig/react-native": "^3.0.0",
"@types/react": "^18.0.24",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.2.1",
"eslint": "^8.19.0",
"jest": "^29.2.1",
"metro-react-native-babel-preset": "0.76.8",
"prettier": "^2.4.1",
"react-test-renderer": "18.2.0",
"typescript": "4.8.4"
},
"engines": {
"node": ">=18"
}
}
{
"name": "ReactNativeSample",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint .",
"start": "react-native start",
"test": "jest"
},
"dependencies": {
"react": "18.2.0",
"react-native": "0.72.7",
"react-native-send-intent": "^1.3.0",
"react-native-webview": "^13.6.3"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/eslint-config": "^0.72.2",
"@react-native/metro-config": "^0.72.11",
"@tsconfig/react-native": "^3.0.0",
"@types/react": "^18.0.24",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.2.1",
"eslint": "^8.19.0",
"jest": "^29.2.1",
"metro-react-native-babel-preset": "0.76.8",
"prettier": "^2.4.1",
"react-test-renderer": "18.2.0",
"typescript": "4.8.4"
},
"engines": {
"node": ">=18"
}
}
디플롯
디플롯OP12mo ago
일단 RN 버전과 react-native-webview 의 버전이 다르긴하네요. @이실장 혹시 작업하신 샘플 앱 환경을 제가 받아볼수있는 방법이 있는지 궁금합니다. ^^; 또, Javascript 영역에서 TossPayments SDK 사용에는 문제점이 없는지도 궁금합니다
이실장
이실장12mo ago
https://github.com/tosspayments/payment-widget-sample/tree/main/react-native 이거 다운받아서 App.tsx AndroidManifest.xml 2가지만 수정해서 사용했습니다.
GitHub
payment-widget-sample/react-native at main · tosspayments/payment-w...
토스페이먼츠 결제위젯 샘플 프로젝트입니다. . Contribute to tosspayments/payment-widget-sample development by creating an account on GitHub.
디플롯
디플롯OP12mo ago
네 감사합니다. github 받아서 저희 환경에서도 확인해보도록 하겠습니다. 결제창 Javascript SDK 사용에는 문제점은 혹시 없을까요?
이실장
이실장12mo ago
네 이상 없습니다. RN외 환경에서 이상없는 부분도 확인되신걸로 알고 있고요
디플롯
디플롯OP12mo ago
넵 맞습니다. 확인 감사합니다. 샘플 코드 기준으로 좀더 원인을 찾아보겠습니다.
토스페이먼츠 BOT
❤️ 기술문의 경험이 어떠셨나요?!
간단히 코멘트 남겨주세요! 제품 발전에 큰 힘이 됩니다.

Did you find this page helpful?