先放上接入两个支付平台的官方文档地址
一、支付宝支付
导入开发资源
1.将支付宝demo中的jar包alipay-sdk-common/alipaySdk-xxxxxxxx.jar
放到项目目录libs/文件夹下。如下图:
2.在Jar包右键选择Add As Library
。如下图:
修改AndroidMenifest
文件
在商户应用工程的AndroidManifest.xml
文件里面添加声明:
<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>
和权限声明:
<uses-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" />
添加混淆规则
-libraryjars libs/alipaySingle-20161222.jar
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}
支付接口调用
需要在非UI线程中调用,示例:
private static final int SDK_PAY_FLAG = 1;
private static final int SDK_AUTH_FLAG = 2;
/**
* 支付宝
*/
private void alipay(String orderInfo)
{
final String mOrderInfo = orderInfo; // 订单信息
Runnable payRunnable = new Runnable() {
@Override
public void run()
{
PayTask alipay = new PayTask(PaymentActivity.this);
Map<String, String> result = alipay.payV2(mOrderInfo, true);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
// 必须异步调用
Thread payThread = new Thread(payRunnable);
payThread.start();
}
orderInfo字符串解释:
该字符串类似于
app_id=2015052600090779&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22seller_id%22%3A%22%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.02%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%22314VYGIAGG7ZOYY%22%7D&charset=utf-8&method=alipay.trade.app.pay&sign_type=RSA2×tamp=2016-08-15%2012%3A12%3A15&version=1.0&sign=MsbylYkCzlfYLy9PeRwUUIg9nZPeN9SfXPNavUCroGKR5Kqvx0nEnd3eRmKxJuthNUx4ERCXe552EV9PfwexqW%2B1wbKOdYtDIb4%2B7PL3Pc94RZL0zKaWcaY3tSL89%2FuAVUsQuFqEJdhIukuKygrXucvejOUgTCfoUdwTi7z%2BZzQ%3D
是由后台服务器拼接完成,安卓端拿到这串字符串调用支付方法即可。如下图:
支付结果获取和处理
Intent mIntent;
@SuppressWarnings("unchecked")
private Handler mHandler = new Handler() {
public void handleMessage(Message msg)
{
switch (msg.what)
{
case SDK_PAY_FLAG:
/**
对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。
*/
PayResult result = new PayResult((Map<String, String>) msg.obj);
String resultStatus = result.getResultStatus();
// 判断resultStatus 为9000则代表支付成功
if (TextUtils.equals(resultStatus, "9000"))
{
//支付成功跳转订单详情页面,以下作示例代码,可删除
mIntent = new Intent(PaymentActivity.this, OrderDetialActivity.class);
startActivity(mIntent);
//跳转动画
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
finish();
} else
{
pd.dismiss();
// 该笔订单真实的支付结果,需要依赖服务端的异步通知,建议在订单详情页面获取服务器端商品支付状态。
Toast.makeText(PaymentActivity.this, "支付失败", Toast.LENGTH_SHORT).show();
}
break;
case SDK_AUTH_FLAG:
break;
}
};
};
获取当前开发包版本号
调用PayTask 的getVersion()获取当前开发包的版本号
PayTask payTask = new PayTask(activity);
String version = payTask.getVersion();
至此支付宝Android支付接入完成
二、微信支付
导入开发资源
1.将微信支付jar包放到项目目录libs/文件夹下。如下图:
2.在Jar包右键选择Add As Library。
后台设置
商户在微信开放平台申请开发应用后,微信开放平台会生成APP的唯一标识APPID。由于需要保证支付安全,需要在开放平台绑定商户应用包名和应用签名,设置好后才能正常发起支付。设置界面在【开放平台】中的栏目【管理中心 / 修改应用 / 修改开发信息】里面,如图所示:
应用包名:是在APP项目配置文件AndroidManifest.xml
中声明的package
值,例如DEMO中的package="net.sourceforge.simcpux"
。
应用签名:根据项目的应用包名和编译使用的keystore,可由签名工具生成一个32位的md5串,在调试的手机上安装签名工具后,运行可生成应用签名串,如图8.9所示,绿色串即应用签名。签名工具下载地址
https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk
注册APPID
商户APP工程中引入微信JAR包,调用API前,需要先向微信注册您的APPID,代码如下:
public class MyApplication extends Application {
IWXAPI msgApi = null;
@Override
public void onCreate()
{
msgApi = WXAPIFactory.createWXAPI(this, null);
// 将该app注册到微信
msgApi.registerApp(Constant.WX_APP_ID);
}
}
Constant.java
代码
public class Constant {
//appid 微信分配的公众账号ID
public static final String WX_APP_ID = "wxc2d0381e95948db6";
//商户号 微信分配的公众账号ID
public static final String WX_MCH_ID = "1432223602";
//API密钥,在商户平台设置
public static final String WX_API_KEY = "";
}
这段代码也可以在Activity
的onCreate()
方法中初始化,视情况而定,建议在Application
中初始化
final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);
// 将该app注册到微信
msgApi.registerApp(Constant.WX_APP_ID);
调起支付
下面是调起支付核心代码
private void startVXInPay(String appid, String mch_id, String nonce_str,
String sign, String prepay_id, String trade_type, String time)
{
PayReq request = new PayReq();
//应用ID 微信开放平台审核通过的应用APPID
request.appId = appid;
//商户号 微信支付分配的商户号
request.partnerId = mch_id;
//预支付交易会话ID 微信返回的支付交易会话ID
request.prepayId = prepay_id;
//扩展字段 暂填写固定值Sign=WXPay
request.packageValue = "Sign=WXPay";
//随机字符串 随机字符串,不长于32位。推荐
//随机数生成算法url:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3
request.nonceStr = nonce_str;
//时间戳 标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数。
// 注意:部分系统取到的值为毫秒级,需要转换成秒(10位数字)。
request.timeStamp = time;// "" + (new DecimalFormat("0")).format(System.currentTimeMillis() / 1000);
//签名 签名,详见 url:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3
request.sign = sign;//sign
api.sendReq(request);//调起支付
}
PayReq的相关参数从后台服务器获取,如
String mAppid, mMch_id, mNonce_str, mSign, mPrepay_id, mTrade_type;
String mTime;
Map<String,String> headers,params;
String url,token;
public void getVXPaymentInfo()
{
headers.clear();
if (!TextUtils.isEmpty(token))
{
headers.put("Token", token);
}
params.clear();
params.put("pay_sys", "Android");
params.put("log_id", log_id);
url = URLS.USER_GET_VX_PAYMENTINFO;
OkHttpUtils.post().url(url).headers(headers).params(params).build().execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int id)
{
MToast.shortToast(getString(R.string.huoqushujushibai));
}
@Override
public void onResponse(String response, int id)
{
if (TextUtils.isEmpty(response))
{
return;
}
//解析服务器返回的json字符串
JSONObject jsonObject = JSONObject.parseObject(response);
boolean success = jsonObject.getBooleanValue("success");
if (success)
{
JSONObject resultObject = JSON.parseObject(jsonObject.getString("app_need"));
mAppid = resultObject.getString("appid");
mMch_id = resultObject.getString("partnerid");
mNonce_str = resultObject.getString("noncestr");
mSign = resultObject.getString("sign");
mPrepay_id = resultObject.getString("prepayid");
mTrade_type = "APP";
mTime = resultObject.getString("timestamp");
//调用微信支付代码
startVXInPay(mAppid, mMch_id, mNonce_str, mSign, mPrepay_id, mTrade_type, mTime);
} else
{
MToast.shortToast(jsonObject.getString("error_msg"));
}
}
});
}
支付结果回调
在项目中新建package wxapi
,并新建Activity WXPayEntryActivity
,名称必须一样,如下:
AndroidManifest
注册WXPayEntryActivity
<!-- 微信支付 -->
<activity
android:name=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop"
android:screenOrientation="portrait"/>
WXPayEntryActivity
需要实现 IWXAPIEventHandler
接口,
public class WXPayEntryActivity extends BaseActivity implements IWXAPIEventHandler {
@Override
public void onCreate(Bundle savedInstanceState, Object obj)
{
//不需要设置contentView
}
// 微信发送请求到第三方应用时,会回调到该方法
@Override
public void onReq(BaseReq req)
{
}
// 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
@Override
public void onResp(BaseResp resp)
{
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX)
{
if (resp.errCode == -2)
{
//支付取消,在这里做相应逻辑
}else if(resp.errCode == 0){
//支付成功,建议依赖服务器返回结果,这里可以跳转到详情界面查询订单信息
}
}
}
@Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
}
回调中errCode
值列表:
名称 | 描述 | 解决方案 |
---|---|---|
0 | 成功 | 展示成功页面 |
-1 | 错误 | 可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。 |
-2 | 用户取消 | 无需处理。发生场景:用户不支付了,点击取消,返回APP。 |
至此微信支付接入完毕