Skip to content

Commit

Permalink
Merge pull request #20 from Adyen/feature/AD-315
Browse files Browse the repository at this point in the history
AD-315 I can't pay with any method if the first payment attempt is ca…
  • Loading branch information
kpieloch authored Sep 30, 2024
2 parents e852fdc + ced3251 commit 162b300
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 66 deletions.
10 changes: 5 additions & 5 deletions projects/adyen-payments/src/lib/adyen-payments.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import {CheckoutAdyenConfigurationService} from "./service/checkout-adyen-config
import {CheckoutConfigurationConnector} from "./core/connectors/checkout-configuration.connector";
import {OccCheckoutConfigAdapter} from "./core/occ/adapters/occ-checkout-config.adapter";
import {CheckoutAdyenEventListener} from "./events/checkout-adyen-event.listener";
import {PlaceOrderConnector} from "./core/connectors/placeorder.connector";
import {OccPlaceOrderAdapter} from "./core/occ/adapters/occ-placeorder.adapter";
import {AdyenOrderService} from "./service/adyen-order.service";
import {OrderAdapter, OrderConnector, OrderHistoryConnector, OrderHistoryAdapter} from "@spartacus/order/core"
import {OccOrderAdapter, OccOrderHistoryAdapter} from "@spartacus/order/occ"
Expand All @@ -18,6 +16,8 @@ import {OccAdditionalDetailsAdapter} from "./core/occ/adapters/occ-additionaldet
import {AdyenRedirectModule} from "./adyen-redirect/adyen-redirect.module";
import {I18nConfig, provideConfig, provideDefaultConfig} from '@spartacus/core';
import {adyenCheckoutTranslationChunksConfig, adyenCheckoutTranslations} from "./assets/translations/translations";
import {AdyenOrderConnector} from "./core/connectors/adyen-order-connector.service";
import {OccAdyenOrderAdapter} from "./core/occ/adapters/occ-adyen-order.adapter";



