Android 支付宝支付

之前写了一个关于微信支付的博文,后来有人问我为什么不写上一个支付宝支付的呢。当初想的是支付宝支付比较简单,不像微信支付里面有很多坑,支付宝支付只是处理好异步回调就可以了,不过既然问到了,那我也写出来支付宝支付,同样还是比较简单,将东西都抽出来,方便调用。

首先是OrderInfoUtil2_0这个基础类。后面调用的很多方法都抽出来了集成在这个类里面,就当这个是一个工具类吧。

publicclassOrderInfoUtil2_0 {

/**

* 构造授权参数列表

*

* @param pid

* @param app_id

* @param target_id

* @return

*/

publicstaticMap buildAuthInfoMap(String pid, String app_id, String target_id) {

Map keyValues =newHashMap();

// 商户签约拿到的app_id,如:2013081700024223

keyValues.put("app_id", app_id);

// 商户签约拿到的pid,如:2088102123816631

keyValues.put("pid", pid);

// 服务接口名称, 固定值

keyValues.put("apiname","com.alipay.account.auth");

// 商户类型标识, 固定值

keyValues.put("app_name","mc");

// 业务类型, 固定值

keyValues.put("biz_type","openservice");

// 产品码, 固定值

keyValues.put("product_id","APP_FAST_LOGIN");

// 授权范围, 固定值

keyValues.put("scope","kuaijie");

// 商户唯一标识,如:kkkkk091125

keyValues.put("target_id", target_id);

// 授权类型, 固定值

keyValues.put("auth_type","AUTHACCOUNT");

// 签名类型

keyValues.put("sign_type","RSA");

returnkeyValues;

}

/**

* 构造支付订单参数列表

*

* @return

*/

publicstaticMap buildOrderParamMap(String app_id, String total_amount, String product_info, String time,String out_trade_no) {

Map keyValues =newHashMap();

keyValues.put("app_id", app_id);

keyValues.put("biz_content","{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\""+ total_amount +"\",\"subject\":\""+ product_info +"\",\"body\":\"兑换\",\"out_trade_no\":\""+out_trade_no +"\"}");

keyValues.put("charset","utf-8");

keyValues.put("method","alipay.trade.app.pay");

keyValues.put("sign_type","RSA");

keyValues.put("timestamp", time);// "2016-07-29 16:55:53"

keyValues.put("version","1.0");

keyValues.put("notify_url","成功回调地址");

returnkeyValues;

}

/**

* 构造支付订单参数信息

*

* @param map 支付订单参数

* @return

*/

publicstaticString buildOrderParam(Map map) {

List keys =newArrayList(map.keySet());

StringBuilder sb =newStringBuilder();

for(inti =0; i < keys.size() -1; i++) {

String key = keys.get(i);

String value = map.get(key);

sb.append(buildKeyValue(key, value,true));

sb.append("&");

}

String tailKey = keys.get(keys.size() -1);

String tailValue = map.get(tailKey);

sb.append(buildKeyValue(tailKey, tailValue,true));

returnsb.toString();

}

/**

* 拼接键值对

*

* @param key

* @param value

* @param isEncode

* @return

*/

privatestaticString buildKeyValue(String key, String value,booleanisEncode) {

StringBuilder sb =newStringBuilder();

sb.append(key);

sb.append("=");

if(isEncode) {

try{

sb.append(URLEncoder.encode(value,"UTF-8"));

}catch(UnsupportedEncodingException e) {

sb.append(value);

}

}else{

sb.append(value);

}

returnsb.toString();

}

/**

* 对支付参数信息进行签名

*

* @param map 待签名授权信息

* @return

*/

publicstaticString getSign(Map map, String rsaKey) {

List keys =newArrayList(map.keySet());

// key排序

Collections.sort(keys);

StringBuilder authInfo =newStringBuilder();

for(inti =0; i < keys.size() -1; i++) {

String key = keys.get(i);

String value = map.get(key);

authInfo.append(buildKeyValue(key, value,false));

authInfo.append("&");

}

String tailKey = keys.get(keys.size() -1);

String tailValue = map.get(tailKey);

authInfo.append(buildKeyValue(tailKey, tailValue,false));

String oriSign = SignUtils.sign(authInfo.toString(), rsaKey);

String encodedSign ="";

try{

encodedSign = URLEncoder.encode(oriSign,"UTF-8");

}catch(UnsupportedEncodingException e) {

e.printStackTrace();

}

return"sign="+ encodedSign;

}

/**

* 要求外部订单号必须唯一。

*

* @return

*/

privatestaticString getOutTradeNo() {

SimpleDateFormat format =newSimpleDateFormat("MMddHHmmss", Locale.getDefault());

Date date =newDate();

String key = format.format(date);

Random r =newRandom();

key = key + r.nextInt();

key = key.substring(0,15);

returnkey;

}

}

/**

* 重要说明:

* 这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成;

* 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;

* 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;

*/

