UNPKG

@adyen/react-native

Version:

Wraps Adyen Checkout Drop-In and Components for iOS and Android for convenient use with React Native

164 lines (156 loc) 6.64 kB
"use strict"; import React, { useRef, useCallback, useEffect, useState, useMemo } from 'react'; import { NativeEventEmitter } from 'react-native'; import { Event, ErrorCode } from '../core'; import { AdyenCheckoutContext } from '../hooks/useAdyenCheckout'; import { getWrapper } from '../modules/base/getWrapper'; import { SessionHelper } from '../modules/session/SessionHelperModule'; import { checkConfiguration, checkPaymentMethodsResponse } from './utils'; /** * Props for AdyenCheckout */ import { jsx as _jsx } from "react/jsx-runtime"; export const AdyenCheckout = ({ config, paymentMethods, session, onSubmit, onError, onAdditionalDetails, onComplete, children }) => { const subscriptions = useRef([]); const onCompleteRef = useRef(onComplete); const onErrorRef = useRef(onError); const [sessionContext, setSessionContext] = useState(undefined); const currentPaymentMethods = useMemo(() => { return paymentMethods ?? sessionContext?.paymentMethods; }, [paymentMethods, sessionContext]); function removeEventListeners() { subscriptions.current.forEach(s => s.remove()); } useEffect(() => { onCompleteRef.current = onComplete; }, [onComplete]); useEffect(() => { onErrorRef.current = onError; }, [onError]); useEffect(() => { SessionHelper.removeAllListeners(); const completeHandler = result => onCompleteRef.current?.(result, SessionHelper); const errorHandler = error => onErrorRef.current?.(error, SessionHelper); SessionHelper.assignCompletionHandler(completeHandler); SessionHelper.assignErrorHandler(errorHandler); return () => { removeEventListeners(); SessionHelper.removeAllListeners(); SessionHelper.hide(true); }; }, []); useEffect(() => { if (session && !sessionContext) { SessionHelper.createSession(session, config).then(sessionResponse => setSessionContext(sessionResponse)).catch(error => { const errorDTO = { message: String(error), errorCode: ErrorCode.sessionError }; onErrorRef.current?.(errorDTO, SessionHelper); }); } }, [session, sessionContext, config, setSessionContext]); const startEventListeners = useCallback(nativeComponent => { removeEventListeners(); const eventEmitter = new NativeEventEmitter(nativeComponent.eventEmitterTarget); subscriptions.current = []; /** Subscribe to an event if supported by native module */ function subscribeIfSupported(event, handler) { if (nativeComponent.isSupported(event)) { subscriptions.current.push(eventEmitter.addListener(event, handler)); } } function submitPayment(data, extra) { const payload = { ...data, returnUrl: data.returnUrl ?? config.returnUrl }; onSubmit?.(payload, nativeComponent, extra); } // Core events subscribeIfSupported(Event.onSubmit, response => submitPayment(response.paymentData, response.extra)); subscribeIfSupported(Event.onError, error => onError?.(error, nativeComponent)); subscribeIfSupported(Event.onComplete, data => onComplete?.(data, nativeComponent)); subscribeIfSupported(Event.onAdditionalDetails, data => onAdditionalDetails?.(data, nativeComponent)); // Stored payment method removal const onDisableStoredPaymentMethodCallback = config.dropin?.onDisableStoredPaymentMethod; if (onDisableStoredPaymentMethodCallback) { const nativeModule = nativeComponent; subscribeIfSupported(Event.onDisableStoredPaymentMethod, data => onDisableStoredPaymentMethodCallback(data, () => nativeModule.removeStored(true), () => nativeModule.removeStored(false))); } // Address lookup const onUpdateAddressCallback = config.card?.onUpdateAddress; const onConfirmAddressCallback = config.card?.onConfirmAddress; if (onUpdateAddressCallback && onConfirmAddressCallback) { const nativeModule = nativeComponent; subscribeIfSupported(Event.onAddressUpdate, async prompt => onUpdateAddressCallback(prompt, nativeModule)); subscribeIfSupported(Event.onAddressConfirm, address => onConfirmAddressCallback(address, nativeModule)); } // Partial payments const onBalanceCheckCallback = config.partialPayment?.onBalanceCheck; const onOrderRequestCallback = config.partialPayment?.onOrderRequest; const onOrderCancelCallback = config.partialPayment?.onOrderCancel; if (onBalanceCheckCallback && onOrderRequestCallback && onOrderCancelCallback) { const component = nativeComponent; subscribeIfSupported(Event.onCheckBalance, async paymentData => onBalanceCheckCallback(paymentData, balance => component.provideBalance(true, balance, undefined), error => component.provideBalance(false, undefined, error))); subscribeIfSupported(Event.onRequestOrder, () => { onOrderRequestCallback(order => component.provideOrder(true, order, undefined), error => component.provideOrder(false, undefined, error)); }); subscribeIfSupported(Event.onCancelOrder, ({ order, shouldUpdatePaymentMethods }) => onOrderCancelCallback(order, shouldUpdatePaymentMethods, component)); } // BIN lookup and value const onBinLookupCallback = config.card?.onBinLookup; if (onBinLookupCallback) { subscribeIfSupported(Event.onBinLookup, onBinLookupCallback); } const onBinValueCallback = config.card?.onBinValue; if (onBinValueCallback) { subscribeIfSupported(Event.onBinValue, onBinValueCallback); } }, [onSubmit, onAdditionalDetails, onComplete, onError, config]); const start = useCallback(typeName => { const validPaymentMethods = checkPaymentMethodsResponse(currentPaymentMethods); const { nativeComponent, paymentMethod } = getWrapper(typeName, validPaymentMethods); checkConfiguration(config); startEventListeners(nativeComponent); if (paymentMethod) { const singlePaymentMethods = { paymentMethods: [paymentMethod] }; const singlePaymentConfig = { ...config, dropin: { skipListWhenSinglePaymentMethod: true } }; nativeComponent.open(singlePaymentMethods, singlePaymentConfig); } else { nativeComponent.open(validPaymentMethods, config); } }, [config, currentPaymentMethods, startEventListeners]); return /*#__PURE__*/_jsx(AdyenCheckoutContext.Provider, { value: { start, config, paymentMethods: currentPaymentMethods, isReady: currentPaymentMethods !== undefined }, children: children }); }; //# sourceMappingURL=AdyenCheckout.js.map