微信支付步骤详解

来源:互联网 发布:大数据云气象阅读答案 编辑:程序博客网 时间:2024/05/22 08:09

1、创建任务类

  1. 签名算法

签名生成的通用步骤如下:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3
第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

特别注意以下重要规则:

因为 我们服务器人员什么都没写,所以下面的生成预支付ID需要我们自己写

◆ 参数名ASCII码从小到大排序(字典序);
◆ 如果参数的值为空不参与签名;
◆ 参数名区分大小写;
◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段

/** * 微信支付的任务类 */public class WebChatPay extends AsyncTask<Object, Void, Map<String, String>> {    private Context mContext;    private ProgressDialog dialog;    private PayOrderBean mOrder;    private IWXAPI msgApi; //我们开发者调用的接口    private PayReq req;//支付请求参数    @Override    protected void onPreExecute() {        dialog = ProgressDialog.show(mContext, "提示",                UIUtils.getInloadMsg());        dialog.setCancelable(false);        dialog.setCanceledOnTouchOutside(false);        msgApi = WXAPIFactory.createWXAPI(mContext, Config.WX_APPID, false);        req = new PayReq();        if (dialog != null && !dialog.isShowing()) {            dialog.show();        }    }    /**     * 1..先获取预支付交易会话PrepayId     */    @Override    protected Map<String, String> doInBackground(Object... params) {        this.mContext = (Context) params[0];        this.mOrder = (PayOrderBean) params[1];        msgApi.registerApp(Config.WX_APPID);        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//请求微信官方统一的支付URL获取会话ID(这个要服务器人员写的)        String entity = genProductArgs(mOrder);//生成产品参数发起统一付款的请求        byte[] buf = Util.httpPost(url, entity);        String content = new String(buf != null ? buf : new byte[0]);        return decodeXml(content);    }    /**     * 2..获取到预支付交易会话PrepayId后,发送支付请求     */    @Override    protected void onPostExecute(Map<String, String> result) {        if (dialog != null) {            dialog.dismiss();        }        String prepayID = result.get("prepay_id"); //获取商品的预支付交易会话ID        if (TextUtils.isEmpty(prepayID)) {            UIUtils.showToast(mContext, "没有获得PrepayId,错误代码为:" +                    result.get("return_code") + "--错误信息为:" + result.get("return_msg"));            return;        }        //发送支付请求        genPayReq(result);    }    /**     * 1.1 生成获取PrepayId 的参数     *   注:请求参数必须按照ASCII排序     */    private String genProductArgs(PayOrderBean order) {        try {            String nonceStr = genNonceStr();            List<NameValuePair> packageParams = new LinkedList<>();            packageParams.add(new BasicNameValuePair("appid", order.getAppID())); //应用ID            packageParams.add(new BasicNameValuePair("body", "aaa"));//商品描述            packageParams.add(new BasicNameValuePair("mch_id", order.getPartnerID())); //商户号            packageParams.add(new BasicNameValuePair("nonce_str", nonceStr)); //随机字符串            packageParams.add(new BasicNameValuePair("notify_url", order.getNoticeUrlForWx()));//回调地址            packageParams.add(new BasicNameValuePair("out_trade_no", order.getOrderNum()));//订单号            packageParams.add(new BasicNameValuePair("spbill_create_ip", "127.0.0.1"));//用户端实际ip            packageParams.add(new BasicNameValuePair("total_fee", order.getPrice()));//金额            packageParams.add(new BasicNameValuePair("trade_type", "APP")); //支付类型            String sign = genAppSign(packageParams);            packageParams.add(new BasicNameValuePair("sign", sign)); //签名            String xmlstring = toXml(packageParams);            return new String(xmlstring.toString().getBytes(), "ISO-8859-1");        } catch (Exception e) {            return null;        }    }    /**     *1.2 生成签名     */    private String genAppSign(List<NameValuePair> params) {        StringBuilder sb = new StringBuilder();        for (NameValuePair param : params) {            if (!TextUtils.isEmpty(param.getName()) && !TextUtils.isEmpty(param.getValue())) {                sb.append(param.getName());                sb.append('=');                sb.append(param.getValue());                sb.append('&');            }        }        sb.append("key=").append(mOrder.getSecretKey()); //商户密钥        String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();        return packageSign;    }    /**     * 获取随机字符串     */    private String genNonceStr() {        Random random = new Random();        return MD5.getMessageDigest(String.valueOf(random.nextInt(32)).getBytes());    }    /**     * 生成XML格式的文件     */    private String toXml(List<NameValuePair> params) {        StringBuilder sb = new StringBuilder();        sb.append("<xml>");        for (NameValuePair param : params) {            sb.append("<").append(param.getName()).append(">");            sb.append(param.getValue());            sb.append("</").append(param.getName()).append(">");        }        sb.append("</xml>");        return sb.toString();    }    /**     * 解析XML     */    public Map<String, String> decodeXml(String content) {        try {            Map<String, String> xmlMap = 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)) {                            // 实例化student对象                            xmlMap.put(nodeName, parser.nextText());                        }                        break;                    case XmlPullParser.END_TAG:                        break;                }                event = parser.next();            }            return xmlMap;        } catch (Exception e) {            Log.e("orion", e.toString());        }        return null;    }    /**     * 3..生成支付参数,发送请求     */    private void genPayReq(Map<String, String> result) {        req.appId = mOrder.getAppID();  //用户APPid        req.nonceStr = genNonceStr(); //随机字符串        req.packageValue = "Sign=WXPay"; //固定的        req.partnerId = mOrder.getPartnerID();  //商户ID        req.prepayId = result.get("prepay_id"); //会话ID ,这个最中意        req.timeStamp = String.valueOf(System.currentTimeMillis() / 1000);        //把支付参数也都生成签名文件        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);        msgApi.sendReq(req);//生成付款请求,提交付款申请    }}

2.导入Demo里的类

这里写图片描述

3.清单文件配置下

 <!-- 微信支付-->        <receiver            android:name=".wxpay.AppRegister">            <intent-filter>                <action android:name="com.enjoydecorate" />            </intent-filter>        </receiver>        <activity android:name=".wxapi.WXPayEntryActivity"/>

4.点击支付

  case R.id.id_bt_submit: //支付提交                new WebChatPay().execute(this,orderBean);                break;

5.支付后的回调

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, Config.WX_APPID);        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    /**     * ,微信APP会返回到商户APP并回调onResp函数,开发者需要在该函数中接收通知,判断返回错误码,     * 如果支付成功则去后台查询支付结果再展示用户实际支付结果。     * 注意一定不能以客户端返回作为用户支付的结果,应以服务器端的接收的支付通知或查询API返回的结果为准     */    public void onResp(BaseResp resp) {        if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { //支付成功的回调码            UIUtils.showToast(this, "支付成功");            LogUtils.d("resp.errCode===" + resp.errCode);        }    }}

6.需要注意的地方

如果你集成了微信的分享,那么支付的jar包就不要导入,重复会引起错误

这里写图片描述
这里写图片描述

0 0