Search in sources :

Example 1 with OrderPayment

use of org.broadleafcommerce.core.payment.domain.OrderPayment in project BroadleafCommerce by BroadleafCommerce.

the class CheckoutTest method addPaymentToOrder.

private OrderPayment addPaymentToOrder(Order order, Address address) {
    OrderPayment payment = new OrderPaymentImpl();
    payment.setBillingAddress(address);
    payment.setAmount(new Money(15D + (15D * 0.05D)));
    payment.setReferenceNumber("1234");
    payment.setType(PaymentType.CREDIT_CARD);
    payment.setPaymentGatewayType(NullIntegrationGatewayType.NULL_INTEGRATION_GATEWAY);
    payment.setOrder(order);
    PaymentTransaction tx = new PaymentTransactionImpl();
    tx.setAmount(payment.getAmount());
    tx.setType(PaymentTransactionType.AUTHORIZE_AND_CAPTURE);
    tx.setOrderPayment(payment);
    payment.getTransactions().add(tx);
    CreditCardPayment cc = new CreditCardPayment() {

        private static final long serialVersionUID = 1L;

        private String referenceNumber = "1234";

        @Override
        public String getCvvCode() {
            return "123";
        }

        @Override
        public Integer getExpirationMonth() {
            return 11;
        }

        @Override
        public Integer getExpirationYear() {
            return 2011;
        }

        @Override
        public Long getId() {
            return null;
        }

        @Override
        public String getPan() {
            return "1111111111111111";
        }

        @Override
        public String getNameOnCard() {
            return "Cardholder Name";
        }

        @Override
        public void setCvvCode(String cvvCode) {
        // do nothing
        }

        @Override
        public void setExpirationMonth(Integer expirationMonth) {
        // do nothing
        }

        @Override
        public void setExpirationYear(Integer expirationYear) {
        // do nothing
        }

        @Override
        public void setId(Long id) {
        // do nothing
        }

        @Override
        public void setNameOnCard(String nameOnCard) {
        // do nothing
        }

        @Override
        public void setPan(String pan) {
        // do nothing
        }

        @Override
        public EncryptionModule getEncryptionModule() {
            return encryptionModule;
        }

        @Override
        public String getReferenceNumber() {
            return referenceNumber;
        }

        @Override
        public void setEncryptionModule(EncryptionModule encryptionModule) {
        // do nothing
        }

        @Override
        public void setReferenceNumber(String referenceNumber) {
            this.referenceNumber = referenceNumber;
        }
    };
    order.getPayments().add(payment);
    return payment;
}
Also used : PaymentTransaction(org.broadleafcommerce.core.payment.domain.PaymentTransaction) Money(org.broadleafcommerce.common.money.Money) CreditCardPayment(org.broadleafcommerce.core.payment.domain.secure.CreditCardPayment) OrderPaymentImpl(org.broadleafcommerce.core.payment.domain.OrderPaymentImpl) PaymentTransactionImpl(org.broadleafcommerce.core.payment.domain.PaymentTransactionImpl) EncryptionModule(org.broadleafcommerce.common.encryption.EncryptionModule) OrderPayment(org.broadleafcommerce.core.payment.domain.OrderPayment)

Example 2 with OrderPayment

use of org.broadleafcommerce.core.payment.domain.OrderPayment in project BroadleafCommerce by BroadleafCommerce.

the class DefaultPaymentGatewayCheckoutService method markPaymentAsInvalid.

