Android 微信App支付集成
Android 微信App支付集成
总结
Android 支付流程:(与android前端有关的步骤,下面有详细流程图)
(1) 请求生成订单(签名)
(2) 返回签名后订单信息
---------------------------------------后台
(3) 调用微信SDK,进行支付
(4) 微信回调(根据支付状态,具体实现)
-----------------------------------------微信
(5) 查询实际支付结果
(6) 返回支付结果
---------------------------------------后台
Android 实际操作:
(1) 申请APPID
(2) 搭建开发环境,添加依赖SDK
(3) 修改Manifest.xml
(4) 注册到微信(推荐程序入口的Activity的OnCreate中)
private void registToWx(){
Api = WXAPIFactory.createWXAPI(this,APPID,true);
Api.registerApp(APPID);
}
(5) 发送请求或相应到微信
boolean sendReq(BaseReq req);//app主动请求微信,发送完成后切回app
boolean sendResp(BaseResp resp);//微信向app请求数据,app响应后返回微信
(6) 接受wx的请求以及返回值
(7) 包名.wixapi.WXEntryActivity,且在manifest中注册,加上exported = ‘true’
(8) 实现IWXAPIEventHandler接口,微信发送的请求将回调onReq(),发送到微信的请求相应结果将回调onResq()
(9) 在WXEntryActivity中将接收到的intent以及实现了IWXAPIEventHandler接口对象传递给IWXAPI接口的handlerIntent()-------->api.handleIntent(getIntent,this);
接入指南:文档很详细
详细介绍
一、微信APP支付接入商户服务中心(需要7个工作日左右)
申请流程图
二、产品流程
步骤1:用户进入商户APP,选择商品下单、确认购买,进入支付环节。商户服务后台生成支付订单,签名后将数据传输到APP端。以微信提供的DEMO为例,见图8.1。
步骤2:用户点击后发起支付操作,进入到微信界面,调起微信支付,出现确认支付界面,见图8.2。
步骤3:用户确认收款方和金额,点击立即支付后出现输入密码界面,可选择零钱或银行卡支付见图8.3。
图8.1 商户APP界面实例 |
图8.2 跳转到微信支付 |
图8.3 用户确认支付 |
第四步:输入正确密码后,支付完成,用户端微信出现支付详情页面。见图8.4。
第五步:回跳到商户APP中,商户APP根据支付结果个性化展示订单处理结果。见图8.5。
图8.4 支付成功提示页面 |
图8.5 返回到商户APP提示 |
三、系统交互流程
以下是交互时序图,统一下单API、支付结果通知API和查询订单API等都涉及签名过程,调用都必须在商户服务器端完成。如图8.6所示。
图8.6 APP支付时序图
商户系统和微信支付系统主要交互说明:
步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。
步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。参见【统一下单API】。
步骤3:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appid,partnerid,prepayid,noncestr,timestamp,package。注意:package的值格式为Sign=WXPay
步骤4:商户APP调起微信支付。api参见本章节【app端开发步骤说明】
步骤5:商户后台接收支付通知。api参见【支付结果通知API】
步骤6:商户后台查询支付结果。,api参见【查询订单API】
四、Android快速集成
引入微信SDK依赖
1.将alipaySdk-xxxxxxxx.jar包放入商户应用工程的libs目录下,如下图。
或者在build.gradle的dependencies中加入以下语句
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:1.0.2'
修改Manifest
在商户应用工程的AndroidManifest.xml文件里面添加声明:
<activity
android:name = “.wxapi.WXPayEntryActivity”
android:exported=“true”
android:launchMode = “singTop”
和权限声明:
<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" />
添加混淆规则
在商户应用工程的proguard-project.txt里添加以下相关规则:
keep class com.tencent.mm.opensdk.** {*;}
-keep class com.tencent.wxop.** {*;}
-keep class com.tencent.mm.sdk.** {*;}
支付接口调用
1.注册微信
private IWXAPI wxapi;
private void registerWeChatPay(){
wxapi = WXAPIFactory.createWXAPI(mContext, WXConstants.APP_ID,false); wxapi.registerApp(WXConstants.APP_ID);
}
1.具体支付操作
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {String url = "http://wxpay.wxutil.com/pub_v2/app/app_pay.php";
ToastUtil.shortToastInBackgroundThread(PayActivity.this, "获取订单中...");try{
byte[] buf = Util.httpGet(url);
if (buf != null && buf.length > 0) {
String content = new String(buf);
Log.e("get server pay params:",content);// {
// appid: "wxb4ba3c02aa476ea1",
// partnerid: "1900006771",
// package: "Sign=WXPay",
// noncestr: "4d0a368730183838d674c0ff2b1cd5b2",
// timestamp: 1523503409,
// prepayid: "wx12112329530219b54071446b1920301102",
// sign: "24154D37575EA7B303AC065B08FC8D72"
// }
JSONObject json = new JSONObject(content);
if(null != json && !json.has("retcode") ){
Log.e("PAY_GET", "json.has(\"retcode\") ----->"+ json.has("retcode") );
PayReq req = new PayReq();
//req.appId = "wxf8b4f85f3a794e77"; // 测试用appId
req.appId = json.getString("appid");
req.partnerId = json.getString("partnerid");
req.prepayId = json.getString("prepayid");
req.nonceStr = json.getString("noncestr");
req.timeStamp = json.getString("timestamp");
req.packageValue = json.getString("package");
req.sign = json.getString("sign");
req.extData = "app data"; // optional
ToastUtil.shortToastInBackgroundThread(PayActivity.this, "正常调起支付");// 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
api.sendReq(req);
}else{
Log.e("PAY_GET", "返回错误"+json.getString("retmsg"));
ToastUtil.shortToastInBackgroundThread(PayActivity.this, "返回错误"+json.getString("retmsg"));
}}else{
Log.d("PAY_GET", "服务器请求错误");
ToastUtil.shortToastInBackgroundThread(PayActivity.this, "服务器请求错误");
}
}catch(Exception e){
Log.e("PAY_GET", "异常:"+e.getMessage());
ToastUtil.shortToastInBackgroundThread(PayActivity.this, "异常:"+e.getMessage());
}
}
}).start();
}
WXPayEntryActivity实现了IWXAPIEventHandler,重写了onResp(BaseResp resp),是微信支付结果的回调,由微信api调用。并将接收到的intent和实现了IWXAPIEventHandler的对象传递给IWXAPI 的handleIntent方法。onResp是微信发送请求的回调,onReq是app发送微信请求结果的回调。
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{
private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
private IWXAPI api;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pay_result);
//注册appID
api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
api.handleIntent(getIntent(), this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);setIntent(intent);
api.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq req) {
}
@Override
public void onResp(BaseResp resp) {
// Log.d(TAG, "onPayFinish,errCode = " + resp.errCode);
int errCode = resp.errCode;
Log.e(TAG,"errCode-------------->" + errCode);
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
//这里就是支付完成后需要做的事,如跳到哪个页面啥的
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.app_tip);
builder.setMessage(getString(R.string.pay_result_callback_msg, String.valueOf(resp.errCode)));builder.show();
}
}
}
五、App支付请求参数说明
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1#
官方文档很详细