publicclassPayDemoActivityextendsFragmentActivity {

/**

* 支付宝支付业务:入参app_id

*/

publicstaticfinalString APPID ="入参app_id";

/**

* 支付宝账户登录授权业务:入参pid值

*/

publicstaticfinalString PID ="入参pid值";

/**

* 支付宝账户登录授权业务:入参target_id值

*/

publicstaticfinalString TARGET_ID ="入参target_id值";

/**

* 商户私钥,pkcs8格式

*/

publicstaticfinalString RSA_PRIVATE ="商户私钥";

privatestaticfinalintSDK_PAY_FLAG =1;

privatestaticfinalintSDK_AUTH_FLAG =2;

@SuppressLint("HandlerLeak")

privateHandler mHandler =newHandler() {

@SuppressWarnings("unused")

publicvoidhandleMessage(Message msg) {

switch(msg.what) {

caseSDK_PAY_FLAG: {

@SuppressWarnings("unchecked")

PayResult payResult =newPayResult((Map) msg.obj);

/**

对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。

*/

String resultInfo = payResult.getResult();// 同步返回需要验证的信息

String resultStatus = payResult.getResultStatus();

// 判断resultStatus 为9000则代表支付成功

if(TextUtils.equals(resultStatus,"9000")) {

// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。

MyToast.makeText(PayDemoActivity.this,"支付成功", Toast.LENGTH_SHORT).show();

}else{

// 该笔订单真实的支付结果,需要依赖服务端的异步通知。

MyToast.makeText(PayDemoActivity.this,"支付失败", Toast.LENGTH_SHORT).show();

}

break;

}

caseSDK_AUTH_FLAG: {

@SuppressWarnings("unchecked")

AuthResult authResult =newAuthResult((Map) msg.obj,true);

String resultStatus = authResult.getResultStatus();

// 判断resultStatus 为“9000”且result_code

// 为“200”则代表授权成功,具体状态码代表含义可参考授权接口文档

if(TextUtils.equals(resultStatus,"9000") && TextUtils.equals(authResult.getResultCode(),"200")) {

// 获取alipay_open_id,调支付时作为参数extern_token 的value

// 传入,则支付账户为该授权账户

MyToast.makeText(PayDemoActivity.this,

"授权成功\n"+ String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT)

.show();

}else{

// 其他状态值则为授权失败

MyToast.makeText(PayDemoActivity.this,

"授权失败"+ String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT).show();

}

break;

}

default:

break;

}

}

;

};

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.pay_main);

SimpleDateFormat dfs =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");

String date_e = dfs.format(newDate());

payV2("0.02","团币兑换", date_e);

}

/**

* 支付宝支付业务

*/

publicvoidpayV2(String price, String product_info, String time) {

if(TextUtils.isEmpty(APPID) || TextUtils.isEmpty(RSA_PRIVATE)) {

newAlertDialog.Builder(this).setTitle("警告").setMessage("需要配置APPID | RSA_PRIVATE")

.setPositiveButton("确定",newDialogInterface.OnClickListener() {

publicvoidonClick(DialogInterface dialoginterface,inti) {

finish();

}

}).show();

return;

}

/**

* 这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成;

* 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;

* 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;

*

* orderInfo的获取必须来自服务端;

*/

//        Map params = OrderInfoUtil2_0.buildOrderParamMap(APPID, price, product_info, time);

Map params=newHashMap();

String orderParam = OrderInfoUtil2_0.buildOrderParam(params);

String sign = OrderInfoUtil2_0.getSign(params, RSA_PRIVATE);

finalString orderInfo = orderParam +"&"+ sign;

Runnable payRunnable =newRunnable() {

@Override

publicvoidrun() {

PayTask alipay =newPayTask(PayDemoActivity.this);

Map result = alipay.payV2(orderInfo,true);

Log.e("msp", result.toString());

Message msg =newMessage();

msg.what = SDK_PAY_FLAG;

msg.obj = result;

mHandler.sendMessage(msg);

}

};

Thread payThread =newThread(payRunnable);

payThread.start();

}

/**

* 支付宝账户授权业务

*

* @param v

*/

publicvoidauthV2(View v) {

if(TextUtils.isEmpty(PID) || TextUtils.isEmpty(APPID) || TextUtils.isEmpty(RSA_PRIVATE)

|| TextUtils.isEmpty(TARGET_ID)) {

newAlertDialog.Builder(this).setTitle("警告").setMessage("需要配置PARTNER |APP_ID| RSA_PRIVATE| TARGET_ID")

.setPositiveButton("确定",newDialogInterface.OnClickListener() {

publicvoidonClick(DialogInterface dialoginterface,inti) {

}

}).show();

return;

}

/**

* 这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成;

* 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;

* 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;

*

* authInfo的获取必须来自服务端;

*/

Map authInfoMap = OrderInfoUtil2_0.buildAuthInfoMap(PID, APPID, TARGET_ID);

String info = OrderInfoUtil2_0.buildOrderParam(authInfoMap);

String sign = OrderInfoUtil2_0.getSign(authInfoMap, RSA_PRIVATE);

finalString authInfo = info +"&"+ sign;

Runnable authRunnable =newRunnable() {

@Override

publicvoidrun() {

// 构造AuthTask 对象

AuthTask authTask =newAuthTask(PayDemoActivity.this);

// 调用授权接口,获取授权结果

Map result = authTask.authV2(authInfo,true);

Message msg =newMessage();

msg.what = SDK_AUTH_FLAG;

msg.obj = result;

mHandler.sendMessage(msg);

}

};

// 必须异步调用

Thread authThread =newThread(authRunnable);

authThread.start();

}