@Override
public void markPaymentAsInvalid(Long orderPaymentId) {
    OrderPayment payment = orderPaymentService.readPaymentById(orderPaymentId);
    if (payment == null) {
        throw new IllegalArgumentException("Could not find payment with id " + orderPaymentId);
    }
    // Do not do an actual delete here, otherwise Hibernate will screw up the relationships by setting parent transactions
    // to null because of the cascades. This manifests itself when you have an AUTHORIZE_AND_CAPTURE transaction and
    // then an immediate VOID (like if there is an exception in the checkout workflow). The VOID transaction should
    // have its parent set to the AUTHORIZE_AND_CAPTURE transaction which works up until we call Hibernate's delete
    // on the payment. By cascading down to the transaction, Hibernate goes and removes the parentTransaction relationship
    // from the VOID transaction
    // The fix is to set archived statuses manually and not rely on Hibernate's @SqlDelete
    payment.setArchived('Y');
    for (PaymentTransaction transaction : payment.getTransactions()) {
        transaction.setArchived('Y');
    }
    orderPaymentService.save(payment);
}
Also used : PaymentTransaction(org.broadleafcommerce.core.payment.domain.PaymentTransaction) OrderPayment(org.broadleafcommerce.core.payment.domain.OrderPayment)

Example 3 with OrderPayment

use of org.broadleafcommerce.core.payment.domain.OrderPayment in project BroadleafCommerce by BroadleafCommerce.

the class DefaultPaymentGatewayCheckoutService method applyPaymentToOrder.

