android微信支付

来源:互联网 发布:java nested查询 编辑:程序博客网 时间:2024/06/05 14:16

首先需要到微信开放平台申请app应用,第三方分享不需要认证,登录和支付需要认证,其实就是给微信平台300rmb

认证一般需要7个工作日

完事以后需要去微信商户平台配置信息,需要吐槽一下360浏览器可能会打不开,建议使用google浏览器,火狐或者其他的

登录以后,看一下开发文档,自己配置一下就会发现,满满的都是坑

获取app的微信签名地址: https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk

public class Constants {    public static final String APP_ID = "appid";    public static class ShowMsgActivity {      public static final String STitle = "title";      public static final String SMessage = "message";      public static final String BAThumbData = "showmsg_thumb_data";   }}
public class AppRegister extends BroadcastReceiver {   @Override   public void onReceive(Context context, Intent intent) {      final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);      // ����appע΢��      msgApi.registerApp(Constants.APP_ID);   }}
MD加密
public class MD5 {   private MD5() {}      public final static String getMessageDigest(byte[] buffer) {      char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };      try {         MessageDigest mdTemp = MessageDigest.getInstance("MD5");         mdTemp.update(buffer);         byte[] md = mdTemp.digest();         int j = md.length;         char str[] = new char[j * 2];         int k = 0;         for (int i = 0; i < j; i++) {            byte byte0 = md[i];            str[k++] = hexDigits[byte0 >>> 4 & 0xf];            str[k++] = hexDigits[byte0 & 0xf];         }         return new String(str);      } catch (Exception e) {         return null;      }   }}
调起微信支付需要用到的util
import java.io.ByteArrayOutputStream;import java.io.File;import java.io.IOException;import java.io.RandomAccessFile;import java.net.Socket;import java.net.UnknownHostException;import java.security.KeyManagementException;import java.security.KeyStore;import java.security.KeyStoreException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.UnrecoverableKeyException;import java.security.cert.X509Certificate;import java.util.ArrayList;import java.util.List;import javax.net.ssl.SSLContext;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;import org.apache.http.HttpResponse;import org.apache.http.HttpStatus;import org.apache.http.HttpVersion;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;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.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 junit.framework.Assert;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Bitmap.CompressFormat;import android.util.Log;public class Util {      private static final String TAG = "SDK_Sample.Util";      public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {      ByteArrayOutputStream output = new ByteArrayOutputStream();      bmp.compress(CompressFormat.PNG, 100, output);      if (needRecycle) {         bmp.recycle();      }            byte[] result = output.toByteArray();      try {         output.close();      } catch (Exception e) {         e.printStackTrace();      }            return result;   }   public static byte[] httpGet(final String url) {      if (url == null || url.length() == 0) {         Log.e(TAG, "httpGet, url is null");         return null;      }      HttpClient httpClient = getNewHttpClient();      HttpGet httpGet = new HttpGet(url);      try {         HttpResponse resp = httpClient.execute(httpGet);         if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {            Log.e(TAG, "httpGet fail, status code = " + resp.getStatusLine().getStatusCode());            return null;         }         return EntityUtils.toByteArray(resp.getEntity());      } catch (Exception e) {         Log.e(TAG, "httpGet exception, e = " + e.getMessage());         e.printStackTrace();         return null;      }   }      public static byte[] httpPost(String url, String entity) {      if (url == null || url.length() == 0) {         Log.e(TAG, "httpPost, url is null");         return null;      }            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) {            Log.e(TAG, "httpGet fail, status code = " + resp.getStatusLine().getStatusCode());            return null;         }         return EntityUtils.toByteArray(resp.getEntity());      } catch (Exception e) {         Log.e(TAG, "httpPost exception, e = " + e.getMessage());         e.printStackTrace();         return null;      }   }      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 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();       }    }      public static byte[] readFromFile(String fileName, int offset, int len) {      if (fileName == null) {         return null;      }      File file = new File(fileName);      if (!file.exists()) {         Log.i(TAG, "readFromFile: file not found");         return null;      }      if (len == -1) {         len = (int) file.length();      }      Log.d(TAG, "readFromFile : offset = " + offset + " len = " + len + " offset + len = " + (offset + len));      if(offset <0){         Log.e(TAG, "readFromFile invalid offset:" + offset);         return null;      }      if(len <=0 ){         Log.e(TAG, "readFromFile invalid len:" + len);         return null;      }      if(offset + len > (int) file.length()){         Log.e(TAG, "readFromFile invalid file len:" + file.length());         return null;      }      byte[] b = null;      try {         RandomAccessFile in = new RandomAccessFile(fileName, "r");         b = new byte[len]; // ���������ļ���С������         in.seek(offset);         in.readFully(b);         in.close();      } catch (Exception e) {         Log.e(TAG, "readFromFile : errMsg = " + e.getMessage());         e.printStackTrace();      }      return b;   }      private static final int MAX_DECODE_PICTURE_SIZE = 1920 * 1440;   public static Bitmap extractThumbNail(final String path, final int height, final int width, final boolean crop) {      Assert.assertTrue(path != null && !path.equals("") && height > 0 && width > 0);      BitmapFactory.Options options = new BitmapFactory.Options();      try {         options.inJustDecodeBounds = true;         Bitmap tmp = BitmapFactory.decodeFile(path, options);         if (tmp != null) {            tmp.recycle();            tmp = null;         }         Log.d(TAG, "extractThumbNail: round=" + width + "x" + height + ", crop=" + crop);         final double beY = options.outHeight * 1.0 / height;         final double beX = options.outWidth * 1.0 / width;         Log.d(TAG, "extractThumbNail: extract beX = " + beX + ", beY = " + beY);         options.inSampleSize = (int) (crop ? (beY > beX ? beX : beY) : (beY < beX ? beX : beY));         if (options.inSampleSize <= 1) {            options.inSampleSize = 1;         }         // NOTE: out of memory error         while (options.outHeight * options.outWidth / options.inSampleSize > MAX_DECODE_PICTURE_SIZE) {            options.inSampleSize++;         }         int newHeight = height;         int newWidth = width;         if (crop) {            if (beY > beX) {               newHeight = (int) (newWidth * 1.0 * options.outHeight / options.outWidth);            } else {               newWidth = (int) (newHeight * 1.0 * options.outWidth / options.outHeight);            }         } else {            if (beY < beX) {               newHeight = (int) (newWidth * 1.0 * options.outHeight / options.outWidth);            } else {               newWidth = (int) (newHeight * 1.0 * options.outWidth / options.outHeight);            }         }         options.inJustDecodeBounds = false;         Log.i(TAG, "bitmap required size=" + newWidth + "x" + newHeight + ", orig=" + options.outWidth + "x" + options.outHeight + ", sample=" + options.inSampleSize);         Bitmap bm = BitmapFactory.decodeFile(path, options);         if (bm == null) {            Log.e(TAG, "bitmap decode failed");            return null;         }         Log.i(TAG, "bitmap decoded size=" + bm.getWidth() + "x" + bm.getHeight());         final Bitmap scale = Bitmap.createScaledBitmap(bm, newWidth, newHeight, true);         if (scale != null) {            bm.recycle();            bm = scale;         }         if (crop) {            final Bitmap cropped = Bitmap.createBitmap(bm, (bm.getWidth() - width) >> 1, (bm.getHeight() - height) >> 1, width, height);            if (cropped == null) {               return bm;            }            bm.recycle();            bm = cropped;            Log.i(TAG, "bitmap croped size=" + bm.getWidth() + "x" + bm.getHeight());         }         return bm;      } catch (final OutOfMemoryError e) {         Log.e(TAG, "decode bitmap failed: " + e.getMessage());         options = null;      }      return null;   }      public static String sha1(String str) {      if (str == null || str.length() == 0) {         return null;      }            char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };            try {         MessageDigest mdTemp = MessageDigest.getInstance("SHA1");         mdTemp.update(str.getBytes());                  byte[] md = mdTemp.digest();         int j = md.length;         char buf[] = new char[j * 2];         int k = 0;         for (int i = 0; i < j; i++) {            byte byte0 = md[i];            buf[k++] = hexDigits[byte0 >>> 4 & 0xf];            buf[k++] = hexDigits[byte0 & 0xf];         }         return new String(buf);      } catch (Exception e) {         return null;      }   }      public static List<String> stringsToList(final String[] src) {      if (src == null || src.length == 0) {         return null;      }      final List<String> result = new ArrayList<String>();      for (int i = 0; i < src.length; i++) {         result.add(src[i]);      }      return result;   }}
微信支付用到的封装的工具类
WeiXinPayMethod
public class WeiXinPayMethod {    private static final String TAG = "MicroMsg.SDKSample.PayActivity";    public static final String APP_ID = "appid";//   // 商户号    public static final String MCH_ID = "商户号";//     // API密钥,在商户平台设置    public static final String API_KEY = "APP秘钥";//    /**     * 包括订单号的结果HashMap     */    public static Map<String, String> resultunifiedorder;    /**     * 生成APP微信支付签名参数Bean     */    public static PayReq req;    private static float addmoney;    /**     * 将该APP注册到微信     */    public static void regist_WeiXinPay(Context context) {        final IWXAPI api = WXAPIFactory.createWXAPI(context, APP_ID);        api.registerApp(APP_ID);    }    /**     * 微信支付方法     */    public static void pay(Context context) {       regist_WeiXinPay(context);        SharedPreferenceUtil.initPreference(context);        addmoney =   Float.parseFloat(SharedPreferenceUtil.getString("addmoney","0"));        GetPrepayIdTask getPrepayId = new GetPrepayIdTask(context);        getPrepayId.execute();    }    private static class GetPrepayIdTask extends            AsyncTask<Void, Void, Map<String, String>> {        private ProgressDialog dialog;        private Context context;        public GetPrepayIdTask(Context context) {            this.context = context;        }        @Override        protected void onPreExecute() {            dialog = ProgressDialog.show(context, "提示", "正在获取预支付订单...");        }        @Override        protected void onPostExecute(Map<String, String> result) {            if (dialog != null) {                dialog.dismiss();            }            resultunifiedorder = result;            Set<String> strings = resultunifiedorder.keySet();            genPayReq(context);        }        @Override        protected void onCancelled() {            super.onCancelled();        }        @Override        protected Map<String, String> 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);            Map<String, String> xml = decodeXml(content);            return xml;        }    }    /**     * 获取商品参数     */    private static String genProductArgs() {        StringBuffer xml = new StringBuffer();        try {            String nonceStr = genNonceStr();            xml.append("</xml>");            List<NameValuePair> packageParams = new LinkedList<NameValuePair>();            packageParams.add(new BasicNameValuePair("appid",                    WeiXinPayMethod.APP_ID));            packageParams.add(new BasicNameValuePair("body", "自己app的名字"));            packageParams.add(new BasicNameValuePair("mch_id",                    WeiXinPayMethod.MCH_ID));            packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
//回调需要的接口            packageParams.add(new BasicNameValuePair("notify_url",                   "回调需要的接口"));            packageParams.add(new BasicNameValuePair("out_trade_no",                    genOutTradNo()));            packageParams.add(new BasicNameValuePair("spbill_create_ip",                    "59.110.65.224"));            // money = String.valueOf(((Double.parseDouble(money)) * 100));//            // 分转换为元            // int a = (int)(Integer.parseInt(money)*100);//            packageParams.add(new BasicNameValuePair("total_fee",(int)(addmoney*100)//                    + ""));
//测试的时候支付1分钱,实际上线的时候,需要用addmoney*100            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(), "ISO-8859-1");        } catch (Exception e) {            return null;        }    }    /**     * 解析XML     */    public 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) {                            // 实例化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;    }    /**     * 拼接XML     */    private static String toXml(List<NameValuePair> params) {        StringBuilder sb = new StringBuilder();        sb.append("<xml>");        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("</xml>");        Log.e("orion", sb.toString());        return sb.toString();    }    private static String genNonceStr() {        Random random = new Random();        return MD5.getMessageDigest(String.valueOf(random.nextInt(10000))                .getBytes());    }    private static String genOutTradNo() {        Random random = new Random();        return MD5.getMessageDigest(String.valueOf(random.nextInt(10000))                .getBytes());    }    /**     * 生成签名     */    private static String genPackageSign(List<NameValuePair> 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(WeiXinPayMethod.API_KEY);        String packageSign = MD5.getMessageDigest(sb.toString().getBytes())                .toUpperCase();        Log.e("orion", packageSign);        return packageSign;    }    /**     * 封装APP微信支付参数     */    public static void genPayReq(Context context) {        req = new PayReq();        req.appId = WeiXinPayMethod.APP_ID;// 公众账号ID(微信分配的公众账号ID)        req.partnerId = WeiXinPayMethod.MCH_ID;// 商户号(微信支付分配的商户号)        req.prepayId = resultunifiedorder.get("prepay_id");// 预支付交易会话ID(微信返回的支付交易会话ID)        req.packageValue = "Sign=WXPay";// 扩展字段(暂填写固定值Sign=WXPay)        // req.packageValue = "prepay_id="+resultunifiedorder.get("prepay_id");        req.nonceStr = genNonceStr();// 随机字符串(随机字符串,不长于32位。推荐随机数生成算法)        req.timeStamp = String.valueOf(System.currentTimeMillis() / 1000);// 时间戳(时间戳,请见接口规则-参数规定)        if (req.prepayId != null) {            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);// 签名()            Log.e("orion", signParams.toString());            sendPayReq(context, req);        }    }    private static String genAppSign(List<NameValuePair> 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(WeiXinPayMethod.API_KEY);        String appSign = MD5.getMessageDigest(sb.toString().getBytes())                .toUpperCase();        Log.e("orion", appSign);        return appSign;    }    /**     * 发送微信支付请求     */    private static void sendPayReq(Context context, PayReq req) {        final IWXAPI api = WXAPIFactory.createWXAPI(context, null);        api.registerApp(WeiXinPayMethod.APP_ID);        api.sendReq(req);    }    /**     * 检查为新版本是否支持支付     */    public boolean supportPay(Context context) {        IWXAPI api = WXAPIFactory.createWXAPI(context, WeiXinPayMethod.APP_ID);        return api.getWXAppSupportAPI() >= Build.PAY_SUPPORTED_SDK_INT;    }}
//支付完成以后,返回到
WXPayEntryActivity
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{
private IWXAPI api;private static final String TAG = "weixinpay";

@Overridepublic void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.pay_result);    pay_type = SharedPreferenceUtil.getString("pay_type", null);    api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);    api.handleIntent(getIntent(), this);}
@Overrideprotected void onNewIntent(Intent intent) {    super.onNewIntent(intent);    setIntent(intent);    api.handleIntent(intent, this);}
@Overridepublic void onReq(BaseReq baseReq) {}
@Overridepublic void onResp(BaseResp resp) {    switch (resp.errCode) {
case 0:
//支付成功
break;
case -1:
//支付失败    Toast.makeText(this, "错误", Toast.LENGTH_SHORT).show();    finish();    break;case -2:
//用户取消    Toast.makeText(this, "用户取消", Toast.LENGTH_SHORT).show();    finish();    break;

}
}
}






原创粉丝点击