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");
}
}
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);
}
}
}
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));
}
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);
});
}
}
Aggregations