一、准备工作
1、开发平台及SDK下载
微信开放平台
下载SDK
微信支付Demo下载
http://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=11_1
2、创建应用
创建移动应用获取 AppID AppSecret
要获取支付功能还需要开发者资质认证,300RMB/年的费用,貌似是开放平台中唯一要收费的…
3、AndroidMainfest文件修改
权限
1
2
3
4
5
|
<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" /> |
二、业务流程
商户系统和微信支付系统主要交互说明:
步骤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】
三、开发
1、注册应用
1
2
|
final IWXAPI msgApi = WXAPIFactory.createWXAPI( this , null ); msgApi.registerApp(Constants.APP_ID); |
2、调用支付统一下单接口,并返回PrepayID
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
private class GetPrepayIdTask extends AsyncTask<Void, Void, Map<String,String>> { private ProgressDialog dialog; @Override protected void onPreExecute() { dialog = ProgressDialog.show(PayActivity. this , getString(R.string.app_tip), getString(R.string.getting_prepayid)); } @Override protected void onPostExecute(Map<String,String> result) { if (dialog != null ) { dialog.dismiss(); } sb.append( "prepay_id
" +result.get( "prepay_id" )+ "
" ); show.setText(sb.toString()); resultunifiedorder=result; } @Override protected void onCancelled() { super .onCancelled(); } @Override protected Map<String,String> doInBackground(Void... params) { String url = String.format( "https://api.mch.weixin.qq.com/pay/unifiedorder" ); String entity = genProductArgs(); Log.e( "orion" ,entity); byte [] buf = Util.httpPost(url, entity); String content = new String(buf); Log.e( "orion" , content); Map<String,String> xml=decodeXml(content); return xml; } } |
设置统一下单参数
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
private String genProductArgs() { StringBuffer xml = new StringBuffer(); try { String nonceStr = genNonceStr(); xml.append( "</xml>" ); List<NameValuePair> packageParams = new LinkedList<NameValuePair>(); packageParams.add( new BasicNameValuePair( "appid" , Constants.APP_ID)); packageParams.add( new BasicNameValuePair( "body" , "APP pay test" )); packageParams.add( new BasicNameValuePair( "mch_id" , Constants.MCH_ID)); packageParams.add( new BasicNameValuePair( "nonce_str" , nonceStr)); packageParams.add( new BasicNameValuePair( "notify_url" , "http://121.40.35.3/test" )); packageParams.add( new BasicNameValuePair( "out_trade_no" ,genOutTradNo())); packageParams.add( new BasicNameValuePair( "spbill_create_ip" , "127.0.0.1" )); packageParams.add( new BasicNameValuePair( "total_fee" , "1" )); packageParams.add( new BasicNameValuePair( "trade_type" , "APP" )); String sign = genPackageSign(packageParams); packageParams.add( new BasicNameValuePair( "sign" , sign)); String xmlstring =toXml(packageParams); return xmlstring; } catch (Exception e) { Log.e(TAG, "genProductArgs fail, ex = " + e.getMessage()); return null ; } } |
3、设置PayReq请求的参数,并发送支付请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//设置PayReq请求的参数 private void genPayReq() { req.appId = Constants.APP_ID; req.partnerId = Constants.MCH_ID; req.prepayId = resultunifiedorder.get( "prepay_id" ); req.packageValue = "prepay_id=" +resultunifiedorder.get( "prepay_id" ); req.nonceStr = genNonceStr(); req.timeStamp = String.valueOf(genTimeStamp()); List<NameValuePair> signParams = new LinkedList<NameValuePair>(); signParams.add( new BasicNameValuePair( "appid" , req.appId)); signParams.add( new BasicNameValuePair( "noncestr" , req.nonceStr)); signParams.add( new BasicNameValuePair( "package" , req.packageValue)); signParams.add( new BasicNameValuePair( "partnerid" , req.partnerId)); signParams.add( new BasicNameValuePair( "prepayid" , req.prepayId)); signParams.add( new BasicNameValuePair( "timestamp" , req.timeStamp)); req.sign = genAppSign(signParams); sb.append( "sign
" +req.sign+ "
" ); show.setText(sb.toString()); Log.e( "orion" , signParams.toString()); } |
1
2
|
//发送请求 msgApi.sendReq(req); |
4、处理结果回调
实现微信API的IWXAPIEventHandler接口
api.handleIntent(getIntent(), new IWXAPIEventHandler);
在IWXAPIEventHandler的onResp(BaseResp resp)中处理请求回调
1
2
3
4
5
6
7
8
9
10
11
12
|
@Override public void onResp(BaseResp resp) { Log.d(TAG, "onPayFinish, errCode = " + resp.errCode); if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { //处理PayReq的回调 AlertDialog.Builder builder = new AlertDialog.Builder( this ); builder.setTitle(R.string.app_tip); builder.setMessage(getString(R.string.pay_result_callback_msg, resp.errStr + ";code=" + String.valueOf(resp.errCode))); builder.show(); } } |