diff --git a/giving-example/src/main/java/com/adyen/giving/api/CheckoutResource.java b/giving-example/src/main/java/com/adyen/giving/api/CheckoutResource.java index d2e05a1..165f8c1 100644 --- a/giving-example/src/main/java/com/adyen/giving/api/CheckoutResource.java +++ b/giving-example/src/main/java/com/adyen/giving/api/CheckoutResource.java @@ -3,15 +3,14 @@ import com.adyen.Client; import com.adyen.giving.ApplicationProperty; import com.adyen.enums.Environment; -import com.adyen.giving.service.DonationService; +import com.adyen.giving.util.DonationUtil; import com.adyen.model.checkout.*; import com.adyen.service.checkout.PaymentsApi; import com.adyen.service.exception.ApiException; import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpSession; +import jakarta.ws.rs.NotFoundException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.view.RedirectView; @@ -33,12 +32,6 @@ public class CheckoutResource { private final PaymentsApi paymentsApi; - @Autowired - private DonationService donationService; - private static final String DONATION_TOKEN = "DonationToken"; - - private static final String PAYMENT_ORIGINAL_PSPREFERENCE = "PaymentOriginalPspReference"; - public CheckoutResource(ApplicationProperty applicationProperty) { this.applicationProperty = applicationProperty; @@ -62,25 +55,32 @@ public CheckoutResource(ApplicationProperty applicationProperty) { */ @PostMapping("/donations") public ResponseEntity donations(@RequestBody Amount body, @RequestHeader String host, HttpServletRequest request) throws IOException, ApiException { - DonationPaymentRequest donationRequest = new DonationPaymentRequest(); - - var pspReference = donationService.getPaymentOriginalPspReference(); - var donationToken = donationService.getDonationToken(); - - donationRequest.amount(body); - donationRequest.reference(UUID.randomUUID().toString()); - donationRequest.setPaymentMethod(new DonationPaymentMethod(new CardDetails())); - donationRequest.setDonationToken(donationToken.toString()); - donationRequest.donationOriginalPspReference(pspReference.toString()); - donationRequest.setDonationAccount(this.applicationProperty.getDonationMerchantAccount()); - donationRequest.returnUrl(request.getScheme() + "://" + host); - donationRequest.setMerchantAccount(this.applicationProperty.getMerchantAccount()); - donationRequest.shopperInteraction(DonationPaymentRequest.ShopperInteractionEnum.CONTAUTH); - - DonationPaymentResponse result = this.paymentsApi.donations(donationRequest); - - return ResponseEntity.ok() - .body(result); + try { + DonationPaymentRequest donationRequest = new DonationPaymentRequest(); + + String pspReference = DonationUtil.getPaymentOriginalPspReference(request.getSession()); + String donationToken = DonationUtil.getDonationToken(request.getSession()); + + donationRequest.amount(body); + donationRequest.reference(UUID.randomUUID().toString()); + donationRequest.setPaymentMethod(new DonationPaymentMethod(new CardDetails())); + donationRequest.setDonationToken(donationToken); + donationRequest.donationOriginalPspReference(pspReference); + donationRequest.setDonationAccount(this.applicationProperty.getDonationMerchantAccount()); + donationRequest.returnUrl(request.getScheme() + "://" + host); + donationRequest.setMerchantAccount(this.applicationProperty.getMerchantAccount()); + donationRequest.shopperInteraction(DonationPaymentRequest.ShopperInteractionEnum.CONTAUTH); + + DonationPaymentResponse result = this.paymentsApi.donations(donationRequest); + + return ResponseEntity.ok().body(result); + } catch (NotFoundException e) { + log.warn(e.getMessage()); + return ResponseEntity.notFound().build(); + } catch (Exception e) { + log.error(e.getMessage()); + return ResponseEntity.status(500).build(); + } } /** @@ -92,14 +92,19 @@ public ResponseEntity donations(@RequestBody Amount bod */ @PostMapping("/getPaymentMethods") public ResponseEntity paymentMethods() throws IOException, ApiException { - var paymentMethodsRequest = new PaymentMethodsRequest(); - paymentMethodsRequest.setMerchantAccount(this.applicationProperty.getMerchantAccount()); - paymentMethodsRequest.setChannel(PaymentMethodsRequest.ChannelEnum.WEB); - - log.info("REST request to get Adyen payment methods {}", paymentMethodsRequest); - var response = paymentsApi.paymentMethods(paymentMethodsRequest); - return ResponseEntity.ok() - .body(response); + try { + var paymentMethodsRequest = new PaymentMethodsRequest(); + paymentMethodsRequest.setMerchantAccount(this.applicationProperty.getMerchantAccount()); + paymentMethodsRequest.setChannel(PaymentMethodsRequest.ChannelEnum.WEB); + + log.info("REST request to get Adyen payment methods {}", paymentMethodsRequest); + var response = paymentsApi.paymentMethods(paymentMethodsRequest); + return ResponseEntity.ok() + .body(response); + } catch (Exception e) { + log.error(e.getMessage()); + return ResponseEntity.status(500).build(); + } } /** @@ -111,41 +116,48 @@ public ResponseEntity paymentMethods() throws IOExceptio */ @PostMapping("/initiatePayment") public ResponseEntity payments(@RequestHeader String host, @RequestBody PaymentRequest body, HttpServletRequest request) throws IOException, ApiException { - var paymentRequest = new PaymentRequest(); - - var orderRef = UUID.randomUUID().toString(); - var amount = new Amount() - .currency("EUR") - .value(10000L); // value is 100€ in minor units - - paymentRequest.setMerchantAccount(this.applicationProperty.getMerchantAccount()); // required - paymentRequest.setChannel(PaymentRequest.ChannelEnum.WEB); - paymentRequest.setReference(orderRef); // required - paymentRequest.setReturnUrl(request.getScheme() + "://" + host + "/api/handleShopperRedirect?orderRef=" + orderRef); - - paymentRequest.setAmount(amount); - // set lineItems required for some payment methods (ie Klarna) - paymentRequest.setLineItems(Arrays.asList( - new LineItem().quantity(1L).amountIncludingTax(5000L).description("Sunglasses"), - new LineItem().quantity(1L).amountIncludingTax(5000L).description("Headphones")) - ); - // required for 3ds2 native flow - paymentRequest.setAdditionalData(Collections.singletonMap("allow3DS2", "true")); - // required for 3ds2 native flow - paymentRequest.setOrigin(request.getScheme() + "://" + host ); - // required for 3ds2 - paymentRequest.setBrowserInfo(body.getBrowserInfo()); - // required by some issuers for 3ds2 - paymentRequest.setShopperIP(request.getRemoteAddr()); - paymentRequest.setPaymentMethod(body.getPaymentMethod()); - - log.info("REST request to make Adyen payment {}", paymentRequest); - var response = paymentsApi.payments(paymentRequest); - - donationService.setDonationTokenAndOriginalPspReference(response.getDonationToken(), response.getPspReference()); - - return ResponseEntity.ok() - .body(response); + try { + var paymentRequest = new PaymentRequest(); + + var orderRef = UUID.randomUUID().toString(); + var amount = new Amount() + .currency("EUR") + .value(10000L); // value is 100€ in minor units + + paymentRequest.setMerchantAccount(this.applicationProperty.getMerchantAccount()); // required + paymentRequest.setChannel(PaymentRequest.ChannelEnum.WEB); + paymentRequest.setReference(orderRef); // required + paymentRequest.setReturnUrl(request.getScheme() + "://" + host + "/api/handleShopperRedirect?orderRef=" + orderRef); + + paymentRequest.setAmount(amount); + // set lineItems required for some payment methods (ie Klarna) + paymentRequest.setLineItems(Arrays.asList( + new LineItem().quantity(1L).amountIncludingTax(5000L).description("Sunglasses"), + new LineItem().quantity(1L).amountIncludingTax(5000L).description("Headphones")) + ); + // required for 3ds2 native flow + paymentRequest.setAdditionalData(Collections.singletonMap("allow3DS2", "true")); + // required for 3ds2 native flow + paymentRequest.setOrigin(request.getScheme() + "://" + host); + // required for 3ds2 + paymentRequest.setBrowserInfo(body.getBrowserInfo()); + // required by some issuers for 3ds2 + paymentRequest.setShopperIP(request.getRemoteAddr()); + paymentRequest.setPaymentMethod(body.getPaymentMethod()); + + log.info("REST request to make Adyen payment {}", paymentRequest); + var response = paymentsApi.payments(paymentRequest); + + DonationUtil.setDonationTokenAndOriginalPspReference(request.getSession(), response.getDonationToken(), response.getPspReference()); + + return ResponseEntity.ok().body(response); + } catch (NotFoundException e) { + log.warn(e.getMessage()); + return ResponseEntity.notFound().build(); + } catch (Exception e) { + log.error(e.getMessage()); + return ResponseEntity.status(500).build(); + } } /** @@ -157,10 +169,14 @@ public ResponseEntity payments(@RequestHeader String host, @Req */ @PostMapping("/submitAdditionalDetails") public ResponseEntity payments(@RequestBody PaymentDetailsRequest detailsRequest) throws IOException, ApiException { - log.info("REST request to make Adyen payment details {}", detailsRequest); - var response = paymentsApi.paymentsDetails(detailsRequest); - return ResponseEntity.ok() - .body(response); + try { + log.info("REST request to make Adyen payment details {}", detailsRequest); + var response = paymentsApi.paymentsDetails(detailsRequest); + return ResponseEntity.ok().body(response); + } catch (Exception e) { + log.error(e.getMessage()); + return ResponseEntity.status(500).build(); + } } /** diff --git a/giving-example/src/main/java/com/adyen/giving/service/DonationService.java b/giving-example/src/main/java/com/adyen/giving/util/DonationUtil.java similarity index 68% rename from giving-example/src/main/java/com/adyen/giving/service/DonationService.java rename to giving-example/src/main/java/com/adyen/giving/util/DonationUtil.java index bee2b86..408f543 100644 --- a/giving-example/src/main/java/com/adyen/giving/service/DonationService.java +++ b/giving-example/src/main/java/com/adyen/giving/util/DonationUtil.java @@ -1,20 +1,14 @@ -package com.adyen.giving.service; +package com.adyen.giving.util; import jakarta.servlet.http.HttpSession; import jakarta.ws.rs.NotFoundException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class DonationService { - @Autowired - protected HttpSession session; +public final class DonationUtil { private static final String DONATION_TOKEN = "DonationToken"; private static final String PAYMENT_ORIGINAL_PSPREFERENCE = "PaymentOriginalPspReference"; - public void setDonationTokenAndOriginalPspReference(String donationToken, String originalPspReference) throws NullPointerException { + public static void setDonationTokenAndOriginalPspReference(HttpSession session, String donationToken, String originalPspReference) throws NullPointerException { if (donationToken == null) { throw new NullPointerException("No donationToken is found. The payments endpoint did not return a donationToken, please enable this in your Customer Area. See README."); } @@ -23,7 +17,7 @@ public void setDonationTokenAndOriginalPspReference(String donationToken, String session.setAttribute(DONATION_TOKEN, donationToken); } - public String getDonationToken() throws NotFoundException { + public static String getDonationToken(HttpSession session) throws NotFoundException { var donationToken = session.getAttribute(DONATION_TOKEN); if (donationToken == null) { throw new NotFoundException("Could not find donationToken in the sessions"); @@ -31,7 +25,7 @@ public String getDonationToken() throws NotFoundException { return (String) donationToken; } - public String getPaymentOriginalPspReference() throws NotFoundException { + public static String getPaymentOriginalPspReference(HttpSession session) throws NotFoundException { var pspReference = session.getAttribute(PAYMENT_ORIGINAL_PSPREFERENCE); if (pspReference == null) { throw new NotFoundException("Could not find originalPspReference in the sessions");