use of alfio.repository.TransactionRepository in project alf.io by alfio-event.
the class MollieWebhookPaymentManager method initPayment.
private PaymentResult initPayment(TicketReservation reservation, PaymentSpecification spec, String baseUrl, Map<ConfigurationKeys, ConfigurationManager.MaybeConfiguration> configuration) throws IOException, InterruptedException {
var purchaseContext = spec.getPurchaseContext();
var purchaseContextUrlComponent = purchaseContext.getType().getUrlComponent();
var publicIdentifier = purchaseContext.getPublicIdentifier();
var reservationId = reservation.getId();
String bookUrl = baseUrl + "/" + purchaseContextUrlComponent + "/" + publicIdentifier + "/reservation/" + reservationId + "/book";
final int items;
if (spec.getPurchaseContext().getType() == PurchaseContext.PurchaseContextType.event) {
items = ticketRepository.countTicketsInReservation(spec.getReservationId());
} else {
items = 1;
}
Map<String, Object> payload = new HashMap<>();
payload.put(AMOUNT, Map.of(VALUE, spec.getOrderSummary().getTotalPrice(), CURRENCY, spec.getPurchaseContext().getCurrency()));
var description = purchaseContext.ofType(PurchaseContext.PurchaseContextType.event) ? "ticket(s) for event" : "x subscription";
payload.put("description", String.format("%s - %d %s %s", configurationManager.getShortReservationID(spec.getPurchaseContext(), reservation), items, description, spec.getPurchaseContext().getDisplayName()));
payload.put("redirectUrl", bookUrl);
payload.put("webhookUrl", baseUrl + UriComponentsBuilder.fromPath(WEBHOOK_URL_TEMPLATE).buildAndExpand(reservationId).toUriString());
payload.put("metadata", MetadataBuilder.buildMetadata(spec, Map.of()));
if (configuration.get(PLATFORM_MODE_ENABLED).getValueAsBooleanOrDefault()) {
payload.put("profileId", configuration.get(MOLLIE_CONNECT_PROFILE_ID).getRequiredValue());
payload.put("testmode", !configuration.get(MOLLIE_CONNECT_LIVE_MODE).getValueAsBooleanOrDefault());
String currencyCode = spec.getCurrencyCode();
FeeCalculator.getCalculator(spec.getPurchaseContext(), configurationManager, currencyCode).apply(items, (long) spec.getPriceWithVAT()).filter(// minimum fee for Mollie is 0.01
fee -> fee > 1L).map(fee -> MonetaryUtil.formatCents(fee, currencyCode)).ifPresent(fee -> payload.put("applicationFee", Map.of(AMOUNT, Map.of(CURRENCY, currencyCode, VALUE, fee), "description", "Reservation" + reservationId)));
}
HttpRequest request = requestFor(PAYMENTS_ENDPOINT, configuration, spec.getPurchaseContext().getConfigurationLevel()).header(HttpUtils.CONTENT_TYPE, HttpUtils.APPLICATION_JSON).POST(HttpRequest.BodyPublishers.ofString(Json.GSON.toJson(payload))).build();
HttpResponse<InputStream> response = client.send(request, HttpResponse.BodyHandlers.ofInputStream());
if (HttpUtils.callSuccessful(response)) {
try (var responseReader = new InputStreamReader(response.body(), UTF_8)) {
var body = new MolliePaymentDetails(JsonParser.parseReader(responseReader).getAsJsonObject());
var paymentId = body.getPaymentId();
var checkoutLink = body.getCheckoutLink();
// we give an additional slack to process the payment
var expiration = body.getExpiresAt().orElseThrow().plusMinutes(5);
ticketReservationRepository.updateReservationStatus(reservationId, EXTERNAL_PROCESSING_PAYMENT.toString());
ticketReservationRepository.updateValidity(reservationId, Date.from(expiration.toInstant()));
invalidateExistingTransactions(reservationId, transactionRepository);
transactionRepository.insert(paymentId, paymentId, reservationId, ZonedDateTime.now(clockProvider.withZone(spec.getPurchaseContext().getZoneId())), spec.getPriceWithVAT(), spec.getPurchaseContext().getCurrency(), "Mollie Payment", PaymentProxy.MOLLIE.name(), 0L, 0L, Transaction.Status.PENDING, Map.of());
return PaymentResult.redirect(checkoutLink);
}
} else {
log.warn("was not able to create a payment for reservation id " + reservationId);
return PaymentResult.failed(ErrorsCode.STEP_2_PAYMENT_REQUEST_CREATION);
}
}
Aggregations