Skip to content

Commit

Permalink
Merge pull request #227 from commercetools/dasanorct/fix_dropin
Browse files Browse the repository at this point in the history
fix(dropin): fixed dropin initialization to load payment methods explicitly
  • Loading branch information
dasanorct authored Sep 23, 2024
2 parents 0976f1a + 5743e54 commit 1bcb29a
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 66 deletions.
65 changes: 48 additions & 17 deletions enabler/src/dropin/dropin-embedded.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
import {
DropinComponent,
DropinOptions,
PaymentDropinBuilder,
} from "../payment-enabler/payment-enabler";
import { DropinComponent, DropinOptions, PaymentDropinBuilder } from "../payment-enabler/payment-enabler";
import { BaseOptions } from "../payment-enabler/adyen-payment-enabler";
import { ICore, SubmitActions, SubmitData } from "@adyen/adyen-web";
import { Dropin } from "@adyen/adyen-web/auto";
import {
ICore,
SubmitActions,
SubmitData,
Dropin,
Card,
PayPal,
GooglePay,
ApplePay,
Redirect,
AmazonPay,
SepaDirectDebit,
Twint,
Klarna,
Bancontact,
EPS,
Blik,
RatePay,
WeChat,
OnlineBankingPL,
Multibanco,
Affirm,
AfterPay,
} from "@adyen/adyen-web";

