频道栏目
首页 > 资讯 > 微信公众平台开发 > 正文

Android 微信支付

16-06-17        来源:[db:作者]  
收藏   我要投稿

由于项目需求,加入这2个功能记录一些需要注意的地方

一.微信支付

微信支付在2016年4月份左右稍微调整了一下支付过程,但是文档却没怎么更新,这也是百度上为什么那么多开发者都说微信是个大坑. 身为一个大型互联网公司,做的事却无法让人理解.

相比之下,支付宝就好太多了.

 

微信支付需要注意地方:

1.要先申请 "商家端"账户, 需要提交公司信息, 个人不好申请的. 申请成功后,需要去 创建一个应用

创建应用需要 注意2个地方 

1>包名, 如果是Android studio开发 ,这个包名要用如下图所示位置的包名, 而不是 androidmanifest.xml中的,因为他俩可能不一样,要以下图为准,当然如果是eclipse开发那就以androidmanifest.xml里面的包名为准了.

2>签名, 这个签名不能用 debug.keystore(Eclipse专用), 或者 debug.jks(AS把后缀名换了), 要用自己创建的的签名文件,比如 shop.jsk , shop.keystore去生成签名

android studio生成签名截图如下: 点击Teminal 启动后,输入图中命令,后面是你jks所在位置. 之后回车 输入密码, 得到MD5值, 它就是微信创建应用时用到的签名,需要去掉冒号,把大写全部改成小写即可. 当然微信还给我们提供了签名工具apk, 你可以把自己的工程打包后,安装到手机,然后启动微信的签名apk,输入包名即可得到签名, 你可以拿它对比一下用命令行得到的签名是否一致, 如果不一致那就说明一个问题 " 你的应用没有经过打包" , 不要通过编译工具直接部署 到手机,这样得到的签名是不对的. 一定要是打包后的.

 

二.下面说下微信在工程中创建需要注意地方:

1. 如果你的包名是com.xxx.text 那么你需要在test之后创建一个包名 com.xxx.text.wxapi, 必须是wxapi,不能错了. 然后必须拷贝一个类过来,WXPayEntryActivity ,这个类的作用是微信支付后,接收微信的支付结果的. 你可以不做任何修改,直接拿来用就行,当然如果你想更改里面的布局,也是完全OK的, 我对他做了一下修改,代码如下, 我修改了2个地方,代码中给出了注释

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{

    private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";

    private IWXAPI api;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
                                //1.第一个修改的地方 我删掉了,它自带的 布局, 当然如果你想保留,完全OK.因为布局太难看所以我干掉他了
        api = WXAPIFactory.createWXAPI(this, Constants.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 req) {}

    @Override
    public void onResp(BaseResp resp) {
                              //2.这是我修改的第二个地方, 原版的是弹出一个对话框, 我觉得太丑,并且原版也没有给出详细问题提示,只给出了 0, -1 ,-2 这样会让客户不明所以,所以我替换成如下3个文本. 此外原版支付后,不会直接跳转到 你的应用,需要按一次 返回键,才行, 所以我加入了finish()便于在提示后,直接返回我的应用
        if(resp.errCode==0){
            Toast.makeText(this,"支付成功!",Toast.LENGTH_SHORT).show();
            //builder.setMessage(getString(R.string.pay_result_callback_msg, "支付成功!"));
        }else if(resp.errCode==-1){
            Toast.makeText(this,"支付失败!",Toast.LENGTH_SHORT).show();
            //builder.setMessage(getString(R.string.pay_result_callback_msg, "支付失败!"));
        }else if(resp.errCode==-2){
            Toast.makeText(this,"取消支付!",Toast.LENGTH_SHORT).show();
            //builder.setMessage(getString(R.string.pay_result_callback_msg, "取消支付!"));
        }
        finish();
    }
}

2. androidmainfest.xml 的配置,直接上代码,这里只需要注意一个地方那就是 appid

     //必须单例
        

        
            
                
            
        
 
            
                
                
                  //这里就是 APPID ,必须和你申请的 应用的 appid保持一致 .否则无法支付,注意,注意,注意
            
        

3.下面是我项目中的支付代码, 先说下支付流程, 首先你要 让负责接口的,给你一个接口, 这个接口 需要app端传递 商品的基本信息过去,比如 商品名字 , 描述,订单号 ,价格等等.也不需要传递太多东西, 我就传递了 以上我列举的4个 ,有人会问 "微信不是帮我们生成了一个 订单号吗?" 我干嘛还要传递给他, 我传递的这个订单号,是用于退款使用的. 所以我要传递一个, 这个订单号,在我 下单的同时, 会生成一个随机数, 当然这都是 后台 接口弄得,你只需要拿来使用就行了.

