{"version":3,"sources":["../src/PaymentEmbed.tsx"],"sourcesContent":["import type * as CheckoutApi from '@noaignite/centra-types'\nimport { isPlainObject } from '@noaignite/utils'\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport isEqual from 'react-fast-compare'\nimport { useCentraHandlers, useCentraSelection } from './Context'\nimport { HtmlEmbed } from './internal/HtmlEmbed'\n\nexport interface PaymentEmbedProps {\n  values: Record<string, unknown>\n  onPaymentSuccess?: (paymentResult: CheckoutApi.SuccessResponse<CheckoutApi.Payment>) => void\n  onPaymentError?: (error: CheckoutApi.Errors) => void\n}\n\n/** This component handles rendering of payment widgets such as Klarna Checkout and Adyen drop-in, if you submit payments yourself directly,\nyou should simply call the submitPayment method of the context instead */\nexport const PaymentEmbed = memo(function PaymentEmbed(\n  props: PaymentEmbedProps,\n): React.ReactElement | null {\n  const { values, onPaymentError, onPaymentSuccess } = props\n\n  const [paymentResult, setPaymentResult] =\n    useState<CheckoutApi.Response<CheckoutApi.Payment> | null>(null)\n  const [paymentCallbackError, setPaymentCallbackError] = useState<CheckoutApi.Errors | null>(null)\n\n  const previousPaymentMethod = useRef<string | null>(null)\n\n  // Get selection\n  const { selection, paymentMethods } = useCentraSelection()\n  const { submitPayment } = useCentraHandlers()\n\n  // Get payment method\n  const paymentMethodId = selection?.paymentMethod\n  const paymentMethod = useMemo(\n    () => paymentMethods?.find((p) => p.paymentMethod === paymentMethodId),\n    [paymentMethods, paymentMethodId],\n  )\n\n  // Submit payment\n  const handlePaymentCallback = useCallback(\n    (event: GlobalEventHandlersEventMap['centra_checkout_payment_callback']) => {\n      const {\n        addressIncluded,\n        billingAddress: detailsAddress,\n        shippingAddress: detailsShippingAddress,\n        paymentMethod: detailsPaymentMethod,\n        paymentMethodSpecificFields,\n      } = event.detail\n\n      const payload = {\n        address: values.address,\n        shippingAddress: values.shippingAddress,\n        paymentMethod: detailsPaymentMethod,\n        paymentMethodSpecificFields,\n        termsAndConditions: values.termsAndConditions,\n      } as Record<string, unknown>\n\n      if (addressIncluded) {\n        // if address is included in event, send that address instead\n        payload.address = detailsAddress\n        payload.shippingAddress = detailsShippingAddress\n      }\n\n      submitPayment?.(payload)\n        .then((result) => {\n          if ('errors' in result && Boolean(result.errors)) {\n            onPaymentError?.(result.errors)\n            // set paymentResult to null so that a new POST /payment request is made to refresh the widget\n            setPaymentResult(null)\n            setPaymentCallbackError(result.errors)\n          } else {\n            onPaymentSuccess?.(result)\n            setPaymentCallbackError(null)\n          }\n        })\n        .catch((err: unknown) => {\n          console.error('@noaignite/react-centra-checkout: Could not submit payment')\n\n          if (isPlainObject(err)) {\n            setPaymentCallbackError(err)\n          }\n\n          console.error(err)\n        })\n    },\n    [submitPayment, onPaymentSuccess, onPaymentError, values],\n  )\n\n  // Reset payment result when method changes\n  useEffect(() => {\n    if (selection?.paymentMethod !== previousPaymentMethod.current) {\n      setPaymentResult(null)\n    }\n  }, [selection?.paymentMethod])\n\n  // Retrieve formHtml\n  useEffect(() => {\n    const shouldRequestPayment =\n      // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- we actually want || here because we are checking for undefined, null and false\n      paymentMethod?.supportsInitiateOnly || paymentMethod?.providesCustomerAddressAfterPayment // if either of these are true, this is a paymentMethod which provides an embed\n\n    if (\n      ((selection?.paymentMethod === previousPaymentMethod.current || !shouldRequestPayment) &&\n        !paymentCallbackError) ||\n      !selection?.paymentMethod\n    ) {\n      return\n    }\n\n    previousPaymentMethod.current = selection.paymentMethod\n\n    // don't send termsAndConditions when fetching embed payments, as we don't want it to fail just yet.\n    submitPayment?.({ ...values, termsAndConditions: undefined })\n      .then((result) => {\n        if ('errors' in result) {\n          console.error(result.errors)\n          onPaymentError?.(result.errors)\n          throw new Error('@noaignite/react-centra-checkout: Error while fetching widget')\n        }\n\n        if (result.action === 'form' && !result.formHtml) {\n          throw new Error('@noaignite/react-centra-checkout: No form to render')\n        }\n\n        setPaymentResult(result)\n        setPaymentCallbackError(null)\n      })\n      .catch((err: unknown) => {\n        console.error(err)\n        setPaymentResult(null)\n      })\n  }, [\n    onPaymentError,\n    paymentCallbackError,\n    paymentMethod,\n    selection?.paymentMethod,\n    selection?.totals?.grandTotalPriceAsNumber,\n    submitPayment,\n    values,\n  ])\n\n  useEffect(() => {\n    // Fires when customer submits payment\n    document.addEventListener('centra_checkout_payment_callback', handlePaymentCallback)\n\n    return () => {\n      document.removeEventListener('centra_checkout_payment_callback', handlePaymentCallback)\n    }\n  }, [handlePaymentCallback])\n\n  const formHtml = paymentResult && 'formHtml' in paymentResult && paymentResult.formHtml\n\n  return formHtml ? <HtmlEmbed html={formHtml} id=\"centra-payment-form\" /> : null\n}, isEqual)\n"],"mappings":"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","names":["PaymentEmbed","isEqual"]}