Android接入支付宝支付实现
接上篇android接入微信支付文章,這篇我們帶你來(lái)接入支付寶支付服務(wù)
簡(jiǎn)介
首先要說(shuō)明的是個(gè)人感覺(jué)接入支付寶比微信簡(jiǎn)單多了,很輕松的,所以同學(xué)們不要緊張~
當(dāng)然還是老規(guī)矩啦,上來(lái)肯定的貼上官網(wǎng)地址,因?yàn)槲疫@些服務(wù)天天在更新,而我的文章是教大家方法,而讓你不是照葫蘆畫(huà)瓢
進(jìn)入app支付文檔有兩種方式,一種是直接在下面的開(kāi)放業(yè)務(wù)里
還有一種是通過(guò)上面的導(dǎo)航欄文檔中心,然后滾動(dòng)到業(yè)務(wù)接入那一欄,可以看到移動(dòng)支付
當(dāng)然也可以直接打開(kāi)這個(gè)地址,文檔還是挺多,可以關(guān)注我勾選的這幾項(xiàng)
首先這里我也要說(shuō)明的是個(gè)人是不能申請(qǐng)的,只能是企業(yè),所以我demo里面的用的一些資料也是demo里面的
這里是交互流程的官方文檔,需要詳細(xì)的可以點(diǎn)進(jìn)去看看
運(yùn)行Demo
我們來(lái)到官方demo的下載地址
可以看到有兩個(gè),選擇你需要的就行了,下載解壓完直接導(dǎo)入eclipse并配置一些參數(shù)運(yùn)行就可以查看效果了
導(dǎo)入jar
將demo里面的alipaySdk-20160223.jar拷貝到我們工程的libs下,并添加到依賴中
配置
權(quán)限
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
<activityandroid:name="com.alipay.sdk.app.H5PayActivity"android:configChanges="orientation|keyboardHidden|navigation"android:exported="false"android:screenOrientation="behind"> </activity> <activityandroid:name="com.alipay.sdk.auth.AuthActivity"android:configChanges="orientation|keyboardHidden|navigation"android:exported="false"android:screenOrientation="behind"> </activity>訂單數(shù)據(jù)生成
這一步,可以在服務(wù)端完成,也可以在本地完成
String orderInfo = getOrderInfo("測(cè)試的商品", "該測(cè)試商品的詳細(xì)描述", "0.01");/*** 特別注意,這里的簽名邏輯需要放在服務(wù)端,切勿將私鑰泄露在代碼中!*/ String sign = sign(orderInfo); try {/*** 僅需對(duì)sign 做URL編碼*/sign = URLEncoder.encode(sign, "UTF-8"); } catch (UnsupportedEncodingException e) {e.printStackTrace(); }/*** 完整的符合支付寶參數(shù)規(guī)范的訂單信息*/ final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();Runnable payRunnable = new Runnable() {@Overridepublic void run() {// 構(gòu)造PayTask 對(duì)象PayTask alipay = new PayTask(MainActivity.this);// 調(diào)用支付接口,獲取支付結(jié)果String result = alipay.pay(payInfo, true);Message msg = new Message();msg.what = SDK_PAY_FLAG;msg.obj = result;mHandler.sendMessage(msg);} };// 必須異步調(diào)用 Thread payThread = new Thread(payRunnable); payThread.start();處理支付結(jié)果
@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);/*** 同步返回的結(jié)果必須放置到服務(wù)端進(jìn)行驗(yàn)證(驗(yàn)證的規(guī)則請(qǐng)看https://doc.open.alipay.com/doc2/* detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&* docType=1) 建議商戶依賴異步通知*/String resultInfo = payResult.getResult();// 同步返回需要驗(yàn)證的信息 String resultStatus = payResult.getResultStatus();// 判斷resultStatus 為“9000”則代表支付成功,具體狀態(tài)碼代表含義可參考接口文檔if (TextUtils.equals(resultStatus, "9000")) {Toast.makeText(MainActivity.this, "支付成功", Toast.LENGTH_SHORT).show();} else {// 判斷resultStatus 為非"9000"則代表可能支付失敗// "8000"代表支付結(jié)果因?yàn)橹Ц肚涝蚧蛘呦到y(tǒng)原因還在等待支付結(jié)果確認(rèn),最終交易是否成功以服務(wù)端異步通知為準(zhǔn)(小概率狀態(tài))if (TextUtils.equals(resultStatus, "8000")) {Toast.makeText(MainActivity.this, "支付結(jié)果確認(rèn)中", Toast.LENGTH_SHORT).show();} else {// 其他值就可以判斷為支付失敗,包括用戶主動(dòng)取消支付,或者系統(tǒng)返回的錯(cuò)誤Toast.makeText(MainActivity.this, "支付失敗", Toast.LENGTH_SHORT).show();}}break;}default:break;}}};這里支付成功了,只是提示用戶,還得從服務(wù)器確認(rèn)是否正在支付了,我這里只寫了本地,其他如果在服務(wù)端實(shí)現(xiàn)是一樣的,你把這代碼直接發(fā)給后端就行了(如果后端是Java開(kāi)發(fā)),可以看到我們已經(jīng)成功調(diào)起支付寶服務(wù)了
完整代碼:
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 = "";// 商戶收款賬號(hào)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);/*** 同步返回的結(jié)果必須放置到服務(wù)端進(jìn)行驗(yàn)證(驗(yàn)證的規(guī)則請(qǐng)看https://doc.open.alipay.com/doc2/* detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&* docType=1) 建議商戶依賴異步通知*/String resultInfo = payResult.getResult();// 同步返回需要驗(yàn)證的信息 String resultStatus = payResult.getResultStatus();// 判斷resultStatus 為“9000”則代表支付成功,具體狀態(tài)碼代表含義可參考接口文檔if (TextUtils.equals(resultStatus, "9000")) {Toast.makeText(MainActivity.this, "支付成功", Toast.LENGTH_SHORT).show();} else {// 判斷resultStatus 為非"9000"則代表可能支付失敗// "8000"代表支付結(jié)果因?yàn)橹Ц肚涝蚧蛘呦到y(tǒng)原因還在等待支付結(jié)果確認(rèn),最終交易是否成功以服務(wù)端異步通知為準(zhǔn)(小概率狀態(tài))if (TextUtils.equals(resultStatus, "8000")) {Toast.makeText(MainActivity.this, "支付結(jié)果確認(rèn)中", Toast.LENGTH_SHORT).show();} else {// 其他值就可以判斷為支付失敗,包括用戶主動(dòng)取消支付,或者系統(tǒng)返回的錯(cuò)誤Toast.makeText(MainActivity.this, "支付失敗", Toast.LENGTH_SHORT).show();}}break;}default:break;}}};@Overrideprotected 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("測(cè)試的商品", "該測(cè)試商品的詳細(xì)描述", "0.01");/*** 特別注意,這里的簽名邏輯需要放在服務(wù)端,切勿將私鑰泄露在代碼中!*/String sign = sign(orderInfo);try {/*** 僅需對(duì)sign 做URL編碼*/sign = URLEncoder.encode(sign, "UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}/*** 完整的符合支付寶參數(shù)規(guī)范的訂單信息*/final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();Runnable payRunnable = new Runnable() {@Overridepublic void run() {// 構(gòu)造PayTask 對(duì)象PayTask alipay = new PayTask(MainActivity.this);// 調(diào)用支付接口,獲取支付結(jié)果String result = alipay.pay(payInfo, true);Message msg = new Message();msg.what = SDK_PAY_FLAG;msg.obj = result;mHandler.sendMessage(msg);}};// 必須異步調(diào)用Thread payThread = new Thread(payRunnable);payThread.start();}/*** create the order info. 創(chuàng)建訂單信息*/private String getOrderInfo(String subject, String body, String price) {// 簽約合作者身份IDString orderInfo = "partner=" + "\"" + PARTNER + "\"";// 簽約賣家支付寶賬號(hào)orderInfo += "&seller_id=" + "\"" + SELLER + "\"";// 商戶網(wǎng)站唯一訂單號(hào)orderInfo += "&out_trade_no=" + "\"" + getOutTradeNo() + "\"";// 商品名稱orderInfo += "&subject=" + "\"" + subject + "\"";// 商品詳情orderInfo += "&body=" + "\"" + body + "\"";// 商品金額orderInfo += "&total_fee=" + "\"" + price + "\"";// 服務(wù)器異步通知頁(yè)面路徑orderInfo += "¬ify_url=" + "\"" + "http://notify.msp.hk/notify.htm" + "\"";// 服務(wù)接口名稱, 固定值orderInfo += "&service=\"mobile.securitypay.pay\"";// 支付類型, 固定值orderInfo += "&payment_type=\"1\"";// 參數(shù)編碼, 固定值orderInfo += "&_input_charset=\"utf-8\"";// 設(shè)置未付款交易的超時(shí)時(shí)間// 默認(rèn)30分鐘,一旦超時(shí),該筆交易就會(huì)自動(dòng)被關(guān)閉。// 取值范圍:1m~15d。// m-分鐘,h-小時(shí),d-天,1c-當(dāng)天(無(wú)論交易何時(shí)創(chuàng)建,都在0點(diǎn)關(guān)閉)。// 該參數(shù)數(shù)值不接受小數(shù)點(diǎn),如1.5h,可轉(zhuǎn)換為90m。orderInfo += "&it_b_pay=\"30m\"";// extern_token為經(jīng)過(guò)快登授權(quán)獲取到的alipay_open_id,帶上此參數(shù)用戶將使用授權(quán)的賬戶進(jìn)行支付// orderInfo += "&extern_token=" + "\"" + extern_token + "\"";// 支付寶處理完請(qǐng)求后,當(dāng)前頁(yè)面跳轉(zhuǎn)到商戶指定頁(yè)面的路徑,可空orderInfo += "&return_url=\"m.alipay.com\"";// 調(diào)用銀行卡支付,需配置此參數(shù),參與簽名, 固定值 (需要簽約《無(wú)線銀行卡快捷支付》才能使用)// orderInfo += "&paymethod=\"expressGateway\"";return orderInfo;}/*** sign the order info. 對(duì)訂單信息進(jìn)行簽名** @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. 生成商戶訂單號(hào),該值在商戶端應(yīng)保持唯一(可自定義格式規(guī)范)*/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;}}如果要測(cè)試demo,請(qǐng)?zhí)鎿Q
MainActivity中PARTNER,SELLER,RSA_PRIVATE為你申請(qǐng)到的值
?
與50位技術(shù)專家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Android接入支付宝支付实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: JS验证身份证
- 下一篇: 纯原生组件化-模块化的探索