public boolean process(PaymentDTOEx payment) throws PluggableTaskException {
    LOG.debug("Payment processing for " + getProcessorName() + " gateway");

    if (payment.getPayoutId() != null) return true;

    SvcType transaction = SvcType.SALE;
    if (BigDecimal.ZERO.compareTo(payment.getAmount()) > 0 || (payment.getIsRefund() != 0)) {
      LOG.debug("Doing a refund using credit card transaction");
      transaction = SvcType.REFUND_CREDIT;
    }

    boolean result;
    try {
      result = doProcess(payment, transaction, null).shouldCallOtherProcessors();
      LOG.debug(
          "Processing result is "
              + payment.getPaymentResult().getId()
              + ", return value of process is "
              + result);

    } catch (Exception e) {
      LOG.error("Exception", e);
      throw new PluggableTaskException(e);
    }
    return result;
  }
  public boolean confirmPreAuth(PaymentAuthorizationDTO auth, PaymentDTOEx payment)
      throws PluggableTaskException {

    LOG.debug("Confirming pre-authorization for " + getProcessorName() + " gateway");

    if (!getProcessorName().equals(auth.getProcessor())) {
      /*  let the processor be called and fail, so the caller can do something
      about it: probably re-call this payment task as a new "process()" run */
      LOG.warn(
          "The processor of the pre-auth is not "
              + getProcessorName()
              + ", is "
              + auth.getProcessor());
    }

    CreditCardDTO card = payment.getCreditCard();
    if (card == null) {
      throw new PluggableTaskException(
          "Credit card is required capturing" + " payment: " + payment.getId());
    }

    if (!isApplicable(payment)) {
      LOG.error("This payment can not be captured" + payment);
      return true;
    }

    return doProcess(payment, SvcType.SETTLE, auth).shouldCallOtherProcessors();
  }
  private Result doFakeAuthorization(PaymentDTOEx payment, String transactionId)
      throws PluggableTaskException {
    CreditCardDTO creditCard = payment.getCreditCard();
    if (creditCard == null || !myFilter.accept(creditCard)) {
      // give real processors a chance
      return new Result(null, true);
    }

    Integer resultId = getProcessResultId(creditCard);
    payment.setPaymentResult(new PaymentResultDAS().find(resultId));
    PaymentAuthorizationDTO authInfo = createAuthorizationDTO(resultId, transactionId);
    storeProcessedAuthorization(payment, authInfo);

    boolean wasProcessed =
        (Constants.RESULT_FAIL.equals(resultId) || Constants.RESULT_OK.equals(resultId));
    boolean shouldCallOthers = !wasProcessed && !myShouldBlockOtherProcessors;
    return new Result(authInfo, shouldCallOthers);
  }
  @Override // implements abstract method
  public NVPList buildRequest(PaymentDTOEx payment, SvcType transaction)
      throws PluggableTaskException {
    NVPList request = new NVPList();

    request.add(PARAMETER_MERCHANT_ID, getMerchantId());
    request.add(PARAMETER_STORE_ID, getStoreId());
    request.add(PARAMETER_TERMINAL_ID, getTerminalId());
    request.add(PARAMETER_SELLER_ID, getSellerId());
    request.add(PARAMETER_PASSWORD, getPassword());

    ContactBL contact = new ContactBL();
    contact.set(payment.getUserId());

    request.add(WorldPayParams.General.STREET_ADDRESS, contact.getEntity().getAddress1());
    request.add(WorldPayParams.General.CITY, contact.getEntity().getCity());
    request.add(WorldPayParams.General.STATE, contact.getEntity().getStateProvince());
    request.add(WorldPayParams.General.ZIP, contact.getEntity().getPostalCode());

    request.add(WorldPayParams.General.FIRST_NAME, contact.getEntity().getFirstName());
    request.add(WorldPayParams.General.LAST_NAME, contact.getEntity().getLastName());
    request.add(WorldPayParams.General.COUNTRY, contact.getEntity().getCountryCode());

    request.add(WorldPayParams.General.AMOUNT, formatDollarAmount(payment.getAmount()));
    request.add(WorldPayParams.General.SVC_TYPE, transaction.getCode());

    CreditCardDTO card = payment.getCreditCard();
    request.add(WorldPayParams.CreditCard.CARD_NUMBER, card.getNumber());
    request.add(
        WorldPayParams.CreditCard.EXPIRATION_DATE,
        EXPIRATION_DATE_FORMAT.format(card.getCcExpiry()));

    if (card.getSecurityCode() != null) {
      request.add(
          WorldPayParams.CreditCard.CVV2,
          String.valueOf(payment.getCreditCard().getSecurityCode()));
    }

    return request;
  }
  @Override
  protected PaymentTask selectDelegate(PaymentDTOEx paymentInfo) throws PluggableTaskException {
    String currencyCode = paymentInfo.getCurrency().getCode();
    Integer selectedTaskId = null;

    try {
      // try to get the task id for this currency
      selectedTaskId = intValueOf(parameters.get(currencyCode));
    } catch (NumberFormatException e) {
      throw new PluggableTaskException("Invalid task id for currency " + "code: " + currencyCode);
    }
    if (selectedTaskId == null) {
      LOG.warn("Could not find processor for " + parameters.get(currencyCode));
      return null;
    }

    LOG.debug("Delegating to task id " + selectedTaskId);
    PaymentTask selectedTask = instantiateTask(selectedTaskId);

    return selectedTask;
  }
  public boolean process(PaymentDTOEx paymentInfo) throws PluggableTaskException {
    FormatLogger log = new FormatLogger(Logger.getLogger(PaymentEmailAuthorizeNetTask.class));
    boolean retValue = super.process(paymentInfo);
    String address = (String) parameters.get(PARAMETER_EMAIL_ADDRESS.getName());
    try {
      UserBL user = new UserBL(paymentInfo.getUserId());
      String message;
      if (new Integer(paymentInfo.getPaymentResult().getId()).equals(Constants.RESULT_OK)) {
        message = "payment.success";
      } else {
        message = "payment.fail";
      }
      String params[] = new String[6];
      params[0] = paymentInfo.getUserId().toString();
      params[1] = user.getEntity().getUserName();
      params[2] = paymentInfo.getId() + "";
      params[3] = paymentInfo.getAmount().toString();
      if (paymentInfo.getAuthorization() != null) {
        params[4] = paymentInfo.getAuthorization().getTransactionId();
        params[5] = paymentInfo.getAuthorization().getApprovalCode();
      } else {
        params[4] = "Not available";
        params[5] = "Not available";
      }
      log.debug(
          "Bkp 6 " + params[0] + " " + params[1] + " " + params[2] + " " + params[3] + " "
              + params[4] + " " + params[5] + " ");
      NotificationBL.sendSapienterEmail(
          address, user.getEntity().getEntity().getId(), message, null, params);
    } catch (Exception e) {

      log.warn("Cant send receit email");
    }

    return retValue;
  }
  public ActionForward execute(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws IOException, ServletException {

    Logger log = Logger.getLogger(MaintainAction.class);
    String forward = null;
    ActionForward retValue = null;
    try {
      IPaymentSessionBean myRemoteSession =
          (IPaymentSessionBean) Context.getBean(Context.Name.PAYMENT_SESSION);

      /*
       * Because of the review step, the payment has some actions that
       * so far makes no sense to dump them in the generic action
       */
      String action = request.getParameter("action");
      HttpSession session = request.getSession(false);
      ActionMessages messages = new ActionMessages();

      String key;
      key = session.getAttribute("jsp_is_refund") == null ? "payment." : "refund.";
      // get the payment/refund information
      String sessionKey;
      if (key.equals("payment.")) {
        sessionKey = Constants.SESSION_PAYMENT_DTO;
      } else {
        sessionKey = Constants.SESSION_PAYMENT_DTO_REFUND;
      }

      if (action.equals("send")) {

        PaymentDTOEx paymentDto = (PaymentDTOEx) session.getAttribute(sessionKey);

        if (paymentDto == null) {
          log.error("dto can't be null when sending");
          throw new ServletException("paymentDTO is null");
        }
        // get the invoice, it might not be there
        Integer invoiceId = null;
        InvoiceDTO invoice = (InvoiceDTO) session.getAttribute(Constants.SESSION_INVOICE_DTO);
        if (invoice != null) {
          invoiceId = invoice.getId();
        }

        boolean isPayout = false;
        PartnerPayout payout = null;
        Partner partner = null;
        if (request.getParameter("payout") != null
            && request.getParameter("payout").equals("yes")) {
          isPayout = true;
          payout = (PartnerPayout) session.getAttribute(Constants.SESSION_PAYOUT_DTO);
          partner = (Partner) session.getAttribute(Constants.SESSION_PARTNER_DTO);
        }

        if (((Boolean) session.getAttribute("tmp_process_now")).booleanValue()) {
          Integer result;
          if (!isPayout) {
            result =
                myRemoteSession.processAndUpdateInvoice(
                    paymentDto,
                    invoiceId,
                    (Integer) session.getAttribute(Constants.SESSION_ENTITY_ID_KEY));
          } else {

            result =
                myRemoteSession.processPayout(
                    paymentDto,
                    payout.getStartingDate(),
                    payout.getEndingDate(),
                    partner.getId(),
                    new Boolean(true));
            payout.setPayment(new PaymentDTO(paymentDto));
          }

          if (result == null) {
            key = key + "no_result";
          } else if (result.equals(Constants.RESULT_OK)) {
            key = key + "result.approved";
          } else if (result.equals(Constants.RESULT_FAIL)) {
            key = key + "result.rejected";
          } else if (result.equals(Constants.RESULT_UNAVAILABLE)) {
            key = key + "result.unavailable";
          } else {
            key = "all.internal";
            log.error("Unsupported result from server:" + result);
          }

        } else {
          if (!isPayout) {
            log.debug(
                "sending payment. Id = "
                    + paymentDto.getId()
                    + " refund "
                    + paymentDto.getIsRefund());
            if (paymentDto.getId() != 0 && paymentDto.getIsRefund() == 0) {
              // it is an update
              myRemoteSession.update(
                  (Integer) session.getAttribute(Constants.SESSION_LOGGED_USER_ID), paymentDto);
            } else {
              // it is a new payment
              paymentDto.setId(myRemoteSession.applyPayment(paymentDto, invoiceId));
              // I need to update the DTO, so the left bar can
              // make the right decitions
              if (invoiceId != null) {
                List<Integer> invoices = new ArrayList<Integer>();
                invoices.add(invoiceId);
                paymentDto.setInvoiceIds(invoices);
              }
            }
          } else {
            myRemoteSession.processPayout(
                paymentDto,
                payout.getStartingDate(),
                payout.getEndingDate(),
                partner.getId(),
                new Boolean(false));
          }
          key = key + "enter.success";
        }

        messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(key));
        if (!isPayout) {
          // the dto has to be refreshed, otherwise the
          // map to the invoice won't be there
          session.setAttribute(
              Constants.SESSION_PAYMENT_DTO,
              myRemoteSession.getPayment(
                  paymentDto.getId(), (Integer) session.getAttribute(Constants.SESSION_LANGUAGE)));
          forward = "payment_view";
        } else {
          forward = "payout_view";
        }
      } else if (action.equals("last_invoice")) {
        forward = "no_invoice";
        // make sure the logged user shows up as the user for the payment
        session.setAttribute(
            Constants.SESSION_USER_ID, session.getAttribute(Constants.SESSION_LOGGED_USER_ID));
        // now find out which is the latest invoice and make it available
        UserDTOEx user = (UserDTOEx) session.getAttribute(Constants.SESSION_USER_DTO);
        Integer invoiceId = user.getLastInvoiceId();
        if (invoiceId != null) {
          IInvoiceSessionBean invoiceSession =
              (IInvoiceSessionBean) Context.getBean(Context.Name.INVOICE_SESSION);
          InvoiceDTO invoice = invoiceSession.getInvoice(invoiceId);
          if (invoice.getToProcess().intValue() == 1) {
            session.setAttribute(Constants.SESSION_INVOICE_DTO, invoice);
            // this will chain the action, but it's effective
            forward = "last_invoice";
          }
        }

        if (forward.equals("no_invoice")) {
          messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("payment.error.noInvoice"));
        }
      } else if (action.equals("current_invoice")) {
        session.setAttribute(
            Constants.SESSION_USER_ID, session.getAttribute(Constants.SESSION_LOGGED_USER_ID));
        // the invoice dto is already in the sesssion .. piece of cake
        forward = "last_invoice";
      } else if (action.equals("cancel")) {
        session.removeAttribute(sessionKey);
        messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("payment.enter.cancel"));
        forward = "payment_list";
      } else if (action.equals("view")) {
        // this is called when a payment is selected from the list
        // for a read-only view

        Integer paymentId;
        if (request.getParameter("id") != null) {
          // this is being called from anywhere, to check out a payment
          paymentId = Integer.valueOf(request.getParameter("id"));
        } else {
          // this is called from the list of payments
          paymentId = (Integer) session.getAttribute(Constants.SESSION_LIST_ID_SELECTED);
        }
        Integer languageId = (Integer) session.getAttribute(Constants.SESSION_LANGUAGE);
        PaymentDTOEx dto = myRemoteSession.getPayment(paymentId, languageId);
        log.debug("my dto is " + dto);
        if (dto.getIsRefund() == 1) {
          session.setAttribute(Constants.SESSION_PAYMENT_DTO_REFUND, dto);
          if (dto.getPayment() != null) {
            session.setAttribute(
                Constants.SESSION_PAYMENT_DTO,
                myRemoteSession.getPayment(dto.getPayment().getId(), languageId));
          } else {
            session.removeAttribute(Constants.SESSION_PAYMENT_DTO);
          }

        } else {
          session.setAttribute(Constants.SESSION_PAYMENT_DTO, dto);
        }

        // now include the invoice and customer dto of this payment
        try {
          // now the user
          session.setAttribute(Constants.SESSION_USER_ID, dto.getUserId());

          ICustomerSessionBean userSession =
              (ICustomerSessionBean) Context.getBean(Context.Name.CUSTOMER_SESSION);
          session.setAttribute(
              Constants.SESSION_CUSTOMER_CONTACT_DTO,
              userSession.getPrimaryContactDTO(dto.getUserId()));

        } catch (Exception e) {
          throw new SessionInternalError(e);
        }

        forward = "payment_view";
      } else if (action.equals("notify")) {
        INotificationSessionBean notificationSession =
            (INotificationSessionBean) Context.getBean(Context.Name.NOTIFICATION_SESSION);
        Integer paymentId = Integer.valueOf(request.getParameter("id"));
        Boolean result = notificationSession.emailPayment(paymentId);
        String field;
        if (result.booleanValue()) {
          field = "email.notify.ok";
        } else {
          field = "email.notify.error";
        }
        messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(field));
        forward = "payment_view";
      } else if (action.equals("unlink")) {
        Integer mapId = Integer.valueOf(request.getParameter("mapId"));
        myRemoteSession.removeInvoiceLink(mapId);
        messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("payment.link.removalDone"));
        // make sure the payment now shows up updated
        session.setAttribute(
            Constants.SESSION_LIST_ID_SELECTED,
            ((PaymentDTO) session.getAttribute(Constants.SESSION_PAYMENT_DTO)).getId());
        session.removeAttribute(Constants.SESSION_PAYMENT_DTO);
        forward = "payment_setupView";
      } else if (action.equals("apply")) {
        // call the server to apply tha payment
        myRemoteSession.applyPayment(
            ((PaymentDTO) session.getAttribute(Constants.SESSION_PAYMENT_DTO)).getId(),
            ((InvoiceDTO) session.getAttribute(Constants.SESSION_INVOICE_DTO)).getId());
        // show a 'done' message
        messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("payment.link.applyDone"));
        // redirect to payment view, with the refreshed payment record
        session.setAttribute(
            Constants.SESSION_LIST_ID_SELECTED,
            ((PaymentDTO) session.getAttribute(Constants.SESSION_PAYMENT_DTO)).getId());
        session.removeAttribute(Constants.SESSION_PAYMENT_DTO);
        forward = "payment_setupView";
      } else {
        PaymentCrudAction delegate = new PaymentCrudAction(myRemoteSession);
        delegate.setServlet(getServlet());
        retValue = delegate.execute(mapping, form, request, response);
      }

      saveMessages(request, messages);
    } catch (Exception e) {
      log.error("Exception ", e);
      retValue = mapping.findForward("error");
      forward = null;
    }

    if (forward != null) {
      retValue = mapping.findForward(forward);
    }
    return retValue;
  }
  protected final void storeProcessedAuthorization(
      PaymentDTOEx paymentInfo, PaymentAuthorizationDTO auth) throws PluggableTaskException {

    new PaymentAuthorizationBL().create(auth, paymentInfo.getId());
    paymentInfo.setAuthorization(auth);
  }