웹뷰에서 외부 앱 열기
웹뷰에서 엑심베이 국내/해외 결제창, 카드사 또는 결제 수단 외부 앱(3rd party 앱)을 열기 위해서는 로직을 추가해야 합니다. 연동에 필요한 외부 앱 스킴(App URL Scheme) 목록과 추가 로직을 확인하세요.
웹뷰에서 외부 앱을 열려면 엑심베이 결제창을 띄울 때 call_from_app을 Y로, call_from_scheme에 가맹점 앱 스킴을 추가해야 합니다.
외부 앱 스킴 추가하기
웹뷰에서 이동할 수 있는 외부 앱(3rd party 앱)은 ISP 앱, 국내 카드사 앱카드, 해외 간편결제 앱 등이 있습니다.
결제사 앱 | 앱 스킴 |
---|---|
ISP 모바일 | ispmobile:// |
롯데 앱카드 | lotteappcard:// |
삼성 앱카드 | mpocket.online.ansimclick:// |
신한 앱카드 | shinhan-sr-ansimclick:// |
현대 앱카드 | hdcardappcardansimclick:// |
농협 올원페이 | nhallonepayansimclick:// |
하나 앱카드 | cloudpay:// |
씨티 앱카드 모바일 | citimobileapp:// |
카카오페이 | kakaotalk:// |
페이코 | payco:// |
스마일페이 | smilepayapp:// |
토스 | supertoss:// |
네이버페이 | naversearchthirdlogin:// |
라인페이 | line:// |
알리페이 플러스 | alipays:// |
위챗 | weixin:// |
IOS
웹뷰에서 실행할 외부 앱 스킴의 리스트를 추가한 뒤 앱 스킴 실행을 위한 코드를 추가하세요.
1. 가맹점 앱 URL Scheme을 설정하세요.
가맹점 앱에 URL Scheme을 등록해야 합니다. 엑심베이 결제창을 열기 위해 JS SDK를 호출할 때 call_from_scheme파라미터의 필드 값으로 가맹점 앱 URL Scheme을 사용해야 합니다.
2. 외부 앱(3rd party 앱) URL Scheme을 등록하세요.
웹뷰에서 외부 앱을 싱행할 때 앱 간 이동(App to App)을 위해 외부 앱 스킴을 아래와 같이 추가해야 합니다. 국내 결제, 해외 결제에 따라 사용할 수 있는 외부 앱 스킴이 다릅니다.
<key>LSApplicationQueriesSchemes</key>
<array>
<!-- 국내 결제 -->
<string> ispmobile </string> <!--ISP 모바일-->
<string> lotteappcard </string> <!--롯데카드 앱카드-->
<string> online.ansimclick </string> <!--삼성카드 앱카드-->
<string> shinhan sr ansimclick </string> <!--신한카드 앱카드-->
<string> hdcardappcardansimclick </string> <!--현대카드 앱카드-->
<string> nhallonepayansimclick </string> <!--농협카드올원페이-->
<string> cloudpay </string> <!--하나카드 앱카드-->
<string> citimobileapp </string> <!--씨티모바일 앱카드-->
<string> kakaotalk </string> <!--카카오페이-->
<string> payco </string> <!--페이코-->
<string> smilepayapp </string> <!--스마일페이-->
<string> supertoss </string> <!--토스-->
<string> naversearchthirdlog in </string> <!-- 네이버페이-->
<!-- 해외 결제-->
<string> line </string> <!--LINEPAY-->
<string> alipays </string> <!--Alipay+-->
<string> weixin </string> <!--Wechat-->
</array>
3. 네트워크 보안 예외를 설정하세요.
웹뷰로 들어오는 HTTPS 요청의 보안 제한을 허용하기 위해 아래와 같이 ATS(App Transport Security)를 설정하세요.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Android
Android 운영체제는 웹뷰에서 외부 앱을 호출하려면 shouldOverriderUrlLoading부분에 카드사, 결제사 앱을 호출하기 위한 로직 추가가 필요합니다.
국내 결제
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (!URLUtil.isNetworkUrl(url) && !URLUti l.isJavaScriptUrl(url)) {
final Uri uri;
Intent intent = null;
try {
uri = Uri.parse(url);
intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
} catch (Exception e){
return false;
}
if ("intent".equals(uri.getScheme())) {
try {
Log.d("LOG", "intent startActivity");
startActivity(intent);
return true;
} catch (ActivityNotFoundExce ption e) {
final String packageName = intent.getPackage();
Log.d("LOG", "ActivityNotFoundException packageName :" + packageName);
if (!TextUtils.isEmpty(packageName)) {
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=" + packageName)));
return true;
}
}
} else if ("supertoss".equals(uri.getScheme())) {//TOSS
try {
Log.d("LOG", "TOSS startActivity");
startActivity(new Intent(Intent.ACTION_VIEW, uri));
return true;
} catch (ActivityNotFoundException e)
Log.d("LOG", "Activi tyNotFoundException TOSS");
startActivity( new Intent (Intent.ACTION_VIEW,
Uri.parse("market://details?id=viva.republica.toss")));
return true;
} catch (Exception e) {
return false;
}
} else if("nidlogin".equals(uri.getScheme())) {//NAVERPAY
try {
Log.d("LOG", "NAVERPAY startActivity");
startActivity(new Intent(Intent.ACTION_VIEW, uri));
return true;
} catch (ActivityNotFoundException e) {
Log.d("LOG", "ActivityNotFoundException NAVERPAY");
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=com.nhn.android.search")));
return true;
}
catch (Exception e) {
return false;
}
} else {
try {
Log.d("LOG", "else startActivity");
startActivity(new Intent(Intent.ACTION_VIEW, uri));
return true;
} catch (ActivityNotFoundException e) {
final String packageName = intent.getPackage();
Log.d("LOG", "4091_else startActivity ActivityNotFoundException
packageName :" + packageName);
if (!TextUtils.isEmpty(pack ageName)) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id="
+ packageName)));
return true;
}
} catch (Exception e) {
return false;
}
}
}
return false;
}
해외 결제
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (!URLUtil.isNetworkUrl(url) && !URLUtil.isJavaScriptUrl(url)) {
final Uri uri;
Intent intent = null;
try {
uri = Uri.parse(url);
intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
} catch (Exception e) {
return false;
}
if ("intent".equals(uri.getScheme())) {
try {
Log.d("LOG", "intent startActivity");
startActivity(intent);
return true;
} catch (ActivityNotFoundException e) {
final String packageName = intent.getPackage();
Log.d("LOG", "ActivityNotFoundException packageName :" + packageName);
if (!TextUtils.isEmpty(packageName)) {
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=" + packageName)));
return true;
}
} else if ("alipays".equals(uri.getScheme())) { //Alipay+
try {
Log.d("LOG", "alipays startA ctivity");
startActivity(new Intent(Intent.ACTION_VIEW, uri));
return true;
} catch (ActivityNotFoundException e) {
Log.d("LOG", "ActivityNotFoundException alipays");
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=com.eg.android.AlipayGphone")));
return true;
} catch (Exception e) {
return false;
}
} else if ("line".equals(uri.getScheme())) { //LINEPAY
try {
Log.d("LOG", "line startActivity");
startActivity(new Intent(Intent.ACTION_VIEW, uri));
return true;
} catch (ActivityNotFoundException e) {
Log.d("LOG", "ActivityNo tFoundException line");
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=jp.naver.line.android")));
return true;
} catch (Exception e) {
return false;
}
} else if ("weixin".equals(uri.getScheme())) { //Wechat
try {
Log.d("LOG", "weixin startActivity");
startActivity(new Intent(Intent.ACTION_VIEW, uri));
return true;
} catch (ActivityNotFoundException e) {
Log.d("LOG", "ActivityNo tFoundException weixin");
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=com.tencent.mm")));
return true;
} catch (Exception e) {
return false;
}
} else {
try {
Log.d("LOG", "else startActivity");
startActivity(new Intent(Intent.ACTION_VIEW, uri));
return true;
} catch (ActivityNotFoundException e) {
final String packageName = intent.getPacka ge();
Log.d("LOG", "4091_else startActivity ActivityNotFoundException packageName :" + packageName);
if (!TextUtils.isEmpty(packageName)) {
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("market://details?id=" + packageName)));
return true;
}
} catch (Exception e) {
return false;
}
}
}
return false;
}
Alipay+ 예외
해외 결제 수단인 Alipay+를 호출하기 위해서는 아래 파라미터를 웹뷰 설정 부분에 추가해야 합니다.
//Enable javascript
webSettings.setJavaScriptEnabled(true);
//Enable scaling
webSettings.setSupportZoom(true);
//Enable scaling controls (buttons)
webSettings.setBuiltInZoomControls(true);
//2 cache mode for WebView (web and WAP). Load no cache here.
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
//Allow JavaScript to open new windows. (false by default)
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
//Allow JavaScript to load the local cache.
webSettings.setDomStorageEnabled(true);
//WAP cache size (No need to manually set)
//webSettings.setAppCacheMaxSize(1024 * 1024 * 8);
//WAP cache path
String absolutePath = getApplicationContext().getCacheDir().getAbsolutePath();
//WAP cache size
webSettings.setAppCachePath(absolutePath);
//Whether allow WebView to access files (true by default)
webSettings.setAllowFileAccess(true);
//Enable to save WAP cache
webSettings.setAppCacheEnabled(true);
//When using overview mode, if the the page width exceeds WebView dispaly, scale the page to adapt to the WebView (false by default)
webSettings.setLoadWithOverviewMode(true);
// support for the viewport HTML meta tag
webSettings.setUseWideViewPort(true);
WeChat H5
앱에서 Eximbay 결제창을 호출하여 WeChat H5 결제가 가능합니다. H5 결제를 위해 안드로이드 환경에서는 사이트 검증을 위해 Referer를 https://secureapi.eximbay.com으로 헤더에 추가해야 합니다. Referrer 설정이 되어 있지 않으면 위챗 앱 내에서 결제창이 정상적으로 호출되지 않으니 아래 샘플 코드를 참조해 추가해주시면 됩니다.
mWebView.setWebViewClient(new WebViewClient() {
@SuppressLint("LongLogTag")
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.d("LOG", "shouldOverrideUrlLoading url : " + url);
Log.d("LOG", "URLUtil.isNetworkUrl(url) : " + URLUtil.isNetworkUrl(url) + ", URLUtil.isJavaScriptUrl(url) : " + URLUtil.isJavaScriptUrl(url));
if (!URLUtil.isNetworkUrl(url) && !URLUtil.isJavaScriptUrl(url)) {
final Uri uri;
Intent intent = null;
try {
uri = Uri.parse(url);
intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
} catch (Exception e) {
return false;
}
if ("weixin".equals(uri.getScheme())) {
try {
Log.d("LOG", "weixin startActivity");
intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// use startActivity function redirect to wallet app
startActivity(intent);
return true;
} catch (ActivityNotFoundException e) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.tencent.mm")));
return true;
} catch (Exception e) {
return false;
}
}
} else if (url.startsWith("https://wx.tenpay.com")) {
Map extraHeaders = new HashMap();
extraHeaders.put("Referer", "https://secureapi.eximbay.com");
view.loadUrl(url, extraHeaders);
return true;
} else {
view.loadUrl(url);
return false;
}
return false;
}
});