Skip to content

Commit

Permalink
fastlane component draft
Browse files Browse the repository at this point in the history
  • Loading branch information
ribeiroguilherme committed Dec 3, 2024
1 parent 590a5c1 commit 30fe041
Show file tree
Hide file tree
Showing 11 changed files with 147 additions and 13 deletions.
5 changes: 3 additions & 2 deletions packages/lib/src/components/Dropin/Dropin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class DropinElement extends UIElement<DropinConfiguration> implements IDropin {
private handleCreate = () => {
const { paymentMethodsConfiguration, showStoredPaymentMethods, showPaymentMethods, instantPaymentTypes } = this.props;

const { paymentMethods, storedPaymentMethods, instantPaymentMethods } = splitPaymentMethods(
const { paymentMethods, storedPaymentMethods, instantPaymentMethods, fastlanePaymentMethod } = splitPaymentMethods(
this.core.paymentMethodsResponse,
instantPaymentTypes
);
Expand All @@ -130,8 +130,9 @@ class DropinElement extends UIElement<DropinConfiguration> implements IDropin {
: [];
const elements = showPaymentMethods ? createElements(paymentMethods, paymentMethodsConfiguration, commonProps, this.core) : [];
const instantPaymentElements = createInstantPaymentElements(instantPaymentMethods, paymentMethodsConfiguration, commonProps, this.core);
const fastlanePaymentElement = createElements([fastlanePaymentMethod], paymentMethodsConfiguration, commonProps, this.core);

return [storedElements, elements, instantPaymentElements];
return [storedElements, elements, instantPaymentElements, fastlanePaymentElement];
};

public handleAction(action: PaymentAction, props = {}): this | null {
Expand Down
73 changes: 65 additions & 8 deletions packages/lib/src/components/Dropin/components/DropinComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, h } from 'preact';
import { Component, Fragment, h } from 'preact';
import PaymentMethodList from './PaymentMethod/PaymentMethodList';
import Status from './status';
import getOrderStatus from '../../../core/Services/order-status';
Expand All @@ -9,17 +9,20 @@ import { sanitizeOrder } from '../../internal/UIElement/utils';
import { PaymentAmount } from '../../../types/global-types';
import { ANALYTICS_RENDERED_STR } from '../../../core/Analytics/constants';
import AdyenCheckoutError from '../../../core/Errors/AdyenCheckoutError';
import Button from '../../internal/Button';

export class DropinComponent extends Component<DropinComponentProps, DropinComponentState> {
public state: DropinComponentState = {
elements: [],
fastlanePaymentElement: null,
instantPaymentElements: [],
storedPaymentElements: [],
orderStatus: null,
isDisabling: false,
status: { type: 'loading', props: undefined },
activePaymentMethod: null,
cachedPaymentMethods: {}
cachedPaymentMethods: {},
showPaymentMethodList: true
};

componentDidMount() {
Expand All @@ -28,12 +31,20 @@ export class DropinComponent extends Component<DropinComponentProps, DropinCompo

public prepareDropinData = () => {
const { order, clientKey, loadingContext } = this.props;
const [storedElementsPromises, elementsPromises, instantPaymentsPromises] = this.props.onCreateElements();
const [storedElementsPromises, elementsPromises, instantPaymentsPromises, fastlanePaymentElementPromise] = this.props.onCreateElements();
const orderStatusPromise = order ? getOrderStatus({ clientKey, loadingContext }, order) : null;

void Promise.all([storedElementsPromises, elementsPromises, instantPaymentsPromises, orderStatusPromise]).then(
([storedPaymentElements, elements, instantPaymentElements, orderStatus]) => {
this.setState({ instantPaymentElements, elements, storedPaymentElements, orderStatus });
void Promise.all([storedElementsPromises, elementsPromises, instantPaymentsPromises, fastlanePaymentElementPromise, orderStatusPromise]).then(
([storedPaymentElements, elements, instantPaymentElements, fastlanePaymentElement, orderStatus]) => {
this.setState({
orderStatus,
elements,
instantPaymentElements,
storedPaymentElements,
fastlanePaymentElement: fastlanePaymentElement[0],
showPaymentMethodList: fastlanePaymentElement.length === 0
});

this.setStatus('ready');

this.props.modules?.analytics.sendAnalytics('dropin', {
Expand Down Expand Up @@ -102,6 +113,12 @@ export class DropinComponent extends Component<DropinComponentProps, DropinCompo
});
};

private onShowPaymentMethodListClick = () => {
this.setState({
showPaymentMethodList: true
});
};

closeActivePaymentMethod() {
this.setState({ activePaymentMethod: null });
}
Expand Down Expand Up @@ -137,7 +154,20 @@ export class DropinComponent extends Component<DropinComponentProps, DropinCompo

private onOrderCancel: (data: onOrderCancelData) => void;

render(props, { elements, instantPaymentElements, storedPaymentElements, status, activePaymentMethod, cachedPaymentMethods }) {
render(
props,
{
elements,
// fastlaneElement,
fastlanePaymentElement,
instantPaymentElements,
storedPaymentElements,
status,
activePaymentMethod,
cachedPaymentMethods,
showPaymentMethodList
}
) {
const isLoading = status.type === 'loading';
const isRedirecting = status.type === 'redirect';
const hasPaymentMethodsToBeDisplayed = elements?.length || instantPaymentElements?.length || storedPaymentElements?.length;
Expand All @@ -157,7 +187,34 @@ export class DropinComponent extends Component<DropinComponentProps, DropinCompo
<div className={`adyen-checkout__dropin adyen-checkout__dropin--${status.type}`}>
{isRedirecting && status.props.component && status.props.component.render()}
{isLoading && status.props && status.props.component && status.props.component.render()}
{!!hasPaymentMethodsToBeDisplayed && (

{/* CLEAN UP THIS */}
{!!fastlanePaymentElement && !showPaymentMethodList && (
<Fragment>
<PaymentMethodList
isLoading={isLoading || isRedirecting}
isDisablingPaymentMethod={this.state.isDisabling}
paymentMethods={[fastlanePaymentElement]}
// instantPaymentMethods={instantPaymentElements}
// storedPaymentMethods={storedPaymentElements}
activePaymentMethod={activePaymentMethod}
cachedPaymentMethods={cachedPaymentMethods}
// order={this.props.order}
// orderStatus={this.state.orderStatus}
// onOrderCancel={this.onOrderCancel}
onSelect={this.handleOnSelectPaymentMethod}
openPaymentMethod={this.props.openPaymentMethod}
openFirstPaymentMethod={this.props.openFirstPaymentMethod}
// openFirstStoredPaymentMethod={this.props.openFirstStoredPaymentMethod}
// onDisableStoredPaymentMethod={this.handleDisableStoredPaymentMethod}
// showRemovePaymentMethodButton={this.props.showRemovePaymentMethodButton}
showRadioButton={this.props.showRadioButton}
/>
<Button variant="primary" label="Other payment methods" onClick={this.onShowPaymentMethodListClick} />
</Fragment>
)}

{!!hasPaymentMethodsToBeDisplayed && showPaymentMethodList && (
<PaymentMethodList
isLoading={isLoading || isRedirecting}
isDisablingPaymentMethod={this.state.isDisabling}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import classNames from 'classnames';
import UIElement from '../../../internal/UIElement';

export interface PaymentMethodsContainerProps {
label: string;
label?: string;
classNameModifiers?: string[];
paymentMethods: UIElement[];
activePaymentMethod?: UIElement;
Expand Down Expand Up @@ -46,7 +46,7 @@ function PaymentMethodsContainer({

return (
<div className="adyen-checkout-payment-methods-container">
{!!label.length && (
{!!label && (
<label htmlFor={selectListId} className="adyen-checkout-payment-methods-list-label">
{label}
</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import PaymentMethods from '../../../core/ProcessResponse/PaymentMethods';

function splitPaymentMethods(paymentMethods: PaymentMethods, instantPaymentTypes: InstantPaymentTypes[]) {
return {
fastlanePaymentMethod: paymentMethods.paymentMethods.find(({ type }) => ['fastlane'].includes(type)),
instantPaymentMethods: paymentMethods.paymentMethods.filter(({ type }) => instantPaymentTypes.includes(type as InstantPaymentTypes)),
paymentMethods: paymentMethods.paymentMethods.filter(({ type }) => !instantPaymentTypes.includes(type as InstantPaymentTypes)),
paymentMethods: paymentMethods.paymentMethods.filter(
({ type }) => !instantPaymentTypes.includes(type as InstantPaymentTypes) && !['fastlane'].includes(type)
),
storedPaymentMethods: paymentMethods.storedPaymentMethods
};
}
Expand Down
3 changes: 3 additions & 0 deletions packages/lib/src/components/Dropin/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,14 @@ export interface DropinStatusProps {

export interface DropinComponentState {
elements: any[];
fastlanePaymentElement: UIElement | null;
// fastlaneElement: UIElement | null;
instantPaymentElements: UIElement[];
storedPaymentElements: UIElement[];
status: DropinStatus;
activePaymentMethod: UIElement;
cachedPaymentMethods: object;
showPaymentMethodList: boolean;
isDisabling: boolean;
orderStatus: OrderStatus;
}
Expand Down
64 changes: 64 additions & 0 deletions packages/lib/src/components/PayPalFastlane/Fastlane.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { h } from 'preact';
import UIElement from '../internal/UIElement';
import { CoreProvider } from '../../core/Context/CoreProvider';
import { TxVariants } from '../tx-variants';
import { UIElementProps } from '../internal/UIElement/types';

interface FastlaneConfiguration extends UIElementProps {
tokenId: string;
customerId: string;
lastFour: string;
brand: string;
email: string;
/**
* Configuration returned by the backend
* @internal
*/
configuration?: {
brands: string[];
};
}

class Fastlane extends UIElement<FastlaneConfiguration> {
public static type = TxVariants.fastlane;

protected override formatData() {
return {
paymentMethod: {
type: Fastlane.type,
fastlaneData: btoa(
JSON.stringify({
tokenId: this.props.tokenId,
customerId: this.props.customerId
})
)
}
};
}

public override async isAvailable(): Promise<void> {
const { tokenId, customerId, lastFour, brand, email } = this.props;

if (tokenId && customerId && lastFour && brand && email) {
return Promise.resolve();
}
return Promise.reject();
}

public override get isValid(): boolean {
return true;
}

render() {
console.log('FASTLANE RENDER');

return (
<CoreProvider i18n={this.props.i18n} loadingContext={this.props.loadingContext} resources={this.resources}>
<div> **** {this.props.lastFour} </div>
<button>pay</button>
</CoreProvider>
);
}
}

export default Fastlane;
1 change: 1 addition & 0 deletions packages/lib/src/components/PayPalFastlane/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './Fastlane';
2 changes: 2 additions & 0 deletions packages/lib/src/components/components-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import Duitnow from './DuitNow';
import Trustly from './Trustly';
import Riverty from './Riverty';
import PayByBankUS from './PayByBankUS';
import Fastlane from './PayPalFastlane/Fastlane';
import { TxVariants } from './tx-variants';

/**
Expand Down Expand Up @@ -114,6 +115,7 @@ export const ComponentsMap = {
[TxVariants.clicktopay]: ClickToPay,
[TxVariants.googlepay]: GooglePay,
[TxVariants.paypal]: PayPal,
[TxVariants.fastlane]: Fastlane,
[TxVariants.paywithgoogle]: GooglePay,
/** Wallets */

Expand Down
1 change: 1 addition & 0 deletions packages/lib/src/components/components-name-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const ComponentsNameMap = {
[TxVariants.clicktopay]: 'ClickToPay',
[TxVariants.googlepay]: 'GooglePay',
[TxVariants.paypal]: 'PayPal',
[TxVariants.fastlane]: 'Fastlane',
[TxVariants.paywithgoogle]: 'GooglePay',
/** Wallets */

Expand Down
1 change: 1 addition & 0 deletions packages/lib/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export { default as CashAppPay } from './CashAppPay';
export { default as ClickToPay } from './ClickToPay';
export { default as GooglePay } from './GooglePay';
export { default as PayPal } from './PayPal';
export { default as Fastlane } from './PayPalFastlane';

/** Vouchers */
export { default as Boleto } from './Boleto';
Expand Down
1 change: 1 addition & 0 deletions packages/lib/src/components/tx-variants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export enum TxVariants {
clicktopay = 'clicktopay',
googlepay = 'googlepay',
paypal = 'paypal',
fastlane = 'fastlane',
paywithgoogle = 'paywithgoogle',
/** Wallets */

Expand Down

0 comments on commit 30fe041

Please sign in to comment.