接入第三方SDK-微信支付

  • Post author:
  • Post category:其他

准备工作:

  1. 首先去微信开发者平台中注册好自己的应用,并申请支付权限,得到appkey;且在
    微信平台中下载获得签名工具,输入包名获取签名填写到开发者平台中去(这一步必须要有);
  2. 导入微信的libs包libammsdk.jar;
  3. 创建一个“应用包名+wxapi“+包名的包;
//回调Actvity,用于支付后的回调
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);
        setContentView(R.layout.pay_result);

        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) {

        Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);

        if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {

            if("0".equals(String.valueOf(resp.errCode))){
            Utils.newInstance().showToast(WXPayEntryActivity.this, "支付成功");
            }
            if("-1".equals(String.valueOf(resp.errCode))){
            Utils.newInstance().showToast
            (WXPayEntryActivity.this, "未知错误,请联系客服");
                finish();
            }
            if("-2".equals(String.valueOf(resp.errCode))){
            (WXPayEntryActivity.this, "支付已取消");
                finish();
            }
        }
    }
}
  • 调用微信支付

     /**
     * 因为微信给的官方demo是连在一起的
     * 我现在把他拆开来,方便大家看的更清楚点
     */
    private void WeiXinPay() {
        // TODO Auto-generated method stub
        Utils.showToast(context, "微信支付启动中...请稍后");
        GetPrepayIdTask getPrepayId = new GetPrepayIdTask();
        getPrepayId.execute();
    }
  • 传入商品信息数据,生成订单json数据,这边可以使用微信写好的方法;不过,大家最好整理一下代码;微信的源码有点乱。
  private class GetPrepayIdTask extends AsyncTask<Void, Void, Map<String, String>> {
        @Override
        protected void onPreExecute() {

        }

        @Override
        protected void onPostExecute(Map<String, String> result) {
            WeixinPay.resultunifiedorder = result;
            WeixinPay.genPayReq();   
            //查看返回订单数据  
            Log.e("tag","resultunifiedorder=="+WeixinPay.resultunifiedorder);
            api.sendReq(WeixinPay.req);

        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
        }
        //这边注意注释下的这几点
        @Override
        protected Map<String, String> doInBackground(Void... params) {
        //这边微信使用已“分”为单位,这里要注意噢~~
            int a = (int) (Double.valueOf(fee) * 100);
            String url = 
            String.format("https://api.mch.weixin.qq.com/pay/unifiedorder");
            /*
            *“NO”为订单号,自己服务器生成的,“a”为金额要转换String格式(微信要
            * 求的),"HttpHelp.BuyCallback",为通知服务器回调url;
            */
            String entity = WeixinPay.genProductArgs(NO, 
            String.valueOf(a),HttpHelp.BuyCallback);
            Log.e("orion", entity);
            byte[] buf = Util.httpPost(url, entity);
            String content = new String(buf);
            Log.e("orion", content);
            Map<String, String> xml = decodeXml(content);
            return xml;
        }
    }

    public Map<String, String> decodeXml(String content) {
        try {
            Map<String, String> xml = new HashMap<String, String>();
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(new StringReader(content));
            int event = parser.getEventType();
            while (event != XmlPullParser.END_DOCUMENT) {
                String nodeName = parser.getName();
                switch (event) {
                    case XmlPullParser.START_DOCUMENT:
                        break;
                    case XmlPullParser.START_TAG:
                        if ("xml".equals(nodeName) == false) {
                            //实例化student对象
                            xml.put(nodeName, parser.nextText());
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        break;
                }
                event = parser.next();
            }
            return xml;
        } catch (Exception e) {
            Log.e("orion", e.toString());
        }
        return null;
    }
  • 序列化订单数据,用于生成xml订单数据,发送给微信调用起微信支付;
/**
 * 类说明:
 * @author MyT
 * @version 创建时间:20152015-10-8 下午5:00:40 
 */
public class WeixinPay {
    private static final String TAG = "MicroMsg.SDKSample.WeixinPay";
    public static Map<String,String> resultunifiedorder
                                    =new HashMap<String, String>();
    public static PayReq req=new PayReq();
    public static String genProductArgs(String name, String total,String url) {

        StringBuffer xml = new StringBuffer();
        try {
            String  nonceStr = genNonceStr();
            xml.append("</xml>");
            List<NameValuePair> packageParams = new LinkedList<NameValuePair>();
            packageParams.add(new BasicNameValuePair("appid", 
            Constants.APP_ID));//微信appid

            packageParams.add(new BasicNameValuePair("body", "*******"));//商品备注
            packageParams.add(new BasicNameValuePair("mch_id", Constants.MCH_ID));//商户ID
            packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
            packageParams.add(new BasicNameValuePair("notify_url", url));
            packageParams.add(new BasicNameValuePair("out_trade_no",name));
            packageParams.add(new 
            BasicNameValuePair("spbill_create_ip","127.0.0.1"));
            packageParams.add(new BasicNameValuePair("total_fee", total));
            packageParams.add(new BasicNameValuePair("trade_type", "APP"));
            String sign = genPackageSign(packageParams);
            packageParams.add(new BasicNameValuePair("sign", sign));
            String xmlstring =toXml(packageParams);
            //有转码错误的风险,参考其他人的做法要加上就可以了吧xml转码下
            return new String(xmlstring.toString().getBytes(), 
        } catch (Exception e) {
            Log.e(TAG, "genProductArgs fail, ex = " + e.getMessage());
            return null;
        }
    }

    public static String genNonceStr() {
        Random random = new Random();
        return 
        MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
    }

    public static String genOutTradNo() {
        Random random = new Random();
        return 
        MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
    }

    /**      生成签名
     */
    public static String genPackageSign(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(Constants.API_KEY);


        String packageSign = 
        MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
        Log.e("orion",packageSign);
        return packageSign;
    }

    public static String toXml(List<NameValuePair> params) {
        StringBuilder sb = new StringBuilder();
        sb.append("<xml>");
        for (int i = 0; i < params.size(); i++) {
            sb.append("<"+params.get(i).getName()+">");


            sb.append(params.get(i).getValue());
            sb.append("</"+params.get(i).getName()+">");
        }
        sb.append("</xml>");

        Log.e("orion",sb.toString());
        return sb.toString();
    }


    public static void genPayReq() {

        req.appId = Constants.APP_ID;
        req.partnerId =Constants.MCH_ID;
        req.prepayId =WeixinPay.resultunifiedorder.get("prepay_id");
        req.packageValue ="Sign=WXPay";
        req.nonceStr = genNonceStr();
        req.timeStamp = String.valueOf(genTimeStamp());


        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));

        req.sign = genAppSign(signParams);
        Log.e("orion", signParams.toString());
    }

    public static long genTimeStamp() {
        return System.currentTimeMillis() / 1000;
    }
    public static 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(Constants.API_KEY);

        String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
        Log.e("orion",appSign);
        return appSign;
    }
}
  • 最后注意一点:一定要用正式包名,就是提交给微信的签名去支付,否则会支付失败;有许多人支付失败,请先清理微信缓存,再进行支付,这个问题,微信也没给出具体的解决方案,只叫我们去清除缓存;
  • 最好自己看一遍微信的文档,虽然旧,但是看的懂大概就行;其他的工具类,全部是微信那边提供下载的,这边我就不提供了;^(* ̄(oo) ̄)^