Search in sources :

Example 1 with PaymentProxy

use of alfio.model.transaction.PaymentProxy in project alf.io by alfio-event.

the class TicketReservationManager method confirm.

public PaymentResult confirm(String gatewayToken, String payerId, Event event, String reservationId, String email, CustomerName customerName, Locale userLanguage, String billingAddress, TotalPrice reservationCost, Optional<String> specialPriceSessionId, Optional<PaymentProxy> method, boolean invoiceRequested, String vatCountryCode, String vatNr, PriceContainer.VatStatus vatStatus) {
    PaymentProxy paymentProxy = evaluatePaymentProxy(method, reservationCost);
    if (!initPaymentProcess(reservationCost, paymentProxy, reservationId, email, customerName, userLanguage, billingAddress)) {
        return PaymentResult.unsuccessful("error.STEP2_UNABLE_TO_TRANSITION");
    }
    try {
        PaymentResult paymentResult;
        ticketReservationRepository.lockReservationForUpdate(reservationId);
        if (reservationCost.getPriceWithVAT() > 0) {
            if (invoiceRequested && configurationManager.hasAllConfigurationsForInvoice(event)) {
                int invoiceSequence = invoiceSequencesRepository.lockReservationForUpdate(event.getOrganizationId());
                invoiceSequencesRepository.incrementSequenceFor(event.getOrganizationId());
                String pattern = configurationManager.getStringConfigValue(Configuration.from(event.getOrganizationId(), event.getId(), ConfigurationKeys.INVOICE_NUMBER_PATTERN), "%d");
                ticketReservationRepository.setInvoiceNumber(reservationId, String.format(pattern, invoiceSequence));
            }
            ticketReservationRepository.updateBillingData(vatStatus, vatNr, vatCountryCode, invoiceRequested, reservationId);
            // 
            extensionManager.handleInvoiceGeneration(event, reservationId, email, customerName, userLanguage, billingAddress, reservationCost, invoiceRequested, vatCountryCode, vatNr, vatStatus).ifPresent(invoiceGeneration -> {
                if (invoiceGeneration.getInvoiceNumber() != null) {
                    ticketReservationRepository.setInvoiceNumber(reservationId, invoiceGeneration.getInvoiceNumber());
                }
            });
            // 
            switch(paymentProxy) {
                case STRIPE:
                    paymentResult = paymentManager.processStripePayment(reservationId, gatewayToken, reservationCost.getPriceWithVAT(), event, email, customerName, billingAddress);
                    if (!paymentResult.isSuccessful()) {
                        reTransitionToPending(reservationId);
                        return paymentResult;
                    }
                    break;
                case PAYPAL:
                    paymentResult = paymentManager.processPayPalPayment(reservationId, gatewayToken, payerId, reservationCost.getPriceWithVAT(), event);
                    if (!paymentResult.isSuccessful()) {
                        reTransitionToPending(reservationId);
                        return paymentResult;
                    }
                    break;
                case OFFLINE:
                    transitionToOfflinePayment(event, reservationId, email, customerName, billingAddress);
                    paymentResult = PaymentResult.successful(NOT_YET_PAID_TRANSACTION_ID);
                    break;
                case ON_SITE:
                    paymentResult = PaymentResult.successful(NOT_YET_PAID_TRANSACTION_ID);
                    break;
                default:
                    throw new IllegalArgumentException("Payment proxy " + paymentProxy + " not recognized");
            }
        } else {
            paymentResult = PaymentResult.successful(NOT_YET_PAID_TRANSACTION_ID);
        }
        completeReservation(event.getId(), reservationId, email, customerName, userLanguage, billingAddress, specialPriceSessionId, paymentProxy);
        return paymentResult;
    } catch (Exception ex) {
        // it is guaranteed that in this case we're dealing with "local" error (e.g. database failure),
        // thus it is safer to not rollback the reservation status
        log.error("unexpected error during payment confirmation", ex);
        return PaymentResult.unsuccessful("error.STEP2_STRIPE_unexpected");
    }
}
Also used : PaymentProxy(alfio.model.transaction.PaymentProxy) PaymentResult(alfio.manager.support.PaymentResult) IOException(java.io.IOException)

Example 2 with PaymentProxy

use of alfio.model.transaction.PaymentProxy in project alf.io by alfio-event.

the class PaymentForm method validate.