@Override
public Long applyPaymentToOrder(PaymentResponseDTO responseDTO, PaymentGatewayConfiguration config) {
    // Payments can ONLY be parsed into Order Payments if they are 'valid'
    if (!responseDTO.isValid()) {
        throw new IllegalArgumentException("Invalid payment responses cannot be parsed into the order payment domain");
    }
    if (config == null) {
        throw new IllegalArgumentException("Config service cannot be null");
    }
    Long orderId = Long.parseLong(responseDTO.getOrderId());
    Order order = orderService.findOrderById(orderId);
    if (!OrderStatus.IN_PROCESS.equals(order.getStatus()) && !OrderStatus.CSR_OWNED.equals(order.getStatus()) && !OrderStatus.QUOTE.equals(order.getStatus())) {
        throw new IllegalArgumentException("Cannot apply another payment to an Order that is not IN_PROCESS or CSR_OWNED");
    }
    Customer customer = order.getCustomer();
    if (customer.isAnonymous()) {
        GatewayCustomerDTO<PaymentResponseDTO> gatewayCustomer = responseDTO.getCustomer();
        if (StringUtils.isEmpty(customer.getFirstName()) && gatewayCustomer != null) {
            customer.setFirstName(gatewayCustomer.getFirstName());
        }
        if (StringUtils.isEmpty(customer.getLastName()) && gatewayCustomer != null) {
            customer.setLastName(gatewayCustomer.getLastName());
        }
        if (StringUtils.isEmpty(customer.getEmailAddress()) && gatewayCustomer != null) {
            customer.setEmailAddress(gatewayCustomer.getEmail());
        }
    }
    // If the gateway sends back an email address and the order does not contain one, set it.
    GatewayCustomerDTO<PaymentResponseDTO> gatewayCustomer = responseDTO.getCustomer();
    if (order.getEmailAddress() == null && gatewayCustomer != null) {
        order.setEmailAddress(gatewayCustomer.getEmail());
    }
    // If the gateway sends back Shipping Information, we will save that to the first shippable fulfillment group.
    dtoToEntityService.populateShippingInfo(responseDTO, order);
    // ALWAYS create a new order payment for the payment that comes in. Invalid payments should be cleaned up by
    // invoking {@link #markPaymentAsInvalid}.
    OrderPayment payment = orderPaymentService.create();
    payment.setType(responseDTO.getPaymentType());
    payment.setPaymentGatewayType(responseDTO.getPaymentGatewayType());
    payment.setAmount(responseDTO.getAmount());
    // If this gateway does not support multiple payments then mark all of the existing payments
    // as invalid before adding the new one
    List<OrderPayment> paymentsToInvalidate = new ArrayList<OrderPayment>();
    Address tempBillingAddress = null;
    if (!config.handlesMultiplePayments()) {
        PaymentGatewayType gateway = config.getGatewayType();
        for (OrderPayment p : order.getPayments()) {
            // - The payment being added has the same gateway type of an existing one.
            if (PaymentGatewayType.TEMPORARY.equals(p.getGatewayType()) || (p.isFinalPayment() && payment.isFinalPayment()) || (p.getGatewayType() != null && p.getGatewayType().equals(gateway))) {
                paymentsToInvalidate.add(p);
                if (PaymentGatewayType.TEMPORARY.equals(p.getGatewayType())) {
                    tempBillingAddress = p.getBillingAddress();
                }
            }
        }
    }
    for (OrderPayment invalid : paymentsToInvalidate) {
        // 2
        markPaymentAsInvalid(invalid.getId());
    }
    // The billing address that will be saved on the order will be parsed off the
    // Response DTO sent back from the Gateway as it may have Address Verification or Standardization.
    // If you do not wish to use the Billing Address coming back from the Gateway, you can override the
    // populateBillingInfo() method or set the useBillingAddressFromGateway property.
    dtoToEntityService.populateBillingInfo(responseDTO, payment, tempBillingAddress, isUseBillingAddressFromGateway());
    // Create the transaction for the payment
    PaymentTransaction transaction = orderPaymentService.createTransaction();
    transaction.setAmount(responseDTO.getAmount());
    transaction.setRawResponse(responseDTO.getRawResponse());
    transaction.setSuccess(responseDTO.isSuccessful());
    transaction.setType(responseDTO.getPaymentTransactionType());
    for (Entry<String, String> entry : responseDTO.getResponseMap().entrySet()) {
        transaction.getAdditionalFields().put(entry.getKey(), entry.getValue());
    }
    // Set the Credit Card Info on the Additional Fields Map
    if (responseDTO.getCreditCard() != null && responseDTO.getCreditCard().creditCardPopulated()) {
        transaction.getAdditionalFields().put(PaymentAdditionalFieldType.NAME_ON_CARD.getType(), responseDTO.getCreditCard().getCreditCardHolderName());
        transaction.getAdditionalFields().put(PaymentAdditionalFieldType.CARD_TYPE.getType(), responseDTO.getCreditCard().getCreditCardType());
        transaction.getAdditionalFields().put(PaymentAdditionalFieldType.EXP_DATE.getType(), responseDTO.getCreditCard().getCreditCardExpDate());
        transaction.getAdditionalFields().put(PaymentAdditionalFieldType.LAST_FOUR.getType(), responseDTO.getCreditCard().getCreditCardLastFour());
    }
    // TODO: validate that this particular type of transaction can be added to the payment (there might already
    // be an AUTHORIZE transaction, for instance)
    // Persist the order payment as well as its transaction
    payment.setOrder(order);
    transaction.setOrderPayment(payment);
    payment.addTransaction(transaction);
    payment = orderPaymentService.save(payment);
    if (transaction.getSuccess()) {
        orderService.addPaymentToOrder(order, payment, null);
    } else {
        // We will have to mark the entire payment as invalid and boot the user to re-enter their
        // billing info and payment information as there may be an error either with the billing address/or credit card
        handleUnsuccessfulTransaction(payment);
    }
    return payment.getId();
}
Also used : Order(org.broadleafcommerce.core.order.domain.Order) Address(org.broadleafcommerce.profile.core.domain.Address) Customer(org.broadleafcommerce.profile.core.domain.Customer) ArrayList(java.util.ArrayList) OrderPayment(org.broadleafcommerce.core.payment.domain.OrderPayment) PaymentGatewayType(org.broadleafcommerce.common.payment.PaymentGatewayType) PaymentTransaction(org.broadleafcommerce.core.payment.domain.PaymentTransaction) PaymentResponseDTO(org.broadleafcommerce.common.payment.dto.PaymentResponseDTO)

Example 4 with OrderPayment

use of org.broadleafcommerce.core.payment.domain.OrderPayment in project BroadleafCommerce by BroadleafCommerce.

the class OrderPaymentServiceImpl method createOrderPaymentFromCustomerPayment.

