• In-App Purchases验证


    package com.demo.controller.web.app;
    
    import java.io.BufferedOutputStream;
    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.URL;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Locale;
    import java.util.Map;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.log4j.Logger;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import sun.misc.BASE64Decoder;
    
    import com.demo.common.Result;
    import com.demo.common.util.StringUtils;
    import com.demo.constant.Constant;
    import com.demo.constant.Enums;
    import com.demo.service.AppEspOrderService;
    import com.demo.service.AppEspProductService;
    import com.demo.service.AppUserInfoService;
    import com.demo.service.AppVersionService;
    import com.demo.service.UserService;
    import com.demo.service.eshop.EspOrderLogService;
    import com.demo.vo.AppEspOrder;
    import com.demo.vo.AppEspProduct;
    import com.demo.vo.AppUserInfo;
    import com.demo.vo.AppVersion;
    import com.demo.vo.EspOrderLog;
    import com.demo.vo.User;
    
    import net.sf.json.JSONObject;
    
    @Controller
    @RequestMapping("/app/*")
    public class AstroCalendarIOSVerifyController {
    	private Logger log = Logger.getLogger(AstroCalendarIOSVerifyController.class);
    	@Autowired
    	private UserService userService;
    	@Autowired
    	private AppEspOrderService appEspOrderService;
    	@Autowired
    	private AppVersionService appVersionService;
    	@Autowired
    	private AppEspProductService appEspProductService;	
    	@Autowired
    	private AppUserInfoService appUserInfoService;
    	@Autowired
    	private EspOrderLogService espOrderLogService;
    
    	private static class TrustAnyTrustManager implements X509TrustManager {
    
    		public void checkClientTrusted(X509Certificate[] chain, String authType)
    				throws CertificateException {
    		}
    
    		public void checkServerTrusted(X509Certificate[] chain, String authType)
    				throws CertificateException {
    		}
    
    		public X509Certificate[] getAcceptedIssuers() {
    			return new X509Certificate[] {};
    		}
    	}
    
    	private static class TrustAnyHostnameVerifier implements HostnameVerifier {
    		public boolean verify(String hostname, SSLSession session) {
    			return true;
    		}
    	}
    
    	private static final String url_sandbox = "https://sandbox.itunes.apple.com/verifyReceipt";
    	private static final String url_verify = "https://buy.itunes.apple.com/verifyReceipt";
    
    	/**
    	 * 
    	 * @param receipt	账单
    	 * @url 要验证的地址
    	 * @return null 或返回结果 沙盒 https://sandbox.itunes.apple.com/verifyReceipt
    	 * 
    	 */
    	public String buyAppVerify(String receipt,String url,Map<String, String> map) {
    		try {
    			SSLContext sc = SSLContext.getInstance("SSL");
    			sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },new java.security.SecureRandom());
    			URL console = new URL(url);
    			HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
    			conn.setSSLSocketFactory(sc.getSocketFactory());
    			conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
    			conn.setRequestMethod("POST");
    			conn.setRequestProperty("content-type", "text/json");
    			conn.setRequestProperty("Proxy-Connection", "Keep-Alive");
    			conn.setDoInput(true);
    			conn.setDoOutput(true);
    			conn.setConnectTimeout(30*1000);//设置连接超时30秒
    			BufferedOutputStream hurlBufOus = new BufferedOutputStream(conn.getOutputStream());
    
    			String str = String.format(Locale.CHINA, "{"receipt-data":""+ receipt + ""}");
    			System.out.println("str:" + str);
    			hurlBufOus.write(str.getBytes());
    			hurlBufOus.flush();
    
    			InputStream is = conn.getInputStream();
    			BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    			String line = null;
    			StringBuffer sb = new StringBuffer();
    			while ((line = reader.readLine()) != null) {
    				sb.append(line);
    			}
    			System.out.println(sb.toString());
    			return sb.toString();
    		} catch (Exception ex) {
    			log.error("系统异常"+ex);
    			map.put("orderStatus", "D");
    //			ex.printStackTrace();
    		}
    		return null;
    	}
    
    	@RequestMapping("/app/validateOrder" + Constant.JSON)
    	@ResponseBody
    	public Map<String, String> validateOrder(HttpServletRequest request) {
    		long start = System.currentTimeMillis();
    		Map<String, String> map = new HashMap<String, String>();
    		User user = checkUserLogin(request);
    		AppUserInfo appUser = null;
    		if(user!=null){
    			appUser = new AppUserInfo();
    			appUser.setUserId(user.getUserId());
    			appUser = appUserInfoService.findByPk(appUser);
    		}
    		//判断app用户表里是否存在此用户
    		if(appUser == null){
    			map.put("loginStatus", "-1");
    		}else{
    			map.put("loginStatus", "0");
    			try {
    				String receipt = request.getParameter("receipt");
    				String orderMonths = request.getParameter("orderMonths");
    				String versionCode = request.getParameter("versionCode");
    				String appId = request.getParameter("appId");
    				String price = request.getParameter("price");
    				if(StringUtils.isBlank(appId) || StringUtils.isBlank(versionCode)){
    					map.put("orderStatus", "D");
    					return map;
    				}
    				Integer vCode = Integer.parseInt(versionCode);
    				Integer appID = Integer.parseInt(appId);
    				
    				AppEspOrder aeo = new AppEspOrder();
    				aeo.setReceipt(receipt);
    				List<AppEspOrder> list = appEspOrderService.freeFindAll(aeo);
    				if(list.size()==0){
    					//添加新订单
    					AppUserInfo aui = new AppUserInfo();
    					aui.setUserId(user.getUserId());
    					aui = appUserInfoService.findByPk(aui);
    					SimpleDateFormat osf = new SimpleDateFormat("yyMMddHH");
    					String orderId = Enums.OrderPrefix.NA + osf.format(new Date())+ StringUtils.getRandomSixNUM();
    					if(aui != null){
    						AppVersion version = new AppVersion();
    						version.setVersionCode(vCode);
    						int count = appVersionService.countFreeFind(version);
    						
    						AppEspProduct aep = new AppEspProduct();
    						aep.setAppId(appID);
    						aep = appEspProductService.findByPK(aep);
    						//检查appID,versionId是否合法
    						if(aep == null || count<0){
    							map.put("orderStatus", "C");
    							return map;
    						}
    						aeo.setAppId(aep.getAppId());
    						aeo.setAppName(aep.getAppName());
    						aeo.setVersionCode(vCode);
    						aeo.setUserId(aui.getUserId());
    						aeo.setNickName(aui.getNickName());
    						aeo.setEmail(aui.getEmail());
    						aeo.setOrderId(orderId);
    						aeo.setOrderMonths(orderMonths);
    						aeo.setSubtotal(new Long(price));
    						aeo.setIsFree("N");
    						aeo.setOrderStatus("A");//新订单
    						aeo.setCreateBy("system");
    						aeo.setCreateDt(new Date());
    						aeo.setPaidDate(new Date());
    						appEspOrderService.insert(aeo);
    						
    						//订单日志
    						EspOrderLog log = new EspOrderLog();
    						log.setRemark("生成新订单,已支付,等待验证...");
    						log.setChangeTime(new Date());
    						log.setChangeUser("system");
    						log.setIsMem("N");
    						log.setType("A");
    						log.setOrderId(orderId);
    						espOrderLogService.addOrderLog(log);
    					}
    					//向苹果服务器发起验证
    					Result result = validateAppleServler(map, receipt, url_verify, aeo, orderId);
    					if(result.isSuccess()==true){
    						validateAppleServler(map, receipt, url_sandbox, aeo, orderId);
    					}
    				}else{//如果该收据已经存在,判断收据的订单状态,再判断是用户及月份是否相同,防止盗用receipt
    					AppEspOrder order = list.get(0);
    					if("A".equals(order.getOrderStatus()) || "D".equals(order.getOrderStatus())){//新订单已经添加尚未验证或验证超时连接错误,需重新请求验证
    						Result result = validateAppleServler(map, order.getReceipt(), url_verify, order, order.getOrderId());
    						if(result.isSuccess()==true){
    							validateAppleServler(map, order.getReceipt(), url_sandbox, order, order.getOrderId());
    						}
    					}else if("B".equals(order.getOrderStatus())){
    						if(receipt.equals(order.getReceipt())&&user.getUserId().equals(order.getUserId())&&orderMonths.equals(order.getOrderMonths())){
    							map.put("orderStatus", "B");
    						}else{
    							map.put("orderStatus", "C");//验证失败
    						}
    					}else{
    						map.put("orderStatus", "C");//验证失败
    					}
    					}
    			} catch (Exception e) {
    				map.put("orderStatus", "D");
    				log.error("系统异常"+e);
    				e.printStackTrace();
    			}
    			}
    		long end = System.currentTimeMillis();
    		System.out.println("验证收据信息耗时:"+(end-start)+"毫秒");
    		return map;
    	}
    	//向苹果服务器发送验证请求
    	private Result validateAppleServler(Map<String, String> map, String receipt, String url, AppEspOrder aeo, String orderId) {
    		Result result = new Result().setSuccess(false);
    		String verifyResult = buyAppVerify(receipt,url,map);
    		if (verifyResult != null) {
    			JSONObject job = JSONObject.fromObject(verifyResult);
    			String status = job.getString("status");
    			if ("0".equals(status)){// 验证成功
    				aeo.setOrderStatus("B");
    				
    				String r_receipt=job.getString("receipt");  
    				System.out.println(r_receipt);
    				System.out.println("-------------------------------");
                    JSONObject returnJson = JSONObject.fromObject(r_receipt);  
                    String product_id = returnJson.getString("product_id");  //产品ID  
                    String quantity = returnJson.getString("quantity"); //数量  
                    String transactionId = returnJson.getString("transaction_id");//交易id
    				System.out.println("产品id:"+product_id+"	"+"数量"+quantity+"	"+"交易id"+transactionId);
    				aeo.setProductId(product_id);
    				int total = 0;
    				if(!StringUtils.isBlank(quantity))
    					total = Integer.parseInt(quantity);
    				aeo.setQuantity(total);
    				aeo.setTransactionId(transactionId);
    				appEspOrderService.update(aeo);
    				
    				EspOrderLog log2 = new EspOrderLog();
    				log2.setRemark("向苹果服务器发送验证成功...");
    				log2.setChangeTime(new Date());
    				log2.setChangeUser("system");
    				log2.setIsMem("N");
    				log2.setType("B");
    				log2.setOrderId(orderId);
    				espOrderLogService.addOrderLog(log2);
    				map.put("orderStatus", "B");
    			}else if("21007".equals(status)){//重新验证,更改路径为正式环境的路径
    				
    				EspOrderLog log1 = new EspOrderLog();
    				log1.setRemark("向苹果正式服务器发送验证失败,得到状态值为21007.");
    				log1.setChangeTime(new Date());
    				log1.setChangeUser("system");
    				log1.setIsMem("N");
    				log1.setType("A");
    				log1.setOrderId(orderId);
    				espOrderLogService.addOrderLog(log1);
    				result.setSuccess(true);
    			}else{//验证失败
    				aeo.setOrderStatus("C");
    				appEspOrderService.update(aeo);
    				
    				EspOrderLog log1 = new EspOrderLog();
    				log1.setRemark("向苹果服务器发送验证失败...");
    				log1.setChangeTime(new Date());
    				log1.setChangeUser("system");
    				log1.setIsMem("N");
    				log1.setType("A");
    				log1.setOrderId(orderId);
    				espOrderLogService.addOrderLog(log1);
    				map.put("orderStatus", "C");
    			}
    		}
    		return result;
    	}
    	private User checkUserLogin(HttpServletRequest request) {
    		String username = request.getParameter("username");
    		String password = request.getParameter("password");
    		if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
    			return null;
    		}
    		User user = new User();
    		try {
    			user.setEmail(username);
    			user.setPassword(password);
    			user = userService.userLogin(user);
    
    		} catch (Exception e) {
    			log.error("登录失败,用户名或密码错误!" + e);
    		}
    		return user;
    	}
    }
    

      

  • 相关阅读:
    [原创]Acronis True Image使用手记
    毕业日志
    我的L6修好了
    三峡实习记之二
    初到华南理工印象
    三峡实习记之三
    SHOW毕业衫
    自己的第一次装机
    iOS Tools
    [转] A few things iOS developers ought to know about the ARM architecture
  • 原文地址:https://www.cnblogs.com/youngjoy/p/4681554.html
Copyright © 2020-2023  润新知