最近在做一个支付模块,支付宝账户手续复杂但审核快,微信支付手续较少但审核慢,但都需要花钱。
android 客户端的处理并不复杂,只是将商品的名称 描述 价格 等一些其他的一些属性上传本地服务器,由服务器为商品签名加密再返回到本地,此时数据经过特殊处理,再将数据上传给马云爸爸就ok了。
项目让我恼火的是总是出ali64错误,其实这主要是公私钥不匹配,个人建议这么排查这个错误:
1.先用支付宝公私钥生成工具再生成一遍公私钥,替换掉开发平台的以及服务器的钥匙
2.如果还是触发ali64错误,检查一遍商品信息里的格式:(最好是客户端上传商品信息,别把官方demo里的那个生成orderinfo的放在客户端里,把他放在服务器里做),这里再出问题应该都是服务器那边的差错,因为客户端只是起到一个网络请求数据的作用。
package utils;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.alipay.sdk.app.PayTask;
import com.google.gson.Gson;
import org.xutils.common.Callback;
import org.xutils.http.HttpMethod;
import org.xutils.http.RequestParams;
import org.xutils.x;
import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.net.URLEncoder;
import Contacts.Contacts;
import jsonbean.AlipayBean;
import jsonbean.AlipayOrderBean;
/**
* Created by hcy on 2016/7/11.
* func:支付宝支付工具类
*/
public class AliPayUtils {
//商户id
private static final String PARTNER = Contacts.ALPAY_PARENT;
//商户收款账号
private static final String SELLER = Contacts.ALIPAY_SELLER;
private AlipayOrderBean order;//订单信息类
private Context context;
private Activity activity;
private MyHandler mHandler;
private Handler callBackHandler;
public AliPayUtils(AlipayOrderBean order, Context context, Activity activity, Handler callBackHandler) {
this.order = order;
this.context = context;
this.activity = activity;
this.callBackHandler = callBackHandler;
mHandler = new MyHandler(activity);
}
/*
支付宝 核心支付功能
*/
public void pay() {
RequestParams requestParams = new RequestParams(Contacts.ALIPAY_SERVER);
requestParams.addBodyParameter("token", Contacts.USER_TOKEN);
requestParams.addBodyParameter("partner", PARTNER);
requestParams.addBodyParameter("seller_id", SELLER);
requestParams.addBodyParameter("subject", order.getSubject());
requestParams.addBodyParameter("body", order.getSubject());
requestParams.addBodyParameter("total_fee", "0.01");
requestParams.addBodyParameter("user_id", order.getApp_userid());
requestParams.addBodyParameter("app", order.getPay_app());
requestParams.addBodyParameter("pay_type", order.getPay_type());
requestParams.addBodyParameter("buy_type", order.getBuy_type());
requestParams.addBodyParameter("counter_fee",order.getCounter_fee());
requestParams.addBodyParameter("count", order.getCount());
requestParams.addBodyParameter("pay_mode", order.getPay_mode());
requestParams.addBodyParameter("pay_dev", order.getPay_dev());
requestParams.addBodyParameter("channel_business", order.getChannel_business());
requestParams.addBodyParameter("app_unit",order.getApp_unit());
requestParams.addBodyParameter("app_course",order.getApp_course());
requestParams.addBodyParameter("pay_start_time",order.getPay_start_time());
requestParams.addBodyParameter("pay_end_time",order.getPay_end_time());
x.http().request(HttpMethod.POST, requestParams, new Callback.CommonCallback<String>() {
@Override
public void onSuccess(String result) {
if (result != null) {
Log.i("马云请求服务器结果:::onSuccess", "" + result);
Message msg = Message.obtain();
msg.what = 1;
msg.obj = result;
mHandler.sendMessage(msg);
}
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
Toast.makeText(activity, "网络错误", Toast.LENGTH_SHORT).show();
Log.i("马云请求服务器结果:::onError", "" + ex.getMessage() + " " + ex.getCause()+" "+ex.getLocalizedMessage()+" "+ex.getStackTrace().toString());
}
@Override
public void onCancelled(CancelledException cex) {
Toast.makeText(activity, "网络错误", Toast.LENGTH_SHORT).show();
Log.i("马云请求服务器结果:::onCancelled", "" + cex.getMessage() + " " + cex.getMessage());
}
@Override
public void onFinished() {
}
});
}
/**
* 处理服务器签名返回后的订单片段
*/
private class MyHandler extends Handler {
private WeakReference<Activity> weakReference;
public MyHandler(Activity activity) {
weakReference = new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(Message msg) {
final Activity activity = weakReference.get();
if (activity != null) {
switch (msg.what) {
case 1:
// 返回订单信息成功
String signJson = (String) msg.obj;
if (!signJson.equals("{\"Info\":{\"Msg\":\"\\u652f\\u4ed8\\u7b7e\\u540d\\u9a8c\\u8bc1\\u9519\\u8bef!\\u4e0d\\u901a\\u8fc7\",\"Code\":20000}}")) {
Gson gson = new Gson();
AlipayBean alipayBean = gson.fromJson(signJson, AlipayBean.class);
try {
String sign = URLEncoder.encode(alipayBean.getSign(), "UTF-8");//必须加
/**
* 完整的符合支付宝参数规范的订单信息
*/
String str = alipayBean.getStr();
Log.i("马云接收服务器结果<<<", "" + str);
String payInfo = str + "&sign=\"" + sign + "\"&" + getSignType();
Log.i("马云处理到完整的订单信息", "" + payInfo);
new MyAlipayAsyncTask(activity).execute(payInfo);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
break;
}
}
super.handleMessage(msg);
}
}
private class MyAlipayAsyncTask extends AsyncTask<String, Void, String> {
private Activity activity;
public MyAlipayAsyncTask(Activity activity) {
this.activity = activity;
}
@Override
protected String doInBackground(String... params) {
// 构造PayTask 对象
PayTask alipay = new PayTask(activity);
// 调用支付接口,获取支付结果
String result = alipay.pay(params[0], true);
return result;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (s != null) {
PayResult payResult = new PayResult(s);
Log.i("马云处理付款结果:::", "" + payResult);
String resultInfo = payResult.getResult();// 同步返回需要验证的信息
Log.i("马云处理付款结果:::2", "" + resultInfo);
String resultStatus = payResult.getResultStatus();
String result = payResult.getResult();//订单数据信息
Log.i("YYYTTSSSSS::", result);
// 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
if (TextUtils.equals(resultStatus, "9000")) {
Toast.makeText(context, "支付成功", Toast.LENGTH_SHORT).show();
Message msg = Message.obtain();
msg.what = 9001;
msg.obj = result;
callBackHandler.sendMessage(msg);
} else {
// 判断resultStatus 为非"9000"则代表可能支付失败
// "8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
if (TextUtils.equals(resultStatus, "8000")) {
Toast.makeText(context, "支付结果确认中", Toast.LENGTH_SHORT).show();
Message msg = Message.obtain();
msg.what = 9002;
// msg.obj=result;
callBackHandler.sendMessage(msg);
} else {
// 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误
Message msg = Message.obtain();
msg.what = 9003;
// msg.obj=result;
callBackHandler.sendMessage(msg);
}
}
}
}
}
/**
* get the sign type we use. 获取签名方式
*/
private String getSignType() {
return "sign_type=\"RSA\"";
}
public class PayResult {
private String resultStatus;
private String result;
private String memo;
public PayResult(String rawResult) {
if (TextUtils.isEmpty(rawResult))
return;
String[] resultParams = rawResult.split(";");
for (String resultParam : resultParams) {
if (resultParam.startsWith("resultStatus")) {
resultStatus = gatValue(resultParam, "resultStatus");
}
if (resultParam.startsWith("result")) {
result = gatValue(resultParam, "result");
}
if (resultParam.startsWith("memo")) {
memo = gatValue(resultParam, "memo");
}
}
}
@Override
public String toString() {
return "resultStatus={" + resultStatus + "};memo={" + memo
+ "};result={" + result + "}";
}
private String gatValue(String content, String key) {
String prefix = key + "={";
return content.substring(content.indexOf(prefix) + prefix.length(),
content.lastIndexOf("}"));
}
/**
* @return the resultStatus
*/
public String getResultStatus() {
return resultStatus;
}
/**
* @return the memo
*/
public String getMemo() {
return memo;
}
/**
* @return the result
*/
public String getResult() {
return result;
}
}
}