package com.lanecard.shop.data.api.v2.trade;
import java.io.File;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.ibm.icu.text.SimpleDateFormat;
import com.lanecard.common.PayOnlineConstants;
import com.lanecard.dao.entity.trade.TradeOrder;
import com.lanecard.dao.entity.trade.TradeOrderPayment;
import com.lanecard.dao.vo.TradeOrderPayStatus;
import com.lanecard.dao.vo.TradeOrderPayType;
import com.lanecard.dao.vo.TradeOrderWXPayStatus;
import com.lanecard.exception.AppException;
import com.lanecard.shop.data.api.error.ErrorUtil;
import com.lanecard.shop.data.api.error.Errors;
import com.lanecard.shop.data.api.v2.BaseApi;
import com.lanecard.shop.service.trade.TradeOrderPaymentService;
import com.lanecard.shop.service.trade.TradeOrderService;
import com.lanecard.taglib.util.BrowserUtils;
import com.lanecard.util.alipay.AlipayCore;
import com.lanecard.util.alipay.AlipayPayNotify;
import com.lanecard.util.alipay.AlipayRefundNotify;
import com.lanecard.util.alipay.AlipaySubmit;
import com.lanecard.util.alipay.RSA;
import com.lanecard.util.tenpay.TenpayHttpClientUtil;
import com.lanecard.util.tenpay.WXUtil;
import com.lanecard.util.tenpay.XMLUtil;
@Controller
@RequestMapping(BaseApi.URI_PREFIX_V2 + “/playOnline”)
public class PayOnlineApi extends BaseApi {
static final Logger log = Logger.getLogger(PayOnlineApi.class);
@Autowired
private TradeOrderService tradeOrderservice;
@Autowired
private TradeOrderPaymentService tradeOrderPaymentService;
//**************************************微信支付*****************************************
/*
微信在线支付 生成 预支付ID
除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再按扫码、JSAPI、APP等
* 有用非必传参数 设备号:device_info 》 APP
* 商品详情:detail 》 商品名称明细列表
* 附加数据:attach 自定义信息
* 交易起始时间:time_start 》 20091225091010
* 交易结束时间:time_expire 》 20091227091010 最短失效时间间隔必须大于5分钟
* 商品标记:goods_tag 商品标记,代金券或立减优惠功能的参数
*/
@RequestMapping("/tenpay/prepaid")
public ModelAndView tenpayPrepaid(String orderId,HttpServletRequest request) throws AppException, IOException{
ModelAndView model = new ModelAndView();
//通过订单号获取订单信息
TradeOrder tradeOrder = tradeOrderservice.getById(orderId);
if(tradeOrder!=null){
boolean b = true;
//首先检查此订单是否支付过和支付状态
TradeOrderPayment checktopay= tradeOrderPaymentService.selectByOrderId(orderId);
if(checktopay!=null){//此订单调用过支付 调用查询接口查看支付状态
//调用查询方法
Map<String,String> map = wzQuery(orderId);
String resultCode = map.get("resultCode");
if("ERROR".equals(resultCode)){//订单查询失败
b = false;
String message = map.get("message");
ErrorUtil.fill(model, Errors.ERR_GLOBAL_500, message);
}else{
String tradeState = map.get("tradeState");//获取订单在微信端状态
//支付成功或者退款中 说明逻辑错误
if(TradeOrderWXPayStatus.SUCCESS.name().equals("tradeState") || TradeOrderWXPayStatus.REFUND.name().equals("tradeState")){
b = false;
ErrorUtil.fill(model, Errors.ERR_GLOBAL_500, "订单已支付成功或者退款中");
}else{//还有4种情况 需要调用关单接口
//调用关单方法
map = wzClose(orderId);
resultCode = map.get("resultCode");
if("ERROR".equals(resultCode)){//订单关单失败
b = false;
String message = map.get("message");
ErrorUtil.fill(model, Errors.ERR_GLOBAL_500, message);
}else{
//关单成功 修改支付表支付状态
TradeOrderPayment tradeOrderPayment = new TradeOrderPayment();
tradeOrderPayment.setOrderId(orderId);
tradeOrderPayment.setStatus(TradeOrderPayStatus.C.name());
tradeOrderPaymentService.save(tradeOrderPayment);
}
}
}
}
if(b){
//在在线支付表trade_order_payment 生成支付记录
insertTradeOrderPayment(TradeOrderPayType.W.name(),tradeOrder);
//调用生成预支付id方法
Map<String,String> map = createPrepayId(tradeOrder, request);
String resultCode = map.get("resultCode");
if("ERROR".equals(resultCode)){//生成预支付订单失败
String message = map.get("message");
ErrorUtil.fill(model, Errors.ERR_GLOBAL_500, message);
}else{
String prepayId = map.get("prepayId");
//为app准备 支付参数
attr(model, "data", prepareParmaForApp(prepayId));
}
}
}else{
log.warn("【生成预支付id失败,订单不存在,订单号="+orderId+"】");
ErrorUtil.fill(model, Errors.ERR_ORDER_NOT_EXIST);
}
return model;
}
/*
微信查询订单
该接口提供所有微信支付订单的查询,商户可以通过该接口主动查询订单状态,完成下一步的业务逻辑。
需要调用查询接口的情况:
◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
◆ 调用支付接口后,返回系统错误或未知交易状态情况;
◆ 调用关单或撤销接口API之前,需确认支付状态;
*/
@RequestMapping("/tenpay/query")
public ModelAndV