✅ 모바일 웹뷰에서 카드 결제창으로 이동할 때 필요한 외부 앱(3rd-party 앱)을 연동하는 과정을 알 수 있어요.
✅ 연동에 필요한 외부 앱 스킴(App URL Scheme) 목록과 로직을 이해할 수 있어요.
웹뷰는 다음과 같이 사용할 수 있습니다.
- 주문 정보를 작성하고 결제창을 호출합니다.
- 카드사를 선택하고 다음 단계로 이동합니다.
- 선택한 카드사·은행의 결제 앱이 열립니다. 외부 앱이 실행되는 시점입니다.
- 결제 정보를 입력하고 결제를 완료합니다.
- 상점의 결제 페이지로 돌아옵니다.
- 앱 스킴(
appScheme
) 파라미터를 추가하면 별도의 처리 없이도 외부 앱에서 상점 앱으로 돌아올 수 있습니다. 결제 요청 파라미터를 참고하세요.
여기서는 3번 단계에서 외부 앱을 여는 방법을 다룹니다. 웹뷰에서 각 은행의 결제 앱을 실행시키면서 앱 간 일어나는 이동(App to App)입니다.
내 상점 앱에서 인증을 위해 이동하게 되는 3rd-party 앱에는 ISP 앱, 카드사별 앱카드 등이 있습니다. 이동할 앱 스킴 리스트를 보고 추가해보세요.
카드사·본인확인기관 | 앱 스킴 |
---|---|
토스페이 | supertoss:// |
국민카드 | kb-acp:// , liivbank:/ , newliiv:// , kbbank:// |
농협카드 | nhappcardansimclick:// , nhallonepayansimclick:// , nonghyupcardansimclick:// |
롯데카드 | lottesmartpay:// , lotteappcard:// |
삼성카드 | mpocket.online.ansimclick:// , vguardstart:// , samsungpay:// ,monimopay:// , monimopayauth:// |
신한카드 | shinhan-sr-ansimclick:// , smshinhanansimclick:// |
우리카드 | com.wooricard.wcard:// , newsmartpib:// |
씨티카드 | citispay:// , citicardappkr:// , citimobileapp:// |
하나카드 | cloudpay:// , hanawalletmembers:// |
현대카드 | hdcardappcardansimclick:// , smhyundaiansimclick:// |
간편결제 | shinsegaeeasypayment:// , payco:// , lpayapp:// |
ISP(BC/국민) | ispmobile:// |
모바일 PASS(본인 인증) | tauthlink:// , ktauthexternalcall:// , upluscorporation:// |
먼저 AndroidManifest.xml
파일에 카드앱·은행앱 패키지를 등록합니다. 패키지를 등록하지 않으면 앱이 설치되어 있어도 스토어로 이동하고, Google 정책을 위반하게 됩니다.
// AndroidManifest.xml
<queries>
<package android:name="com.kakao.talk" /> <!-- 카카오톡 -->
<package android:name="com.nhn.android.search" /> <!-- 네이버페이 -->
<package android:name="com.samsung.android.spay" /> <!-- 삼성페이 -->
<package android:name="net.ib.android.smcard" /> <!-- 모니모페이 -->
<package android:name="com.mobiletoong.travelwallet" /> <!-- 신한카드 트레블월렛 -->\
<package android:name="com.samsung.android.spaylite" /> <!-- 삼성페이 -->
<package android:name="com.ssg.serviceapp.android.egiftcertificate" /> <!-- SSGPAY -->
<package android:name="com.nhnent.payapp" /> <!-- PAYCO -->
<package android:name="com.lottemembers.android" /> <!-- L.POINT -->
<package android:name="viva.republica.toss" /> <!-- 토스-->
<package android:name="com.shinhan.smartcaremgr" /> <!-- 신한 슈퍼SOL -->
<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" /> <!-- KB Pay -->
<package android:name="com.kbstar.liivbank" /> <!-- Liiv(KB국민은행) -->
<package android:name="com.kbstar.reboot" /> <!-- Liiv Reboot(KB국민은행) -->
<package android:name="com.kbstar.kbbank" /> <!-- 스타뱅킹(KB국민은행) -->
<package android:name="kvp.jjy.MispAndroid320" /> <!-- ISP/페이북 -->
<package android:name="com.lcacApp" /> <!-- 롯데카드 -->
<package android:name="com.hanaskcard.paycla" /> <!-- 하나카드 -->
<package android:name="com.hanaskcard.rocomo.potal" /> <!--하나카드-->
<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" /> <!-- 우리WON뱅킹 -->
<package android:name="com.lguplus.paynow" /> <!-- 페이나우 -->
<package android:name="com.kftc.bankpay.android" /> <!-- 뱅크페이 -->
<package android:name="com.TouchEn.mVaccine.webs" /> <!-- TouchEn mVaccine (신한) -->
<package android:name="kr.co.shiftworks.vguardweb" /> <!-- V-Guard (삼성) -->
<package android:name="com.ahnlab.v3mobileplus" /> <!-- V3 (NH, 현대) -->
</queries>
AndroidManifest.xml
파일에 필요한 앱 스킴을 추가했다면, 앱 간 이동에 필요한 아래 코드를 살펴보세요.
WebViewClient의 shouldOverrideUrlLoading
함수에 오버라이딩 로직을 추가하세요.
추가하지 않으면 웹뷰에서 외부 앱을 호출하거나 마켓(market://
)으로 연결할 때 net::ERR_UNKNOWN_URL_SCHEME
에러가 발생합니다.
// API 수준 24 이상을 위한 메소드
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
val url = request.url.toString()
return handleUrl(url)
}
// (선택) API 수준 24 미만을 타겟팅하려면 다음 코드를 추가해 주세요
@Deprecated("Deprecated in Java")
@Suppress("DEPRECATION")
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return handleUrl(url)
}
return super.shouldOverrideUrlLoading(view, url)
}
// 공통 URL 처리 로직
private fun handleUrl(url: String): Boolean {
if (!URLUtil.isNetworkUrl(url) && !URLUtil.isJavaScriptUrl(url)) {
val uri = try {
Uri.parse(url)
} catch (e: Exception) {
return false
}
return when (uri.scheme) {
"intent" -> {
startSchemeIntent(url)
}
else -> {
return try {
startActivity(Intent(Intent.ACTION_VIEW, uri))
true
} catch (e: Exception) {
false
}
}
}
} else {
return false
}
}
private fun startSchemeIntent(url: String): Boolean {
val schemeIntent: Intent = try {
Intent.parseUri(url, Intent.URI_INTENT_SCHEME)
} catch (e: URISyntaxException) {
return false
}
try {
startActivity(schemeIntent)
return true
} catch (e: ActivityNotFoundException) {
val packageName = schemeIntent.getPackage()
if (!packageName.isNullOrBlank()) {
startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse("market://details?id=$packageName")
)
)
return true
}
}
return false
}
위와 같이 구현하기 어려우면 패키지 공개 상태 관리 대응을 확인해보세요.
먼저 Info.plist
에 LSApplicationQueriesSchemes 를 추가하고 카드사, 은행의 앱 스킴을 배열에 넣어 주세요. 설정하지 않으면, 앱이 열리지 않고 콘솔 쪽에 canOpenURL : failed for URL
에러가 발생합니다.
//Info.plist
<key>LSApplicationQueriesSchemes</key>
<array>
<string>supertoss</string>
<string>kb-acp</string>
<string>liivbank</string>
<string>newliiv</string>
<string>kbbank</string>
<string>nhappcardansimclick</string>
<string>nhallonepayansimclick</string>
<string>nonghyupcardansimclick</string>
<string>lottesmartpay</string>
<string>lotteappcard</string>
<string>mpocket.online.ansimclick</string>
<string>ansimclickscard</string>
<string>tswansimclick</string>
<string>ansimclickipcollect</string>
<string>vguardstart</string>
<string>samsungpay</string>
<string>scardcertiapp</string>
<string>shinhan-sr-ansimclick</string>
<string>smshinhanansimclick</string>
<string>com.wooricard.wcard</string>
<string>newsmartpib</string>
<string>citispay</string>
<string>citicardappkr</string>
<string>citimobileapp</string>
<string>cloudpay</string>
<string>hanawalletmembers</string>
<string>hdcardappcardansimclick</string>
<string>smhyundaiansimclick</string>
<string>shinsegaeeasypayment</string>
<string>payco</string>
<string>lpayapp</string>
<string>ispmobile</string>
<string>tauthlink</string>
<string>ktauthexternalcall</string>
<string>upluscorporation</string>
<string>kftc-bankpay</string>
<string>kakaotalk</string>
<string>wooripay</string>
<string>lmslpay</string>
<string>naversearchthirdlogin</string>
<string>hanaskcardmobileportal</string>
<string>kb-bankpay</string>
</array>
XCode에 필요한 앱 스킴을 추가했다면, 앱 간(App to App) 이동에 필요한 아래 코드를 살펴보세요.
웹뷰에서 URL이 변경될 때 페이지 전환 대신 내 상점의 앱 스킴을 실행시키려면 WKNavigationDelegate protocol 중 아래 코드에 해당하는 메서드를 구현해야 합니다.
func webView(
_ webView: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void
) {
if let url = navigationAction.request.url,
url.scheme != "http" && url.scheme != "https" {
UIApplication.shared.open(url, options: [:], completionHandler:{ (success) in
if !(success){
/*앱이 설치되어 있지 않을 때*/
}
})
decisionHandler(.cancel)
} else {
decisionHandler(.allow)
}
}
pubspec.yaml
파일에 가장 최신 버전의 토스페이먼츠 플러그인을 추가해주세요.
dependencies:
tosspayments_widget_sdk_flutter: ^0.X.X
Flutter 웹뷰에서는 Intent URL을 앱 스킴 URL로 변환해야 카드사 앱으로 이동합니다. 아래 예시와 같이 tossPaymentsWebview()
함수를 정의해서 사용하세요.
import 'package:tosspayments_widget_sdk_flutter/model/tosspayments_url.dart';
tossPaymentsWebview(url) {
final appScheme = ConvertUrl(url); // Intent URL을 앱 스킴 URL로 변환
if (appScheme.isAppLink()) { // 앱 스킴 URL인지 확인
appScheme.launchApp(mode: LaunchMode.externalApplication); // 앱 설치 상태에 따라 앱 실행 또는 마켓으로 이동
return NavigationDecision.prevent;
}
}
ConvertUrl (url : String)
- url
앱 스킴 형태로 변환하고 싶은 Intent 스킴 URL입니다. 예를 들어
intent:appScheme://...#Intent;...;end;
형태의 Intent URL이appScheme://...
형태의 앱 스킴 URL로 바뀝니다.
npm 또는 yarn으로 토스페이먼츠 결제위젯 React Native SDK를 설치하세요.
# npm
npm install @tosspayments/widget-sdk-react-native
# yarn
yarn add @tosspayments/widget-sdk-react-native
React Native 웹뷰에서는 Intent URL을 앱 스킴 URL로 변환해야 카드사 앱으로 이동합니다. 아래 예시와 같이 urlConverter()
함수를 정의해서 사용하세요.
import { ConvertUrl } from '@tosspayments/widget-sdk-react-native/src/utils/convertUrl'
const urlConverter = (url: string) => {
const convertUrl = new ConvertUrl(url) // Intent URL을 앱 스킴 URL로 변환
if (convertUrl.isAppLink()) {
// 앱 스킴 URL인지 확인
convertUrl.launchApp().then(isLaunch => {
// 앱 설치 상태에 따라 카드사 앱 실행 또는 앱마켓으로 이동
if (isLaunch === false) {
// 앱 실행 실패시 처리 로직
}
})
} else {
return true
}
}
class ConvertUrl {
url: string;
appScheme?: string;
appLink?: string;
package?: string;
}
- url
앱 스킴 형태로 변환하고 싶은 Intent 스킴 URL입니다. 예를 들어
intent:appScheme://...#Intent;...;end;
형태입니다. - appScheme
url
의 앱스킴입니다. - appLink
url
의 앱스킴 링크입니다. 예를 들어appScheme://...
형태입니다. - package
url
의 앱 패키지 정보입니다.