您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關如何在Android中接入微信支付,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
1、先在微信開放平臺申請開發應用,微信開放平臺會生成APP的唯一標識APPID。由于需要保證支付安全,需要在開放平臺綁定商戶應用包名和應用簽名,設置好后才能正常發起支付。
2、注冊APPID (這個可以放在項目的application里)
商戶APP工程中引入微信JAR包,調用API前,需要先向微信注冊您的APPID,代碼如下:
final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null); // 將該app注冊到微信 msgApi.registerApp("wxd930ea5d5a258f4f");
3、調用統一下單api生成預付單,獲取到prepay_id后將參數再次簽名傳輸給APP發起支付。
例:
下面代碼中的訂單號是需要后臺生成的
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; WXPrePost post = new WXPrePost(); post.appid = "你的appId"; post.mch_id = "你的商戶號"; post.nonce_str = StringUtils.genNonceStr();//隨機字符串 **1 post.body = "商品名稱"; post.detail = "商品的描述"; post.out_trade_no = out_trade_no; //商戶訂單號 **2 post.total_fee = "商品價格";//單位是分 post.spbill_create_ip = getLocalIpAddress();//ip地址 **3 post.notify_url = "";//這里是后臺接受支付結果通知的url地址 post.trade_type = "APP"; post.sign = genPackageSign(post);//簽名 **4 List<NameValuePair> firstSignParams = getFirstSignParams(post); String xml = toXml(firstSignParams); String entity = null; try { entity = new String(xml.getBytes(), "ISO8859-1"); byte[] buf = Util.httpPost(url, entity); if (buf != null) { String content = new String(buf); Map<String, String> map = decodeXml(content); if (map != null) { //再次簽名(參與簽名的字段有 :Appid partnerId prepayId nonceStr TimeStamp package) String appId = ""; String prepayId = ""; String nonceStr = ""; for (Map.Entry<String, String> entry : map.entrySet()) { if ("appid".equals(entry.getKey())) { appId = entry.getValue(); } else if ("prepay_id".equals(entry.getKey())) { prepayId = entry.getValue(); } else if ("nonce_str".equals(entry.getKey())) { nonceStr = entry.getValue(); } } Log.d(TAG, "run: :" + appId + "/" + prepayId + "/" + nonceStr + "/"); String TimeStamp = String.valueOf(genTimeStamp()); //ok 獲取二次簽名 String secondPackageSign = genSecondPackageSign(getSecondSignParams(appId, prepayId, nonceStr, TimeStamp)); PayReq req = new PayReq(); req.appId = appId; req.partnerId = "商戶號"; req.prepayId = prepayId; req.nonceStr = nonceStr; req.timeStamp = TimeStamp; req.packageValue = "Sign=WXPay"; req.sign = secondPackageSign; req.extData = "app data"; // optional // System.out.println("genPackageSign3:"+post.getSign()+"/"+secondPackageSign); // 在支付之前,如果應用沒有注冊到微信,應該先調用IWXMsg.registerApp將應用注冊到微信 mApi.sendReq(req); Log.d(TAG, "run: " + appId + "/" + prepayId + "/" + nonceStr + "/" + TimeStamp + "/" + secondPackageSign); } } } catch (Exception e) { }
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; } }
//獲取隨機字符串的方法 public static String genNonceStr() { Random random = new Random(); return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes()); }
private 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>"); return sb.toString(); }
public Map<String, String> decodeXml(String content) { try { Map<String, String> xml = new HashMap<>(); 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)) { xml.put(nodeName, parser.nextText()); } break; case XmlPullParser.END_TAG: break; } event = parser.next(); } return xml; } catch (Exception e) { } return null; }
@NonNull private List<NameValuePair> getFirstSignParams(WXPrePost params) { List<NameValuePair> packageParams = new LinkedList<>(); packageParams.add(new BasicNameValuePair("appid", "appId")); packageParams.add(new BasicNameValuePair("body", params.body)); packageParams.add(new BasicNameValuePair("detail", params.detail)); packageParams.add(new BasicNameValuePair("mch_id", "商戶號")); packageParams.add(new BasicNameValuePair("nonce_str", params.nonce_str)); packageParams.add(new BasicNameValuePair("notify_url", params.notify_url)); packageParams.add(new BasicNameValuePair("out_trade_no", params.out_trade_no)); packageParams.add(new BasicNameValuePair("spbill_create_ip", params.spbill_create_ip)); packageParams.add(new BasicNameValuePair("total_fee", params.total_fee + "")); packageParams.add(new BasicNameValuePair("trade_type", params.trade_type)); packageParams.add(new BasicNameValuePair("sign", params.sign)); return packageParams; }
public class WXPrePost { //必須帶的參數 public String appid; //微信開放平臺審核通過的應用APPID public String mch_id; //微信支付分配的商戶號 public String nonce_str; //隨機字符串,不長于32位。推薦隨機數生成算法 public String sign; //簽名,詳見簽名生成算法 public String body; // 商品描述交易字段格式根據不同的應用場景按照以下格式:APP——需傳入應用市場上的APP名字-實際商品名稱,天天愛消除-游戲充值。 public String out_trade_no; // 商戶系統內部的訂單號,32個字符內、可包含字母, 其他說明見商戶訂單號 public int total_fee; // 訂單總金額,單位為分,詳見支付金額 public String spbill_create_ip; // 用戶端實際ip public String notify_url; // 接收微信支付異步通知回調地址,通知url必須為直接可訪問的url,不能攜帶參數。(后臺提供的) public String trade_type; // 支付類型 // 非必須攜帶的參數 public String device_info; // 終端設備號(門店號或收銀設備ID),默認請傳"WEB" public String detail; // 商品名稱明細列表 public String attach; // 附加數據,在查詢API和支付通知中原樣返回,該字段主要用于商戶攜帶訂單的自定義數據 public String fee_type; // 符合ISO 4217標準的三位字母代碼,默認人民幣:CNY,其他值列表詳見貨幣類型 // public String time_start; // 訂單生成時間,格式為yyyyMMddHHmmss,如2009年12月25日9點10分10秒表示為20091225091010。其他詳見時間規則 // public String time_expire; // 訂單失效時間,格式為yyyyMMddHHmmss,如2009年12月27日9點10分10秒表示為20091227091010。其他詳見時間規則 注意:最短失效時間間隔必須大于5分鐘 public String goods_tag; // 商品標記,代金券或立減優惠功能的參數,說明詳見代金券或立減優惠 // public String limit_pay; //no_credit--指定不能使用信用卡支付 public String getAppid() { return appid; } public void setAppid(String appid) { this.appid = appid; } public String getMch_id() { return mch_id; } public void setMch_id(String mch_id) { this.mch_id = mch_id; } public String getNonce_str() { return nonce_str; } public void setNonce_str(String nonce_str) { this.nonce_str = nonce_str; } public String getSign() { return sign; } public void setSign(String sign) { this.sign = sign; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getOut_trade_no() { return out_trade_no; } public void setOut_trade_no(String out_trade_no) { this.out_trade_no = out_trade_no; } public int getTotal_fee() { return total_fee; } public void setTotal_fee(int total_fee) { this.total_fee = total_fee; } public String getSpbill_create_ip() { return spbill_create_ip; } public void setSpbill_create_ip(String spbill_create_ip) { this.spbill_create_ip = spbill_create_ip; } public String getNotify_url() { return notify_url; } public void setNotify_url(String notify_url) { this.notify_url = notify_url; } public String getTrade_type() { return trade_type; } public void setTrade_type(String trade_type) { this.trade_type = trade_type; } public String getDevice_info() { return device_info; } public void setDevice_info(String device_info) { this.device_info = device_info; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } public String getAttach() { return attach; } public void setAttach(String attach) { this.attach = attach; } public String getFee_type() { return fee_type; } public void setFee_type(String fee_type) { this.fee_type = fee_type; } public String getTime_start() { return time_start; } public void setTime_start(String time_start) { this.time_start = time_start; } public String getTime_expire() { return time_expire; } public void setTime_expire(String time_expire) { this.time_expire = time_expire; } public String getGoods_tag() { return goods_tag; } public void setGoods_tag(String goods_tag) { this.goods_tag = goods_tag; } public String getLimit_pay() { return limit_pay; } public void setLimit_pay(String limit_pay) { this.limit_pay = limit_pay; } }
這里給出的參數都是可以移動端自己獲取到的,當然,最好是后臺提供給我們,出于安全性考慮
支付完成,微信會回調WXPayEntryActivity,這里就不詳細說了,微信文檔說的很清晰
在WXPayEntryActivity的onResp()里面返回的微信支付的結果(注:這個結果不能作為我們購買商品成功與否的結果,要以微信回調給回臺,然后回臺告訴我們的支付結果為準)
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { int code = resp.errCode; switch (code) { case 0: Log.d(TAG, "onPayFinish, errCode = " + "支付成功"); //微信支付成功后去調后臺,以后臺返回的支付結果為準 //這里是微信支付完成后的回調,在這里請求后臺,讓他來告訴我們到底支付成功沒。 break; case -1: Toast.makeText(this, "支付失敗1", Toast.LENGTH_SHORT).show(); Log.d(TAG, "onPayFinish, errCode = " + "支付失敗1"); finish(); break; case -2: Toast.makeText(this, "支付取消", Toast.LENGTH_SHORT).show(); Log.d(TAG, "onPayFinish, errCode = " + "支付取消"); finish(); break; default: // Toast.makeText(this, "支付失敗2", Toast.LENGTH_SHORT).show(); Log.d(TAG, "onPayFinish, errCode = " + "支付失敗2"); setResult(RESULT_OK); finish(); break; } }
Android是一種基于Linux內核的自由及開放源代碼的操作系統,主要使用于移動設備,如智能手機和平板電腦,由美國Google公司和開放手機聯盟領導及開發。
上述就是小編為大家分享的如何在Android中接入微信支付了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。