Android studio集成比较简单 错误错误编码code=-1的原因一般要注意,手机端的签名是要第二次生成的,是用调起支付的6个字段生成的
麻烦点主要是注册开通支付功能,验证比较麻烦
在注册时一定要先打包再使用微信工具生成签名,填写签名时一定要认真,一旦签名错误,即使通过了,将来支付时也会报错,在使用微信分享和支付时,先打包才能测试分享和支付功能,debug版是测试不了支付和分享功能的
集成开始
第一步是统一下单 这一步后台做的,
后台请求成功后会返回
<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[wx2421b1c4370ec43b]]></appid>
<mch_id><![CDATA[10000100]]></mch_id>
<nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
<sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
<trade_type><![CDATA[APP]]></trade_type>
</xml>
然后让后台用 prepay_id的值wx201411101639507cbf6ffd8b077995087
和下面这几个字段再次生成签名
把第二次生成签名的值 sign 传给手机端
其中 prepayid noncestr timestamp 也需要传给手机端,这三个字段就是第二次生成签名时的值
appid partnerid package是固定值,在手机端直接赋值也行,后台传也行
手机端做的事情很简单
手机端准备
添加
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+' }
这个文件夹的名字 还在activity的名字一定要是下面的这个,名字不一样不行
声明
<activity android:name=".wxapi.WXPayEntryActivity" android:exported="true" android:launchMode="singleTop"> </activity>
准备好之后就可以调起支付了,一定要打包在测试支付,不然code 的是 -1
WXPayUtils.WXPayBuilder builder = new WXPayUtils.WXPayBuilder(); builder.setAppId(Confing.WXAPPID) .setPartnerId("填写你的商户账号")////商户账号 .setPrepayId("预支付交易会话ID")// 后台返回的 预支付交易会话ID .setSign("后台返回的签名sign 注意一定要第二次的签名就是吊起支付的那六个字段生成的sign") //后台返回的签名 .setNonceStr("随机字符串") .setTimeStamp("时间戳") .build().toWXPayNotSign("this","appID");
public class WXPayUtils { private IWXAPI iwxapi; //微信支付api private WXPayBuilder builder; private WXPayUtils(WXPayBuilder builder) { this.builder = builder; } /** * 调起微信支付的方法,不需要在客户端签名 **/ public void toWXPayNotSign(Context context, String appid) { iwxapi = WXAPIFactory.createWXAPI(context, null); //初始化微信api iwxapi.registerApp(appid); //注册appid appid可以在开发平台获取 Runnable payRunnable = new Runnable() { //这里注意要放在子线程 @Override public void run() { PayReq request = new PayReq(); //调起微信APP的对象 //下面是设置必要的参数,也就是前面说的参数,这几个参数从何而来请看上面说明 request.appId = builder.getAppId(); request.partnerId = builder.getPartnerId(); request.prepayId = builder.getPrepayId(); request.packageValue = "Sign=WXPay"; request.nonceStr = builder.getNonceStr(); request.timeStamp = builder.getTimeStamp();// request.sign = builder.getSign(); iwxapi.sendReq(request);//发送调起微信的请求 } }; Thread payThread = new Thread(payRunnable); payThread.start(); } /** * 调起微信支付的方法,需要在客户端签名 **/ public void toWXPayAndSign(Context context, String appid,final String key) { iwxapi = WXAPIFactory.createWXAPI(context, null); //初始化微信api iwxapi.registerApp(appid); //注册appid appid可以在开发平台获取 Runnable payRunnable = new Runnable() { //这里注意要放在子线程 @Override public void run() { if (TextUtils.isEmpty(builder.getAppId()) ||TextUtils.isEmpty(builder.getPartnerId()) ||TextUtils.isEmpty(builder.getPrepayId())){ Log.e("chx", "toWXPayAndSign: "+"必须在builder中设置appId、PartnerId、PrepayId"); return; } PayReq request = new PayReq(); //调起微信APP的对象 //下面是设置必要的参数,也就是前面说的参数,这几个参数从何而来请看上面说明 request.appId = builder.getAppId(); request.partnerId = builder.getPartnerId(); request.prepayId = builder.getPrepayId(); request.packageValue = "Sign=WXPay"; request.nonceStr = genNonceStr(); request.timeStamp = String.valueOf(genTimeStamp()); request.sign = builder.getSign(); //签名 LinkedHashMap<String, String> signParams = new LinkedHashMap<>(); signParams.put("appid", request.appId); signParams.put("noncestr", request.nonceStr); signParams.put("package", request.packageValue); signParams.put("partnerid", request.partnerId); signParams.put("prepayid", request.prepayId); signParams.put("timestamp", request.timeStamp); request.sign = genPackageSign(signParams,key); iwxapi.sendReq(request);//发送调起微信的请求 } }; Thread payThread = new Thread(payRunnable); payThread.start(); } /** * 调起微信APP支付,签名 * 生成签名 */ private String genPackageSign(LinkedHashMap<String, String> params,String key) { StringBuilder sb = new StringBuilder(); for (Map.Entry<String,String> entry: params.entrySet()) { sb.append(entry.getKey()); sb.append('='); sb.append(entry.getValue()); sb.append('&'); } sb.append("key="); sb.append(key); String packageSign = getMessageDigest(sb.toString().getBytes()).toUpperCase(); return packageSign; } /** * md5加密 * @param buffer * @return */ private 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; } } /** * 获取随机数 * * @return */ private String genNonceStr() { Random random = new Random(); return getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); } /** * 获取时间戳 * * @return */ private long genTimeStamp() { return System.currentTimeMillis() / 1000; } public static class WXPayBuilder { public String appId; public String partnerId; public String prepayId; public String packageValue; public String nonceStr; public String timeStamp; public String sign; public WXPayUtils build() { return new WXPayUtils(this); } public String getAppId() { return appId; } public WXPayBuilder setAppId(String appId) { this.appId = appId; return this; } public String getPartnerId() { return partnerId; } public WXPayBuilder setPartnerId(String partnerId) { this.partnerId = partnerId; return this; } public String getPrepayId() { return prepayId; } public WXPayBuilder setPrepayId(String prepayId) { this.prepayId = prepayId; return this; } public String getPackageValue() { return packageValue; } public WXPayBuilder setPackageValue(String packageValue) { this.packageValue = packageValue; return this; } public String getNonceStr() { return nonceStr; } public WXPayBuilder setNonceStr(String nonceStr) { this.nonceStr = nonceStr; return this; } public String getTimeStamp() { return timeStamp; } public WXPayBuilder setTimeStamp(String timeStamp) { this.timeStamp = timeStamp; return this; } public String getSign() { return sign; } public WXPayBuilder setSign(String sign) { this.sign = sign; return this; } } }
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler { private IWXAPI api; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.tou_ming_layout); api = WXAPIFactory.createWXAPI(this, Confing.WXAPPID); api.handleIntent(getIntent(), this); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); api.handleIntent(intent, this); } @Override public void onReq(BaseReq baseReq) { } @Override public void onResp(BaseResp baseResp) { if (baseResp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { // 支付 int errCode = baseResp.errCode; if (errCode == -1) { Toast.makeText(getApplicationContext(), "支付失败=", Toast.LENGTH_SHORT).show(); finish(); } else if (errCode == 0) { //EventBus.getDefault().post(new Event("Just do it")); MessageModel messageModel = new MessageModel(); messageModel.setMsg("支付完成"); EventBus.getDefault().post(messageModel); Toast.makeText(getApplicationContext(), "支付完成", Toast.LENGTH_SHORT).show(); this.finish(); } else { Toast.makeText(getApplicationContext(), "支付失败", Toast.LENGTH_SHORT).show(); finish(); } } } }
如果打包后测试支付还是code = -1 那一般就是签名错误,让后台打印一下 第二次生成签名时的字符串,检查一下字符串拼接是否正确,
生成签名时的key 在商户平台找,设置的32位字符串