웹뷰에서 외부 앱 열기

웹뷰에서 엑심베이 국내/해외 결제창, 카드사 또는 결제 수단 외부 앱(3rd party 앱)을 열기 위해서는 로직을 추가해야 합니다. 연동에 필요한 외부 앱 스킴(App URL Scheme) 목록과 추가 로직을 확인하세요.

웹뷰에서 외부 앱을 열려면 엑심베이 결제창을 띄울 때 call_from_appY로, 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부분에 카드사, 결제사 앱을 호출하기 위한 로직 추가가 필요합니다.

Java
                      
국내 결제

@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;
                }
                      
                  
Java
                                
          해외 결제
          
          @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;
                     
              }
          });