ios支付比普通的支付要麻煩許多,由於要走內購,並且像支付寶,微信那種還能夠給回調,Apple PAY根被不會回調啊,因此要麼找第三方的支付平臺,要麼自行接入,本篇是直接接入的,applepay的支付手續費是總金額的30%,因此業務邏輯要自行改變。java
流程是這樣的:ios
1,IOS傳過來的參數通過非空校驗及驗證碼重複校驗後先要判斷驗證碼的重複,驗證碼是手機端向apple請求後,apple返回的data通過MD5加密存庫,留個備份,每次驗證的時候判斷一下重複。web
2.向apple請求,參數是地址,IOS的data,訂單ID,換取status,bid,productId,訂單ID微信
public static Map verifyReceipt(String reqUrl, String receiptDataJson, String appTransactionId) throws Exception{ reqUrl=https://buy.itunes.apple.com/verifyReceipt int status = -1; String bid = ""; String productId = ""; String transactionId = ""; //This is the URL of the REST webservice in iTunes App Store URL url = new URL(reqUrl); //make connection, use post mode HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setDoOutput(true); connection.setAllowUserInteraction(false); //Write the JSON query object to the connection output stream PrintStream ps = new PrintStream(connection.getOutputStream()); ps.print(receiptDataJson); ps.close(); //Call the service BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream())); //Extract response String str; StringBuffer sb = new StringBuffer(); while ((str = br.readLine()) != null) { sb.append(str); } br.close(); String response = sb.toString(); //System.out.println("AppleAppStoreVerifyRequest----response:"+response); JSONObject resutl = JSON.parseObject(response); status = resutl.containsKey("status") ? resutl.getInteger("status") : status; JSONObject receipt = resutl.containsKey("receipt") ? resutl.getJSONObject("receipt") : null; if(receipt != null && !StringUtils.isBlank(receipt.toString())){ bid = receipt.containsKey("bundle_id") ? receipt.getString("bundle_id") : bid; JSONArray inApp = receipt.getJSONArray("in_app"); if(inApp != null && !StringUtils.isBlank(inApp.toString())) { if(StringUtils.isBlank(appTransactionId)) { //若是未給訂單號,則默認獲取第一個 JSONObject inAppJSONObjectTemp = inApp.getJSONObject(0); if (inAppJSONObjectTemp != null && !inAppJSONObjectTemp.isEmpty()) { productId = inAppJSONObjectTemp.containsKey("product_id") ? inAppJSONObjectTemp.getString("product_id") : productId; transactionId = inAppJSONObjectTemp.containsKey("transaction_id") ? inAppJSONObjectTemp.getString("transaction_id") : transactionId; } } else { //若是APP已給定訂單號時用訂單號進行查找 for(int i=0; i<inApp.size(); i++) { JSONObject inAppJSONObjectTemp = inApp.getJSONObject(i); if (inAppJSONObjectTemp != null && !inAppJSONObjectTemp.isEmpty()) { String transactionIdTemp = inAppJSONObjectTemp.containsKey("transaction_id") ? inAppJSONObjectTemp.getString("transaction_id") : transactionId; if(appTransactionId.equals(transactionIdTemp)) { productId = inAppJSONObjectTemp.containsKey("product_id") ? inAppJSONObjectTemp.getString("product_id") : productId; transactionId = transactionIdTemp; } } } } } } Map resMap = new HashMap(); resMap.put("status",status); resMap.put("bid",bid); resMap.put("productId",productId); resMap.put("transactionId",transactionId); resMap.put("resutl",resutl == null ?"":resutl.toJSONString()); return resMap; }
3.而後去驗證返回的status是否合法:app
int resultStauts = Integer.valueOf(String.valueOf(verifyMap.get("status"))); if (resultStauts == 21007) { //本次支付爲沙盒支付 if (!"165".equals(thridPartyNotifyVo.getUserId())) { //非蘋果審批帳號 沙盒進行充值不進行飯票增長 return false; } }
判斷bid,productId是否合法,這一步必定要驗,要不會出現替換充值的bug:post
String bid = String.valueOf(verifyMap.get("bid")); String productId = String.valueOf(verifyMap.get("productId")); transactionId = String.valueOf(verifyMap.get("transactionId")); if(!"申請的bid".equals(bid)) {//蘋果內購支付使用的iPhone程序的bundle標識是否合法 return false } if(StringUtils.isBlank(productId) || StringUtils.isBlank(transactionId)) { //是否返回商品信息 return false }
4.最後進行下面的業務邏輯,更餘額,把加密好的data存庫留底,改狀態。加密
注意:productID必定要給IOS,並且不能對錯,6元的商品對應com.starunion.xxxxxx_Purchase_6Yuan.url
去IOS請求後的bid,必定要驗。由於不是IOS給的回調驗證必定要當心謹慎,code