您的位置:首页 > 移动开发 > 微信开发

微信支付核心部分,记录在此防止再次被坑

2016-02-23 10:33 453 查看
首先导入微信jar包(官网有)

在MyApplication中初始化IWXAPI 对象

// 微信支付初始化
static IWXAPI msgApi;

public static IWXAPI getWXAPI() {
return msgApi;
}
// 微信支付初始化
msgApi = WXAPIFactory.createWXAPI(this, null);
msgApi.registerApp(GlobalConstant.WEIXINID);


WEIXINID是开发者账号审核之后取到的appid


在支付的时候app把订单号和价钱传给服务器,由服务与微信通信之后返回相应的订单数据,之后将返回的数据设置到PayReq中去,并排序调用
msgApi<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">.sendReq(req);</span>
这个方法有一个boolean型的返回值,虽然微信没有明说有啥用,不过粗略的观察到,只要配置不对,appid,key之类的不正确都会导致返回值为false,能正确吊起支付页面的返回值都是true,虽然也遇到过返回了true但是支付页面都没显示的情况,这种多半是服务器没配置好或者apk签名与微信那边的记录不符

以下是吊起支付的核心代码

PayReq req = new PayReq();
req.appId = object.optString("appid");
req.partnerId = object.optString("mch_id");
req.prepayId = object.optString("prepay_id");
req.nonceStr = object.optString("nonce_str");
req.timeStamp = gettimes();
req.packageValue = "Sign=WXPay";
req.extData = getIntent().getStringExtra("OrderId"); // optional
// 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("appid", req.appId));
params.add(new BasicNameValuePair("noncestr", req.nonceStr));
params.add(new BasicNameValuePair("package", req.packageValue));
params.add(new BasicNameValuePair("partnerid", req.partnerId));
params.add(new BasicNameValuePair("prepayid", req.prepayId));
params.add(new BasicNameValuePair("timestamp", req.timeStamp));

req.sign = genAppSign(params);
boolean isok = api.sendReq(req);


req.timeStamp的值是一个10位数的随机数,没有严格要求,微信有说明,好像是为了避免并发的情况

我取的是随机数

private String gettimes() {
String str = "";
for (int i = 0; i < 10; i++) {
str += (int) (10 * (Math.random())) + "";
}
return str;
}


req.sign的值为,正确排序微信返回来的那几个值之后用MD5加密的key

加密算法:

private String genAppSign(List<NameValuePair> params) {
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(GlobalConstant.WEIXIN_KEY);
System.out.println("str=" + sb.toString());
String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
Log.w("orion", appSign);
return appSign;
}


WEIXIN_KEY是申请到微信开发者账号之后再次申请到的“支付能力”在拿到appid下面有个选项是获取支付能力,需求再申请一个微信商户账号,然后安装秘钥什么的,最后自己设置一个32位的key,服务器端和app都需要用到,具体做法参见http://help.ecmoban.com/article-2085.html


MD5加密方法来自微信demo

public class MD5 {

private MD5() {
}

public final static String getMessageDigest(byte[] buffer) {
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
try {
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
mdTemp.update(buffer);
byte[] md = mdTemp.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
return null;
}
}
}
同时项目中的包名下面必须有一个包名为wxapi的包存在,里面必须有一个Activity名为WXPayEntryActivity,并且extends Activity implements IWXAPIEventHandler

在@Override

public void onResp(BaseResp resp) {

方法中处理微信支付的回调,如果没有这个activity可能导致支付失败

不过微信支付的成功与否还是以服务器为准,微信也是这么说的

处理方法:

if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX && resp.errCode == 0) {
//成功
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("支付失败");
builder.setOnCancelListener(new OnCancelListener() {

@Override
public void onCancel(DialogInterface dialog) {
finish();
}
});
builder.show();
}
调用微信支付的activity在声明的时候需要加入以下内容:

<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />

<data android:scheme="你的appid" />
</intent-filter>


支付回调的声明:

<activity
android:name=".wxapi.WXPayEntryActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: