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;
}
}

  

In-App Purchases验证的更多相关文章

  1. 安卓APP测试验证点总结

    最近较懒,加之闺女出生后记忆没完全恢复,总是忘东忘西,关于安卓APP测试的验证点还是总结一下,方便设计测试用例时查阅,也给各位博友参考! 1.除APP的正常功能点外,还有以下验证点: 安装/卸载(考虑 ...

  2. In App Purchases(IAP 应用程序內购买): 完全攻略

    原文: http://troybrant.net/blog/2010/01/in-app-purchases-a-full-walkthrough/ 参考: http://www.cocoachina ...

  3. in App Purchases一个注意事项

    在completeTransaction中通过transaction.originalTransaction.payment.productIdentifier得到的productIdentifier ...

  4. [IPA]IOS In App Purchase(内购)验证

    参考我之前的笔记 苹果内购笔记,在客户端向苹果购买成功之后,我们需要进行二次验证. 二次验证 IOS在沙箱环境下购买成功之后,向苹果进行二次验证,确认用户是否购买成功. 当应用向Apple服务器请求购 ...

  5. 苹果开发——App内购以及验证store的收据(二)

    原地址:http://zengwu3915.blog.163.com/blog/static/2783489720137605156966?suggestedreading 三. 客户端使用Store ...

  6. ris'In App Purchase总结

    原地址:http://www.cocoachina.com/bbs/read.php?tid=38555&page=1 In App Purchase属于iPhone SDK3.0的新特性,用 ...

  7. In App Purchase翻译

    一.In App Purchase概览 Store Kit代表App和App Store之间进行通信.程序将从App Store接收那些你想要提供的产品的信息,并将它们显示出来供用户购买.当用户需要购 ...

  8. App Store内购

    一.In App Purchase概览 Store Kit代表App和App Store之间进行通信.程序将从App Store接收那些你想要提供的产品的信息,并将它们显示出来供用户购买.当用户需要购 ...

  9. AppStore苹果应用支付开发(In App Purchase)翻译

    http://yarin.blog.51cto.com/1130898/549141 一.In App Purchase概览 Store Kit代表App和App Store之间进行通信.程序将从Ap ...

随机推荐

  1. struts2升级报ActionContextCleanUp<<is deprecated。Please use the new filters

    把web.xml中配置struts.xml的文件改成 <?xml version="1.0" encoding="UTF-8"?> <web- ...

  2. NServiceBus 结合 RabbitMQ 使用

    参考官方教程: Step by Step Guide 新建4个项目: A Console Application named Client A Console Application named Se ...

  3. hdu1828 线段树+离散化+扫描线

    添加lb[],rb[]数组,来标记竖边.添加num,来计算竖边的个数,因为计算周长的时候,未覆盖的竖边都要加. #include<stdio.h> #include<stdlib.h ...

  4. 缓存插件 EHCache 对象缓存(Spring)

    对象缓存就是将查询的数据,添加到缓存中,下次再次查询的时候直接从缓存中获取,而不去数据库中查询. 对象缓存一般是针对方法.类而来的,结合Spring的Aop对象.方法缓存就很简单.这里需要用到切面编程 ...

  5. Struts2的使用以及Spring整合Struts2

    一.如何单独使用Struts2 (1)引入struts2的jar包 commons-fileupload-1.2.1.jar freemarker-2.3.15.jar ognl-2.7.3.jar ...

  6. BZOJ-1975 魔法猪学院 K短路 (A*+SPFA)

    1975: [Sdoi2010]魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MB Submit: 1323 Solved: 433 [Submit][Statu ...

  7. 洛谷P1121 环状最大两段子段和

    题目描述 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 输入文件maxsum2.in的第一行是一个正整数N,表示了序列 ...

  8. linux 下用户管理

    linux 下用户管理 一.用户的分类 1.超级用户:root UID=0 2.系统用户:不需要登录系统,对应用程序服务,主要维护系统的正常运行:UID = 1 ~ 499(RHEL7 = 1 ~ 9 ...

  9. Java中数据类型转换问题

    boolean类型不可以转换为替他的数据类型. Java中byte(8位).short(16位).char三种类型的优先级是相同的,相同优先级之间是不能进行自动转换的(如果相互转换的话,必须强制类型转 ...

  10. U盘中的autorun.inf

    怎么删除u盘里的autorun.inf 如果U盘中毒,刚插进机子时按住SHIFT五秒,这样就可以跳过预读,这样防止了预读时把病毒感染到机子上,在U盘盘符上点右键,看看有没有“Auto”选项: 1.如果 ...