android 项目集成 微信支付

0.环境 下载 libammsdk.jar

1.需要的常量值

public class Constant {

    /** 微信中用到的常量值 */
    public static final class WX_CONSTANT {
        /** 微信支付 APP_ID */
        public static final String APP_ID = "xxx";
        /** 微信支付 商户号 */
        public static final String MCH_ID = "xxx";
        /** 微信支付 API密钥 */
        public static final String API_KEY = "xxx";
    }
}

2.package_name.wxapi 新建 WXPayEntryActivity.java (路径和文件名必须是这个)

package com.iotlife.action.wxapi;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

import com.iotlife.action.R;
import com.iotlife.action.common.Constant;
import com.iotlife.action.util.LogUtil;
import com.iotlife.action.util.ThreadPoolUtil;
import com.iotlife.action.util.ToastUtil;
import com.iotlife.action.util.ViewUtil;
import com.iotlife.action.util.WXUtil;
import com.tencent.mm.opensdk.constants.ConstantsAPI;
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;


public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
    public static void start(Context context) {
        context.startActivity(new Intent(context, WXPayEntryActivity.class));
    }

    private IWXAPI api;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wechat_pay);

        api = WXAPIFactory.createWXAPI(this, Constant.WX_CONSTANT.APP_ID);
        api.handleIntent(getIntent(), this);


        ViewUtil.$(this, R.id.btnPay).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ThreadPoolUtil.execute(new Runnable() {
                    @Override
                    public void run() {
                        WXUtil.submitOrder();
                    }
                });
            }
        });
    }

    @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) {
        LogUtil.d("HttpUtil", "微信支付回调onPayFinish, errCode = " + resp.errCode);
        if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
            if (resp.errCode == 0) {
                ToastUtil.show("支付成功");
            } else {
                ToastUtil.show("支付失败");
            }
            finish();
        }
    }
}

3.工具类 WXUtil.java

package com.iotlife.action.util;

import android.util.Xml;

import com.iotlife.action.application.EJYApplication;
import com.iotlife.action.common.Constant;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.xmlpull.v1.XmlPullParser;