说的有点乱了,给个步骤吧

1>传递商品信息给我们自己的后台

2>我们自己的后台会拿着这些商品信息 然后加上 + 商户号id+商户秘钥 (申请商家端时获取的), 给我们app端返回一个json,该json中包含7个字段,需要解析,后面给出代码

3>我们解析后, 通过 api.sendReq(req); 调用微信支付 

代码如下:

float total3 = orderTotalPrice * 100;  //注意微信支付付款 是按照分为单位的,需要把商品价格 乘以100 ,然后强转为 int类型 ,这里(int)total3
param ="?ordertype="+"old"+"&sworkOrderCode="+out_trade_no+"&serviceFee=" +(int)total3+"&serviceItem="+orderItem.orderName.trim()+"&serviceClass="+orderItem.serviceItem.trim(); 
testWxPay(v);//开始解析接口给我们返回的json

参数:old 是,一个版本区分,因为我们过个app都用到了微信支付,并且他们都有关联,所以你可以直接无视该参数
参数:out_trade_no 是我从我们的接口获取到的随机订单号
参数:(int)total3 是商品价格, "分" 为单位,必须转为 整形, 也不知道 int会不会越界,反正我用了int,你可用long
参数:serviceItem 商品名字
参数:serviceClass商品描述

 public void testWxPay(View view) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String url = HttpUrl.host1+"WeiXinApi.asmx/CreatePrePay_id"+param;
                Log.e("xxx",url);
                ToastUtil.shortToastInBackgroundThread(getActivity(), "获取订单中...");
                try {
                    byte[] buf = Util.httpGet(url);
                    if (buf != null && buf.length > 0) {
                        String content = new String(buf);
                        Log.e("get server pay params", content);
                        JSONObject json = new JSONObject(content);
                        if (null != json && !json.has("retcode")) {
                            req = new PayReq();
                            req.appId = json.getString("appid");    //appid
                            req.partnerId = json.getString("partnerid"); //商户号
                            req.prepayId = json.getString("prepayid"); //预支付交易会话id
                            req.nonceStr = json.getString("noncestr"); //随机字符串,不超过32位
                            req.timeStamp = json.getString("timestamp");//时间戳
                            req.packageValue = json.getString("package");//扩展字段
                            req.sign = json.getString("sign");//签名信息MD5加密后的

                            ToastUtil.shortToastInBackgroundThread(getActivity(), "正常调起支付");
                            toPay();
                        } else {
                            Log.d("PAY_GET", "返回错误" + json.getString("retmsg"));
                            ToastUtil.shortToastInBackgroundThread(getActivity(), "返回错误" + json.getString("retmsg"));
                        }
                    } else {
                        Log.d("PAY_GET", "服务器请求错误");
                        ToastUtil.shortToastInBackgroundThread(getActivity(), "服务器请求错误");
                    }
                } catch (Exception e) {
                    Log.e("PAY_GET", "异常:" + e.getMessage());
                    ToastUtil.shortToastInBackgroundThread(getActivity(), "异常:" + e.getMessage());
                }
            }
        }).start();}
    private void toPay() {
        // 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
        api.registerApp(Constants.APP_ID);
        api.sendReq(req);
        Log.e("跳转结果--",api.sendReq(req)+"");
    }
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            toPay();
        }
    };

整个支付代码非常少,一共就这么多.  需要注意的一点是, 解析的 7个 参数中, sign 是我们自己服务端 二次加密得到的,这里容易出错, 当然我说的是,接口里面容易出错,和我们app端没有半毛钱关系,  因为这个 加密,老版本微信是我们 app端生成的, 新版的 是接口生成的.

sign 生成过程时, 前6个参数+ 商家秘钥 经过MD5加密就得到了. (这个加密用的前6个参数,需要安装字母排序,不能乱用,商家秘钥不需排序放到最后即可,当然这都是接口的需要完成的,我们app端 了解即可)

如果这个sign 接口没有弄好, 极容易出错,无法调起支付页. 我在做的时候,就是因为接口的生成sign是,少写一个 = 连接符造成的.

 

相关TAG标签
上一篇:与企业微信、钉钉相争?CC转向企业服务
下一篇:利用微信搜索抓取公众号文章(转载)
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站