Expand All @@ -32,9 +32,9 @@ import {adyenCheckoutTranslationChunksConfig, adyenCheckoutTranslations} from ".
providers: [CheckoutAdyenConfigurationService,
AdyenOrderService,
AdyenAddressService,
PlaceOrderConnector,
AdditionalDetailsConnector,
OrderConnector,
AdditionalDetailsConnector,
AdyenOrderConnector,
{
provide: OrderAdapter,
useClass: OccOrderAdapter,
Expand All @@ -52,7 +52,7 @@ import {adyenCheckoutTranslationChunksConfig, adyenCheckoutTranslations} from ".
provide: OrderHistoryAdapter,
useClass: OccOrderHistoryAdapter
},
OccPlaceOrderAdapter,
OccAdyenOrderAdapter,
OccAdditionalDetailsAdapter,
OccCheckoutConfigAdapter,
CheckoutAdyenEventListener,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component, OnInit} from '@angular/core';
import {Component, OnDestroy, OnInit} from '@angular/core';
import {CartType, MultiCartFacade} from '@spartacus/cart/base/root';
import {
GlobalMessageService,
Expand All @@ -9,14 +9,16 @@ import {
UserIdService
} from '@spartacus/core';
import {errorCodePrefix} from "../assets/translations/translations";
import {Subscription} from "rxjs";

@Component({
selector: 'adyen-redirect-error',
templateUrl: './adyen-redirect.component.html',
})
export class AdyenRedirectErrorComponent implements OnInit {
export class AdyenRedirectErrorComponent implements OnInit, OnDestroy {
private messageTimeout: number = 20000;
private placeOrderErrorCodePrefix: string = errorCodePrefix + '.';
private subscriptions = new Subscription();

constructor(protected routingService: RoutingService,
protected globalMessageService: GlobalMessageService,
Expand All @@ -27,7 +29,7 @@ export class AdyenRedirectErrorComponent implements OnInit {
}

private addErrorMessage() {
this.routingService.getParams().subscribe(params => {
let subscribeRouting = this.routingService.getParams().subscribe(params => {
let errorCode = params['errorCode'];

if (errorCode) {
Expand All @@ -39,20 +41,27 @@ export class AdyenRedirectErrorComponent implements OnInit {

this.multiCartFacade.reloadCart(OCC_CART_ID_CURRENT)

this.userIdService.takeUserId().subscribe((userId) => {
let subscribeUser = this.userIdService.takeUserId().subscribe((userId) => {
this.multiCartFacade.loadCart({cartId: OCC_CART_ID_CURRENT, userId})

this.multiCartFacade.getCartIdByType(CartType.ACTIVE).subscribe((cartId) => {

let subscribeCart = this.multiCartFacade.getCartIdByType(CartType.ACTIVE).subscribe((cartId) => {
this.routingService.go({cxRoute: "checkoutAdyenPaymentDetails"})
})
})
});
this.subscriptions.add(subscribeCart);
});
this.subscriptions.add(subscribeUser);
}
})
});
this.subscriptions.add(subscribeRouting);
}


ngOnInit(): void {
this.addErrorMessage();
}

ngOnDestroy(): void {
this.subscriptions.unsubscribe();
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import {ChangeDetectionStrategy, Component, ElementRef, OnDestroy, OnInit, ViewChild,} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {ActiveCartFacade} from '@spartacus/cart/base/root';
import {CheckoutDeliveryAddressFacade, CheckoutPaymentFacade,} from '@spartacus/checkout/base/root';
import {ActiveCartFacade, CartType, MultiCartFacade} from '@spartacus/cart/base/root';
import {CheckoutDeliveryAddressFacade,} from '@spartacus/checkout/base/root';
import {
Address,
EventService,
getLastValueSync,
GlobalMessageService,
OCC_CART_ID_CURRENT,
PaymentDetails,
RoutingService,
TranslationService,
UserIdService,
UserPaymentService,
} from '@spartacus/core';
import {BehaviorSubject, Subscription,} from 'rxjs';
import {filter, map, take,switchMap,} from 'rxjs/operators';
import {filter, map, switchMap, take,} from 'rxjs/operators';
import {CheckoutStepService} from "@spartacus/checkout/base/components";
import AdyenCheckout from '@adyen/adyen-web';
import {CheckoutAdyenConfigurationService} from "../service/checkout-adyen-configuration.service";
Expand All @@ -25,8 +26,6 @@ import AdyenCheckoutError from "@adyen/adyen-web/dist/types/core/Errors/AdyenChe
import {PlaceOrderResponse} from "../core/models/occ.order.models";
import {AdyenOrderService} from "../service/adyen-order.service";
import {CheckoutAdyenConfigurationReloadEvent} from "../events/checkout-adyen.events";
import { UserIdService } from '@spartacus/core';
import { EventService } from '@spartacus/core';

@Component({
selector: 'cx-payment-method',
Expand Down Expand Up @@ -58,17 +57,15 @@ export class CheckoutAdyenPaymentMethodComponent implements OnInit, OnDestroy {
constructor(
protected userPaymentService: UserPaymentService,
protected checkoutDeliveryAddressFacade: CheckoutDeliveryAddressFacade,
protected checkoutPaymentFacade: CheckoutPaymentFacade,
protected activatedRoute: ActivatedRoute,
protected translationService: TranslationService,
protected routingService: RoutingService,
protected activeCartFacade: ActiveCartFacade,
protected checkoutStepService: CheckoutStepService,
protected globalMessageService: GlobalMessageService,
protected checkoutAdyenConfigurationService: CheckoutAdyenConfigurationService,
protected adyenOrderService: AdyenOrderService,
protected eventService: EventService,
private userIdService: UserIdService
private userIdService: UserIdService,
protected multiCartFacade: MultiCartFacade,
) {
}

Expand Down Expand Up @@ -141,7 +138,7 @@ export class CheckoutAdyenPaymentMethodComponent implements OnInit, OnDestroy {
holderNameRequired: adyenConfig.cardHolderNameRequired,
enableStoreDetails: adyenConfig.showRememberTheseDetails
},
paypal: {
paypal: {
intent: "authorize"
}
},
Expand All @@ -166,9 +163,7 @@ export class CheckoutAdyenPaymentMethodComponent implements OnInit, OnDestroy {
onPaymentCompleted(data: OnPaymentCompletedData, element?: UIElement) {
console.info(data, element);
},
onError(error: AdyenCheckoutError, element?: UIElement) {
console.error(error.name, error.message, error.stack, element);
},
onError: (error: AdyenCheckoutError) => this.handleError(error),
onSubmit: (state: any, element: UIElement) => this.handlePayment(state.data),
onAdditionalDetails: (state: any, element?: UIElement) => this.handleAdditionalDetails(state.data),
onActionHandled(data: ActionHandledReturnObject) {
Expand Down Expand Up @@ -233,6 +228,25 @@ export class CheckoutAdyenPaymentMethodComponent implements OnInit, OnDestroy {
}
}

private handleError(error: AdyenCheckoutError) {
let subscribeCancel = this.adyenOrderService.sendPaymentCancelled().subscribe(() => {
this.multiCartFacade.reloadCart(OCC_CART_ID_CURRENT)

let subscribeUser = this.userIdService.takeUserId().subscribe((userId) => {
this.multiCartFacade.loadCart({cartId: OCC_CART_ID_CURRENT, userId})

let subscribeCart = this.multiCartFacade.getCartIdByType(CartType.ACTIVE).subscribe((cartId) => {
this.eventService.dispatch(
new CheckoutAdyenConfigurationReloadEvent()
);
});
subscribeCart.unsubscribe();
});
subscribeUser.unsubscribe();
subscribeCancel.unsubscribe();
});
}

private resetDropInComponent() {
this.dropIn.unmount();
this.dropIn.mount(this.hook.nativeElement)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { OccPlaceOrderAdapter } from '../occ/adapters/occ-placeorder.adapter';
import {PlaceOrderRequest, PlaceOrderResponse} from "../models/occ.order.models";
import {OccAdditionalDetailsAdapter} from "../occ/adapters/occ-additionaldetails.adapter";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { OccPlaceOrderAdapter } from '../occ/adapters/occ-placeorder.adapter';
import {PlaceOrderRequest, PlaceOrderResponse} from "../models/occ.order.models";
import {OccAdyenOrderAdapter} from "../occ/adapters/occ-adyen-order.adapter";

@Injectable()
export class PlaceOrderConnector {
constructor(protected adapter: OccPlaceOrderAdapter) {}
export class AdyenOrderConnector {
constructor(protected adapter: OccAdyenOrderAdapter) {}

placeOrder(userId: string, cartId: string, orderData: PlaceOrderRequest): Observable<PlaceOrderResponse> {
return this.adapter.placeOrder(userId, cartId, orderData);
}

paymentCanceled(userId: string, cartId: string, orderCode: string): Observable<void> {
return this.adapter.cancelPayment(userId, cartId, orderCode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {OccEndpointsService} from '@spartacus/core';
import {Observable} from 'rxjs';
import {PlaceOrderRequest, PlaceOrderResponse} from "../../models/occ.order.models";

@Injectable()
export class OccAdyenOrderAdapter {

constructor(
protected http: HttpClient,
protected occEndpoints: OccEndpointsService
) {
}

public placeOrder(userId: string, cartId: string, orderData: PlaceOrderRequest): Observable<PlaceOrderResponse> {
return this.http.post<PlaceOrderResponse>(this.getPlaceOrderEndpoint(userId, cartId), orderData);
}

protected getPlaceOrderEndpoint(userId: string, cartId: string): string {
return this.occEndpoints.buildUrl('users/${userId}/carts/${cartId}/adyen/place-order', {
urlParams: {
userId,
cartId,
}
});
}

public cancelPayment(userId: string, cartId: string, orderCode: string): Observable<void> {
return this.http.post<void>(this.getPaymentCanceledEndpoint(userId, cartId, orderCode), {})
}

protected getPaymentCanceledEndpoint(userId: string, cartId: string, orderCode: string): string {
return this.occEndpoints.buildUrl('users/${userId}/adyen/payment-canceled/${orderCode}', {
urlParams: {
userId,
cartId,
orderCode
}
});
}

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,23 @@ export class OrderConfirmationPaymentStatusComponent implements OnInit, OnDestro
constructor(protected orderPaymentStatusService: OrderPaymentStatusService,
protected adyenOrderService: AdyenOrderService) {
adyenOrderService.getOrderDetails().subscribe(orderData => {
this.orderCode = orderData!.code as string;
this.orderCode = orderData? orderData.code : undefined;
})
}

private timerDelay = 5000; //ms
private numberOfRetries = 30;
private currentRetry = 1;

private orderCode: string;
private orderCode?: string;

paymentStatus$: BehaviorSubject<string | undefined>;

private timer: Subscription


private timerCallback() {
if (this.currentRetry <= this.numberOfRetries) {
if (this.currentRetry <= this.numberOfRetries && this.orderCode) {
this.orderPaymentStatusService.getOrderStatus(this.orderCode).subscribe((status) => {
this.paymentStatus$.next(status);
if (status !== 'waiting') {
Expand Down
Loading

0 comments on commit 162b300

Please sign in to comment.