接上篇android接入微信支付文章,這篇咱們帶你來接入支付寶支付服務java
首先要說明的是我的感受接入支付寶比微信簡單多了,很輕鬆的,因此同窗們沒關係張~android
固然仍是老規矩啦,上來確定的貼上官網地址,由於我這些服務每天在更新,而個人文章是教你們方法,而讓你不是照葫蘆畫瓢express
進入app支付文檔有兩種方式,一種是直接在下面的開放業務裏後端
還有一種是經過上面的導航欄文檔中心,而後滾動到業務接入那一欄,能夠看到移動支付服務器
固然也能夠直接打開這個地址,文檔仍是挺多,能夠關注我勾選的這幾項微信
首先這裏我也要說明的是我的是不能申請的,只能是企業,因此我demo裏面的用的一些資料也是demo裏面的app
這裏是交互流程的官方文檔,須要詳細的能夠點進去看看dom
咱們來到官方demo的下載地址eclipse
能夠看到有兩個,選擇你須要的就好了,下載解壓完直接導入eclipse並配置一些參數運行就能夠查看效果了異步
將demo裏面的alipaySdk-20160223.jar拷貝到咱們工程的libs下,並添加到依賴中
權限
ses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
activity
<activity android:name="com.alipay.sdk.app.H5PayActivity" android:configChanges="orientation|keyboardHidden|navigation" android:exported="false" android:screenOrientation="behind"> </activity> <activity android:name="com.alipay.sdk.auth.AuthActivity" android:configChanges="orientation|keyboardHidden|navigation" android:exported="false" android:screenOrientation="behind"> </activity>
這一步,能夠在服務端完成,也能夠在本地完成
String orderInfo = getOrderInfo("測試的商品", "該測試商品的詳細描述", "0.01"); /** * 特別注意,這裏的簽名邏輯須要放在服務端,切勿將私鑰泄露在代碼中! */ String sign = sign(orderInfo); try { /** * 僅需對sign 作URL編碼 */ sign = URLEncoder.encode(sign, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } /** * 完整的符合支付寶參數規範的訂單信息 */ final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType(); Runnable payRunnable = new Runnable() { @Override public void run() { // 構造PayTask 對象 PayTask alipay = new PayTask(MainActivity.this); // 調用支付接口,獲取支付結果 String result = alipay.pay(payInfo, true); Message msg = new Message(); msg.what = SDK_PAY_FLAG; msg.obj = result; mHandler.sendMessage(msg); } }; // 必須異步調用 Thread payThread = new Thread(payRunnable); payThread.start();
處理支付結果
@SuppressLint("HandlerLeak") private Handler mHandler = new Handler() { @SuppressWarnings("unused") public void handleMessage(Message msg) { switch (msg.what) { case SDK_PAY_FLAG: { PayResult payResult = new PayResult((String) msg.obj); /** * 同步返回的結果必須放置到服務端進行驗證(驗證的規則請看https://doc.open.alipay.com/doc2/ * detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665& * docType=1) 建議商戶依賴異步通知 */ String resultInfo = payResult.getResult();// 同步返回須要驗證的信息 String resultStatus = payResult.getResultStatus(); // 判斷resultStatus 爲「9000」則表明支付成功,具體狀態碼錶明含義可參考接口文檔 if (TextUtils.equals(resultStatus, "9000")) { Toast.makeText(MainActivity.this, "支付成功", Toast.LENGTH_SHORT).show(); } else { // 判斷resultStatus 爲非"9000"則表明可能支付失敗 // "8000"表明支付結果由於支付渠道緣由或者系統緣由還在等待支付結果確認,最終交易是否成功以服務端異步通知爲準(小几率狀態) if (TextUtils.equals(resultStatus, "8000")) { Toast.makeText(MainActivity.this, "支付結果確認中", Toast.LENGTH_SHORT).show(); } else { // 其餘值就能夠判斷爲支付失敗,包括用戶主動取消支付,或者系統返回的錯誤 Toast.makeText(MainActivity.this, "支付失敗", Toast.LENGTH_SHORT).show(); } } break; } default: break; } } };
這裏支付成功了,只是提示用戶,還得從服務器確認是否正在支付了,我這裏只寫了本地,其餘若是在服務端實現是同樣的,你把這代碼直接發給後端就好了(若是後端是Java開發),能夠看到咱們已經成功調起支付寶服務了
完整代碼:
package cn.woblog.testalipay; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.DialogInterface; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.view.View; import android.widget.Toast; import com.alipay.sdk.app.PayTask; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.Random; import cn.woblog.testalipay.domain.PayResult; import cn.woblog.testalipay.util.SignUtils; public class MainActivity extends AppCompatActivity { public static final String PARTNER = ""; // 商戶收款帳號 public static final String SELLER = ""; // 商戶私鑰,pkcs8格式 public static final String RSA_PRIVATE = ""; private static final int SDK_PAY_FLAG = 1; @SuppressLint("HandlerLeak") private Handler mHandler = new Handler() { @SuppressWarnings("unused") public void handleMessage(Message msg) { switch (msg.what) { case SDK_PAY_FLAG: { PayResult payResult = new PayResult((String) msg.obj); /** * 同步返回的結果必須放置到服務端進行驗證(驗證的規則請看https://doc.open.alipay.com/doc2/ * detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665& * docType=1) 建議商戶依賴異步通知 */ String resultInfo = payResult.getResult();// 同步返回須要驗證的信息 String resultStatus = payResult.getResultStatus(); // 判斷resultStatus 爲「9000」則表明支付成功,具體狀態碼錶明含義可參考接口文檔 if (TextUtils.equals(resultStatus, "9000")) { Toast.makeText(MainActivity.this, "支付成功", Toast.LENGTH_SHORT).show(); } else { // 判斷resultStatus 爲非"9000"則表明可能支付失敗 // "8000"表明支付結果由於支付渠道緣由或者系統緣由還在等待支付結果確認,最終交易是否成功以服務端異步通知爲準(小几率狀態) if (TextUtils.equals(resultStatus, "8000")) { Toast.makeText(MainActivity.this, "支付結果確認中", Toast.LENGTH_SHORT).show(); } else { // 其餘值就能夠判斷爲支付失敗,包括用戶主動取消支付,或者系統返回的錯誤 Toast.makeText(MainActivity.this, "支付失敗", Toast.LENGTH_SHORT).show(); } } break; } default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void testAlipay(View view) { if (TextUtils.isEmpty(PARTNER) || TextUtils.isEmpty(RSA_PRIVATE) || TextUtils.isEmpty(SELLER)) { new AlertDialog.Builder(this).setTitle("警告").setMessage("須要配置PARTNER | RSA_PRIVATE| SELLER") .setPositiveButton("肯定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialoginterface, int i) { // finish(); } }).show(); return; } String orderInfo = getOrderInfo("測試的商品", "該測試商品的詳細描述", "0.01"); /** * 特別注意,這裏的簽名邏輯須要放在服務端,切勿將私鑰泄露在代碼中! */ String sign = sign(orderInfo); try { /** * 僅需對sign 作URL編碼 */ sign = URLEncoder.encode(sign, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } /** * 完整的符合支付寶參數規範的訂單信息 */ final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType(); Runnable payRunnable = new Runnable() { @Override public void run() { // 構造PayTask 對象 PayTask alipay = new PayTask(MainActivity.this); // 調用支付接口,獲取支付結果 String result = alipay.pay(payInfo, true); Message msg = new Message(); msg.what = SDK_PAY_FLAG; msg.obj = result; mHandler.sendMessage(msg); } }; // 必須異步調用 Thread payThread = new Thread(payRunnable); payThread.start(); } /** * create the order info. 建立訂單信息 */ private String getOrderInfo(String subject, String body, String price) { // 簽約合做者身份ID String orderInfo = "partner=" + "\"" + PARTNER + "\""; // 簽約賣家支付寶帳號 orderInfo += "&seller_id=" + "\"" + SELLER + "\""; // 商戶網站惟一訂單號 orderInfo += "&out_trade_no=" + "\"" + getOutTradeNo() + "\""; // 商品名稱 orderInfo += "&subject=" + "\"" + subject + "\""; // 商品詳情 orderInfo += "&body=" + "\"" + body + "\""; // 商品金額 orderInfo += "&total_fee=" + "\"" + price + "\""; // 服務器異步通知頁面路徑 orderInfo += "¬ify_url=" + "\"" + "http://notify.msp.hk/notify.htm" + "\""; // 服務接口名稱, 固定值 orderInfo += "&service=\"mobile.securitypay.pay\""; // 支付類型, 固定值 orderInfo += "&payment_type=\"1\""; // 參數編碼, 固定值 orderInfo += "&_input_charset=\"utf-8\""; // 設置未付款交易的超時時間 // 默認30分鐘,一旦超時,該筆交易就會自動被關閉。 // 取值範圍:1m~15d。 // m-分鐘,h-小時,d-天,1c-當天(不管交易什麼時候建立,都在0點關閉)。 // 該參數數值不接受小數點,如1.5h,可轉換爲90m。 orderInfo += "&it_b_pay=\"30m\""; // extern_token爲通過快登受權獲取到的alipay_open_id,帶上此參數用戶將使用受權的帳戶進行支付 // orderInfo += "&extern_token=" + "\"" + extern_token + "\""; // 支付寶處理完請求後,當前頁面跳轉到商戶指定頁面的路徑,可空 orderInfo += "&return_url=\"m.alipay.com\""; // 調用銀行卡支付,需配置此參數,參與簽名, 固定值 (須要簽約《無線銀行卡快捷支付》才能使用) // orderInfo += "&paymethod=\"expressGateway\""; return orderInfo; } /** * sign the order info. 對訂單信息進行簽名 * * @param content 待簽名訂單信息 */ private String sign(String content) { return SignUtils.sign(content, RSA_PRIVATE); } /** * get the sign type we use. 獲取簽名方式 */ private String getSignType() { return "sign_type=\"RSA\""; } /** * get the out_trade_no for an order. 生成商戶訂單號,該值在商戶端應保持惟一(可自定義格式規範) */ private String getOutTradeNo() { SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault()); Date date = new Date(); String key = format.format(date); Random r = new Random(); key = key + r.nextInt(); key = key.substring(0, 15); return key; } }
若是要測試demo,請替換
MainActivity中PARTNER,SELLER,RSA_PRIVATE爲你申請到的值