public void validate(BindingResult bindingResult, TotalPrice reservationCost, Event event, List<TicketFieldConfiguration> fieldConf) {
    List<PaymentProxy> allowedPaymentMethods = event.getAllowedPaymentProxies();
    Optional<PaymentProxy> paymentProxyOptional = Optional.ofNullable(paymentMethod);
    PaymentProxy paymentProxy = paymentProxyOptional.filter(allowedPaymentMethods::contains).orElse(PaymentProxy.STRIPE);
    boolean priceGreaterThanZero = reservationCost.getPriceWithVAT() > 0;
    boolean multiplePaymentMethods = allowedPaymentMethods.size() > 1;
    if (multiplePaymentMethods && priceGreaterThanZero && !paymentProxyOptional.isPresent()) {
        bindingResult.reject(ErrorsCode.STEP_2_MISSING_PAYMENT_METHOD);
    } else if (priceGreaterThanZero && (paymentProxy == PaymentProxy.STRIPE && StringUtils.isBlank(stripeToken))) {
        bindingResult.reject(ErrorsCode.STEP_2_MISSING_STRIPE_TOKEN);
    }
    if (Objects.isNull(termAndConditionsAccepted) || !termAndConditionsAccepted) {
        bindingResult.reject(ErrorsCode.STEP_2_TERMS_NOT_ACCEPTED);
    }
    email = StringUtils.trim(email);
    fullName = StringUtils.trim(fullName);
    firstName = StringUtils.trim(firstName);
    lastName = StringUtils.trim(lastName);
    billingAddress = StringUtils.trim(billingAddress);
    ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "email", ErrorsCode.STEP_2_EMPTY_EMAIL);
    rejectIfOverLength(bindingResult, "email", ErrorsCode.STEP_2_MAX_LENGTH_EMAIL, email, 255);
    if (event.mustUseFirstAndLastName()) {
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "firstName", ErrorsCode.STEP_2_EMPTY_FIRSTNAME);
        rejectIfOverLength(bindingResult, "firstName", ErrorsCode.STEP_2_MAX_LENGTH_FIRSTNAME, fullName, 255);
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "lastName", ErrorsCode.STEP_2_EMPTY_LASTNAME);
        rejectIfOverLength(bindingResult, "lastName", ErrorsCode.STEP_2_MAX_LENGTH_LASTNAME, fullName, 255);
    } else {
        ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "fullName", ErrorsCode.STEP_2_EMPTY_FULLNAME);
        rejectIfOverLength(bindingResult, "fullName", ErrorsCode.STEP_2_MAX_LENGTH_FULLNAME, fullName, 255);
    }
    rejectIfOverLength(bindingResult, "billingAddress", ErrorsCode.STEP_2_MAX_LENGTH_BILLING_ADDRESS, billingAddress, 450);
    if (email != null && !email.contains("@") && !bindingResult.hasFieldErrors("email")) {
        bindingResult.rejectValue("email", ErrorsCode.STEP_2_INVALID_EMAIL);
    }
    if (hasPaypalTokens() && !PaypalManager.isValidHMAC(new CustomerName(fullName, firstName, lastName, event), email, billingAddress, hmac, event)) {
        bindingResult.reject(ErrorsCode.STEP_2_INVALID_HMAC);
    }
    if (!postponeAssignment) {
        boolean success = Optional.ofNullable(tickets).filter(m -> !m.isEmpty()).map(m -> m.entrySet().stream().map(e -> Validator.validateTicketAssignment(e.getValue(), fieldConf, Optional.empty(), event))).filter(s -> s.allMatch(ValidationResult::isSuccess)).isPresent();
        if (!success) {
            bindingResult.reject(ErrorsCode.STEP_2_MISSING_ATTENDEE_DATA);
        }
    }
}
Also used : PaymentProxy(alfio.model.transaction.PaymentProxy) ValidationResult(alfio.model.result.ValidationResult) java.util(java.util) PaypalManager(alfio.manager.PaypalManager) PaymentProxy(alfio.model.transaction.PaymentProxy) ValidationUtils(org.springframework.validation.ValidationUtils) alfio.model(alfio.model) Data(lombok.Data) BindingResult(org.springframework.validation.BindingResult) ErrorsCode(alfio.util.ErrorsCode) Validator(alfio.util.Validator) StringUtils(org.apache.commons.lang3.StringUtils) Serializable(java.io.Serializable) ValidationResult(alfio.model.result.ValidationResult)

Example 3 with PaymentProxy

use of alfio.model.transaction.PaymentProxy in project alf.io by alfio-event.

the class ReservationApiController method validateEUVat.

