Cordova從零開始插件開發-支付寶插件(二)

上節我們實現了簡單的插件編寫。那麼這一節,我們開始真正的實現支付寶插件的編寫。

一、下載支付寶接口文檔及DEMO

具體怎麼下載,請自行度娘解決。下載完畢如下所以。

二、解壓後如下:

請自行根據openssl中“生成命令.txt”的指導,生成商戶公鑰,私鑰及轉換pkcs8格式

若根據指導無法完成,請自行度娘,有超詳細的介紹。

生成完畢,上傳用戶公鑰到支付寶用戶私鑰管理。如下圖:

點擊查看PID|Key,查看自己的商戶ID,以及上傳商戶公鑰。

好了,到此支付寶的服務器配置方面已經完畢!

下面開始代碼的編寫。

一、複製DEMO中的類庫文件到我們的項目中。即複製到我們的插件包中(com.demo.plugs)

項目結構如下:



新建PlugAlipay.java文件,並打開DEMO中PayDemoActivity.java文件,複製代碼到我們的文件中

        // 商戶PID
	public static final String PARTNER = "";
	// 商戶收款賬號
	public static final String SELLER = "";
	// 商戶私鑰,pkcs8格式
	public static final String RSA_PRIVATE = "";
我們只需要這幾個參數,其他的不考慮。不影響集成。

public boolean execute(String action , JSONArray args, CallbackContext callbackContext ){
    PARTNER = "2088xxxxxxxxxx";
    SELLER = "你的支付寶收款賬戶   [email protected]";
    這個地方的私鑰是pkcs8格式的。
    RSA_PRIVATE = "MIICdgIBADANBgkqhkiG9xxxxxxxxxxx.....";
    try {
                    //從傳遞的參數中獲取以下參數 
                    //subject:商品名稱
                    //body:商品詳情
                    //price:付款金額
                    //fromUrlScheme:支付完畢後,跳轉到用戶應用的頁面地址。
                    //notifyUrl:服務器異步通知接收文件
                    
                    //整理參數
                    JSONObject arguments = args.getJSONObject(0);
                    
                    //System.out.println("參數傳遞:"+arguments.toString());
                    
                    String subject = arguments.getString("subject");
                    String body = arguments.getString("body");
                    String price = arguments.getString("price");
                    String fromUrlScheme = arguments.getString("fromUrlScheme");
                    String notifyUrl = arguments.getString("notifyUrl");
                    
                    //執行方法
                    this.pay( subject, body, price, fromUrlScheme, notifyUrl);
                } catch (JSONException e) {
                    e.printStackTrace();
                    Toast.makeText(
                            this.cordova.getActivity().getApplicationContext(), 
                            "參數傳遞錯誤", 
                            Toast.LENGTH_LONG
                            ).show();
                    return false;
                }
                return true;

 }

添加pay方法,這裏基本是從demo中copy過來的,可根據自己的需求變更。

public void pay(String subject, String body, String price, final String fromUrlScheme, String notifyUrl) {
		// 訂單
        String orderInfo = getOrderInfo(subject, body, price,  notifyUrl);
        
        System.out.println("封裝訂單信息:"+orderInfo);
        // 對訂單做RSA 簽名
        String sign = sign(orderInfo);
        
        System.out.println("封裝簽名信息:"+sign);
        try {
            // 僅需對sign 做URL編碼
            sign = URLEncoder.encode(sign, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        // 完整的符合支付寶參數規範的訂單信息
        final String payInfo = orderInfo + "&sign=\"" + sign + "\"&"
                + getSignType();
        
        System.out.println("封裝完整訂單信息:"+payInfo);
        
        cordova.getThreadPool().execute(new Runnable() {
            @Override
            public void run() {
                // 構造PayTask 對象
                PayTask alipay = new PayTask(cordova.getActivity());
                // 調用支付接口,獲取支付結果
                String result = alipay.pay(payInfo);
                
                System.out.println("支付結果:"+result);
                
                //對支付寶返回的消息進行處理
                PayResult payResult = new PayResult(result);

		// 支付寶返回此次支付結果及加簽,建議對支付寶簽名信息拿簽約時支付寶提供的公鑰做驗籤
		String resultInfo = payResult.getResult();

		String resultStatus = payResult.getResultStatus();

		// 判斷resultStatus 爲“9000”則代表支付成功,具體狀態碼代表含義可參考接口文檔
		if (TextUtils.equals(resultStatus, "9000")) {

                       toastMsg("支付成功");//這個方式是自定義的toast方法
					
		} else {
			// 判斷resultStatus 爲非“9000”則代表可能支付失敗
			// “8000”代表支付結果因爲支付渠道原因或者系統原因還在等待支付結果確認,最終交易是否成功以服務端異步通知爲準(小概率狀態)
			if (TextUtils.equals(resultStatus, "8000")) {
						toastMsg("支付結果確認中");
			} else {
				// 其他值就可以判斷爲支付失敗,包括用戶主動取消支付,或者系統返回的錯誤
				toastMsg("支付失敗");
			}
		}
				
		//不管執行是否成功,顯示Toast信息後,返回商戶界面
                Intent backUrl = new Intent(Intent.ACTION_VIEW,
                        Uri.parse(fromUrlScheme + result));
                cordova.getActivity().startActivity(backUrl);
            }
        });
    }
自定義Toast方法

/**
	 * 自定義顯示Toast消息方法。
	 * @param toamsg 
	 */
	private void toastMsg(String toamsg) {
		Toast.makeText(this.cordova.getActivity().getApplicationContext(), toamsg, Toast.LENGTH_LONG).show();
	}

這裏基本的編寫就完畢了。

現在來js文件中調用測試。

function a1(){
	var sstr = {
		subject:1,
		body:"繳費第三",
		price:"0.01",
		fromUrlScheme:"file:///android_assets/www/index.html",//這裏是支付完成後,返回到用戶app
		notifyUrl:"http://www.xxx.com:9121/"   //這裏的地址支持花生殼解析的,隨便什麼地址都可以,只要通過外網可以訪問到就行。
	};
	
	cordova.exec(null,null,"PlugAlipay",null,[sstr]);
}

因爲這裏我們是新建了一個java文件來執行支付寶的操作,所以,在res\xml\config.xml中要更改配置,不然會訪問不到。

<feature name="PlugAlipay">
	    <param name="android-package" value="com.demo.plugs.PlugAlipay" />
	</feature>
這裏就可以了。。


我在做這個的時候,出現了一個問題,就是提示 系統繁忙 請稍後再試(ALI64)  ,網上找了好多,都是說私鑰,公鑰,什麼的,上傳不對應之類的。

其實是我在傳遞json參數的時候,fromUrlScheme 和 notifyUrl 的值傳遞的是空值所造成的。

這2個值不允許爲空。否則就是那個錯誤,一直提示!


到這裏,基本就結束了插件的代碼編寫,,下一節,我們把做好的插件進行優化並遵從開源精神發佈一下!




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章