import java.io.IOException;
import java.io.StringReader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class WXUtil {
    private static final String TAG = "HttpUtil";
    private static final IWXAPI msgApi = WXAPIFactory.createWXAPI(EJYApplication.getInstance(), null);

    /**
     * 微信支付
     * https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1
     * <p>
     * https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3
     * 注释分别为:字段名称,是否必填
     */
    public static void submitOrder() {
        PayReq req = new PayReq();
       req.nonceStr = StringUtil.md5(UUID.randomUUID().toString());
        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
        map.put("appid", Constant.WX_CONSTANT.APP_ID); // 应用ID
        map.put("mch_id", Constant.WX_CONSTANT.MCH_ID);// 商户号
        map.put("device_info", "WEB");// 设备号,否
        map.put("nonce_str", req.nonceStr);// 随机字符串
        // map.put("sign_type", "md5");// 签名类型,否
        map.put("body", "body");// 商品描述
        // map.put("detail", "detail");// 商品详情,否
        map.put("attach", "attach");// 附加数据,否
        map.put("out_trade_no", (System.currentTimeMillis() + 1415659990999L) + "");// 商户订单号
        // map.put("fee_type", "CNY");// 货币类型,否
        map.put("total_fee", "1");// 总金额,单位是分,不是元,不能有小数
        map.put("spbill_create_ip", "14.23.150.211");// 终端IP
        map.put("time_start", "");// 交易起始时间,否
        map.put("time_expire", "");// 交易结束时间,否
        map.put("goods_tag", "");// 订单优惠标记,否
        map.put("notify_url", "https://www.baidu.com");// 通知地址
        map.put("trade_type", "APP");// 交易类型
        // map.put("limit_pay", "no_credit");// 指定支付方式,否

        String key = Constant.WX_CONSTANT.API_KEY;
        String sign = WXUtil.getSign(map, key);
        map.put("sign", sign);
        String entity = toXml(map);
        LogUtil.d(TAG, entity);
        byte[] buf = httpPost(entity);
        String content = new String(buf);
        LogUtil.d(TAG, "content " + content);

        Map<String, String> resultunifiedorder = decodeXml(content);
        req.appId = map.get("appid");
        req.partnerId = map.get("mch_id");
        if (resultunifiedorder != null) {
            req.prepayId = resultunifiedorder.get("prepay_id");
            req.packageValue = "prepay_id=" + resultunifiedorder.get("prepay_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));

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < signParams.size(); i++) {
            sb.append(signParams.get(i).getName());
            sb.append('=');
            sb.append(signParams.get(i).getValue());
            sb.append('&');
        }
        sb.append("key=");
        sb.append(Constant.WX_CONSTANT.API_KEY);

        req.sign = StringUtil.md5(sb.toString());
        LogUtil.d(TAG, "req.sign = " + req.sign);

        msgApi.registerApp(Constant.WX_CONSTANT.APP_ID);
        msgApi.sendReq(req);
    }

    private static byte[] httpPost(String entity) {
        final String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

        HttpClient httpClient = getNewHttpClient();
        HttpPost httpPost = new HttpPost(url);
        try {
            httpPost.setEntity(new StringEntity(entity));
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Content-type", "application/json");

            HttpResponse resp = httpClient.execute(httpPost);
            if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                LogUtil.d(TAG, "httpGet fail, status code = " + resp.getStatusLine().getStatusCode());
                return null;
            }

            return EntityUtils.toByteArray(resp.getEntity());
        } catch (Exception e) {
            LogUtil.d(TAG, "httpPost exception, e = " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    private static HttpClient getNewHttpClient() {
        try {
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);

            SSLSocketFactory sf = new SSLSocketFactoryEx(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            HttpParams params = new BasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));

            ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

            return new DefaultHttpClient(ccm, params);
        } catch (Exception e) {
            return new DefaultHttpClient();
        }
    }


    /**
     * 微信公众平台支付接口调试工具
     * https://pay.weixin.qq.com/wiki/tools/signverify/
     *
     * @param map
     * @param key 商户Key
     * @return
     */
    private static String getSign(Map<String, String> map, String key) {
        if (map == null || map.size() < 1) {
            LogUtil.d("HttpUtil", "map 为空");
            return "";
        }
        StringBuilder sb = new StringBuilder();
        List list = new ArrayList<>(map.keySet());
        Collections.sort(list);
        for (int i = 0; i < list.size(); i++) {
            if (map.get(list.get(i)) != null && !map.get(list.get(i)).equals("")) {
                if (list.get(i).equals("notify_url")) {
                    sb.append(list.get(i)).append("=").append(map.get(list.get(i))).append("&");
                } else {
                    sb.append(list.get(i)).append("=").append(StringUtil.encoder(map.get(list.get(i)))).append("&");
                }
            }
        }
        String stringA = sb.toString();
        stringA = stringA.substring(0, stringA.length() - 1);
        String stringSignTemp = stringA + "&key=" + key;
        String sign = StringUtil.md5(stringSignTemp).toUpperCase();
        LogUtil.d("HttpUtil", "stringA =  " + stringA);
        LogUtil.d("HttpUtil", "stringSignTemp = " + stringSignTemp);
        LogUtil.d("HttpUtil", "sign = " + sign);
        return sign;
    }

    private static String toXml(Map<String, String> map) {
        if (map == null || map.size() < 1) {
            LogUtil.d("HttpUtil", "map 为空");
            return "";
        }
        StringBuilder sb = new StringBuilder("<xml>");
        for (String key : map.keySet()) {
            if (map.get(key) != null && !map.get(key).equals("")) {
                sb.append("<").append(key).append(">").append(map.get(key)).append("</").append(key).append(">");
            }
        }
        return sb.append("</xml>").toString();
    }

    private static class SSLSocketFactoryEx extends SSLSocketFactory {

        SSLContext sslContext = SSLContext.getInstance("TLS");

        public SSLSocketFactoryEx(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
            super(truststore);

            TrustManager tm = new X509TrustManager() {

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
                }
            };

            sslContext.init(null, new TrustManager[]{tm}, null);
        }

        @Override
        public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
            return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
        }

        @Override
        public Socket createSocket() throws IOException {
            return sslContext.getSocketFactory().createSocket();
        }
    }

    private static 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) {
                            xml.put(nodeName, parser.nextText());
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        break;
                }
                event = parser.next();
            }
            return xml;
        } catch (Exception e) {
            LogUtil.d(TAG, "xml decoder error" + e.toString());
        }
        return null;
    }


}
原文地址:https://www.cnblogs.com/Westfalen/p/6909108.html