@SuppressWarnings("unchecked")
 @Override
 public boolean verifyNotify(String sn, NotifyMethod notifyMethod, HttpServletRequest request) {
   PluginConfig pluginConfig = getPluginConfig();
   Payment payment = getPayment(sn);
   if (generateSign(request.getParameterMap()).equals(request.getParameter("signature"))
       && pluginConfig.getAttribute("partner").equals(request.getParameter("merId"))
       && sn.equals(request.getParameter("orderNumber"))
       && CURRENCY.equals(request.getParameter("orderCurrency"))
       && "00".equals(request.getParameter("respCode"))
       && payment
               .getAmount()
               .multiply(new BigDecimal(100))
               .compareTo(new BigDecimal(request.getParameter("orderAmount")))
           == 0) {
     Map<String, Object> parameterMap = new HashMap<String, Object>();
     parameterMap.put("version", "1.0.0");
     parameterMap.put("charset", "UTF-8");
     parameterMap.put("transType", "01");
     parameterMap.put("merId", pluginConfig.getAttribute("partner"));
     parameterMap.put("orderNumber", sn);
     parameterMap.put("orderTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
     parameterMap.put("merReserved", "");
     parameterMap.put("signMethod", "MD5");
     parameterMap.put("signature", generateSign(parameterMap));
     String result = post("https://unionpaysecure.com/api/Query.action", parameterMap);
     if (ArrayUtils.contains(result.split("&"), "respCode=00")) {
       return true;
     }
   }
   return false;
 }
 @Override
 public Map<String, Object> getParameterMap(
     String sn, String description, HttpServletRequest request) {
   Setting setting = SettingUtils.get();
   PluginConfig pluginConfig = getPluginConfig();
   Payment payment = getPayment(sn);
   Map<String, Object> parameterMap = new HashMap<String, Object>();
   parameterMap.put("version", "1.0.0");
   parameterMap.put("charset", "UTF-8");
   parameterMap.put("transType", "01");
   parameterMap.put("origQid", "");
   parameterMap.put("merId", pluginConfig.getAttribute("partner"));
   parameterMap.put(
       "merAbbr",
       StringUtils.abbreviate(
           setting.getSiteName().replaceAll("[^0-9a-zA-Z\\u4e00-\\u9fa5 ]", ""), 40));
   parameterMap.put("acqCode", "");
   parameterMap.put("merCode", "");
   parameterMap.put("commodityUrl", setting.getSiteUrl());
   parameterMap.put(
       "commodityName",
       StringUtils.abbreviate(description.replaceAll("[^0-9a-zA-Z\\u4e00-\\u9fa5 ]", ""), 200));
   parameterMap.put("commodityUnitPrice", "");
   parameterMap.put("commodityQuantity", "");
   parameterMap.put("commodityDiscount", "");
   parameterMap.put("transferFee", "");
   parameterMap.put("orderNumber", sn);
   parameterMap.put(
       "orderAmount", payment.getAmount().multiply(new BigDecimal(100)).setScale(0).toString());
   parameterMap.put("orderCurrency", CURRENCY);
   parameterMap.put("orderTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
   parameterMap.put("customerIp", request.getLocalAddr());
   parameterMap.put("customerName", "");
   parameterMap.put("defaultPayType", "");
   parameterMap.put("defaultBankNumber", "");
   parameterMap.put("transTimeout", getTimeout() * 60000);
   parameterMap.put("frontEndUrl", getNotifyUrl(sn, NotifyMethod.sync));
   parameterMap.put("backEndUrl", getNotifyUrl(sn, NotifyMethod.async));
   parameterMap.put("merReserved", "");
   parameterMap.put("signMethod", "MD5");
   parameterMap.put("signature", generateSign(parameterMap));
   return parameterMap;
 }
  @Override
  public void payment(Order order, Payment payment, Admin operator) {
    Assert.notNull(order);
    Assert.notNull(payment);

    orderDao.lock(order, LockModeType.PESSIMISTIC_WRITE);

    payment.setOrder(order);
    paymentDao.merge(payment);
    if (payment.getMethod() == Payment.Method.deposit) {
      Member member = order.getMember();
      memberDao.lock(member, LockModeType.PESSIMISTIC_WRITE);
      member.setBalance(member.getBalance().subtract(payment.getAmount()));
      memberDao.merge(member);

      Deposit deposit = new Deposit();
      deposit.setType(operator != null ? Deposit.Type.adminPayment : Deposit.Type.memberPayment);
      deposit.setCredit(new BigDecimal(0));
      deposit.setDebit(payment.getAmount());
      deposit.setBalance(member.getBalance());
      deposit.setOperator(operator != null ? operator.getUsername() : null);
      deposit.setMember(member);
      deposit.setOrder(order);
      depositDao.persist(deposit);
    }

    Setting setting = SettingUtils.get();
    if (!order.getIsAllocatedStock()
        && setting.getStockAllocationTime() == StockAllocationTime.payment) {
      for (OrderItem orderItem : order.getOrderItems()) {
        if (orderItem != null) {
          Product product = orderItem.getProduct();
          productDao.lock(product, LockModeType.PESSIMISTIC_WRITE);
          if (product != null && product.getStock() != null) {
            product.setAllocatedStock(
                product.getAllocatedStock()
                    + (orderItem.getQuantity() - orderItem.getShippedQuantity()));
            productDao.merge(product);
            orderDao.flush();
            staticService.build(product);
          }
        }
      }
      order.setIsAllocatedStock(true);
    }

    order.setAmountPaid(order.getAmountPaid().add(payment.getAmount()));
    order.setFee(payment.getFee());
    order.setExpire(null);
    if (order.getAmountPaid().compareTo(order.getAmount()) >= 0) {
      order.setOrderStatus(OrderStatus.confirmed);
      order.setPaymentStatus(PaymentStatus.paid);
    } else if (order.getAmountPaid().compareTo(new BigDecimal(0)) > 0) {
      order.setOrderStatus(OrderStatus.confirmed);
      order.setPaymentStatus(PaymentStatus.partialPayment);
    }
    orderDao.merge(order);

    OrderLog orderLog = new OrderLog();
    orderLog.setType(Type.payment);
    orderLog.setOperator(operator != null ? operator.getUsername() : null);
    orderLog.setOrder(order);
    orderLogDao.persist(orderLog);
  }