@Override
@Transactional(value = TransactionUtils.DEFAULT_TRANSACTION_MANAGER)
public OrderPayment createOrderPaymentFromCustomerPayment(Order order, CustomerPayment customerPayment, Money amount) {
    OrderPayment orderPayment = create();
    orderPayment.setOrder(order);
    orderPayment.setBillingAddress(addressService.copyAddress(customerPayment.getBillingAddress()));
    PaymentGatewayType gatewayType = customerPayment.getPaymentGatewayType();
    PaymentType paymentType = customerPayment.getPaymentType();
    Map<String, String> additionalFields = customerPayment.getAdditionalFields();
    if (gatewayType == null || paymentType == null) {
        if (MapUtils.isEmpty(additionalFields)) {
            additionalFields = new HashMap<>();
        }
        String paymentTypeKey = PaymentAdditionalFieldType.PAYMENT_TYPE.getType();
        if (additionalFields.containsKey(paymentTypeKey)) {
            paymentType = PaymentType.getInstance(additionalFields.get(paymentTypeKey));
        }
        String gatewayTypeKey = PaymentAdditionalFieldType.GATEWAY_TYPE.getType();
        if (additionalFields.containsKey(gatewayTypeKey)) {
            gatewayType = PaymentGatewayType.getInstance(additionalFields.get(gatewayTypeKey));
        }
    }
    orderPayment.setPaymentGatewayType(gatewayType);
    orderPayment.setType(paymentType);
    orderPayment.setAmount(amount);
    PaymentTransaction unconfirmedTransaction = createTransaction();
    unconfirmedTransaction.setAmount(amount);
    unconfirmedTransaction.setType(PaymentTransactionType.UNCONFIRMED);
    unconfirmedTransaction.setOrderPayment(orderPayment);
    unconfirmedTransaction.getAdditionalFields().put(PaymentAdditionalFieldType.TOKEN.getType(), customerPayment.getPaymentToken());
    unconfirmedTransaction.getAdditionalFields().putAll(customerPayment.getAdditionalFields());
    orderPayment.getTransactions().add(unconfirmedTransaction);
    return save(orderPayment);
}
Also used : PaymentTransaction(org.broadleafcommerce.core.payment.domain.PaymentTransaction) PaymentType(org.broadleafcommerce.common.payment.PaymentType) OrderPayment(org.broadleafcommerce.core.payment.domain.OrderPayment) PaymentGatewayType(org.broadleafcommerce.common.payment.PaymentGatewayType) Transactional(org.springframework.transaction.annotation.Transactional)

Example 5 with OrderPayment

use of org.broadleafcommerce.core.payment.domain.OrderPayment in project BroadleafCommerce by BroadleafCommerce.

the class BroadleafBillingInfoController method saveBillingAddress.

/**
 * Processes the request to save a billing address.
 *
 * Note: this default Broadleaf implementation will create an OrderPayment of
 * type CREDIT_CARD if it doesn't exist and save the passed in billing address
 *
 * @param request
 * @param response
 * @param model
 * @param billingForm
 * @return the return path
 * @throws org.broadleafcommerce.common.exception.ServiceException
 */
