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+"\t"+"数量"+quantity+"\t"+"交易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;

	}

}

  

你可能感兴趣的:(APP)