Skip to content

Commit

Permalink
Merge pull request #428 from Adyen/feature/AD-290
Browse files Browse the repository at this point in the history
AD-290 Redirect Handling for Guest and Registered Users: We are expec…
  • Loading branch information
pjaneta authored Aug 20, 2024
2 parents 7e8a9c4 + f9b0a45 commit e992970
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,18 @@ public ResponseEntity<String> postIdForPaymentStatus(@RequestBody String orderCo
return ResponseEntity.badRequest().build();
}
}

@RequireHardLogIn
@PostMapping("/get-order-code")
public ResponseEntity<String> postGUIDForOrderCode(@RequestBody String orderGUID) {
String checkoutGuid = sessionService.getAttribute(WebConstants.ANONYMOUS_CHECKOUT_GUID);

try {
String paymentStatus = adyenOrderFacade.getOrderCodeForGUID(orderGUID, checkoutGuid);
return ResponseEntity.ok().body(paymentStatus);
} catch (Exception exception) {
LOG.error(exception);
return ResponseEntity.badRequest().build();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import de.hybris.platform.acceleratorstorefrontcommons.annotations.RequireHardLogIn;
import de.hybris.platform.basecommerce.model.site.BaseSiteModel;
import de.hybris.platform.commercefacades.order.CartFacade;
import de.hybris.platform.commerceservices.strategies.CheckoutCustomerStrategy;
import de.hybris.platform.order.InvalidCartException;
import de.hybris.platform.order.exceptions.CalculationException;
import de.hybris.platform.site.BaseSiteService;
Expand Down Expand Up @@ -51,6 +52,9 @@ public class AdyenPlaceOrderController extends PlaceOrderControllerBase {
@Autowired
private AdyenCheckoutFacade adyenCheckoutFacade;

@Resource(name = "checkoutCustomerStrategy")
private CheckoutCustomerStrategy checkoutCustomerStrategy;

@RequireHardLogIn
@PostMapping("/place-order")
public ResponseEntity<PlaceOrderResponse> onPlaceOrder(@RequestBody PlaceOrderRequest placeOrderRequest, HttpServletRequest request) throws Exception {
Expand Down Expand Up @@ -113,4 +117,9 @@ public SiteBaseUrlResolutionService getSiteBaseUrlResolutionService() {
public AdyenCheckoutFacade getAdyenCheckoutFacade() {
return adyenCheckoutFacade;
}

@Override
public CheckoutCustomerStrategy getCheckoutCustomerStrategy() {
return checkoutCustomerStrategy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.adyen.model.checkout.PaymentDetailsRequest;
import com.adyen.v6.facades.AdyenCheckoutFacade;
import de.hybris.platform.acceleratorstorefrontcommons.annotations.RequireHardLogIn;
import de.hybris.platform.commercefacades.order.data.OrderData;
import de.hybris.platform.commerceservices.strategies.CheckoutCustomerStrategy;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -28,6 +30,9 @@ public class AdyenRedirectResponseController extends RedirectControllerBase {
@Resource(name = "adyenCheckoutFacade")
private AdyenCheckoutFacade adyenCheckoutFacade;

@Resource(name = "checkoutCustomerStrategy")
private CheckoutCustomerStrategy checkoutCustomerStrategy;

@GetMapping(value = AUTHORISE_3D_SECURE_PAYMENT_URL)
@RequireHardLogIn
public String authoriseRedirectGetPayment(final HttpServletRequest request) {
Expand All @@ -47,7 +52,10 @@ public String getErrorRedirectUrl(String errorMessage) {
}

@Override
public String getOrderConfirmationUrl(String orderCode) {
public String getOrderConfirmationUrl(OrderData orderData) {

String orderCode = checkoutCustomerStrategy.isAnonymousCheckout() ? orderData.getGuid() : orderData.getCode();

return REDIRECT_PREFIX + ORDER_CONFIRMATION_URL + '/' + orderCode;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ import {PaymentFailed} from "./PaymentFailed";
import {PaymentRejected} from "./PaymentRejected";
import {PaymentTimeout} from "./PaymentTimeout";
import {PaymentStatusService} from "../../service/paymentStatusService";
import {isNotEmpty} from "../../util/stringUtil";
import {isEmpty, isNotEmpty} from "../../util/stringUtil";
import {isGuid} from "../../util/guidUtil";

interface Props {
orderCode: string
}

interface State {
numberOfStatusChecks: number,
paymentStatus: PaymentStatus
paymentStatus: PaymentStatus,
displayedOrderCode: string
}

export class ThankYouPage extends React.Component<Props, State> {
Expand All @@ -27,12 +29,29 @@ export class ThankYouPage extends React.Component<Props, State> {
super(props);
this.state = {
numberOfStatusChecks: 0,
paymentStatus: "waiting"
paymentStatus: "waiting",
displayedOrderCode: ""
}
}

componentDidMount() {
async componentDidMount() {
this.timer = setInterval(() => this.checkStatus(), this.statusRequestInterval);
if (isGuid(this.props.orderCode)) {
let orderCode = await PaymentStatusService.fetchOrderCodeForGUID(this.props.orderCode);
this.setState((state): State => {
return {
...state,
displayedOrderCode: orderCode
}
})
} else {
this.setState((state): State => {
return {
...state,
displayedOrderCode: this.props.orderCode
}
})
}
}

componentWillUnmount() {
Expand Down Expand Up @@ -85,15 +104,22 @@ export class ThankYouPage extends React.Component<Props, State> {
}
}

private renderOrderNumberSection(): React.JSX.Element {
if (isEmpty(this.state.displayedOrderCode)) {
return <></>
}
return <p>{translationsStore.get("text.account.order.orderNumberLabel")}<strong> {this.state.displayedOrderCode}</strong>
</p>
}

render() {
return (
<div className="checkout-success">
<div className="checkout-success__body">
<div className="checkout-success__body__headline">
{translationsStore.get("checkout.orderConfirmation.thankYouForOrder")}
</div>
<p>{translationsStore.get("text.account.order.orderNumberLabel")}<strong> {this.props.orderCode}</strong>
</p>
{this.renderOrderNumberSection()}
{this.renderPaymentStatus()}
</div>
</div>)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,20 @@ export class PaymentStatusService {
return false
})
}

static fetchOrderCodeForGUID(orderGUID: string) {
return adyenAxios.post(urlContextPath + '/api/checkout/get-order-code', orderGUID, {
headers: {
'Content-Type': 'application/json',
'CSRFToken': CSRFToken
}
})
.then(response => {
return response.data
})
.catch((errorResponse: AxiosError<ErrorResponse>) => {
console.error("Payment status fetch error.")
return false
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

const guidRegexp = /^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$/

export function isGuid(string: string): boolean {
return guidRegexp.test(string)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import de.hybris.platform.acceleratorservices.urlresolver.SiteBaseUrlResolutionService;
import de.hybris.platform.commercefacades.order.CartFacade;
import de.hybris.platform.commerceservices.request.mapping.annotation.ApiVersion;
import de.hybris.platform.commerceservices.strategies.CheckoutCustomerStrategy;
import de.hybris.platform.order.InvalidCartException;
import de.hybris.platform.order.exceptions.CalculationException;
import de.hybris.platform.site.BaseSiteService;
Expand Down Expand Up @@ -59,6 +60,9 @@ public class PlaceOrderController extends PlaceOrderControllerBase {
@Autowired
private WebServicesBaseUrlResolver webServicesBaseUrlResolver;

@Resource(name = "checkoutCustomerStrategy")
private CheckoutCustomerStrategy checkoutCustomerStrategy;

@Secured({"ROLE_CUSTOMERGROUP", "ROLE_CLIENT", "ROLE_CUSTOMERMANAGERGROUP", "ROLE_TRUSTED_CLIENT"})
@PostMapping(value = "/place-order", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(operationId = "placeOrder", summary = "Handle place order request", description =
Expand Down Expand Up @@ -130,4 +134,9 @@ public SiteBaseUrlResolutionService getSiteBaseUrlResolutionService() {
public AdyenCheckoutFacade getAdyenCheckoutFacade() {
return adyenCheckoutFacade;
}

@Override
public CheckoutCustomerStrategy getCheckoutCustomerStrategy() {
return checkoutCustomerStrategy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.adyen.commerce.controllerbase.RedirectControllerBase;
import com.adyen.model.checkout.PaymentDetailsRequest;
import com.adyen.v6.facades.AdyenCheckoutFacade;
import de.hybris.platform.commercefacades.order.data.OrderData;
import de.hybris.platform.commerceservices.i18n.CommerceCommonI18NService;
import de.hybris.platform.commerceservices.request.mapping.annotation.ApiVersion;
import de.hybris.platform.servicelayer.config.ConfigurationService;
Expand Down Expand Up @@ -65,8 +66,8 @@ public String getErrorRedirectUrl(String errorMessage) {
}

@Override
public String getOrderConfirmationUrl(String orderCode) {
return getSpartacusUrlPrefix() + ADYEN_REDIRECT_URL + orderCode;
public String getOrderConfirmationUrl(OrderData orderData) {
return getSpartacusUrlPrefix() + ADYEN_REDIRECT_URL + orderData.getCode();

}

Expand Down
1 change: 1 addition & 0 deletions adyenv6core/src/com/adyen/v6/facades/AdyenOrderFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
public interface AdyenOrderFacade {
String getPaymentStatus(final String orderCode, final String sessionGuid);
String getPaymentStatusOCC(final String code);
String getOrderCodeForGUID(final String orderGUID, final String sessionGuid);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ public String getPaymentStatusOCC(final String code) {
return getPaymentStatusForOrder(orderModel);
}

@Override
public String getOrderCodeForGUID(final String orderGUID, final String sessionGuid) {
final BaseStoreModel baseStoreModel = baseStoreService.getCurrentBaseStore();

if (checkoutCustomerStrategy.isAnonymousCheckout()) {
OrderModel orderModel = customerAccountService.getGuestOrderForGUID(orderGUID, baseStoreModel);
if (StringUtils.substringBefore(orderModel.getUser().getUid(), "|")
.equals(sessionGuid)) {
return orderModel.getCode();
}
}
LOG.error("Get order for guid on not anonymous checkout");
return "";
}

private String getPaymentStatusForOrder(final OrderModel orderModel) {
List<PaymentTransactionModel> paymentTransactions = orderModel.getPaymentTransactions();
if (paymentTransactions.isEmpty()) {
Expand Down Expand Up @@ -74,7 +89,7 @@ private OrderModel getOrderModelForCode(final String code, final String sessionG

OrderModel orderModel = null;
if (checkoutCustomerStrategy.isAnonymousCheckout()) {
orderModel = customerAccountService.getOrderForCode(code, baseStoreModel);
orderModel = customerAccountService.getGuestOrderForGUID(code, baseStoreModel);
if (!StringUtils.substringBefore(orderModel.getUser().getUid(), "|")
.equals(sessionGuid)) {
orderModel = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import de.hybris.platform.acceleratorfacades.flow.CheckoutFlowFacade;
import de.hybris.platform.acceleratorservices.urlresolver.SiteBaseUrlResolutionService;
import de.hybris.platform.basecommerce.model.site.BaseSiteModel;
import de.hybris.platform.commercefacades.order.CartFacade;
import de.hybris.platform.commercefacades.order.data.CartData;
import de.hybris.platform.commercefacades.order.data.OrderData;
import de.hybris.platform.commerceservices.strategies.CheckoutCustomerStrategy;
import de.hybris.platform.order.InvalidCartException;
import de.hybris.platform.order.exceptions.CalculationException;
import de.hybris.platform.site.BaseSiteService;
Expand Down Expand Up @@ -76,8 +76,11 @@ public PlaceOrderResponse handleAdditionalDetails(final PaymentDetailsRequest pa
public OCCPlaceOrderResponse handleAdditionalDetailsOCC(final PaymentDetailsRequest paymentDetailsRequest) {
try {
OrderData orderData = getAdyenCheckoutApiFacade().placeOrderWithAdditionalDetails(paymentDetailsRequest);

String orderCode = getCheckoutCustomerStrategy().isAnonymousCheckout() ? orderData.getGuid() : orderData.getCode();

OCCPlaceOrderResponse placeOrderResponse = new OCCPlaceOrderResponse();
placeOrderResponse.setOrderNumber(orderData.getCode());
placeOrderResponse.setOrderNumber(orderCode);
placeOrderResponse.setOrderData(orderData);
return placeOrderResponse;
} catch (Exception e) {
Expand All @@ -86,7 +89,7 @@ public OCCPlaceOrderResponse handleAdditionalDetailsOCC(final PaymentDetailsRequ
}
}

public void handleCancel() throws InvalidCartException, CalculationException{
public void handleCancel() throws InvalidCartException, CalculationException {
getAdyenCheckoutFacade().restoreCartFromOrderCodeInSession();
}

Expand Down Expand Up @@ -121,7 +124,7 @@ private void preHandleAndValidateRequest(PlaceOrderRequest placeOrderRequest, St
throw new AdyenControllerException(CHECKOUT_ERROR_FORM_ENTRY_INVALID, getFieldCodesFromValidation(bindingResult));
}

getAdyenCheckoutApiFacade().preHandlePlaceOrder(placeOrderRequest.getPaymentRequest(),adyenPaymentMethod,
getAdyenCheckoutApiFacade().preHandlePlaceOrder(placeOrderRequest.getPaymentRequest(), adyenPaymentMethod,
placeOrderRequest.getBillingAddress(), placeOrderRequest.isUseAdyenDeliveryAddress());
}

Expand Down Expand Up @@ -161,7 +164,7 @@ private boolean isCartValid() {
return true;
}

private OCCPlaceOrderResponse handlePayment(HttpServletRequest request, PlaceOrderRequest placeOrderRequest) {
private OCCPlaceOrderResponse handlePayment(HttpServletRequest request, PlaceOrderRequest placeOrderRequest) {
final CartData cartData = getCartFacade().getSessionCart();

String errorMessage = CHECKOUT_ERROR_AUTHORIZATION_FAILED;
Expand All @@ -170,8 +173,10 @@ private OCCPlaceOrderResponse handlePayment(HttpServletRequest request, PlaceOr
cartData.setAdyenReturnUrl(getPaymentRedirectReturnUrl());
OrderData orderData = getAdyenCheckoutApiFacade().placeOrderWithPayment(request, cartData, placeOrderRequest.getPaymentRequest());

String orderCode = getCheckoutCustomerStrategy().isAnonymousCheckout() ? orderData.getGuid() : orderData.getCode();

OCCPlaceOrderResponse placeOrderResponse = new OCCPlaceOrderResponse();
placeOrderResponse.setOrderNumber(orderData.getCode());
placeOrderResponse.setOrderNumber(orderCode);
placeOrderResponse.setOrderData(orderData);
return placeOrderResponse;

Expand Down Expand Up @@ -219,4 +224,7 @@ private OCCPlaceOrderResponse executeAction(PaymentResponse paymentsResponse) {
public abstract SiteBaseUrlResolutionService getSiteBaseUrlResolutionService();

public abstract AdyenCheckoutFacade getAdyenCheckoutFacade();

public abstract CheckoutCustomerStrategy getCheckoutCustomerStrategy();

}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ private String authoriseRedirectPayment(final PaymentDetailsRequest details) {

LOGGER.debug("Redirecting to confirmation");

return getOrderConfirmationUrl(orderData.getCode());
return getOrderConfirmationUrl(orderData);

} catch (AdyenNonAuthorizedPaymentException e) {
LOGGER.debug(NON_AUTHORIZED_ERROR);
Expand Down Expand Up @@ -89,7 +89,7 @@ private String authoriseRedirectPayment(final PaymentDetailsRequest details) {

public abstract String getErrorRedirectUrl(String errorMessage);

public abstract String getOrderConfirmationUrl(String orderCode);
public abstract String getOrderConfirmationUrl(OrderData orderData);

public abstract String getCartUrl();

Expand Down

0 comments on commit e992970

Please sign in to comment.