public String saveBillingAddress(HttpServletRequest request, HttpServletResponse response, Model model, BillingInfoForm billingForm, BindingResult result) throws PricingException, ServiceException {
    Order cart = CartState.getCart();
    CustomerPayment customerPayment = null;
    if (billingForm.isUseShippingAddress()) {
        copyShippingAddressToBillingAddress(cart, billingForm);
    }
    Boolean useCustomerPayment = billingForm.getUseCustomerPayment();
    if (useCustomerPayment && billingForm.getCustomerPaymentId() != null) {
        customerPayment = customerPaymentService.readCustomerPaymentById(billingForm.getCustomerPaymentId());
        if (customerPayment != null) {
            Address address = customerPayment.getBillingAddress();
            if (address != null) {
                billingForm.setAddress(addressService.copyAddress(address));
            }
        }
    }
    addressService.populateAddressISOCountrySub(billingForm.getAddress());
    billingInfoFormValidator.validate(billingForm, result);
    if (result.hasErrors()) {
        return getCheckoutView();
    }
    if ((billingForm.getAddress().getPhonePrimary() != null) && (StringUtils.isEmpty(billingForm.getAddress().getPhonePrimary().getPhoneNumber()))) {
        billingForm.getAddress().setPhonePrimary(null);
    }
    if ((billingForm.getAddress().getPhoneSecondary() != null) && (StringUtils.isEmpty(billingForm.getAddress().getPhoneSecondary().getPhoneNumber()))) {
        billingForm.getAddress().setPhoneSecondary(null);
    }
    if ((billingForm.getAddress().getPhoneFax() != null) && (StringUtils.isEmpty(billingForm.getAddress().getPhoneFax().getPhoneNumber()))) {
        billingForm.getAddress().setPhoneFax(null);
    }
    boolean found = false;
    String paymentName = billingForm.getPaymentName();
    Boolean saveNewPayment = billingForm.getSaveNewPayment();
    for (OrderPayment p : cart.getPayments()) {
        if (PaymentType.CREDIT_CARD.equals(p.getType()) && p.isActive()) {
            if (p.getBillingAddress() == null) {
                p.setBillingAddress(billingForm.getAddress());
            } else {
                Address updatedAddress = addressService.copyAddress(p.getBillingAddress(), billingForm.getAddress());
                p.setBillingAddress(updatedAddress);
            }
            found = true;
        }
    }
    if (!found) {
        // A Temporary Order Payment will be created to hold the billing address.
        // The Payment Gateway will send back any validated address and
        // the PaymentGatewayCheckoutService will persist a new payment of type CREDIT_CARD when it applies it to the Order
        OrderPayment tempOrderPayment = orderPaymentService.create();
        tempOrderPayment.setType(PaymentType.CREDIT_CARD);
        tempOrderPayment.setPaymentGatewayType(PaymentGatewayType.TEMPORARY);
        tempOrderPayment.setBillingAddress(billingForm.getAddress());
        tempOrderPayment.setOrder(cart);
        cart.getPayments().add(tempOrderPayment);
    }
    orderService.save(cart, true);
    if (isAjaxRequest(request)) {
        // Add module specific model variables
        checkoutControllerExtensionManager.getProxy().addAdditionalModelVariables(model);
        return getCheckoutView();
    } else {
        return getCheckoutPageRedirect();
    }
}
Also used : Order(org.broadleafcommerce.core.order.domain.Order) Address(org.broadleafcommerce.profile.core.domain.Address) CustomerPayment(org.broadleafcommerce.profile.core.domain.CustomerPayment) OrderPayment(org.broadleafcommerce.core.payment.domain.OrderPayment)

Aggregations

OrderPayment (org.broadleafcommerce.core.payment.domain.OrderPayment)33 Order (org.broadleafcommerce.core.order.domain.Order)16 PaymentTransaction (org.broadleafcommerce.core.payment.domain.PaymentTransaction)11 Money (org.broadleafcommerce.common.money.Money)7 ArrayList (java.util.ArrayList)6 Transactional (org.springframework.transaction.annotation.Transactional)6 PaymentResponseDTO (org.broadleafcommerce.common.payment.dto.PaymentResponseDTO)5 Address (org.broadleafcommerce.profile.core.domain.Address)5 HashMap (java.util.HashMap)4 CheckoutException (org.broadleafcommerce.core.checkout.service.exception.CheckoutException)3 Customer (org.broadleafcommerce.profile.core.domain.Customer)3 Test (org.testng.annotations.Test)3 PaymentGatewayType (org.broadleafcommerce.common.payment.PaymentGatewayType)2 PaymentRequestDTO (org.broadleafcommerce.common.payment.dto.PaymentRequestDTO)2 PaymentGatewayConfigurationService (org.broadleafcommerce.common.payment.service.PaymentGatewayConfigurationService)2 AdminPresentationMergeOverride (org.broadleafcommerce.common.presentation.override.AdminPresentationMergeOverride)2 OrderPaymentImpl (org.broadleafcommerce.core.payment.domain.OrderPaymentImpl)2 WorkflowException (org.broadleafcommerce.core.workflow.WorkflowException)2 CustomerAddress (org.broadleafcommerce.profile.core.domain.CustomerAddress)2 Collection (java.util.Collection)1