一:准备
首先,copy官方demo中的部分代码(我这里是Android),工具类为MD5.java和Util.java,AppRegister.java类作用是讲应用注册到微信(这个是一个坑。。不注册会导致弹不出支付页面),然后是PayActivity.java
二:开始集成
首先要说明的是,笔者集成的时候使用官方demo中原生的代码,几乎这是把测试的一些参数变成正式参数。
按照PayActivity中的示范,首先使用GetAccessTokenTask去获得AccessToken,然后使用刚才获得的AccessToken配合GetPrepayIdTask去获得PrepayId。重点来了,
坑点1:genProductArgs方法中关于金额的参数
private String genProductArgs(Activity activity, String money,String pack,String partnerid,String appid,String appkey) {
JSONObject json = new JSONObject();
try {
json.put("appid", appid);
String traceId = getTraceId(); // traceId
// 由开发者自定义,可用于订单的查询与跟踪,建议根据支付用户信息生成此id
json.put("traceid", traceId);
nonceStr = genNonceStr();
json.put("noncestr", nonceStr);
ConsumeInfo consumeInfoHandler = ConsumeInfoHandler.getCmccInfo(activity);
String name = consumeInfoHandler.getGameName();
List<NameValuePair> packageParams = new LinkedList<NameValuePair>();
packageParams.add(new BasicNameValuePair("bank_type", "WX"));
packageParams.add(new BasicNameValuePair("body", name));
packageParams.add(new BasicNameValuePair("fee_type", "1"));
packageParams.add(new BasicNameValuePair("input_charset", "UTF-8"));
packageParams.add(new BasicNameValuePair("notify_url", APIList.NOTIFY_URL));
packageParams.add(new BasicNameValuePair("out_trade_no", traceId));
packageParams.add(new BasicNameValuePair("partner", partnerid));
packageParams.add(new BasicNameValuePair("spbill_create_ip", "127.0.0.1"));
packageParams.add(new BasicNameValuePair("total_fee", money));
packageValue = genPackage(packageParams, pack);
json.put("package", packageValue);
timeStamp = genTimeStamp();
json.put("timestamp", timeStamp);
List<NameValuePair> signParams = new LinkedList<NameValuePair>();
signParams.add(new BasicNameValuePair("appid", appid));
signParams.add(new BasicNameValuePair("appkey", appkey));
signParams.add(new BasicNameValuePair("noncestr", nonceStr));
signParams.add(new BasicNameValuePair("package", packageValue));
signParams.add(new BasicNameValuePair("timestamp", String.valueOf(timeStamp)));
signParams.add(new BasicNameValuePair("traceid", traceId));
String genSign = genSign(signParams);
json.put("app_signature", genSign);
Log.e("mikoto", "sign " + genSign);
json.put("sign_method", "sha1");
} catch (Exception e) {
return null;
}
return json.toString();
}
方法中:需要变动的参数为:
body:商品名;notify_url:回调支付结果的服务器地址;out_trade_no:这个参数在服务器生成,同时在微信回调服务器时候会被附加,最后通过此参数去服务器查询微信支付结果;total_fee:金额数,注意单位是分,1就是1分钱100才是1元人民币,整数类型 。其他正常填写即可。
sendPayReq方法中,官方demo有一行是这样写的:req.packageValue = "Sign=Wxpay";//"Sign=" + packageValue; 所以需要改动一下变成req.packageValue = "Sign="+packageValue;这个相信大家都会注意到。
三:集成结束
坑点2:拉不出支付页面
笔者按照demo指示,运行工程,走到了最后一步boolean sendReq = api.sendReq(req);查看log发现这个值是true,然而拉不起支付页面,这是怎么回事呢?
上网搜了一下,原因有很多,1,签名;2,未执行IWXMsg.registerApp完成注册
一步一步来,这次不运行工程(eclipse运行程序默认使用的debug.keystore)而是用在微信平台提交的keystore打包,ok,可以了,正常支付页面也有了,但是发现潜在的问题是个别手机还是拉不出来,为神马,代码参数全方位检查,都是正常的。纠结了好久,后来给AppRegister类打log发现,那些个别拉不出支付页面的手机,未执行AppRegister类中的注册代码,好吧,我纯手动,改为支付前先执行IWXMsg.registerApp方法完成注册,OK,大功告成,还差结果回调了!
四:支付结果回调
坑点3:接收不到结果
笔者观察微信支付demo中回调支付结果的是WXPayEntryActivity类,果断copy到自己工程中并导出apk进行,然而无回调。什么情况呢,经多方咨询查找,原来是微信支付sdk对WXPayEntryActivity类做了约束,必须放在 "工程包名"+".wxapi"下面,否则无法接收回调。笔者调试一番,一切正常!
坑点4:微信支付sdk无法检测用户是否登陆
这个问题我的处理是:在执行微信支付前先启动一个Activity,改Activity需要跟WXPayEntryActivity放在同一个目录下,具体如下:
public class WechatPayActivity extends Activity {
public static int STATUS = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
STATUS = 0;
//在这里执行微信支付真正的支付方法!!!
}
@Override
protected void onResume() {
super.onResume();
Log.e("WechatPayActivity", "onResume STATUS = " + STATUS);
if (STATUS == 2) {
finish();
} else if (STATUS == 0) {
STATUS = 1;
} else {
Log.e("mikoto", "支付时,用户可能未登陆微信,点击返回!");
finish();
}
}
public static void setStatus(int status) {
STATUS = status;
}
}
然后在WXPayEntryActivity中onResp方法中做如下处理
@Override
public void onResp(BaseResp resp) {
Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
<span style="color:#FF0000;">WechatPayActivity.setStatus(2);</span>
Log.e("WXPayEntryActivity", "onResume STATUS = " + WechatPayActivity.STATUS);
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
//执行支付成功相关处
finish();
}else {
//执行支付成功相关处理
finish();
}
}
}