- 第一步是申请相关的资料,开同商户认证什么的.个人来说相对比较难,基本都是公司给开.所以假设你已经拿到了相应的信息:如下
String APP_ID = “wx2************1ca”; // appid
String PARTNER_ID = “14*******2”; //商户id
String API_KEY = “b**f******y2******t***d******92V”; //app_key 需要注意的是,在申请上述信息的时候,需要在微信开放平台填写安卓app的信息,包名和签名.验证码可以通过下边的微信连接下载微信的获取签名的apk.
https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk
把它装到你的手机上,同事把你开发的app用正式签名打包后安装到手机上,在威信的app里输入包名就可以获得了.
注意签名就是小写的,别写错.集成微信支付的第三方库 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417751808&token=&lang=zh_CN ,按照这个步骤的前三部做就可以了.第四部不详细,不用看.
- 看一下威信的业务流程
简单解释 :1 在自己的app中调用自己的后台向威信下单,
2 自己的后台将订单中的prepay_id 预支付的id和一些参数返回给我们自己的app中
3 我们自己在手机中封装微信请求,吊起微信客户端中的支付界面.
4自己在app中实现威信appz支付的回调界面(按照微信的要求写,很简单),在我们app中的微信回调界面中通过返回码判断成功还是失败,然后请求自己的后台确认支付结果. 支付逻辑就算完成 先实现微信的回调界面
这是我的项目结果,我的包名路径是com.jiawang.qingkegongyu ,一定要在这个包名路径下新建wxapi的包,然后写一个 WXPayEntryActivity(固定就是这个名字) 的activity
写法如下 –可以当作模版用
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler { private IWXAPI api; String msg = ""; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); api = WXAPIFactory.createWXAPI(this, IpInfo.APP_ID); 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) { Toast.makeText(this, "openid = " + baseReq.openId, Toast.LENGTH_SHORT).show(); } @Override public void onResp(BaseResp resp) { String result=""; if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { switch (resp.errCode) { case BaseResp.ErrCode.ERR_OK: result = "发送成功"; break; case BaseResp.ErrCode.ERR_USER_CANCEL: result = "发送取消"; break; case BaseResp.ErrCode.ERR_AUTH_DENIED: result = "发送被拒绝"; break; case BaseResp.ErrCode.ERR_UNSUPPORT: result = "不支持错误"; break; default: result = 发送返回; break; } } } }
对应的 manifest 中
<activity
android:name="com.jiawang.qingkegongyu.wxapi.WXPayEntryActivity"
android:exported="true" --此行不能少
android:launchMode="singleTop"/> --此行不能少
而作为启动的activity 需要配置 appid
<activity
android:name=".activities.SplashActivity"
android:exported="true"
android:launchMode="singleTop"
>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter> --这一部分都不能少
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="wx2************1ca"/> --最开始的app_id
</intent-filter>
</activity>
当在app中下单,后台生成prepay_id返回给前台时,前台拉起微信,先看下官方文档
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2
注意,最后三一个sign,需要之前所有的值座位参数生成,最后三个要么后台提供给你,要么你自己生成就可以.
下边把后三个参数的生成方法贴上.亲测可以使用
1,随机字符串
public static String getNonceStr() { Random random = new Random(); return getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); } /** * md5 加密 * * @param buffer * @return */ 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; } }
2 时间戳
public static String getCurrentTimeString() { return String.valueOf(System.currentTimeMillis() / 1000); }
3 签名 ,这里使用了 NameValuePair 这个类 是org.apache.http 包下的一个接口,需要导入 这个包,网上随便找找就行
签名比较麻烦 此处的参数 key的顺序是按照字典排序从小到大,就保持这样,不要更改
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)); String signStr =getSign(signParams);
然后是 封装签名的方法
public static String getSign(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(IpInfo.API_KEY);
String appSign = getMessageDigest(sb.toString().getBytes()).toUpperCase();
Log.e("orion", appSign);
return appSign;
}
接下来是拉起微信的操作,代码很简单,
IWXAPI wxapi = WXAPIFactory.createWXAPI(mContext, null); if (wxapi.isWXAppInstalled() && wxapi.getWXAppSupportAPI() >= Build.PAY_SUPPORTED_SDK_INT) { //判断微信版本是否支持支付 } else { ToastUtils.showTextShortToast(mContext, "威信版本不支持,请升级微信"); return; } //注册app wxapi.registerApp(IpInfo.APP_ID); PayReq req = new PayReq(); //应用ID req.appId = IpInfo.APP_ID; //商户号 req.partnerId = IpInfo.PARTNER_ID;// 微信支付分配的商户id req.prepayId = prepay_id;// 预支付订单号,app服务器调用“统一下单”接口获取 //暂填写固定值Sign=WXPay req.packageValue = IpInfo.PACKAGE;// 固定值Sign=WXPay,可以直接写死 //随机字符串,不长于32位。 req.nonceStr = CommonTools.getNonceStr(); 随机字符串,不长于32位 //时间戳 s 为单位 req.timeStamp = CommonTools.getCurrentTimeString(); 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)); String signStr = CommonTools.getSign(signParams); req.sign = signStr;// 签名 wxapi.registerApp(IpInfo.APP_ID); //注册app到威信 wxapi.sendReq(req); //拉起微信
至此,不出意外的话,威信支付应该可以被成功拉起来了..不过一般微信开发,都是有很多坑,讲讲我遇到的.
1,WXPayEntryActivity里你可以打log查看是否被吊起,没吊起的话看看你的路径,必须是–包名.wxapi.WXPayEntryActivity, 看看manifest里的属性配置,住activity的intentfilter配置有没有问题
2,在微信没登录时能弹出威信的登录界面,登录后返回-1, 说明你能拉起微信了,但是参数有错误,看看prepay_id 基本格式是这个样子的 WX1217752501201407033233368018 你的应该也差不多,中间掺杂这英文.
3.微信开放平台的签名应该是小写.之前有文章说是大写,不行.
4.签名有问题了.一定是打包的时候不对,不能使用debug模式来调试支付功能.- android-studio打包签名的时候
我的as是2.3的 要选择后一项来签名, 不然也会有问题.
目前就这么多.还有问题可以留言.
引用 http://blog.csdn.net/u011629490/article/details/48005103 这个文章讲的也很好,并且他的demo使用eclipse导入然后更改包名,使用你自己的app签名文件签名后是可以成功支付的.