@RequestMapping(value = "/event/{eventName}/reservation/{reservationId}/vat-validation", method = RequestMethod.POST)
@Transactional
public ResponseEntity<VatDetail> validateEUVat(@PathVariable("eventName") String eventName, @PathVariable("reservationId") String reservationId, PaymentForm paymentForm, Locale locale, HttpServletRequest request) {
    String country = paymentForm.getVatCountryCode();
    Optional<Triple<Event, TicketReservation, VatDetail>> vatDetail = eventRepository.findOptionalByShortName(eventName).flatMap(e -> ticketReservationRepository.findOptionalReservationById(reservationId).map(r -> Pair.of(e, r))).filter(e -> EnumSet.of(INCLUDED, NOT_INCLUDED).contains(e.getKey().getVatStatus())).filter(e -> vatChecker.isVatCheckingEnabledFor(e.getKey().getOrganizationId())).flatMap(e -> vatChecker.checkVat(paymentForm.getVatNr(), country, e.getKey().getOrganizationId()).map(vd -> Triple.of(e.getLeft(), e.getRight(), vd)));
    vatDetail.filter(t -> t.getRight().isValid()).ifPresent(t -> {
        VatDetail vd = t.getRight();
        String billingAddress = vd.getName() + "\n" + vd.getAddress();
        PriceContainer.VatStatus vatStatus = determineVatStatus(t.getLeft().getVatStatus(), t.getRight().isVatExempt());
        ticketReservationRepository.updateBillingData(vatStatus, vd.getVatNr(), country, paymentForm.isInvoiceRequested(), reservationId);
        OrderSummary orderSummary = ticketReservationManager.orderSummaryForReservationId(reservationId, t.getLeft(), Locale.forLanguageTag(t.getMiddle().getUserLanguage()));
        ticketReservationRepository.addReservationInvoiceOrReceiptModel(reservationId, Json.toJson(orderSummary));
        ticketReservationRepository.updateTicketReservation(reservationId, t.getMiddle().getStatus().name(), paymentForm.getEmail(), paymentForm.getFullName(), paymentForm.getFirstName(), paymentForm.getLastName(), locale.getLanguage(), billingAddress, null, Optional.ofNullable(paymentForm.getPaymentMethod()).map(PaymentProxy::name).orElse(null));
        paymentForm.getTickets().forEach((ticketId, owner) -> {
            if (isNotEmpty(owner.getEmail()) && ((isNotEmpty(owner.getFirstName()) && isNotEmpty(owner.getLastName())) || isNotEmpty(owner.getFullName()))) {
                ticketHelper.preAssignTicket(eventName, reservationId, ticketId, owner, Optional.empty(), request, (tr) -> {
                }, Optional.empty());
            }
        });
    });
    return vatDetail.map(Triple::getRight).map(vd -> {
        if (vd.isValid()) {
            return ResponseEntity.ok(vd);
        } else {
            return new ResponseEntity<VatDetail>(HttpStatus.BAD_REQUEST);
        }
    }).orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
Also used : Triple(org.apache.commons.lang3.tuple.Triple) ValidationResult(alfio.model.result.ValidationResult) java.util(java.util) TicketHelper(alfio.controller.api.support.TicketHelper) PaymentProxy(alfio.model.transaction.PaymentProxy) TicketReservationRepository(alfio.repository.TicketReservationRepository) PaymentForm(alfio.controller.form.PaymentForm) BindingResult(org.springframework.validation.BindingResult) StringUtils.isNotEmpty(org.apache.commons.lang3.StringUtils.isNotEmpty) RequestContextUtils(org.springframework.web.servlet.support.RequestContextUtils) Json(alfio.util.Json) Model(org.springframework.ui.Model) HttpServletRequest(javax.servlet.http.HttpServletRequest) Pair(org.apache.commons.lang3.tuple.Pair) EuVatChecker(alfio.manager.EuVatChecker) UserDetails(org.springframework.security.core.userdetails.UserDetails) Triple(org.apache.commons.lang3.tuple.Triple) VatStatus(alfio.model.PriceContainer.VatStatus) TemplateManager(alfio.util.TemplateManager) UpdateTicketOwnerForm(alfio.controller.form.UpdateTicketOwnerForm) EventRepository(alfio.repository.EventRepository) Collectors(java.util.stream.Collectors) HttpStatus(org.springframework.http.HttpStatus) TicketReservationManager(alfio.manager.TicketReservationManager) alfio.model(alfio.model) org.springframework.web.bind.annotation(org.springframework.web.bind.annotation) ResponseEntity(org.springframework.http.ResponseEntity) I18nManager(alfio.manager.i18n.I18nManager) AllArgsConstructor(lombok.AllArgsConstructor) Authentication(org.springframework.security.core.Authentication) Transactional(org.springframework.transaction.annotation.Transactional) PaymentProxy(alfio.model.transaction.PaymentProxy) VatStatus(alfio.model.PriceContainer.VatStatus) Transactional(org.springframework.transaction.annotation.Transactional)

Example 4 with PaymentProxy

use of alfio.model.transaction.PaymentProxy in project alf.io by alfio-event.

the class TicketReservationManager method acquireItems.

private void acquireItems(TicketStatus ticketStatus, AdditionalServiceItemStatus asStatus, PaymentProxy paymentProxy, String reservationId, String email, CustomerName customerName, String userLanguage, String billingAddress, int eventId) {
    Map<Integer, Ticket> preUpdateTicket = ticketRepository.findTicketsInReservation(reservationId).stream().collect(toMap(Ticket::getId, Function.identity()));
    int updatedTickets = ticketRepository.updateTicketsStatusWithReservationId(reservationId, ticketStatus.toString());
    Map<Integer, Ticket> postUpdateTicket = ticketRepository.findTicketsInReservation(reservationId).stream().collect(toMap(Ticket::getId, Function.identity()));
    postUpdateTicket.forEach((id, ticket) -> {
        auditUpdateTicket(preUpdateTicket.get(id), Collections.emptyMap(), ticket, Collections.emptyMap(), eventId);
    });
    int updatedAS = additionalServiceItemRepository.updateItemsStatusWithReservationUUID(reservationId, asStatus);
    Validate.isTrue(updatedTickets + updatedAS > 0, "no items have been updated");
    specialPriceRepository.updateStatusForReservation(singletonList(reservationId), Status.TAKEN.toString());
    ZonedDateTime timestamp = ZonedDateTime.now(ZoneId.of("UTC"));
    int updatedReservation = ticketReservationRepository.updateTicketReservation(reservationId, TicketReservationStatus.COMPLETE.toString(), email, customerName.getFullName(), customerName.getFirstName(), customerName.getLastName(), userLanguage, billingAddress, timestamp, paymentProxy.toString());
    Validate.isTrue(updatedReservation == 1, "expected exactly one updated reservation, got " + updatedReservation);
    waitingQueueManager.fireReservationConfirmed(reservationId);
    if (paymentProxy == PaymentProxy.PAYPAL || paymentProxy == PaymentProxy.ADMIN) {
        // we must notify the plugins about ticket assignment and send them by email
        Event event = eventRepository.findByReservationId(reservationId);
        TicketReservation reservation = findById(reservationId).orElseThrow(IllegalStateException::new);
        findTicketsInReservation(reservationId).stream().filter(ticket -> StringUtils.isNotBlank(ticket.getFullName()) || StringUtils.isNotBlank(ticket.getFirstName()) || StringUtils.isNotBlank(ticket.getEmail())).forEach(ticket -> {
            Locale locale = Locale.forLanguageTag(ticket.getUserLanguage());
            if (paymentProxy == PaymentProxy.PAYPAL) {
                sendTicketByEmail(ticket, locale, event, getTicketEmailGenerator(event, reservation, locale));
            }
            extensionManager.handleTicketAssignment(ticket);
        });
    }
}
Also used : alfio.repository(alfio.repository) PaymentProxy(alfio.model.transaction.PaymentProxy) DiscountType(alfio.model.PromoCodeDiscount.DiscountType) ZonedDateTime(java.time.ZonedDateTime) PaymentResult(alfio.manager.support.PaymentResult) AdditionalServicePriceContainer(alfio.model.decorator.AdditionalServicePriceContainer) PartialTicketTextGenerator(alfio.manager.support.PartialTicketTextGenerator) Mailer(alfio.manager.system.Mailer) TicketStatus(alfio.model.Ticket.TicketStatus) StringUtils(org.apache.commons.lang3.StringUtils) Collections.singletonList(java.util.Collections.singletonList) BigDecimal(java.math.BigDecimal) MonetaryUtil.formatCents(alfio.util.MonetaryUtil.formatCents) DateUtils.truncate(org.apache.commons.lang3.time.DateUtils.truncate) Pair(org.apache.commons.lang3.tuple.Pair) OFFLINE_PAYMENT(alfio.model.TicketReservation.TicketReservationStatus.OFFLINE_PAYMENT) Arrays.asList(java.util.Arrays.asList) ASReservationWithOptionalCodeModification(alfio.model.modification.ASReservationWithOptionalCodeModification) DefaultTransactionDefinition(org.springframework.transaction.support.DefaultTransactionDefinition) Triple(org.apache.commons.lang3.tuple.Triple) OrganizationRepository(alfio.repository.user.OrganizationRepository) Organization(alfio.model.user.Organization) Predicate(java.util.function.Predicate) FeeCalculator(alfio.manager.support.FeeCalculator) Visit(de.danielbechler.diff.node.Visit) Collectors(java.util.stream.Collectors) ZoneId(java.time.ZoneId) DiffNode(de.danielbechler.diff.node.DiffNode) Role(alfio.model.user.Role) Stream(java.util.stream.Stream) PlatformTransactionManager(org.springframework.transaction.PlatformTransactionManager) alfio.model(alfio.model) UserRepository(alfio.repository.user.UserRepository) AdditionalServiceItemPriceContainer(alfio.model.decorator.AdditionalServiceItemPriceContainer) Configuration(alfio.model.system.Configuration) AdditionalServiceItemStatus(alfio.model.AdditionalServiceItem.AdditionalServiceItemStatus) AdditionalServiceReservationModification(alfio.model.modification.AdditionalServiceReservationModification) OptionalWrapper.optionally(alfio.util.OptionalWrapper.optionally) IntStream(java.util.stream.IntStream) java.util(java.util) MonetaryUtil.unitToCents(alfio.util.MonetaryUtil.unitToCents) TransactionDefinition(org.springframework.transaction.TransactionDefinition) ConfigurationManager(alfio.manager.system.ConfigurationManager) Function(java.util.function.Function) alfio.util(alfio.util) TicketPriceContainer(alfio.model.decorator.TicketPriceContainer) IN_PAYMENT(alfio.model.TicketReservation.TicketReservationStatus.IN_PAYMENT) UserDetails(org.springframework.security.core.userdetails.UserDetails) TicketReservationStatus(alfio.model.TicketReservation.TicketReservationStatus) MessageSource(org.springframework.context.MessageSource) ObjectDifferBuilder(de.danielbechler.diff.ObjectDifferBuilder) TicketReservationWithOptionalCodeModification(alfio.model.modification.TicketReservationWithOptionalCodeModification) UpdateTicketOwnerForm(alfio.controller.form.UpdateTicketOwnerForm) IOException(java.io.IOException) Status(alfio.model.SpecialPrice.Status) DateUtils.addHours(org.apache.commons.lang3.time.DateUtils.addHours) Component(org.springframework.stereotype.Component) Validate(org.apache.commons.lang3.Validate) ChronoUnit(java.time.temporal.ChronoUnit) CategoryEvaluator(alfio.manager.support.CategoryEvaluator) TransactionTemplate(org.springframework.transaction.support.TransactionTemplate) Log4j2(lombok.extern.log4j.Log4j2) Clock(java.time.Clock) ConfigurationKeys(alfio.model.system.ConfigurationKeys) Transactional(org.springframework.transaction.annotation.Transactional) ZonedDateTime(java.time.ZonedDateTime)

Aggregations

PaymentProxy (alfio.model.transaction.PaymentProxy)4 alfio.model (alfio.model)3 UpdateTicketOwnerForm (alfio.controller.form.UpdateTicketOwnerForm)2 PaymentResult (alfio.manager.support.PaymentResult)2 ValidationResult (alfio.model.result.ValidationResult)2 IOException (java.io.IOException)2 java.util (java.util)2 BindingResult (org.springframework.validation.BindingResult)2 TicketHelper (alfio.controller.api.support.TicketHelper)1 PaymentForm (alfio.controller.form.PaymentForm)1 EuVatChecker (alfio.manager.EuVatChecker)1 PaypalManager (alfio.manager.PaypalManager)1 TicketReservationManager (alfio.manager.TicketReservationManager)1 I18nManager (alfio.manager.i18n.I18nManager)1 CategoryEvaluator (alfio.manager.support.CategoryEvaluator)1 FeeCalculator (alfio.manager.support.FeeCalculator)1 PartialTicketTextGenerator (alfio.manager.support.PartialTicketTextGenerator)1 ConfigurationManager (alfio.manager.system.ConfigurationManager)1 Mailer (alfio.manager.system.Mailer)1 AdditionalServiceItemStatus (alfio.model.AdditionalServiceItem.AdditionalServiceItemStatus)1