安卓集成微信支付--(通过吊起微信app实现支付)

  1. 第一步是申请相关的资料,开同商户认证什么的.个人来说相对比较难,基本都是公司给开.所以假设你已经拿到了相应的信息:如下
    String APP_ID = “wx2************1ca”; // appid
    String PARTNER_ID = “14*******2”; //商户id
    String API_KEY = “b**f******y2******t***d******92V”; //app_key
  2. 需要注意的是,在申请上述信息的时候,需要在微信开放平台填写安卓app的信息,包名和签名.验证码可以通过下边的微信连接下载微信的获取签名的apk.
    https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk
    把它装到你的手机上,同事把你开发的app用正式签名打包后安装到手机上,在威信的app里输入包名就可以获得了.这里写图片描述
    注意签名就是小写的,别写错.

  3. 集成微信支付的第三方库 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417751808&token=&lang=zh_CN ,按照这个步骤的前三部做就可以了.第四部不详细,不用看.

  4. 看一下威信的业务流程
    这里写图片描述
    简单解释 :1 在自己的app中调用自己的后台向威信下单,
    2 自己的后台将订单中的prepay_id 预支付的id和一些参数返回给我们自己的app中
    3 我们自己在手机中封装微信请求,吊起微信客户端中的支付界面.
    4自己在app中实现威信appz支付的回调界面(按照微信的要求写,很简单),在我们app中的微信回调界面中通过返回码判断成功还是失败,然后请求自己的后台确认支付结果. 支付逻辑就算完成
  5. 先实现微信的回调界面
    这里写图片描述
    这是我的项目结果,我的包名路径是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>

  1. 当在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;
    }

  1. 接下来是拉起微信的操作,代码很简单,


     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); //拉起微信
    

  2. 至此,不出意外的话,威信支付应该可以被成功拉起来了..不过一般微信开发,都是有很多坑,讲讲我遇到的.
    1,WXPayEntryActivity里你可以打log查看是否被吊起,没吊起的话看看你的路径,必须是–包名.wxapi.WXPayEntryActivity, 看看manifest里的属性配置,住activity的intentfilter配置有没有问题
    2,在微信没登录时能弹出威信的登录界面,登录后返回-1, 说明你能拉起微信了,但是参数有错误,看看prepay_id 基本格式是这个样子的 WX1217752501201407033233368018 你的应该也差不多,中间掺杂这英文.
    3.微信开放平台的签名应该是小写.之前有文章说是大写,不行.
    4.签名有问题了.一定是打包的时候不对,不能使用debug模式来调试支付功能.

  3. android-studio打包签名的时候这里写图片描述
    我的as是2.3的 要选择后一项来签名, 不然也会有问题.
    目前就这么多.还有问题可以留言.

引用 http://blog.csdn.net/u011629490/article/details/48005103 这个文章讲的也很好,并且他的demo使用eclipse导入然后更改包名,使用你自己的app签名文件签名后是可以成功支付的.

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页