Paypal-Express Checkout快捷支付方式的android端开发心得(二)
一、前导
上一篇讲的不是非常好,这里再又一次讲一下。
Paypal手机支付有2种形式:
1.Mobile Express Checkout,MEC,快捷支付
2.MPL
假设採用MEC支付方式,这样的方式点击Checkoutbutton之后的页面一直到付款结束都是url的形式,必须先有Web网站的支付,所以仅仅能通过WebView的形式进行记载,使用起来和Web网站效果一样,假设载入的页面中有些内容不想显示,能够隐藏。
二、MEC支付案例
package com.sound.chinabuye.activity; import http.HttpUrls; import java.util.List; import org.apache.http.cookie.Cookie; import tool.NewTokenCallBack; import tool.TokenTools; import tool.UserInfo; import android.app.Activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.ProgressDialog; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Bitmap; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.webkit.CookieManager; import android.webkit.CookieSyncManager; import android.webkit.JsResult; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; import com.sound.chinabuye.R; import com.sound.chinabuye.bean.BroadAction; public class CheckoutActivity2 extends Activity { public static final String TAG = "CheckoutActivity2"; private WebView webView; private List<Cookie> cookies; private ProgressDialog dialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); manageActivity(); webView = new WebView(this); webView.setWebViewClient(new MyWebViewClient()); webView.setWebChromeClient(new MyChromeClient()); WebSettings webSettings = webView.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setUseWideViewPort(false); webSettings.setSupportZoom(false); setContentView(webView); dialog = new ProgressDialog(this); dialog.setMessage(getString(R.string.loading)); dialog.setCancelable(false); // 请求获得cookies requestData(); } private void requestData() { TokenTools.requestNewToken(CheckoutActivity2.this, new NewTokenCallBack() { @Override public void getNewTokenSuccess(String newAccessToken) { if (newAccessToken != null) { String customerid = UserInfo.getUserInfoInstance().getUserid(); String url = "http://www.chinabuye.com/service/product/listcartweb" + "?productid=64396&qty=1&customerid=" + customerid + "&ACCESSTOKEN=" + newAccessToken; webView.loadUrl(url); } } }); } @Override protected void onDestroy() { super.onDestroy(); CookieSyncManager.createInstance(CheckoutActivity2.this); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.removeAllCookie(); CookieSyncManager.getInstance().sync(); } private void setCookiesVia2Url(String fromUrl, String toUrl) { CookieSyncManager.createInstance(CheckoutActivity2.this); CookieManager cookieManager = CookieManager.getInstance(); String value = cookieManager.getCookie(fromUrl); cookieManager.setCookie(toUrl, value); CookieSyncManager.getInstance().sync(); } private void manageActivity() { ActivityInstanceManager.getActivityInstanceManager().addActivity(this); } private class MyWebViewClient extends WebViewClient { private String currentUrl; @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { Log.e(TAG, "start:" + url); currentUrl = url; // 開始跳转Paypal登录界面 if (url.contains("http://www.chinabuye.com/service/product/listcartweb")) { dialog.show(); } // 開始载入Place Order,包括从其它页面返回的情况和開始提交订单的情况 if (url.contains("http://www.chinabuye.com/m/paypal/express/saveOrder") || url.contains("PayerID") || url.contains("http://www.chinabuye.com/m/paypal/express/review")) { if (dialog.isShowing()) { dialog.dismiss(); } dialog.show(); } // 開始载入 下单成功的界面 if (url.contains("http://www.chinabuye.com/m/checkout/onepage/success")) { dialog.show(); } super.onPageStarted(view, url, favicon); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { Log.e(TAG, "load:" + url); /** 这里不做不论什么拦截操作 ***/ // view.loadUrl(url); // return true; return super.shouldOverrideUrlLoading(view, url); } @Override public void onPageFinished(WebView view, String url) { Log.e(TAG, "finish:" + url); if (url.contains("customerid")) { String url2 = "http://www.chinabuye.com/m/checkout/cart";// 这个直接使用Web购物车,測试没问题 String url3 = "http://www.chinabuye.com/paypal/express/shortcut";// 这个直接拦截到登录界面,临时没发现问题 setCookiesVia2Url(url, url3); view.loadUrl(url3); } // paypal登录界面载入完成 if (url.contains("https://www.paypal.com/au/cgi-bin/webscr") && url.contains("#m")) { dialog.dismiss(); } // Place Order界面载入完成 if (url.contains("http://www.chinabuye.com/m/paypal/express/review")) { // 虽然在这之前已经进行了隐藏操作,可是偶尔还是会出现没有隐藏的情况,这里又一次载入一次 hidePlaceOrderJS(view); dialog.dismiss(); } // 下单成功的界面载入完成 if (url.contains("http://www.chinabuye.com/m/checkout/onepage/success")) { // 虽然在这之前已经进行了隐藏操作,可是偶尔还是会出现没有隐藏的情况,这里又一次载入一次 hideSaveOrderJS(view); dialog.dismiss(); // 发送广播,清空购物车 Intent intent = new Intent(); intent.setAction(BroadAction.EMPTY); CheckoutActivity2.this.sendBroadcast(intent); Log.e("sendbroad", "buy.success"); } // 用户邮箱信息为空 if (url.contains("http://www.chinabuye.com/m/customer/account/edit")) { Toast.makeText(CheckoutActivity2.this, "Invalid email address NULL", 0).show(); } super.onPageFinished(view, url); } // 处理在浏览器中的按键事件 @Override public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) { if (event.equals(KeyEvent.KEYCODE_BACK) && view.canGoBack()) { view.goBack(); return true; } else if (event.equals(KeyEvent.KEYCODE_BACK)) { CheckoutActivity2.this.finish(); return true; } return super.shouldOverrideKeyEvent(view, event); } // 载入页面资源时会调用,比方载入图片时,每载入一张图片会调用一次 @Override public void onLoadResource(WebView view, String url) { // Log.e(TAG, "loadResource:" + url); // Web购物车 if (currentUrl.contains("http://www.chinabuye.com/m/checkout/cart")) { hideMCartJS(view); } // Place Order if (currentUrl.contains("http://www.chinabuye.com/m/paypal/express/review")) { hidePlaceOrderJS(view); } // 下单成功的页面 if (currentUrl.contains("http://www.chinabuye.com/m/checkout/onepage/success")) { hideSaveOrderJS(view); } // 改动地址的时候,最先调用的是该方法,为了体验好,这里先显示对话框 if (url.contains("http://www.chinabuye.com/m/paypal/express/ajaxEditAddress")) { dialog.show(); } super.onLoadResource(view, url); } } // 隐藏M Cart界面的头部和底部 private void hideMCartJS(WebView view) { view.loadUrl("javascript:window.handler.show(document.getElementById('topheader').style.display='none');"); view.loadUrl("javascript:window.handler.show(document.getElementById('footer').style.display='none');"); } // 隐藏Place Order界面 private void hidePlaceOrderJS(WebView view) { // 隐藏用户和logo信息 view.loadUrl("javascript:window.handler.show(document.getElementById('topheader').style.display='none');"); // 隐藏placeorder之后 view.loadUrl("javascript:window.handler.show(document.getElementById('iph_menu').style.display='none');"); // 隐藏最底部联系我们等信息 view.loadUrl("javascript:window.handler.show(document.getElementById('footer').style.display='none');"); // 隐藏Review Review Order和Shipping Reminders信息 view.loadUrl("javascript:window.handler.show(document.getElementById('paypal_page_head').style.display='none');"); view.loadUrl("javascript:window.handler.show(document.getElementById('paypal_important').style.display='none');"); // 细节隐藏 // view.loadUrl("javascript:window.handler.show(document.getElementById('paypal_change_shipping_address').style.display='none');"); view.loadUrl("javascript:window.handler.show(document.getElementById('paypal_change_payment_method').style.display='none');"); view.loadUrl("javascript:window.handler.show(document.getElementById('paypal_edit_shopping_cart').style.display='none');"); } // 隐藏Save Order界面 private void hideSaveOrderJS(WebView view) { view.loadUrl("javascript:window.handler.show(document.getElementById('topheader').style.display='none');"); view.loadUrl("javascript:window.handler.show(document.getElementById('footer').style.display='none');"); view.loadUrl("javascript:window.handler.show(document.getElementById('iph_menu').style.display='none');"); view.loadUrl("javascript:window.handler.show(document.getElementsByClassName('button-set')[0].style.display='none');"); } private class MyChromeClient extends WebChromeClient { // 处理javascript中的confirm,确认 // 登录界面有该对话框 // 继续页面有该对话框 @Override public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) { Builder builder = new Builder(CheckoutActivity2.this); builder.setTitle("Confirm Dialog"); builder.setMessage("Cancle the purchase and return to the ShoppingCart"); Log.e(TAG, "Mesage:" + message); Log.e(TAG, "JsResult:" + result.toString()); builder.setPositiveButton(R.string.ok, new AlertDialog.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // result.confirm(); // 拦截确定button Intent intent = new Intent(CheckoutActivity2.this, CartActivity.class); startActivity(intent); finish(); } }); builder.setNegativeButton(R.string.cancel, new AlertDialog.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 拦截取消button result.cancel(); } }); builder.setCancelable(false); builder.create(); builder.show(); return true; } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_BACK){ //这样会出现非常多奇怪的问题,还是直接结束 // if(webView.canGoBack()){ // webView.goBack(); // }else{ // CheckoutActivity2.this.finish(); // } CheckoutActivity2.this.finish(); return true; } return super.onKeyDown(keyCode, event); } }上面这个案例是我在app中实际使用到的,没有发现有什么问题。做MEC支付,主要思想是过滤URL,进行对话框的显示和消失、页面隐藏操作等,中间涉及JS。