@Override
  public PaymentResponseDTO translateWebResponse(HttpServletRequest request)
      throws PaymentException {
    PaymentResponseDTO responseDTO =
        new PaymentResponseDTO(
                PaymentType.THIRD_PARTY_ACCOUNT, NullPaymentGatewayType.NULL_HOSTED_GATEWAY)
            .rawResponse(webResponsePrintService.printRequest(request));

    Map<String, String[]> paramMap = request.getParameterMap();

    Money amount = Money.ZERO;
    if (paramMap.containsKey(NullPaymentGatewayConstants.TRANSACTION_AMT)) {
      String amt = paramMap.get(NullPaymentGatewayConstants.TRANSACTION_AMT)[0];
      amount = new Money(amt);
    }

    responseDTO
        .successful(true)
        .completeCheckoutOnCallback(
            Boolean.parseBoolean(
                paramMap.get(NullPaymentGatewayConstants.COMPLETE_CHECKOUT_ON_CALLBACK)[0]))
        .amount(amount)
        .paymentTransactionType(PaymentTransactionType.UNCONFIRMED)
        .orderId(paramMap.get(NullPaymentGatewayConstants.ORDER_ID)[0])
        .responseMap(
            NullPaymentGatewayConstants.RESULT_MESSAGE,
            paramMap.get(NullPaymentGatewayConstants.RESULT_MESSAGE)[0]);

    return responseDTO;
  }
  @Override
  public PaymentResponseDTO capture(PaymentRequestDTO paymentRequestDTO) throws PaymentException {
    PaymentResponseDTO responseDTO =
        new PaymentResponseDTO(PaymentType.CREDIT_CARD, NullPaymentGatewayType.NULL_GATEWAY);
    responseDTO
        .valid(true)
        .paymentTransactionType(PaymentTransactionType.CAPTURE)
        .amount(new Money(paymentRequestDTO.getTransactionTotal()))
        .rawResponse("Successful Capture")
        .successful(true);

    return responseDTO;
  }
 @Override
 public void handleUnsuccessfulTransaction(
     Model model, RedirectAttributes redirectAttributes, PaymentResponseDTO responseDTO)
     throws PaymentException {
   if (LOG.isTraceEnabled()) {
     LOG.trace(
         "The Transaction was unsuccessful for "
             + GATEWAY_CONTEXT_KEY
             + ". Adding Errors to Redirect Attributes.");
   }
   redirectAttributes.addAttribute(
       PAYMENT_PROCESSING_ERROR,
       responseDTO.getResponseMap().get(BraintreePaymentGatewayConstants.RESULT_MESSAGE));
 }
  /**
   * Does minimal Credit Card Validation (luhn check and expiration date is after today). Mimics the
   * Response of a real Payment Gateway.
   *
   * @param creditCardDTO
   * @return
   */
  protected PaymentResponseDTO commonCreditCardProcessing(
      PaymentRequestDTO requestDTO, PaymentTransactionType paymentTransactionType) {
    PaymentResponseDTO responseDTO =
        new PaymentResponseDTO(PaymentType.CREDIT_CARD, NullPaymentGatewayType.NULL_GATEWAY);
    responseDTO.valid(true).paymentTransactionType(paymentTransactionType);

    CreditCardDTO creditCardDTO = requestDTO.getCreditCard();
    String transactionAmount = requestDTO.getTransactionTotal();

    CreditCardValidator visaValidator = new CreditCardValidator(CreditCardValidator.VISA);
    CreditCardValidator amexValidator = new CreditCardValidator(CreditCardValidator.AMEX);
    CreditCardValidator mcValidator = new CreditCardValidator(CreditCardValidator.MASTERCARD);
    CreditCardValidator discoverValidator = new CreditCardValidator(CreditCardValidator.DISCOVER);

    if (StringUtils.isNotBlank(transactionAmount)
        && StringUtils.isNotBlank(creditCardDTO.getCreditCardNum())
        && (StringUtils.isNotBlank(creditCardDTO.getCreditCardExpDate())
            || (StringUtils.isNotBlank(creditCardDTO.getCreditCardExpMonth())
                && StringUtils.isNotBlank(creditCardDTO.getCreditCardExpYear())))) {

      boolean validCard = false;
      if (visaValidator.isValid(creditCardDTO.getCreditCardNum())) {
        validCard = true;
      } else if (amexValidator.isValid(creditCardDTO.getCreditCardNum())) {
        validCard = true;
      } else if (mcValidator.isValid(creditCardDTO.getCreditCardNum())) {
        validCard = true;
      } else if (discoverValidator.isValid(creditCardDTO.getCreditCardNum())) {
        validCard = true;
      }

      boolean validDateFormat = false;
      boolean validDate = false;
      String[] parsedDate = null;
      if (StringUtils.isNotBlank(creditCardDTO.getCreditCardExpDate())) {
        parsedDate = creditCardDTO.getCreditCardExpDate().split("/");
      } else {
        parsedDate = new String[2];
        parsedDate[0] = creditCardDTO.getCreditCardExpMonth();
        parsedDate[1] = creditCardDTO.getCreditCardExpYear();
      }

      if (parsedDate.length == 2) {
        String expMonth = parsedDate[0];
        String expYear = parsedDate[1];
        try {
          DateTime expirationDate =
              new DateTime(Integer.parseInt("20" + expYear), Integer.parseInt(expMonth), 1, 0, 0);
          expirationDate = expirationDate.dayOfMonth().withMaximumValue();
          validDate = expirationDate.isAfterNow();
          validDateFormat = true;
        } catch (Exception e) {
          // invalid date format
        }
      }

      if (!validDate || !validDateFormat) {
        responseDTO
            .amount(new Money(0))
            .rawResponse("cart.payment.expiration.invalid")
            .successful(false);
      } else if (!validCard) {
        responseDTO.amount(new Money(0)).rawResponse("cart.payment.card.invalid").successful(false);
      } else {
        responseDTO
            .amount(new Money(requestDTO.getTransactionTotal()))
            .rawResponse("Success!")
            .successful(true);
      }

    } else {
      responseDTO.amount(new Money(0)).rawResponse("cart.payment.invalid").successful(false);
    }

    return responseDTO;
  }