브라우저가 아닌 모바일 웹뷰로 카드 결제창을 띄울 때 카드사별 결제 수단 인증을 위해 외부 앱(3rd-party 앱)을 연동해야 합니다. 연동을 위해 필요한 외부 앱 스킴(App URL Scheme)목록과 추가 로직을 살펴보세요.
웹뷰는 아래와 같은 과정에서 사용됩니다.
- 주문 정보를 작성하고 결제창을 호출합니다.
- 카드사를 선택하고 다음 단계로 이동합니다.
- 선택한 카드사·은행의 결제 앱이 열립니다. 외부 앱이 실행되는 시점입니다.
- 결제 정보를 입력하고 결제를 완료합니다.
- 상점의 결제 페이지로 돌아옵니다.
- 결제창을 호출하기 위해 결제 정보에 앱 스킴(
appScheme
) 파라미터를 추가하면 별도의 처리 없이도 외부 앱에서 상점 앱으로 돌아올 수 있습니다. 카드 결제 정보 파라미터를 참고하세요.
- 결제창을 호출하기 위해 결제 정보에 앱 스킴(
이 페이지에서는 3번 단계에서 외부 앱을 여는 방법을 다룹니다. 웹뷰에서 각 은행의 결제 앱을 실행시키면서 앱 간 이동(App to App)이 일어나는 경우입니다.
내 상점 앱에서 인증을 위해 이동하게 되는 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:// |
앱 스킴을 추가했다면 앱 간(App to App) 이동을 구현할 때 추가되어야 하는 로직을 살펴보세요.
Android는 웹뷰에서 외부 앱을 호출하거나 마켓 연결(market://
)으로 연결할 때 WebViewClient의 shouldOverrideUrlLoading
함수를 사용합니다. shouldOverrideUrlLoading
함수에 오버라이딩 로직을 추가하지 않으면 net::ERR_UNKNOWN_URL_SCHEME
에러가 발생합니다.
override fun shouldOverrideUrlLoading(view: WebView, 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
}
@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;
}
위와 같이 구현하기 어려운 경우 패키지 공개 상태 관리 대응에 대해 확인해보세요.
웹뷰에서 외부 앱 호출이 가능한 리스트를 정의한 뒤 앱 스킴 실행을 위한 코드를 추가해보세요.
웹뷰에서 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.openURL(url)
decisionHandler(.cancel)
} else {
decisionHandler(.allow)
}
}
- (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"]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}