package com.mgw.member.http.pay; import java.security.MessageDigest; import java.util.LinkedList; import java.util.List; import java.util.Random; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.message.BasicNameValuePair; import org.json.JSONObject; import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; import android.util.Log; import android.widget.Toast; import com.mgw.member.constant.Define_C; import com.mgw.member.R; import com.tencent.mm.sdk.modelmsg.SendMessageToWX; import com.tencent.mm.sdk.modelmsg.WXMediaMessage; import com.tencent.mm.sdk.modelmsg.WXTextObject; import com.tencent.mm.sdk.modelpay.PayReq; import com.tencent.mm.sdk.openapi.IWXAPI; import com.tencent.mm.sdk.openapi.WXAPIFactory; /** * 微信支付 */ public class WXPayRequest { private final IWXAPI api; Context mContext; JSONObject mItem = null; // feb4d7b6ad242d966f0d0780eb83b639 // c2f53c437e6f1f26477150510088b724 public WXPayRequest(Context context, JSONObject obj) { mContext = context; api = WXAPIFactory.createWXAPI(mContext, null); api.registerApp(Define_C.APP_ID); mItem = obj; } public void WXPay() { new GetAccessTokenTask().execute(); } private String genPackage(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(Define_C.PARTNER_KEY); // 注意:不能hardcode在客户端,建议genPackage这个过程都由服务器端完成 // 进行md5摘要前,params内容为原始内容,未经过url encode处理 String packageSign = getMessageDigest(sb.toString().getBytes()).toUpperCase(); return URLEncodedUtils.format(params, "utf-8") + "&sign=" + packageSign; } 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; } } // /** // * Appid // */ // public static final String APP_ID = "wx2d3a5e9147827ac9"; // // /** // * 微信公众平台商户模块和商户约定的密钥 // * // * 注意:不能hardcode在客户端,建议genPackage这个过程由服务器端完成 // */ // // private static final String PARTNER_KEY = // "8eafc1f9c81c1fabb7e2d255a546b6e4"; // // /** // * 微信开放平台和商户约定的密钥 // * // * 注意:不能hardcode在客户端,建议genSign这个过程由服务器端完成 // */ // // private static final String APP_SECRET = // "7d824c680093c16fb488ecf94f340ded"; // wxd930ea5d5a258f4f // /** // * 微信开放平台和商户约定的支付密钥 // * // * 注意:不能hardcode在客户端,建议genSign这个过程由服务器端完成(客户端生成) // */ // // private static final String APP_KEY = // "6jpZQmbQKorTReKxJe4EEwvcqqqj4hQFvjPpN8oWFx7j4jdjinDI8BXEaRCChXp6EvdFFW38nTV6OHhMLZlM6E44aPT3sQ0IY1zaa7KgOGRhwnfyMXloqvOxzjZbD3aJ"; // // wxd930ea5d5a258f4f // 对应的支付密钥 // TODO 1 private class GetAccessTokenTask extends AsyncTask<Void, Void, GetAccessTokenResult> { private ProgressDialog dialog; @Override protected void onPreExecute() { dialog = ProgressDialog.show(mContext, "", ""); } @Override protected void onPostExecute(GetAccessTokenResult result) { if (dialog != null) { dialog.dismiss(); } if (result.localRetCode == LocalRetCode.ERR_OK) { GetPrepayIdTask getPrepayId = new GetPrepayIdTask(result.accessToken); getPrepayId.execute(); } else { Toast.makeText(mContext, mContext.getString(R.string.get_access_token_fail, result.localRetCode.name()), Toast.LENGTH_LONG).show(); } } @Override protected GetAccessTokenResult doInBackground(Void... params) { GetAccessTokenResult result = new GetAccessTokenResult(); String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", Define_C.APP_ID, Define_C.APP_SECRET); byte[] buf = WXUtil.httpGet(url); if (buf == null || buf.length == 0) { result.localRetCode = LocalRetCode.ERR_HTTP; return result; } String content = new String(buf); result.parseFrom(content); return result; } } /** * 获得preayid * */ private class GetPrepayIdTask extends AsyncTask<Void, Void, GetPrepayIdResult> { private ProgressDialog dialog; private final String accessToken; public GetPrepayIdTask(String accessToken) { this.accessToken = accessToken; } @Override protected void onPreExecute() { dialog = ProgressDialog.show(mContext, "", ""); } @Override protected GetPrepayIdResult doInBackground(Void... params) { String url = String.format("https://api.weixin.qq.com/pay/genprepay?access_token=%s", accessToken); String entity = genProductArgs(); GetPrepayIdResult result = new GetPrepayIdResult(); /* * Log.e("wxUrl",url); Log.e("wxentiy",entity); */ byte[] buf = WXUtil.httpPost(url, entity); if (buf == null || buf.length == 0) { result.localRetCode = LocalRetCode.ERR_HTTP; return result; } String content = new String(buf); result.parseFrom(content); return result; } @Override protected void onPostExecute(GetPrepayIdResult result) { if (dialog != null) { dialog.dismiss(); } if (result.localRetCode == LocalRetCode.ERR_OK) { sendPayReq(result); } else { Toast.makeText(mContext, mContext.getString(R.string.get_prepayid_fail, result.localRetCode.name()), Toast.LENGTH_LONG).show(); } } @Override protected void onCancelled() { super.onCancelled(); } } private static enum LocalRetCode { ERR_OK, ERR_HTTP, ERR_JSON, ERR_OTHER } /** * AccessToken结果 * * @author Administrator * */ private static class GetAccessTokenResult { private static final String TAG = "MicroMsg.SDKSample.PayActivity.GetAccessTokenResult"; public LocalRetCode localRetCode = LocalRetCode.ERR_OTHER; public String accessToken; public int expiresIn; public int errCode; public String errMsg; public void parseFrom(String content) { if (content == null || content.length() <= 0) { Log.e(TAG, "parseFrom fail, content is null"); localRetCode = LocalRetCode.ERR_JSON; return; } try { JSONObject json = new JSONObject(content); if (json.has("access_token")) { // success case accessToken = json.getString("access_token"); expiresIn = json.getInt("expires_in"); localRetCode = LocalRetCode.ERR_OK; } else { errCode = json.getInt("errcode"); errMsg = json.getString("errmsg"); localRetCode = LocalRetCode.ERR_JSON; } } catch (Exception e) { localRetCode = LocalRetCode.ERR_JSON; } } } /** * PrepayId结果 * * @author Administrator * */ private static class GetPrepayIdResult { private static final String TAG = "MicroMsg.SDKSample.PayActivity.GetPrepayIdResult"; public LocalRetCode localRetCode = LocalRetCode.ERR_OTHER; public String prepayId; public int errCode; public String errMsg; public void parseFrom(String content) { if (content == null || content.length() <= 0) { Log.e(TAG, "parseFrom fail, content is null"); localRetCode = LocalRetCode.ERR_JSON; return; } try { JSONObject json = new JSONObject(content); if (json.has("prepayid")) { // success case prepayId = json.getString("prepayid"); localRetCode = LocalRetCode.ERR_OK; } else { localRetCode = LocalRetCode.ERR_JSON; } errCode = json.getInt("errcode"); errMsg = json.getString("errmsg"); } catch (Exception e) { localRetCode = LocalRetCode.ERR_JSON; } } } private String genNonceStr() { Random random = new Random(); return getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); } private long genTimeStamp() { return System.currentTimeMillis() / 1000; } /** * 建议 traceid 字段包含用户信息及订单信息,方便后续对订单状态的查询和跟踪 */ private String getTraceId() { return "crestxu_" + genTimeStamp(); } /** * 注意:商户系统内部的订单号,32个字符内、可包含字母,确保在商户系统唯一 */ private String genOutTradNo() { Random random = new Random(); return getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); } private long timeStamp; private String nonceStr, packageValue; private String genSign(List<NameValuePair> params) { StringBuilder sb = new StringBuilder(); int i = 0; for (; i < params.size() - 1; i++) { sb.append(params.get(i).getName()); sb.append('='); sb.append(params.get(i).getValue()); sb.append('&'); } sb.append(params.get(i).getName()); sb.append('='); sb.append(params.get(i).getValue()); String sha1 = WXUtil.sha1(sb.toString()); return sha1; } /** * 获得产品参数 * * @return Created by Administrator */ private String genProductArgs() { JSONObject json = new JSONObject(); try { json.put("appid", Define_C.APP_ID); String traceId = getTraceId(); // traceId // 由开发者自定义,可用于订单的查询与跟踪,建议根据支付用户信息生成此id json.put("traceid", traceId); nonceStr = genNonceStr(); json.put("noncestr", nonceStr); float fee = Float.parseFloat(mItem.getString("amount")); String strFee = String.format("%d", (int) (fee * 100)); List<NameValuePair> packageParams = new LinkedList<NameValuePair>(); packageParams.add(new BasicNameValuePair("bank_type", "WX")); packageParams.add(new BasicNameValuePair("body", mItem.getString("pname"))); packageParams.add(new BasicNameValuePair("fee_type", "1")); packageParams.add(new BasicNameValuePair("input_charset", "UTF-8")); packageParams.add(new BasicNameValuePair("notify_url", mItem.getString("notify_url"))); packageParams.add(new BasicNameValuePair("out_trade_no", mItem.getString("trade_no"))); packageParams.add(new BasicNameValuePair("partner", Define_C.PARTNER_ID)); packageParams.add(new BasicNameValuePair("spbill_create_ip", "196.168.1.1")); packageParams.add(new BasicNameValuePair("total_fee", strFee)); packageValue = genPackage(packageParams); json.put("package", packageValue); timeStamp = genTimeStamp(); json.put("timestamp", timeStamp); List<NameValuePair> signParams = new LinkedList<NameValuePair>(); signParams.add(new BasicNameValuePair("appid", Define_C.APP_ID)); // signParams.add(new BasicNameValuePair("appkey", // Define_C.APP_KEY)); signParams.add(new BasicNameValuePair("noncestr", nonceStr)); signParams.add(new BasicNameValuePair("package", packageValue)); signParams.add(new BasicNameValuePair("timestamp", String.valueOf(timeStamp))); signParams.add(new BasicNameValuePair("traceid", traceId)); json.put("app_signature", genSign(signParams)); json.put("sign_method", "sha1"); } catch (Exception e) { return null; } return json.toString(); } /** * 发送支付请求 * * @param result * Created by Administrator */ private void sendPayReq(GetPrepayIdResult result) { PayReq req = new PayReq(); req.appId = Define_C.APP_ID; req.partnerId = Define_C.PARTNER_ID; req.prepayId = result.prepayId; req.nonceStr = nonceStr; req.timeStamp = String.valueOf(timeStamp); req.packageValue = "Sign=" + packageValue; List<NameValuePair> signParams = new LinkedList<NameValuePair>(); signParams.add(new BasicNameValuePair("appid", req.appId)); // signParams.add(new BasicNameValuePair("appkey", Define_C.APP_KEY)); 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 = genSign(signParams); api.sendReq(req); } public void sendmsgReq(String text) { WXTextObject wxTextObject = new WXTextObject(); wxTextObject.text = text; WXMediaMessage mediaMessage = new WXMediaMessage(); mediaMessage.mediaObject = wxTextObject; mediaMessage.description = text; SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = String.valueOf(System.currentTimeMillis()); req.message = mediaMessage; api.sendReq(req); } }