웹뷰(WebView) 사용하기

브라우저가 아닌 모바일 웹뷰로 카드 결제창을 띄울 때 카드사 별 결제수단 인증을 위해 외부 앱(3rd-party 앱)을 연동해야 합니다. 연동을 위해 필요한 외부 앱 스킴(App URL Scheme)목록과 추가 로직을 살펴보세요.

시작하기 전에

웹뷰는 아래와 같은 과정에서 사용됩니다.

  1. 주문정보를 작성하고 결제창을 호출합니다.
  2. 카드사를 선택하고 다음 단계로 이동합니다.
  3. 선택한 카드사/은행의 결제 앱이 열립니다. 외부 앱이 실행되는 시점입니다.
  4. 결제정보를 입력하고 결제를 완료합니다.
  5. 가맹점 결제 페이지로 돌아옵니다.
    • 결제창을 호출하기 위해 결제정보에 가맹점 앱 스킴(appScheme) 파라미터를 추가하면 별도의 처리 없이도 외부 앱에서 가맹점 앱으로 돌아올 수 있습니다. 카드 결제정보 파라미터를 참고하세요.

이 페이지에서는 3번 단계에서 외부 앱을 여는 방법을 다룹니다. 웹뷰에서 각 은행의 결제 앱을 실행시키면서 앱 간 이동(App to App)이 일어나는 경우입니다.

1 앱 스킴 리스트 추가하기

가맹점 앱에서 인증을 위해 이동하게 되는 3rd-party 앱에는 ISP 앱, 카드사별 앱카드 등이 있습니다. 이동할 앱 스킴 리스트를 보고 추가해보세요.

카드사/본인확인기관앱 스킴
토스 간편결제supertoss://
국민카드kb-acp://, liivbank:/
농협카드nhappcardansimclick://, nhallonepayansimclick://, nonghyupcardansimclick://
롯데카드lottesmartpay://, lotteappcard://
삼성카드mpocket.online.ansimclick://, ansimclickscard://, tswansimclick://, ansimclickipcollect://, vguardstart://, samsungpay://, scardcertiapp://
신한카드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://

2 앱 스킴 실행을 위한 코드 추가하기

앱 스킴을 추가했다면 앱 간(App to App) 이동을 구현할 때 추가되어야 하는 로직을 살펴보세요.

Android

Android는 웹뷰에서 외부 앱을 호출하거나 마켓 연결(market://)으로 연결할 때 WebViewClientshouldOverrideUrlLoading 함수를 사용합니다. shouldOverrideUrlLoading 함수에 오버라이딩 로직을 추가하지 않으면 net::ERR_UNKNOWN_URL_SCHEME 에러가 발생합니다.

Kotlin
protected open fun overrideUrl(url: String?): Boolean {
url?.let {
if (!URLUtil.isNetworkUrl(url) && !URLUtil.isJavaScriptUrl(url)) {
val uri = try {
Uri.parse(url)
} catch (e: Exception) {
return false
}
return when (uri.scheme) {
"intent" -> {
startSchemeIntent(it)
}
else -> {
return try {
startActivity(Intent(Intent.ACTION_VIEW, uri))
true
} catch (e: java.lang.Exception) {
false
}
}
}
} else {
return false
}
} ?: 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
}
Java
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (!URLUtil.isNetworkUrl(url) && !URLUtil.isJavaScriptUrl(url)) {
final Uri uri;
try {
uri = Uri.parse(url);
} catch (Exception e) {
return false;
}
if ("intent".equals(uri.getScheme())) {
return startSchemeIntent(url);
} else {
try {
startActivity(new Intent(Intent.ACTION_VIEW, uri));
return true;
} catch (Exception e) {
return false;
}
}
}
return false;
}
private boolean startSchemeIntent(String url) {
final Intent schemeIntent;
try {
schemeIntent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
} catch (URISyntaxException e) {
return false;
}
try {
startActivity(schemeIntent);
return true;
} catch (ActivityNotFoundException e) {
final String packageName = schemeIntent.getPackage();
if (!TextUtils.isEmpty(packageName)) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + packageName)));
return true;
}
}
return false;
}

iOS

웹뷰에서 외부 앱 호출이 가능한 리스트를 정의한 뒤 앱 스킴 실행을 위한 코드를 추가해보세요.

먼저 외부 호출될 앱 스킴을 앱에 관한 정보를 담고 있는 info.plist에 나열해두면 외부 앱 실행을 묻는 대화창이 나타나면서 자동으로 처리됩니다.

<key>LSApplicationQueriesSchemes</key>
<array>
<string>supertoss</string> <!-- 토스간편결제 -->
<string>hdcardappcardansimclick</string> <!-- 현대카드앱카드 -->
<string>smhyundaiansimclick</string> <!-- 현대카드공인인증서 -->
<string>wooripay</string> <!-- 우리카드앱카드 -->
<string>shinhan-sr-ansimclick</string> <!-- 신한카드앱카드 -->
<string>smshinhanansimclick</string> <!-- 신한카드공인인증서 -->
<string>kb-acp</string> <!-- 국민카드앱카드 -->
<string>lottesmartpay</string> <!-- 롯데카드모바일결제 -->
<string>lotteappcard</string> <!-- 롯데카드앱카드 -->
<string>cloudpay</string> <!-- 하나카드앱카드 -->
<string>nhappvardansimclick</string> <!-- 농협카드-앱카드 -->
<string>nonghyupcardansimclick</string> <!-- 농협카드공인인증서 -->
<string>citispay</string> <!-- 씨티카드앱카드 -->
<string>citicardappkr</string> <!-- 씨티카드공인인증서 -->
<string>ispmobile</string> <!-- ISP모바일 -->
...
</array>

iOS는 9.0 버전에서 보안을 위해 LSApplicationQueriesSchemes 항목을 추가했습니다. 웹뷰에서 URL scheme으로 외부 앱을 열 때 등록이 되어 있는 URL scheme만 열 수 있도록 제한을 해서 보안 정책을 강화하기 위함입니다. 따라서 iOS 9.0 이상 버전에서 canOpenURL을 사용해 다양한 카드사 앱을 열려면 허용 목록(info.plist)을 추가해야 합니다.

웹뷰에서 URL이 변경될 때 페이지 전환 대신 앱 스킴을 실행시키려면 WKNavigationDelegate protocol 중 아래 코드에 해당하는 메서드를 구현해야 합니다.

Swift
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.openURL(url)
decisionHandler(.cancel)
} else {
decisionHandler(.allow)
}
}
Objective-C
- (void)webView:(WKWebView *)webView
decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURL* url = navigationAction.request.URL;
if (url != nil && ![url.scheme isEqual:@"http"] &&
![url.scheme isEqual:@"https"]) {
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
}
decisionHandler(WKNavigationActionPolicyAllow);
}
  • 더 궁금한 내용이 있나요?자주 묻는 질문
  • 코드 샘플을 참고하세요TossPayments GitHub
  • 기술지원이 필요한가요?디스코드 채팅|이메일 보내기