微信支付集成

一个app里面肯定会有支付,而绝大多数会集成微信支付,当然也不是很难,我只是将我踩过的坑填补,然后提供比较好的工具出来,方便大家使用。

GetPrepayIdTask getPrepayIdTask = new GetPrepayIdTask(this, price + "", "" + tuanbi_info, logid);
                        getPrepayIdTask.execute();

这个就是开始,但是在这里那个price很关键,微信是以分为最小单位,但是不可以出现10.0这样的情况,而且最好不要使用double的数据类型,应该使用float,double数据类型会有精度丢失的问题,所以经常会看到9.99999的情况。这个是不合理的。然后我粘贴处GetPrePayIdTask:

import java.io.StringReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.xmlpull.v1.XmlPullParser;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.provider.DocumentsContract.Root;
import android.util.Log;
import android.util.Xml;

import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;


/**
 * Created by Administrator on 2017/4/12.
 * 微信支付
 */

public class GetPrepayIdTask extends AsyncTask> {
    /**
     * 微信支付业务:入参app_id
     */
    public static final String WXAPPID = "";
    public static final String MCH_ID = "";
    public static final String API_KEY = "";
    private StringBuffer sb = new StringBuffer();
    private Map resultunifiedorder;
    private PayReq req = new PayReq();
    private IWXAPI msgApi;
    private Context c;
    private String price;
    /**
     * 订单号
     */
    private String orderNo;
    /*商品描述交易字段格式根据不同的应用场景按照以下格式:
    APP——需传入应用市场上的APP名字-实际商品名称,天天爱消除-游戏充值。*/

    /**
     * 多个订单
     */
    private String orderNos;

    public GetPrepayIdTask(Context c, String price, String orderNo, String orderNos) {
        msgApi = WXAPIFactory.createWXAPI(c, null);
        this.c = c;
        this.price = price;
        this.orderNo = orderNo;
        this.orderNos = orderNos;
    }

    private ProgressDialog dialog;

    @Override
    protected void onPreExecute() {
        dialog = ProgressDialog.show(c, "弹窗提示", "正在加载");
    }

    @Override
    protected void onPostExecute(Map result) {
        if (dialog != null) {
            dialog.dismiss();
        }

        sb.append("prepay_id\n" + result.get("prepay_id") + "\n\n");

        resultunifiedorder = result;
        genPayReq();
        msgApi.registerApp(WXAPPID);
        msgApi.sendReq(req);
    }

    @Override
    protected void onCancelled() {
        super.onCancelled();
    }

    @Override
    protected Map doInBackground(Void... params) {

        String url = String.format("https://api.mch.weixin.qq.com/pay/unifiedorder");
        String entity = genProductArgs();

        byte[] buf = Util.httpPost(url, entity);

        String content = new String(buf);
        Log.e("orion", content);
        Map xml = decodeXml(content);

        return xml;
    }

    private void genPayReq() {

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

        List signParams = new LinkedList();
        signParams.add(new BasicNameValuePair("appid", req.appId));
        // signParams.add(new BasicNameValuePair("appkey", Constants.API_KEY));
        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);

        sb.append("sign\n" + req.sign + "\n\n");