/**

* get the sdk version. 获取SDK版本号

*/

publicvoidgetSDKVersion() {

PayTask payTask =newPayTask(this);

String version = payTask.getVersion();

MyToast.makeText(this, version, Toast.LENGTH_SHORT).show();

}

/**

* 原生的H5(手机网页版支付切natvie支付) 【对应页面网页支付按钮】

*

* @param v

*/

publicvoidh5Pay(View v) {

Intent intent =newIntent(this, H5PayDemoActivity.class);

Bundle extras =newBundle();

/**

* url是测试的网站,在app内部打开页面是基于webview打开的,demo中的webview是H5PayDemoActivity,

* demo中拦截url进行支付的逻辑是在H5PayDemoActivity中shouldOverrideUrlLoading方法实现,

* 商户可以根据自己的需求来实现

*/

String url ="http://m.taobao.com";

// url可以是一号店或者淘宝等第三方的购物wap站点,在该网站的支付过程中,支付宝sdk完成拦截支付

extras.putString("url", url);

intent.putExtras(extras);

startActivity(intent);

}

}

剩下就是支付宝支付的业务逻辑了。下面的out_trade_no是自己请求服务器返回过来的订单号,time就是当前时间,product_info就是显示在支付页面上的字段,自己设定,试试就知道。

/**

* 支付宝支付业务

*/

publicvoidpayV2(String price, String product_info, String time, String out_trade_no) {

if(TextUtils.isEmpty(APPID) || TextUtils.isEmpty(RSA_PRIVATE)) {

newAlertDialog.Builder(this).setTitle("警告").setMessage("需要配置APPID | RSA_PRIVATE")

.setPositiveButton("确定",newDialogInterface.OnClickListener() {

publicvoidonClick(DialogInterface dialoginterface,inti) {

finish();

}

}).show();

return;

}

/**

* 这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成;

* 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;

* 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;

*

* orderInfo的获取必须来自服务端;

*/

Map params = OrderInfoUtil2_0.buildOrderParamMap(APPID, price, product_info, time, out_trade_no);

String orderParam = OrderInfoUtil2_0.buildOrderParam(params);

String sign = OrderInfoUtil2_0.getSign(params, RSA_PRIVATE);

finalString orderInfo = orderParam +"&"+ sign;

Runnable payRunnable =newRunnable() {

@Override

publicvoidrun() {

PayTask alipay =newPayTask(RechargeMoneyActivity.this);

Map result = alipay.payV2(orderInfo,true);

Message msg =newMessage();

msg.what = SDK_PAY_FLAG;

msg.obj = result;

mHandler.sendMessage(msg);

}

};

Thread payThread =newThread(payRunnable);

payThread.start();

}

handler处理

[java]view plaincopy

privateHandler mHandler =newHandler() {

@SuppressWarnings("unused")

publicvoidhandleMessage(Message msg) {

switch(msg.what) {

caseSDK_PAY_FLAG: {

@SuppressWarnings("unchecked")

PayResult payResult =newPayResult((Map) msg.obj);

/**

对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。

*/

String resultInfo = payResult.getResult();// 同步返回需要验证的信息

String memo = payResult.getMemo();

String resultStatus = payResult.getResultStatus();

// 判断resultStatus 为9000则代表支付成功

if(TextUtils.equals(resultStatus,"9000")) {

// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。

//                        showHintDialog("支付成功");

}else{

pay_state ="0";

}

String sign = TGmd5.getMD5(logid + pay_state + memo);

tuanbiExchangePresenter.doAlipay(logid, pay_state, memo, sign);

break;

}

caseSDK_AUTH_FLAG: {

@SuppressWarnings("unchecked")

AuthResult authResult =newAuthResult((Map) msg.obj,true);

String resultStatus = authResult.getResultStatus();

// 判断resultStatus 为“9000”且result_code

// 为“200”则代表授权成功,具体状态码代表含义可参考授权接口文档

if(TextUtils.equals(resultStatus,"9000") && TextUtils.equals(authResult.getResultCode(),"200")) {

// 获取alipay_open_id,调支付时作为参数extern_token 的value

// 传入,则支付账户为该授权账户

MyToast.makeText(RechargeMoneyActivity.this,

"授权成功\n"+ String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT)

.show();

}else{

// 其他状态值则为授权失败

MyToast.makeText(RechargeMoneyActivity.this,

"授权失败"+ String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT).show();

}

break;

}

default:

break;

}

}

;

};

这样一个支付宝支付就集成了,是不是很简单。复制代码就能写出,注意里面代码注解。填写各种id。


csdn项目地址:http://blog.csdn.net/greatdaocaoren/article/details/75257603

你可能感兴趣的:(Android 支付宝支付)