zoukankan      html  css  js  c++  java
  • 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;
        }
    
    
    }
  • 相关阅读:
    Git tag
    Docker学习笔记五 仓库
    Docker学习笔记四 Docker容器
    Docker学习笔记二 使用镜像
    Docker学习笔记一 概念、安装、镜像加速
    element-UI 下拉条数多渲染慢
    scroll-view——小程序横向滚动
    Jquery slider范围滑块,为两个滑块设置不同的setp值
    自说自话2
    自说自话1
  • 原文地址:https://www.cnblogs.com/Westfalen/p/6909108.html
Copyright © 2011-2022 走看看