开发Android APP微信支付功能,需要完成三个步骤:第一步生成预支付订单、第二步生成微信支付参数、第三步调起微信APP支付。除了需要审核通过的APP应用外,还需要获得微信支付接口权限,然后获取对应的商户号、API密钥,这两者缺一不可,并且在APP微信支付中使用
获得商户号、API密钥
在微信开放平台中查看审核通过的APP应用,是否申请支付功能,若已申请,登录微信支付|商户平台:http://pay.weixin.qq.com 查看对应的商户号、API密钥
》申请微信支付接口
》登录商户平台
》查看商户号
》获取API密钥
第一步:生成预支付订单
将商品信息、商户信息使用BasicNameValuePair存放,然后存储在List列表中,并构造成xml字符串格式,以POST方式微信提供的接口:https://api.mch.weixin.qq.com/pay/unifiedorder 发送数据,接收返回信息,获取prepay_id预支付订单编号
》生成订单请求
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 String genProductArgs() {
StringBuffer xml = new StringBuffer();
try {
String nonceStr = genNonceStr();
xml.append( "" );
List new LinkedList
packageParams
.add( new BasicNameValuePair( "appid" , Constants.APP_ID));
packageParams.add( new BasicNameValuePair( "body" , "weixin" ));
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 ;
}
}
|
》获取预支付订单编号
1
2
3
4
5
6
7
8
9
10
|
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
|
第二步:生成微信支付参数
appId对应APP应用的APPID,partnerId对应商户号,prepayId对应第一步获得的预支付订单,packageValue取值Sign=WXPay,nonceStr是一串随机数,timeStamp生成的时间戳,sign对应APP签名
》支付参数配置
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 void genPayReq() {
req.appId = Constants.APP_ID;
req.partnerId = Constants.MCH_ID;
req.prepayId = resultunifiedorder.get( "prepay_id" );
req.packageValue = "Sign=WXPay" ;
req.nonceStr = genNonceStr();
req.timeStamp = String.valueOf(genTimeStamp());
List new LinkedList
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\n" + req.sign + "\n\n" );
show.setText(sb.toString());
Log.e( "orion" , signParams.toString());
}
|
》nonceStr随机数
1
2
3
4
5
|
private String genNonceStr() {
Random random = new Random();
return MD5.getMessageDigest(String.valueOf(random.nextInt( 10000 ))
.getBytes());
}
|
》timeStamp时间戳
1
2
3
|
private long genTimeStamp() {
return System.currentTimeMillis() / 1000 ;
}
|
》APP签名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
private String genAppSign(List
StringBuilder sb = new StringBuilder();
for ( int i = 0 ; i < params.size(); i++) {
sb.append(params.get(i).getName());
sb.append( '=' );
sb.append(params.get(i).getValue());
sb.append( '&' );
}
sb.append( "key=" );
sb.append(Constants.API_KEY);
this .sb.append( "sign str\n" + sb.toString() + "\n\n" );
String appSign = MD5.getMessageDigest(sb.toString().getBytes())
.toUpperCase();
Log.e( "orion" , appSign);
return appSign;
}
|
第三步:调起微信APP支付
支付之前,需要手机安装微信客户端,如果没有,会提示下载安装微信,然后再调起支付,在AndroidManifest.xml文件中添加如下配置
1
2
3
4
5
6
7
8
9
10
11
12
|
android:name= ".act.PayActivity"
android:exported= "true"
android:launchMode= "singleTop" >
|
》调起微信支付
1
2
3
4
5
|
private void sendPayReq() {
msgApi.registerApp(Constants.APP_ID);
msgApi.sendReq(req);
}
|
接收微信返回结果
在实现了IWXAPIEventHandler接口的Activity中重写onResp(BaseResp)方法,接收微信结果
》接收支付结果
1
2
3
4
5
6
7
8
9
10
11
|
public void onResp(BaseResp resp) {
Log.d(TAG, "onPayFinish, errCode = " + resp.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,
resp.errStr + ";code=" + String.valueOf(resp.errCode)));
builder.show();
}
}
|