export class DropinEmbeddedBuilder implements PaymentDropinBuilder {
public dropinHasSubmit = false;
Expand Down Expand Up @@ -54,6 +72,26 @@ export class DropinComponents implements DropinComponent {
.catch((error) => console.error(error));
}
},
paymentMethodComponents: [
Affirm,
AfterPay,
AmazonPay,
ApplePay,
Bancontact,
Blik,
Card,
GooglePay,
EPS,
Klarna,
Multibanco,
OnlineBankingPL,
PayPal,
RatePay,
Redirect,
SepaDirectDebit,
Twint,
WeChat,
],
paymentMethodsConfiguration: {
applepay: {
buttonType: "pay" as any, // "pay" type is not included in Adyen's types, try to force it
Expand Down Expand Up @@ -109,22 +147,15 @@ export class DropinComponents implements DropinComponent {
}

submit(): void {
throw new Error(
"Method not available. Submit is managed by the Dropin component."
);
throw new Error("Method not available. Submit is managed by the Dropin component.");
}

private overrideOnSubmit() {
const parentOnSubmit = this.adyenCheckout.options.onSubmit;

this.adyenCheckout.options.onSubmit = async (
state: SubmitData,
component: Dropin,
actions: SubmitActions
) => {
this.adyenCheckout.options.onSubmit = async (state: SubmitData, component: Dropin, actions: SubmitActions) => {
const paymentMethod = state.data.paymentMethod.type;
const hasOnClick =
component.props.paymentMethodsConfiguration[paymentMethod]?.onClick;
const hasOnClick = component.props.paymentMethodsConfiguration[paymentMethod]?.onClick;
if (!hasOnClick && this.dropinOptions.onPayButtonClick) {
try {
await this.dropinOptions.onPayButtonClick();
Expand Down
64 changes: 15 additions & 49 deletions enabler/src/payment-enabler/adyen-payment-enabler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import {
SubmitActions,
SubmitData,
UIElement,
AdyenCheckout,
} from "@adyen/adyen-web";
import { AdyenCheckout } from "@adyen/adyen-web/auto";
import "@adyen-css";
import {
DropinType,
Expand Down Expand Up @@ -64,9 +64,7 @@ export class AdyenPaymentEnabler implements PaymentEnabler {
this.setupData = AdyenPaymentEnabler._Setup(options);
}

private static _Setup = async (
options: AdyenEnablerOptions
): Promise<{ baseOptions: BaseOptions }> => {
private static _Setup = async (options: AdyenEnablerOptions): Promise<{ baseOptions: BaseOptions }> => {
const [sessionResponse, configResponse] = await Promise.all([
fetch(options.processorUrl + "/sessions", {
method: "POST",
Expand All @@ -85,24 +83,15 @@ export class AdyenPaymentEnabler implements PaymentEnabler {
}),
]);

const [sessionJson, configJson] = await Promise.all([
sessionResponse.json(),
configResponse.json(),
]);
const [sessionJson, configJson] = await Promise.all([sessionResponse.json(), configResponse.json()]);

const { sessionData: data, paymentReference } = sessionJson;

if (!data || !data.id) {
throw new AdyenInitError(
"Not able to initialize Adyen, session data missing",
options.sessionId
);
throw new AdyenInitError("Not able to initialize Adyen, session data missing", options.sessionId);
} else {
const adyenCheckout = await AdyenCheckout({
onPaymentCompleted: (
result: PaymentCompletedData,
_component: UIElement
) => {
onPaymentCompleted: (result: PaymentCompletedData, _component: UIElement) => {
console.info("payment completed", result.resultCode);
},
onPaymentFailed: (result: PaymentFailedData, _component: UIElement) => {
Expand All @@ -117,11 +106,7 @@ export class AdyenPaymentEnabler implements PaymentEnabler {
}
options.onError && options.onError(error);
},
onSubmit: async (
state: SubmitData,
component: UIElement,
actions: SubmitActions
) => {
onSubmit: async (state: SubmitData, component: UIElement, actions: SubmitActions) => {
try {
const reqData = {
...state.data,
Expand All @@ -138,21 +123,14 @@ export class AdyenPaymentEnabler implements PaymentEnabler {
});
const data = await response.json();
if (data.action) {
if (
["threeDS2", "qrCode"].includes(data.action.type) &&
options.onActionRequired
) {
if (["threeDS2", "qrCode"].includes(data.action.type) && options.onActionRequired) {
options.onActionRequired({ type: "fullscreen" });
}
component.handleAction(data.action);
} else {
if (
data.resultCode === "Authorised" ||
data.resultCode === "Pending"
) {
if (data.resultCode === "Authorised" || data.resultCode === "Pending") {
component.setStatus("success");
options.onComplete &&
options.onComplete({ isSuccess: true, paymentReference });
options.onComplete && options.onComplete({ isSuccess: true, paymentReference });
} else {
options.onComplete && options.onComplete({ isSuccess: false });
component.setStatus("error");
Expand Down Expand Up @@ -192,13 +170,9 @@ export class AdyenPaymentEnabler implements PaymentEnabler {
body: JSON.stringify(requestData),
});
const data = await response.json();
if (
data.resultCode === "Authorised" ||
data.resultCode === "Pending"
) {
if (data.resultCode === "Authorised" || data.resultCode === "Pending") {
component.setStatus("success");
options.onComplete &&
options.onComplete({ isSuccess: true, paymentReference });
options.onComplete && options.onComplete({ isSuccess: true, paymentReference });
} else {
options.onComplete && options.onComplete({ isSuccess: false });
component.setStatus("error");
Expand Down Expand Up @@ -237,9 +211,7 @@ export class AdyenPaymentEnabler implements PaymentEnabler {
}
};

async createComponentBuilder(
type: string
): Promise<PaymentComponentBuilder | never> {
async createComponentBuilder(type: string): Promise<PaymentComponentBuilder | never> {
const setupData = await this.setupData;
if (!setupData) {
throw new Error("AdyenPaymentEnabler not initialized");
Expand All @@ -262,17 +234,13 @@ export class AdyenPaymentEnabler implements PaymentEnabler {
};
if (!Object.keys(supportedMethods).includes(type)) {
throw new Error(
`Component type not supported: ${type}. Supported types: ${Object.keys(
supportedMethods
).join(", ")}`
`Component type not supported: ${type}. Supported types: ${Object.keys(supportedMethods).join(", ")}`
);
}
return new supportedMethods[type](setupData.baseOptions);
}

async createDropinBuilder(
type: DropinType
): Promise<PaymentDropinBuilder | never> {
async createDropinBuilder(type: DropinType): Promise<PaymentDropinBuilder | never> {
const setupData = await this.setupData;
if (!setupData) {
throw new Error("AdyenPaymentEnabler not initialized");
Expand All @@ -283,9 +251,7 @@ export class AdyenPaymentEnabler implements PaymentEnabler {
};
if (!Object.keys(supportedMethods).includes(type)) {
throw new Error(
`Dropin type not supported: ${type}. Supported types: ${Object.keys(
supportedMethods
).join(", ")}`
`Dropin type not supported: ${type}. Supported types: ${Object.keys(supportedMethods).join(", ")}`
);
}

Expand Down

0 comments on commit 1bcb29a

Please sign in to comment.