        Log.e("orion", signParams.toString());
        // req.appId = Constants.APP_ID;
        // req.partnerId = Constants.MCH_ID;
        // req.prepayId="wx20150928191247ec2bfe36120916857122";
        // req.packageValue = "Sign=WXPay";
        // req.nonceStr="lPLaOjotrEy9MYx3";
        // req.sign="10DD9C41A6857B4C4AEA98E24605925C";
        // req.timeStamp="1443437278";
    }

    private String genAppSign(List 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(API_KEY);

        this.sb.append("sign str\n" + sb.toString() + "\n\n");
        String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
        Log.e("orionAppSign", appSign);
        return appSign;
    }

    private String genProductArgs() {
        StringBuffer xml = new StringBuffer();

        try {
            String nonceStr = genNonceStr();

            xml.append("");
            List packageParams = new LinkedList();
            packageParams.add(new BasicNameValuePair("appid", WXAPPID));
            packageParams.add(new BasicNameValuePair("body", orderNo));
            packageParams.add(new BasicNameValuePair("mch_id", MCH_ID));
            packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
            packageParams.add(new BasicNameValuePair("notify_url", "http://agent.quygt.com/tenpay/tenpaynotify"));
//            packageParams.add(new BasicNameValuePair("notify_url", "http://lvgounet.oicp.net:24561/tenpay/tenpaynotify"));
            // 订单
//            packageParams.add(new BasicNameValuePair("out_trade_no", genOutTradNo(orderNos)));
            packageParams.add(new BasicNameValuePair("out_trade_no", orderNos));
            // 订单价格
//            long total_fee = (long) (1);
            // 订单
            packageParams.add(new BasicNameValuePair("spbill_create_ip", "127.0.0.1"));
            packageParams.add(new BasicNameValuePair("total_fee", price));
//            Log.e("sjdfajsadf", "==============="+price );
//            packageParams.add(new BasicNameValuePair("total_fee", "1"));
            packageParams.add(new BasicNameValuePair("trade_type", "APP"));

            String sign = genPackageSign(packageParams);
            packageParams.add(new BasicNameValuePair("sign", sign));

            String xmlstring = toXml(packageParams);
            return new String(xmlstring.toString().getBytes(), "ISO8859-1");//这句加上就可以了吧xml转码下
//            return xmlstring;

        } catch (Exception e) {
            // Log.e(TAG, "genProductArgs fail, ex = " + e.getMessage());
            return null;
        }

    }

    public Map decodeXml(String content) {

        try {
            Map xml = new HashMap();
            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;

    }

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

    private long genTimeStamp() {
        return System.currentTimeMillis() / 1000;
    }

    /**
     * 生成签名
     */

    private String genPackageSign(List 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(API_KEY);

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

    private String toXml(List params) {
        StringBuilder sb = new StringBuilder();
        sb.append("");
        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("");

        Log.e("orionsdsd", sb.toString());//new String(sb2.toString().getBytes(), "ISO8859-1")
        return sb.toString();
    }

    /**
     * 订单号信息
     *
     * @return
     */
    private String genOutTradNo(String orderNos) {
        // Random random = new Random();
        return MD5.getMessageDigest(String.valueOf(orderNos).getBytes());
    }
}

这里就是将spbill_create_ip这个参数的ip设置为固定值,这样会大大减少请求的时间。

还有使用微信支付,一定要在自己项目里新建一个位置为wxapi,还要新建WXPayEntryActivity这样一个类,

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.lvgou.distribution.utils.MyToast;import android.widget.Toast;

import com.lvgou.distribution.R;
import com.lvgou.distribution.activity.BaseActivity;
import com.lvgou.distribution.activity.RechargeRecordListActivity;
import com.lvgou.distribution.presenter.TuanbiExchangePresenter;
import com.lvgou.distribution.utils.TGmd5;
import com.lvgou.distribution.view.GroupView;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import org.greenrobot.eventbus.EventBus;

/**
 * Created by Administrator on 2017/4/11.
 */

public class WXPayEntryActivity extends BaseActivity implements IWXAPIEventHandler, GroupView {
    private TuanbiExchangePresenter tuanbiExchangePresenter;
    private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
    /**
     * 微信支付业务:入参app_id
     */
    public static final String WXAPPID = "";

    private IWXAPI api;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pay_result);
        tuanbiExchangePresenter = new TuanbiExchangePresenter(this);
        api = WXAPIFactory.createWXAPI(this, 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 req) {
    }


    @Override
    public void onResp(BaseResp resp) {
        int errCode = resp.errCode;
        if (errCode == 0) {
            //0 成功 展示成功页面
//            MyToast.makeText(this, "支付成功", Toast.LENGTH_SHORT).show();
            /*Intent intent = new Intent(Constant.ACTION_NAME);
            sendBroadcast(intent);*/
            showLoadingProgressDialog(this, "");
            String logid = mcache.getAsString("wxlogid");
            String sign = TGmd5.getMD5(logid + "1" + "-");
            tuanbiExchangePresenter.doAlipay(logid, "1", "-", sign);

        } else if (errCode == -1) {
            //-1 错误 可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。
            MyToast.makeText(this, "支付失败", Toast.LENGTH_SHORT).show();
            showLoadingProgressDialog(this, "");
            String logid = mcache.getAsString("wxlogid");
            String sign = TGmd5.getMD5(logid + "0" + resp.errStr);
            tuanbiExchangePresenter.doAlipay(logid, "0", resp.errStr, sign);
        } else if (errCode == -2) {
            //-2 用户取消 无需处理。发生场景:用户不支付了,点击取消,返回APP。
            MyToast.makeText(this, "取消支付", Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    @Override
    public void OnFamousSuccCallBack(String state, String respanse) {
        closeLoadingProgressDialog();
//        MyToast.makeText(this, "=" + respanse, Toast.LENGTH_SHORT).show();
//        Log.e("kjhaskfhs", "===========" + respanse);
        openActivity(RechargeRecordListActivity.class);
        EventBus.getDefault().post("rechargesuccess");
        finish();
//        finish();
    }

    @Override
    public void OnFamousFialCallBack(String state, String respanse) {
        closeLoadingProgressDialog();
//        Log.e("kjhaskfhs", "**********" + respanse);
//        MyToast.makeText(this, "*" + respanse, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void closeProgress() {

    }

    @Override
    public void showProgress() {

    }
}
其实就这么简单,但是没有集成过微信支付可能会走弯路,可能会被它的xml拼接和xml解析给困惑,现在这只是我的一种处理方式,有更好的希望大家给给意见。

猜你喜欢

转载自blog.csdn.net/greatdaocaoren/article/details/73504254