From fcd07f15a98ddd8c380e41f58be2a0a42476a47b Mon Sep 17 00:00:00 2001 From: yangkai Date: Mon, 17 Dec 2018 20:30:14 +0800 Subject: [PATCH] init coupon processors --- .../mappers/log/CouponAccuessLogMapper.java | 8 + .../CtripCouponOnlyLogProcessor.java | 194 +++++++++++++ .../CtripCouponProvideProcessor.java | 266 ++++++++++++++++++ 3 files changed, 468 insertions(+) create mode 100644 src/main/java/au/com/royalpay/payment/manage/processors/CtripCouponOnlyLogProcessor.java create mode 100644 src/main/java/au/com/royalpay/payment/manage/processors/CtripCouponProvideProcessor.java diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/log/CouponAccuessLogMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/log/CouponAccuessLogMapper.java index 8f62c7c2b..cb60bf3df 100644 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/log/CouponAccuessLogMapper.java +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/log/CouponAccuessLogMapper.java @@ -30,4 +30,12 @@ public interface CouponAccuessLogMapper { List findCouponByOrderId(@Param("order_id") String order_id); PageList getCouponAccuessLog(@Param("client_id")int client_id, @Param("keyword")String keyword, PageBounds pageBounds); + + @AutoSql(type = SqlType.SELECT) + @AdvanceSelect(addonWhereClause = "is_valid = 0") + List findAccuessLogByOrderId(@Param("order_id") String order_id, PageBounds pageBounds); + + @AutoSql(type = SqlType.SELECT) + @AdvanceSelect(addonWhereClause = "is_valid = 1") + List findUsedCouponByOrderIdList(@Param("order_id") String order_id); } diff --git a/src/main/java/au/com/royalpay/payment/manage/processors/CtripCouponOnlyLogProcessor.java b/src/main/java/au/com/royalpay/payment/manage/processors/CtripCouponOnlyLogProcessor.java new file mode 100644 index 000000000..c11c56ba5 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/processors/CtripCouponOnlyLogProcessor.java @@ -0,0 +1,194 @@ +package au.com.royalpay.payment.manage.processors; + +import au.com.royalpay.payment.core.PaymentApi; +import au.com.royalpay.payment.core.beans.PreOrderRequest; +import au.com.royalpay.payment.core.beans.coupon.CouponInfo; +import au.com.royalpay.payment.core.events.PaymentFinishedEvent; +import au.com.royalpay.payment.core.events.RefundSendEvent; +import au.com.royalpay.payment.core.processors.PaymentProcessor; +import au.com.royalpay.payment.manage.mappers.log.CouponAccuessLogMapper; +import au.com.royalpay.payment.tools.CommonConsts; +import au.com.royalpay.payment.tools.env.PlatformEnvironment; +import au.com.royalpay.payment.tools.env.SysConfigManager; +import au.com.royalpay.payment.tools.merchants.core.MerchantInfoProvider; +import au.com.royalpay.payment.tools.utils.CurrencyAmountUtils; +import cn.yixblog.platform.http.HttpRequestGenerator; +import cn.yixblog.platform.http.HttpRequestResult; +import com.alibaba.fastjson.JSONObject; +import com.github.miemiedev.mybatis.paginator.domain.Order; +import com.github.miemiedev.mybatis.paginator.domain.PageBounds; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.util.UriComponentsBuilder; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +@Service +public class CtripCouponOnlyLogProcessor implements PaymentProcessor { + + // todo 重构逻辑 + private org.slf4j.Logger logger = LoggerFactory.getLogger(getClass()); + + + private static final String COUPON_ID = "CTRIP_COUPON_ONLY_LOG"; + + @Value("${app.customer.host}") + private String CUSTOMER_HOST; + + @Value("${customer.app.appid}") + private String CUSTOMER_APP_ID; + + @Value("${customer.app.auth-code}") + private String CUSTOMER_AUTH_CODE; + + @Resource + private MerchantInfoProvider merchantInfoProvider; + + @Resource + private SysConfigManager sysConfigManager; + + @Resource + private CouponAccuessLogMapper payCouponAccuessLogMapper; + @Resource + private PaymentApi paymentApi; + @Override + public String processorId() { + return COUPON_ID + "_USE"; + } + + @Override + public void handleBeforeOrderSending(PreOrderRequest paymentInfo, JSONObject order) { + JSONObject tmpEle = paymentInfo.getTmpEle(); + if (tmpEle == null) { + return; + } + if (StringUtils.isEmpty(tmpEle.getString("ctrip_coupon_id"))) { + return; + } + if (!isOnlyLogMerchant(order.getIntValue("client_id"))) { + return; + } + JSONObject couponInfo = getPreOrderCoupon(tmpEle.getString("ctrip_coupon_id"), order.getIntValue("client_id")); + if (couponInfo == null) { + return; + } + BigDecimal payFee = paymentInfo.getTotalFee(); + BigDecimal exchange = paymentApi.channelApi(paymentInfo.getChannel()).queryExchangeRateDecimal(paymentInfo.getClientId()); + if (StringUtils.equals(paymentInfo.getCurrency(), "CNY")) { + payFee = CurrencyAmountUtils.scale(payFee.divide(exchange,2, BigDecimal.ROUND_HALF_UP), PlatformEnvironment.getEnv().getForeignCurrency()); + } + BigDecimal couponCondition = couponInfo.getBigDecimal("condition") == null ? BigDecimal.ZERO + : couponInfo.getBigDecimal("condition"); + if (payFee.compareTo(couponCondition) < 0) { + return; + } + JSONObject couponAccuessLog = new JSONObject(); + couponAccuessLog.put("client_id",order.getIntValue("client_id")); + couponAccuessLog.put("customer_openid","创建订单时无"); + couponAccuessLog.put("creation_date",new Date()); + couponAccuessLog.put("order_id",order.getString("order_id")); + couponAccuessLog.put("coupon_id","CTRIP_"+tmpEle.getString("ctrip_coupon_id")); + //携程满减 + if (StringUtils.equals(couponInfo.getString("type"), "31")) { + BigDecimal actureAmount = couponInfo.getBigDecimal("acture_amount"); + if (StringUtils.equals(paymentInfo.getCurrency(), "CNY")) { + actureAmount = CurrencyAmountUtils.scale(couponInfo.getBigDecimal("acture_amount").multiply(exchange), PlatformEnvironment.getEnv().getForeignCurrency()); + } + couponAccuessLog.put("coupon_deal_amount", actureAmount); + } + //携程折扣 + if (StringUtils.equals(couponInfo.getString("type"), "32")) { + BigDecimal couponDiscount = couponInfo.getBigDecimal("discount").divide(CommonConsts.HUNDRED, 4, BigDecimal.ROUND_HALF_UP); + BigDecimal couponDealAmount = CurrencyAmountUtils.scale(couponDiscount.multiply(paymentInfo.getTotalFee()), PlatformEnvironment.getEnv().getForeignCurrency()); + couponAccuessLog.put("coupon_deal_amount", couponDealAmount); + } + couponAccuessLog.put("currency", order.getString("currency")); + couponAccuessLog.put("min_pay_amount", couponCondition); + payCouponAccuessLogMapper.save(couponAccuessLog); + } + + @Override + public void handleAfterOrderPaid(PaymentFinishedEvent finishedEvent) { + JSONObject order = finishedEvent.getOrder(); + String orderId = order.getString("order_id"); + List accuessCouponLogs = payCouponAccuessLogMapper.findAccuessLogByOrderId(orderId, new PageBounds(Order.formString("last_update_date.desc"))); + if (accuessCouponLogs != null&&accuessCouponLogs.size()>0) { + if (!isOnlyLogMerchant(order.getIntValue("client_id"))) { + return; + } + JSONObject accuessCouponLog = accuessCouponLogs.get(0); + String couponLogId = accuessCouponLog.getString("coupon_id"); + logger.info("订单 [" + orderId + "]成功使用Ctrip卡券=======>[" + couponLogId + "]"); + accuessCouponLog.put("is_valid", 1); + accuessCouponLog.put("last_update_date", new Date()); + accuessCouponLog.put("customer_openid",order.getString("customer_id")); + + payCouponAccuessLogMapper.update(accuessCouponLog); + } + } + + @Override + public void registerCoupon(JSONObject client, String customerOpenId, String channel, List coupons) { + return; + } + + @Override + public void handleAfterRefund(RefundSendEvent event) { + //do nothing + JSONObject refundOrder = event.getRefundOrder(); + String orderId = refundOrder.getString("order_id"); + List accuessCouponLogs = payCouponAccuessLogMapper.findUsedCouponByOrderIdList(orderId); + if (accuessCouponLogs != null&& accuessCouponLogs.size()>0) { + if (!isOnlyLogMerchant(refundOrder.getIntValue("client_id"))) { + return; + } + JSONObject accuessCouponLog = accuessCouponLogs.get(0); + accuessCouponLog.put("is_valid", 0); + accuessCouponLog.put("last_update_date", new Date()); + accuessCouponLog.put("refund_id",refundOrder.getString("refund_id")); + payCouponAccuessLogMapper.update(accuessCouponLog); + } + } + + @Override + public String registerBanner(JSONObject client, String channel) { + return null; + } + + // 使用券的信息 + private JSONObject getPreOrderCoupon(String couponLogId,int clientId) { + JSONObject client = merchantInfoProvider.getClientInfo(clientId); + String timestamp = System.currentTimeMillis() + ""; + String base = CUSTOMER_APP_ID + timestamp + CUSTOMER_AUTH_CODE; + String sign = DigestUtils.sha256Hex(base).toLowerCase(); + String uri = UriComponentsBuilder.fromHttpUrl(CUSTOMER_HOST + "coupon/" + couponLogId + "/couponLogInfo").queryParam("appid", CUSTOMER_APP_ID) + .queryParam("timestamp", timestamp).queryParam("sign", sign).queryParam("client_moniker", client.getString("client_moniker")).toUriString(); + HttpRequestGenerator gen = new HttpRequestGenerator(uri, RequestMethod.GET); + try { + HttpRequestResult result = gen.execute(); + if (result.isSuccess()) { + return result.getResponseContentJSONObj(); + } + } catch (Exception ignored) { + logger.error("积分商城优惠券 [" + couponLogId + "]使用失败"); + ignored.printStackTrace(); + } + return null; + } + + private boolean isOnlyLogMerchant(int clientId) { + JSONObject client = merchantInfoProvider.getClientInfo(clientId); + JSONObject sysConfig = sysConfigManager.getSysConfig(); + if (sysConfig.getString("ctrip_coupon_only_log_merchant_list").contains(client.getString("client_moniker"))) { + return true; + } + return false; + } +} diff --git a/src/main/java/au/com/royalpay/payment/manage/processors/CtripCouponProvideProcessor.java b/src/main/java/au/com/royalpay/payment/manage/processors/CtripCouponProvideProcessor.java new file mode 100644 index 000000000..1354d7813 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/processors/CtripCouponProvideProcessor.java @@ -0,0 +1,266 @@ +package au.com.royalpay.payment.manage.processors; + +import au.com.royalpay.payment.core.PaymentApi; +import au.com.royalpay.payment.core.TransactionService; +import au.com.royalpay.payment.core.beans.PaymentQueryResult; +import au.com.royalpay.payment.core.beans.PreOrderRequest; +import au.com.royalpay.payment.core.beans.coupon.CouponInfo; +import au.com.royalpay.payment.core.events.PaymentFinishedEvent; +import au.com.royalpay.payment.core.events.RefundSendEvent; +import au.com.royalpay.payment.core.mappers.PmtOrderMapper; +import au.com.royalpay.payment.core.processors.PaymentProcessor; +import au.com.royalpay.payment.manage.mappers.log.CouponAccuessLogMapper; +import au.com.royalpay.payment.tools.CommonConsts; +import au.com.royalpay.payment.tools.env.PlatformEnvironment; +import au.com.royalpay.payment.tools.env.SysConfigManager; +import au.com.royalpay.payment.tools.merchants.core.MerchantInfoProvider; +import au.com.royalpay.payment.tools.utils.CurrencyAmountUtils; +import cn.yixblog.platform.http.HttpRequestGenerator; +import cn.yixblog.platform.http.HttpRequestResult; +import com.alibaba.fastjson.JSONObject; +import com.github.miemiedev.mybatis.paginator.domain.Order; +import com.github.miemiedev.mybatis.paginator.domain.PageBounds; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.util.UriComponentsBuilder; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +@Service +public class CtripCouponProvideProcessor implements PaymentProcessor { + + // todo 重构逻辑 + private org.slf4j.Logger logger = LoggerFactory.getLogger(getClass()); + + + private static final String COUPON_ID = "CTRIP_COUPON"; + + @Value("${app.customer.host}") + private String CUSTOMER_HOST; + + @Value("${customer.app.appid}") + private String CUSTOMER_APP_ID; + + @Value("${customer.app.auth-code}") + private String CUSTOMER_AUTH_CODE; + + @Resource + private MerchantInfoProvider merchantInfoProvider; + @Resource + private SysConfigManager sysConfigManager; + @Resource + private CouponAccuessLogMapper payCouponAccuessLogMapper; + @Resource + private PaymentApi paymentApi; + @Resource + private PmtOrderMapper pmtOrderMapper; + @Resource + private TransactionService transactionService; + @Override + public String processorId() { + return COUPON_ID + "_USE"; + } + + @Override + public void handleBeforeOrderSending(PreOrderRequest paymentInfo, JSONObject order) { + /*if (order.getIntValue("client_id") != 9) { + return; + }*/ + JSONObject tmpEle = paymentInfo.getTmpEle(); + if (tmpEle == null) { + return; + } + if (StringUtils.isEmpty(tmpEle.getString("ctrip_coupon_id"))) { + return; + } + logger.info("tmpEle:" + tmpEle.toJSONString()); + if (isOnlyLogMerchant(order.getIntValue("client_id"))) { + return; + } + JSONObject couponInfo = getPreOrderCoupon(tmpEle.getString("ctrip_coupon_id"), order.getIntValue("client_id")); + if (couponInfo == null) { + return; + } + BigDecimal payFee = paymentInfo.getTotalFee(); + BigDecimal exchange = paymentApi.channelApi(paymentInfo.getChannel()).queryExchangeRateDecimal(paymentInfo.getClientId()); + if (StringUtils.equals(paymentInfo.getCurrency(), "CNY")) { + payFee = CurrencyAmountUtils.scale(payFee.divide(exchange,2, BigDecimal.ROUND_HALF_UP), PlatformEnvironment.getEnv().getForeignCurrency()); + } + BigDecimal couponCondition = couponInfo.getBigDecimal("condition") == null ? BigDecimal.ZERO + : couponInfo.getBigDecimal("condition"); + if (payFee.compareTo(couponCondition) < 0) { + return; + } + JSONObject couponAccuessLog = new JSONObject(); + couponAccuessLog.put("client_id",order.getIntValue("client_id")); + couponAccuessLog.put("customer_openid","创建订单时无"); + couponAccuessLog.put("creation_date",new Date()); + couponAccuessLog.put("order_id",order.getString("order_id")); + couponAccuessLog.put("coupon_id","CTRIP_"+tmpEle.getString("ctrip_coupon_id")); + BigDecimal currentDiscount = paymentInfo.getDiscount(); + //携程满减 + if (StringUtils.equals(couponInfo.getString("type"), "31")) { + BigDecimal actureAmount = couponInfo.getBigDecimal("acture_amount"); + if (StringUtils.equals(paymentInfo.getCurrency(), "CNY")) { + actureAmount = CurrencyAmountUtils.scale(couponInfo.getBigDecimal("acture_amount").multiply(exchange), PlatformEnvironment.getEnv().getForeignCurrency()); + } + paymentInfo.setDiscount(currentDiscount.add(actureAmount)); + couponAccuessLog.put("coupon_deal_amount", actureAmount); + } + //携程折扣 + if (StringUtils.equals(couponInfo.getString("type"), "32")) { + BigDecimal couponDiscount = couponInfo.getBigDecimal("discount").divide(CommonConsts.HUNDRED, 4, BigDecimal.ROUND_HALF_UP); + BigDecimal couponDealAmount = CurrencyAmountUtils.scale(couponDiscount.multiply(paymentInfo.getTotalFee()), PlatformEnvironment.getEnv().getForeignCurrency()); + paymentInfo.setDiscount(currentDiscount.add(couponDealAmount)); + couponAccuessLog.put("coupon_deal_amount", couponDealAmount); + } + couponAccuessLog.put("currency", order.getString("currency")); + couponAccuessLog.put("min_pay_amount", couponCondition); + payCouponAccuessLogMapper.save(couponAccuessLog); + + JSONObject updateOrder = new JSONObject(); + BigDecimal customerPay = paymentInfo.getUserPayAmount(); + updateOrder.put("customer_payment_amount", customerPay); + BigDecimal couponDiscount = paymentInfo.getDiscount(); + updateOrder.put("coupon_payment_amount", couponDiscount); + updateOrder.put("order_id", paymentInfo.getOrderId()); + + pmtOrderMapper.update(updateOrder); + + order.put("customer_payment_amount", customerPay); + order.put("coupon_payment_amount", couponDiscount); + } + + @Override + public void handleAfterOrderPaid(PaymentFinishedEvent finishedEvent) { + JSONObject order = finishedEvent.getOrder(); + /*if (order.getIntValue("client_id") != 9) { + return; + }*/ + String orderId = order.getString("order_id"); + List accuessCouponLogs = payCouponAccuessLogMapper.findAccuessLogByOrderId(orderId, new PageBounds(Order.formString("last_update_date.desc"))); + if (accuessCouponLogs != null&&accuessCouponLogs.size()>0) { + if (isOnlyLogMerchant(order.getIntValue("client_id"))) { + return; + } + JSONObject accuessCouponLog = accuessCouponLogs.get(0); + String couponLogId = accuessCouponLog.getString("coupon_id"); + logger.info("订单 [" + orderId + "]成功使用Ctrip卡券=======>[" + couponLogId + "]"); + + //传入流水 + JSONObject useCoupontrans = new JSONObject(); + useCoupontrans.put("org_id", order.getIntValue("org_id")); + useCoupontrans.put("system_transaction_id", accuessCouponLog.getString("accuess_id")); + useCoupontrans.put("order_id", order.getString("order_id")); + useCoupontrans.put("client_id", order.getIntValue("client_id")); + useCoupontrans.put("transaction_currency", order.getString("currency")); + if (StringUtils.equals(order.getString("currency"), "CNY")) { + useCoupontrans.put("cny_amount", accuessCouponLog.getBigDecimal("coupon_deal_amount")); + } + useCoupontrans.put("clearing_currency", PlatformEnvironment.getEnv().getForeignCurrency()); + useCoupontrans.put("clearing_amount", accuessCouponLog.getBigDecimal("coupon_deal_amount")); + useCoupontrans.put("transaction_amount", accuessCouponLog.getBigDecimal("coupon_deal_amount")); + useCoupontrans.put("exchange_rate", finishedEvent.getExchangeRate()); + useCoupontrans.put("channel", order.getString("channel")); + useCoupontrans.put("transaction_type", "Credit"); + PaymentQueryResult pay = finishedEvent.getPaymentQueryResult(); + useCoupontrans.put("transaction_time", pay.getPayTime()); + useCoupontrans.put("clearing_status", 0); + useCoupontrans.put("system_generate", 1); + useCoupontrans.put("remark", "Ctrip Coupon from Customer:" + couponLogId); + accuessCouponLog = payCouponAccuessLogMapper.findAccuessLogByOrderId(orderId,new PageBounds(Order.formString("last_update_date.desc"))).get(0); + if (accuessCouponLog != null) { + transactionService.saveTransaction(useCoupontrans); + accuessCouponLog.put("is_valid", 1); + accuessCouponLog.put("last_update_date", new Date()); + accuessCouponLog.put("transaction_id", useCoupontrans.getString("transaction_id")); + accuessCouponLog.put("customer_openid",order.getString("customer_id")); + payCouponAccuessLogMapper.update(accuessCouponLog); + } + + } + } + + @Override + public void registerCoupon(JSONObject client, String customerOpenId, String channel, List coupons) { + return; + } + + @Override + public void handleAfterRefund(RefundSendEvent event) { + //do nothing + JSONObject refundOrder = event.getRefundOrder(); + /*if (refundOrder.getIntValue("client_id") != 9) { + return; + }*/ + logger.info("积分商城携程优惠券开始退款"); + String orderId = refundOrder.getString("order_id"); + List accuessCouponLogs = payCouponAccuessLogMapper.findUsedCouponByOrderIdList(orderId); + if (accuessCouponLogs != null&& accuessCouponLogs.size()>0) { + if (isOnlyLogMerchant(refundOrder.getIntValue("client_id"))) { + return; + } + JSONObject accuessCouponLog = accuessCouponLogs.get(0); + JSONObject trans = transactionService.findTransaction(accuessCouponLog.getString("transaction_id")); + if (trans != null) { + logger.info("正在退款的券的初始信息" + trans.toJSONString()); + trans.remove("transaction_id"); + trans.put("transaction_type", "Debit"); + String coupon_id = accuessCouponLog.getString("coupon_id"); + trans.put("refund_id", refundOrder.getString("refund_id")); + trans.put("transaction_time", new Date()); + trans.put("remark", "Refund for Customer Ctrip Coupon:" + coupon_id); + logger.info("正在退款的券的信息" + trans.toJSONString()); + transactionService.saveTransaction(trans); + logger.error("订单[" + orderId + "]发送全额退款,携程优惠券【" + coupon_id + "】转为Debit"); + accuessCouponLog.put("transaction_refund_id", trans.getString("transaction_id")); + accuessCouponLog.put("refund_id", refundOrder.getString("refund_id")); + accuessCouponLog.put("is_valid", 0); + accuessCouponLog.put("last_update_date", new Date()); + payCouponAccuessLogMapper.update(accuessCouponLog); + } + } + } + + @Override + public String registerBanner(JSONObject client, String channel) { + return null; + } + + // 使用券的信息 + private JSONObject getPreOrderCoupon(String couponLogId,int clientId) { + JSONObject client = merchantInfoProvider.getClientInfo(clientId); + String timestamp = System.currentTimeMillis() + ""; + String base = CUSTOMER_APP_ID + timestamp + CUSTOMER_AUTH_CODE; + String sign = DigestUtils.sha256Hex(base).toLowerCase(); + String uri = UriComponentsBuilder.fromHttpUrl(CUSTOMER_HOST + "coupon/" + couponLogId + "/couponLogInfo").queryParam("appid", CUSTOMER_APP_ID) + .queryParam("timestamp", timestamp).queryParam("sign", sign).queryParam("client_moniker", client.getString("client_moniker")).toUriString(); + HttpRequestGenerator gen = new HttpRequestGenerator(uri, RequestMethod.GET); + try { + HttpRequestResult result = gen.execute(); + if (result.isSuccess()) { + return result.getResponseContentJSONObj(); + } + } catch (Exception ignored) { + logger.error("积分商城优惠券 [" + couponLogId + "]使用失败"); + ignored.printStackTrace(); + } + return null; + } + + private boolean isOnlyLogMerchant(int clientId) { + JSONObject client = merchantInfoProvider.getClientInfo(clientId); + JSONObject sysConfig = sysConfigManager.getSysConfig(); + if (sysConfig.getString("ctrip_coupon_only_log_merchant_list").contains(client.getString("client_moniker"))) { + return true; + } + return false; + } +}