package cn.jeesoft.mvc.action.callbacks;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import cn.jeesoft.core.utils.LogUtils;
import cn.jeesoft.core.utils.ResponseUtils;
import cn.jeesoft.core.utils.StringUtils;
import cn.jeesoft.core.utils.Txt;
import cn.jeesoft.mvc.Config;
import cn.jeesoft.mvc.action.app.BaseTradeAction;
import cn.jeesoft.mvc.bean.BalanceChange;
import cn.jeesoft.mvc.bean.SysTrade;
import cn.jeesoft.mvc.bean.TradeCall;
import cn.jeesoft.mvc.helper.GenerateSN;
import cn.jeesoft.mvc.model.PayType;
import cn.jeesoft.mvc.model.ResultCode;
import cn.jeesoft.mvc.model.TradeState;
import cn.jeesoft.mvc.model.TradeType;
import cn.jeesoft.mvc.outapi.AllinpayHelper;
import cn.jeesoft.mvc.outapi.AllinpayHelper.AllinpayEntity;
import cn.jeesoft.mvc.outapi.CallRechargeHelper;
import cn.jeesoft.mvc.outapi.KklPayHelper;
import cn.jeesoft.mvc.services.TradeBalanceService;
import cn.jeesoft.mvc.services.TradeCallService;
import com.alibaba.fastjson.JSONObject;
/**
* 支付回调
* @author king
*/
@RestController("pay")
@RequestMapping("pay")
public class PayCallbackAction extends BaseTradeAction {
@Autowired
private TradeCallService tradeCallService;
@Autowired
private TradeBalanceService tradeBalanceService;
/**
* 卡卡联支付(NFC支付)
* @param request
* @return
*/
@ResponseBody
@RequestMapping(value="kklpay_nfc_notify")
public String kklpayNfcNotify(HttpServletRequest request) {
return payKklNotify(request, PayType.KKLPAY);
}
/**
* 卡卡联支付(认证支付)
* @param request
* @return
*/
@ResponseBody
@RequestMapping(value="kklpay_auth_notify")
public String kklpayAuthNotify(HttpServletRequest request) {
return payKklNotify(request, PayType.AUTH);
}
/**
* 通联支付
* @param request
* @return
*/
@ResponseBody
@RequestMapping(value="allinpay_normal_notify")
public String allinpayNormalNotify(HttpServletRequest request) {
// 验签是商户为了验证接收到的报文数据确实是支付网关发送的
AllinpayEntity entity = AllinpayHelper.getEntity(request);
LogUtils.logFile(entity.toString());
if (entity.isVerify()) {
// 更新订单支付信息
String sn = entity.getOrderNo();
String orderId = entity.getPaymentOrderId();
//验签成功,还需要判断订单状态,为"1"表示支付成功。
if(entity.isPaySuccess()){
if (payFinish(sn, orderId, PayType.ALLINPAY)) {
return "true";
}
} else {
if (payFail(sn, orderId, PayType.ALLINPAY)) {
return "true";
}
}
}
return "false";
}
/**
* 卡卡联支付回调
* @param request
* @param payType
* @return
*/
private String payKklNotify(HttpServletRequest request, PayType payType) {
// 商户入网代码 支付订单号 交易类型 商户订单ID 交易时间 交易金额
// "merchantCode" "instructCode" "transType" "outOrderId" "transTime" "totalAmount"
// "1000000183" "150515002063" "00200" "356386839588" "20150515170332" 10
JSONObject packet = KklPayHelper.getPacket(request);
String md5Key = Config.KKL_KEY;
Boolean verify = KklPayHelper.verify(packet, md5Key);
if(verify != null && verify) {
// 更新订单支付信息
String sn = packet.getString("outOrderId");
String orderId = packet.getString("instructCode");
//Integer money = packet.getIntValue("totalAmount");
LogUtils.logFile("KKLPay [payType="+payType.getName()+", sn="+sn+", orderId="+orderId+"]");
if (payFinish(sn, orderId, payType)) {
return "{\"code\":\"00\"}";
}
}
return "{\"code\":\"01\",\"msg\":\"verify fail\"}";
}
/**
* 支付失败
* @param sn 系统订单号
* @param paySn 支付订单号
* @param payType 支付方式
* @return
*/
private boolean payFail(String sn, String paySn, PayType payType) {
SysTrade sys = new SysTrade();
sys.setSn(sn);
sys.setState(TradeState.FAILED);
sys.setType(null);
sys.setPaySn(paySn);
sys.setPayType(payType);
sys.setEndTime(new Date());
// 执行更新
int sysUpdate = 0;
try {
sysUpdate = getService().update(sys);
} catch (Exception e) {
}
return sysUpdate > 0;
}
/**
* 支付完成
* @param sn 系统订单号
* @param paySn 支付订单号
* @param payType 支付方式
* @return
*/
private boolean payFinish(String sn, String paySn, PayType payType) {
// 查询该订单
BalanceChange change = new BalanceChange();
change.setSn(sn);
change = tradeBalanceService.selectOne(change);
if (change != null) {
// 更新充值订单为到账
SysTrade sys = new SysTrade();
sys.setSn(sn);
sys = getService().selectOne(sys);
if (sys == null) {
System.out.println("订单号找不到");
} else {
if (sys.getState() == TradeState.SUCCESS) {
// 已处理的订单
return true;
} else {
// 未处理的订单
sys.setState(TradeState.SUCCESS);
sys.setType(null);
sys.setPaySn(paySn);
sys.setPayType(payType);
sys.setEndTime(new Date());
// 执行更新
int sysUpdate = 0;
try {
sysUpdate = getService().finish(sys);
} catch (Exception e) {
}
if (sysUpdate > 0) {
// 为用户充值
// TODO begin 更改余额 应通过 存储过程实现
// 以订单产生的金额为准,可提供付款单号查询实际付款金额,进行人工修正
// change.setMoney(money);
int changeUpdate = tradeBalanceService.update(change);
if (changeUpdate > 0) {
int finish = tradeBalanceService.finish(change.getSn());
System.out.println("更新余额变动状态:"+finish);
// 处理关联账单
boolean handle = handleLinkSn(change.getLinkSn());
if (handle) {
return true;
}
}
// TODO end 更改余额 应通过 存储过程实现
}
}
}
}
return false;
}
/**
* 掉单补单
* @param sysTrade 【sn\paySn\payType】
* @return
*/
@ResponseBody
@RequestMapping(value="restore")
public String restore(SysTrade sysTrade) {
if (StringUtils.isEmpty(sysTrade.getSn())) {
return toFailure(ResultCode.FAILURE, "参数不正确");
}
TradeType type = GenerateSN.get(sysTrade.getSn());
if (StringUtils.isEmpty(type)) {
return toFailure(ResultCode.FAILURE, "参数不正确");
}
switch (type) {
case RECHARGE:
if (payFinish(sysTrade.getSn(), sysTrade.getPaySn(), sysTrade.getPayType())) {
return ResponseUtils.toSuccess();
}
break;
case CALL:
if (handleLinkSn(sysTrade.getSn())) {
return ResponseUtils.toSuccess();
}
break;
}
return ResponseUtils.toFailure(ResultCode.FAILURE, "处理失败");
}
/**
* 处理关联账单
* @param linkSn
* @return
*/
private boolean handleLinkSn(String sn) {
if (StringUtils.isEmpty(sn)) {
return true;
}
boolean isHandle = false;
TradeType type = GenerateSN.get(sn);
switch (type) {
case CALL:
// 话费充值
TradeCall call = new TradeCall();
call.setSn(sn);
call = tradeCallService.selectOne(call);
if (call != null) {
isHandle = CallRechargeHelper.recharge(call.getSn(), call.getCallMoney(), call.getPhone());
// 修改话费充值订单为已支付/充值
SysTrade sys = new SysTrade();
sys.setFromId(call.getFromId());
sys.setMoney(call.getCallMoney());
sys.setFeesMoney(call.getMoney()-call.getCallMoney());
sys.setSn(sn);
sys.setEndTime(new Date());
// sys.setPayType(PayType.BALANCE);
// 修改话费充值订单的状态
if (isHandle) {
// 修改话费充值订单为已充值
sys.setState(TradeState.SUCCESS);
// 执行更新
int sysUpdate = 0;
try {
sysUpdate = getService().finish(sys);
} catch (Exception e) {
}
if (sysUpdate > 0) {
// 发起扣款的订单
BalanceChange change = new BalanceChange();
change.setCreateTime(new Date());
change.setFromId(call.getFromId());
change.setIsAdd(false);
change.setIsArrival(true);
change.setLinkSn(call.getSn());
change.setMoney(call.getMoney());
change.setSn(GenerateSN.create(TradeType.WITHDRAW));
tradeBalanceService.deduct(change);
}
} else {
// 修改话费充值订单为已充值
sys.setState(TradeState.PAYOFF);
// 执行更新
int sysUpdate = 0;
try {
sysUpdate = getService().update(sys);
} catch (Exception e) {
}
}
}
break;
case TRANSFER:
// TODO 转账
break;
case SHOP:
// TODO 购物
break;
case P2P:
// TODO P2P金融
break;
default:
isHandle = false;
break;
}
return isHandle;
}
/**
* 话费充值
* @param request
* @return
*/
@ResponseBody
@RequestMapping(value="recharge_notify")
public String rechargeNotify(HttpServletRequest request) {
String OrderInfo = request.getParameter("Orderinfo");
String Sign = request.getParameter("Sign");
if (!StringUtils.isEmpty(OrderInfo) && !StringUtils.isEmpty(Sign)) {
OrderInfo = StringUtils.toCharset(OrderInfo, "ISO8859-1", "GB2312");
String[] orderArray = Txt.split(OrderInfo, "|");
if (orderArray.length >= 12) {
synchronized (this) {
String sn = orderArray[2];
// boolean isSuccess = "1".equals(orderArray[3]);
// int money = StringUtils.toInt(orderArray[6], 0) / 100;
// Date time = DateUtils.parse(orderArray[10]);
String orderId = orderArray[11];
//
// System.out.println("编号:"+orderSn);
// System.out.println("是否成功:"+isSuccess);
// System.out.println("到账金额:"+money);
// System.out.println("到账时间:"+DateUtils.format(time, "yyyy-MM-dd HH:mm:ss"));
// System.out.println("充值编号:"+orderId);
// 更新数据库
TradeCall call = new TradeCall();
call.setSn(sn);
call.setOrderSn(orderId);
call.setIsArrival(true);
int updateId = tradeCallService.update(call);
if (updateId > 0) {
return "OK";
}
}
}
}
return "ERROR";
}
}