微信支付步骤详解

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包就不要导入,重复会引起错误

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值