diff --git a/src/components/EReceiptThumbnail.tsx b/src/components/EReceiptThumbnail.tsx
index c0206ba41974..4b0c0caa1035 100644
--- a/src/components/EReceiptThumbnail.tsx
+++ b/src/components/EReceiptThumbnail.tsx
@@ -21,7 +21,7 @@ type IconSize = 'x-small' | 'small' | 'medium' | 'large';
 
 type EReceiptThumbnailProps = {
     /** TransactionID of the transaction this EReceipt corresponds to. */
-    transactionID?: string;
+    transactionID: string;
 
     /** Border radius to be applied on the parent view. */
     borderRadius?: number;
diff --git a/src/components/MoneyRequestConfirmationListFooter.tsx b/src/components/MoneyRequestConfirmationListFooter.tsx
index fd5e9a295835..0c934ff12500 100644
--- a/src/components/MoneyRequestConfirmationListFooter.tsx
+++ b/src/components/MoneyRequestConfirmationListFooter.tsx
@@ -22,8 +22,8 @@ import {hasEnabledTags} from '@libs/TagsOptionsListUtils';
 import {getTagForDisplay, getTaxAmount, getTaxName, isAmountMissing, isCreatedMissing, shouldShowAttendees as shouldShowAttendeesTransactionUtils} from '@libs/TransactionUtils';
 import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot';
 import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow';
-import type {IOUAction, IOUType} from '@src/CONST';
 import CONST from '@src/CONST';
+import type {IOUAction, IOUType} from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import ROUTES from '@src/ROUTES';
 import type * as OnyxTypes from '@src/types/onyx';
@@ -827,7 +827,6 @@ function MoneyRequestConfirmationListFooter({
                     ? receiptThumbnailContent
                     : shouldShowReceiptEmptyState && (
                           <ReceiptEmptyState
-                              transactionID={transactionID}
                               onPress={() => {
                                   if (!transactionID) {
                                       return;
@@ -837,7 +836,6 @@ function MoneyRequestConfirmationListFooter({
                                       ROUTES.MONEY_REQUEST_STEP_SCAN.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID, Navigation.getActiveRouteWithoutParams()),
                                   );
                               }}
-                              shouldAllowReceiptDrop
                           />
                       ))}
             {primaryFields}
diff --git a/src/components/ReceiptEmptyState.tsx b/src/components/ReceiptEmptyState.tsx
index d8d9d70cd168..08d83b6962af 100644
--- a/src/components/ReceiptEmptyState.tsx
+++ b/src/components/ReceiptEmptyState.tsx
@@ -1,22 +1,11 @@
-import {Str} from 'expensify-common';
-import React, {useState} from 'react';
+import React from 'react';
 import {View} from 'react-native';
 import useLocalize from '@hooks/useLocalize';
 import useTheme from '@hooks/useTheme';
 import useThemeStyles from '@hooks/useThemeStyles';
-import {setMoneyRequestReceipt} from '@libs/actions/IOU';
-import {resizeImageIfNeeded} from '@libs/fileDownload/FileUtils';
-import {validateReceipt} from '@libs/ReceiptUtils';
-import ReceiptDropUI from '@pages/iou/ReceiptDropUI';
 import variables from '@styles/variables';
-import CONST from '@src/CONST';
-import type {TranslationPaths} from '@src/languages/types';
-import type {FileObject} from './AttachmentModal';
-import ConfirmModal from './ConfirmModal';
-import FullScreenLoadingIndicator from './FullscreenLoadingIndicator';
 import Icon from './Icon';
 import * as Expensicons from './Icon/Expensicons';
-import PDFThumbnail from './PDFThumbnail';
 import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback';
 
 type ReceiptEmptyStateProps = {
@@ -29,85 +18,13 @@ type ReceiptEmptyStateProps = {
     disabled?: boolean;
 
     isThumbnail?: boolean;
-
-    shouldAllowReceiptDrop?: boolean;
-
-    transactionID: string | undefined;
 };
 
 // Returns an SVG icon indicating that the user should attach a receipt
-function ReceiptEmptyState({hasError = false, onPress, disabled = false, isThumbnail = false, shouldAllowReceiptDrop = false, transactionID}: ReceiptEmptyStateProps) {
+function ReceiptEmptyState({hasError = false, onPress, disabled = false, isThumbnail = false}: ReceiptEmptyStateProps) {
     const styles = useThemeStyles();
     const {translate} = useLocalize();
     const theme = useTheme();
-    const [isAttachmentInvalid, setIsAttachmentInvalid] = useState(false);
-    const [attachmentInvalidReasonTitle, setAttachmentInvalidReasonTitle] = useState<TranslationPaths>();
-    const [attachmentInvalidReason, setAttachmentValidReason] = useState<TranslationPaths>();
-    const [pdfFile, setPdfFile] = useState<null | FileObject>(null);
-    const [isLoadingReceipt, setIsLoadingReceipt] = useState(false);
-
-    /**
-     * Sets the upload receipt error modal content when an invalid receipt is uploaded
-     */
-    const setUploadReceiptError = (isInvalid: boolean, title: TranslationPaths, reason: TranslationPaths) => {
-        setIsAttachmentInvalid(isInvalid);
-        setAttachmentInvalidReasonTitle(title);
-        setAttachmentValidReason(reason);
-        setPdfFile(null);
-    };
-
-    const setReceipt = (originalFile: FileObject, isPdfValidated?: boolean) => {
-        validateReceipt(originalFile).then((result) => {
-            if (!result.isValid) {
-                if (result.title && result.reason) {
-                    setUploadReceiptError(true, result.title, result.reason);
-                }
-                return;
-            }
-
-            // If we have a pdf file and if it is not validated then set the pdf file for validation and return
-            if (Str.isPDF(originalFile.name ?? '') && !isPdfValidated) {
-                setPdfFile(originalFile);
-                return;
-            }
-
-            // With the image size > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE, we use manipulateAsync to resize the image.
-            // It takes a long time so we should display a loading indicator while the resize image progresses.
-            if (Str.isImage(originalFile.name ?? '') && (originalFile?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) {
-                setIsLoadingReceipt(true);
-            }
-
-            resizeImageIfNeeded(originalFile).then((file) => {
-                setIsLoadingReceipt(false);
-                const source = URL.createObjectURL(file as Blob);
-                if (transactionID) {
-                    // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
-                    setMoneyRequestReceipt(transactionID, source, file.name || '', true);
-                }
-            });
-        });
-    };
-
-    const hideReceiptModal = () => {
-        setIsAttachmentInvalid(false);
-    };
-
-    const PDFThumbnailView = pdfFile ? (
-        <PDFThumbnail
-            style={styles.invisiblePDF}
-            previewSourceURL={pdfFile.uri ?? ''}
-            onLoadSuccess={() => {
-                setPdfFile(null);
-                setReceipt(pdfFile, true);
-            }}
-            onPassword={() => {
-                setUploadReceiptError(true, 'attachmentPicker.attachmentError', 'attachmentPicker.protectedPDFNotSupported');
-            }}
-            onLoadError={() => {
-                setUploadReceiptError(true, 'attachmentPicker.attachmentError', 'attachmentPicker.errorWhileSelectingCorruptedAttachment');
-            }}
-        />
-    ) : null;
 
     const Wrapper = onPress ? PressableWithoutFeedback : View;
 
@@ -121,14 +38,11 @@ function ReceiptEmptyState({hasError = false, onPress, disabled = false, isThumb
             style={[
                 styles.alignItemsCenter,
                 styles.justifyContentCenter,
-                styles.moneyRequestImage,
+                styles.moneyRequestViewImage,
                 isThumbnail ? styles.moneyRequestAttachReceiptThumbnail : styles.moneyRequestAttachReceipt,
                 hasError && styles.borderColorDanger,
             ]}
         >
-            {isLoadingReceipt && <FullScreenLoadingIndicator />}
-            {PDFThumbnailView}
-
             <View>
                 <Icon
                     fill={theme.border}
@@ -145,27 +59,6 @@ function ReceiptEmptyState({hasError = false, onPress, disabled = false, isThumb
                     />
                 )}
             </View>
-
-            {shouldAllowReceiptDrop && !disabled && (
-                <ReceiptDropUI
-                    onDrop={(e) => {
-                        const file = e?.dataTransfer?.files[0];
-                        if (file) {
-                            file.uri = URL.createObjectURL(file);
-                            setReceipt(file);
-                        }
-                    }}
-                />
-            )}
-            <ConfirmModal
-                title={attachmentInvalidReasonTitle ? translate(attachmentInvalidReasonTitle) : ''}
-                onConfirm={hideReceiptModal}
-                onCancel={hideReceiptModal}
-                isVisible={isAttachmentInvalid}
-                prompt={attachmentInvalidReason ? translate(attachmentInvalidReason) : ''}
-                confirmText={translate('common.close')}
-                shouldShowCancelButton={false}
-            />
         </Wrapper>
     );
 }
diff --git a/src/components/ReceiptImage.tsx b/src/components/ReceiptImage.tsx
index 0f558dad1c6d..bca1ef8b74e6 100644
--- a/src/components/ReceiptImage.tsx
+++ b/src/components/ReceiptImage.tsx
@@ -114,7 +114,6 @@ function ReceiptImage({
                 isThumbnail
                 onPress={onPress}
                 disabled={!onPress}
-                transactionID={transactionID}
             />
         );
     }
@@ -133,7 +132,7 @@ function ReceiptImage({
         return (
             <View style={style ?? [styles.w100, styles.h100]}>
                 <EReceiptThumbnail
-                    transactionID={transactionID}
+                    transactionID={transactionID ?? '-1'}
                     iconSize={iconSize}
                     // eslint-disable-next-line react/jsx-props-no-spreading
                     {...props}
diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx
index 611b18486055..10c72dbd8841 100644
--- a/src/components/ReportActionItem/MoneyRequestView.tsx
+++ b/src/components/ReportActionItem/MoneyRequestView.tsx
@@ -1,7 +1,7 @@
 import React, {useCallback, useMemo} from 'react';
 import {View} from 'react-native';
-import type {OnyxEntry} from 'react-native-onyx';
 import {useOnyx} from 'react-native-onyx';
+import type {OnyxEntry} from 'react-native-onyx';
 import * as Expensicons from '@components/Icon/Expensicons';
 import MenuItem from '@components/MenuItem';
 import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
@@ -16,15 +16,14 @@ import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'
 import useLocalize from '@hooks/useLocalize';
 import useNetwork from '@hooks/useNetwork';
 import useThemeStyles from '@hooks/useThemeStyles';
-import type {ViolationField} from '@hooks/useViolations';
 import useViolations from '@hooks/useViolations';
+import type {ViolationField} from '@hooks/useViolations';
 import {convertToDisplayString} from '@libs/CurrencyUtils';
 import DistanceRequestUtils from '@libs/DistanceRequestUtils';
 import {hasEnabledOptions} from '@libs/OptionsListUtils';
 import {getTagLists, hasDependentTags, isTaxTrackingEnabled} from '@libs/PolicyUtils';
 import {getThumbnailAndImageURIs} from '@libs/ReceiptUtils';
 import {getOriginalMessage, isMoneyRequestAction, isPayAction} from '@libs/ReportActionsUtils';
-import type {TransactionDetails} from '@libs/ReportUtils';
 import {
     canEditFieldOfMoneyRequest,
     canEditMoneyRequest,
@@ -40,6 +39,7 @@ import {
     isSettled as isSettledReportUtils,
     isTrackExpenseReport,
 } from '@libs/ReportUtils';
+import type {TransactionDetails} from '@libs/ReportUtils';
 import {hasEnabledTags} from '@libs/TagsOptionsListUtils';
 import {
     didReceiptScanSucceed as didReceiptScanSucceedTransactionUtils,
@@ -70,13 +70,13 @@ import CONST from '@src/CONST';
 import type {TranslationPaths} from '@src/languages/types';
 import ONYXKEYS from '@src/ONYXKEYS';
 import ROUTES from '@src/ROUTES';
-import type {Report, Transaction, TransactionViolation, ViolationName} from '@src/types/onyx';
+import type * as OnyxTypes from '@src/types/onyx';
 import type {TransactionPendingFieldsKey} from '@src/types/onyx/Transaction';
 import ReportActionItemImage from './ReportActionItemImage';
 
 type MoneyRequestViewProps = {
     /** The report currently being looked at */
-    report: OnyxEntry<Report>;
+    report: OnyxEntry<OnyxTypes.Report>;
 
     /** Whether we should display the animated banner above the component */
     shouldShowAnimatedBackground: boolean;
@@ -88,17 +88,17 @@ type MoneyRequestViewProps = {
     isFromReviewDuplicates?: boolean;
 
     /** Updated transaction to show in duplicate transaction flow  */
-    updatedTransaction?: OnyxEntry<Transaction>;
+    updatedTransaction?: OnyxEntry<OnyxTypes.Transaction>;
 };
 
-const receiptImageViolationNames: ViolationName[] = [
+const receiptImageViolationNames: OnyxTypes.ViolationName[] = [
     CONST.VIOLATIONS.RECEIPT_REQUIRED,
     CONST.VIOLATIONS.RECEIPT_NOT_SMART_SCANNED,
     CONST.VIOLATIONS.CASH_EXPENSE_WITH_NO_RECEIPT,
     CONST.VIOLATIONS.SMARTSCAN_FAILED,
 ];
 
-const receiptFieldViolationNames: ViolationName[] = [CONST.VIOLATIONS.MODIFIED_AMOUNT, CONST.VIOLATIONS.MODIFIED_DATE];
+const receiptFieldViolationNames: OnyxTypes.ViolationName[] = [CONST.VIOLATIONS.MODIFIED_AMOUNT, CONST.VIOLATIONS.MODIFIED_DATE];
 
 function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = false, updatedTransaction, isFromReviewDuplicates = false}: MoneyRequestViewProps) {
     const styles = useThemeStyles();
@@ -219,7 +219,7 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals
 
     const {getViolationsForField} = useViolations(transactionViolations ?? [], isReceiptBeingScanned || !isPaidGroupPolicy(report));
     const hasViolations = useCallback(
-        (field: ViolationField, data?: TransactionViolation['data'], policyHasDependentTags = false, tagValue?: string): boolean =>
+        (field: ViolationField, data?: OnyxTypes.TransactionViolation['data'], policyHasDependentTags = false, tagValue?: string): boolean =>
             getViolationsForField(field, data, policyHasDependentTags, tagValue).length > 0,
         [getViolationsForField],
     );
@@ -293,7 +293,7 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals
     const getPendingFieldAction = (fieldPath: TransactionPendingFieldsKey) => (pendingAction ? undefined : transaction?.pendingFields?.[fieldPath]);
 
     const getErrorForField = useCallback(
-        (field: ViolationField, data?: TransactionViolation['data'], policyHasDependentTags = false, tagValue?: string) => {
+        (field: ViolationField, data?: OnyxTypes.TransactionViolation['data'], policyHasDependentTags = false, tagValue?: string) => {
             // Checks applied when creating a new expense
             // NOTE: receipt field can return multiple violations, so we need to handle it separately
             const fieldChecks: Partial<Record<ViolationField, {isError: boolean; translationPath: TranslationPaths}>> = {
@@ -538,7 +538,6 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals
                         <ReceiptEmptyState
                             hasError={hasErrors}
                             disabled={!canEditReceipt}
-                            transactionID={transaction?.transactionID}
                             onPress={() => {
                                 if (!transaction?.transactionID || !report?.reportID) {
                                     return;
diff --git a/src/libs/ReceiptUtils.ts b/src/libs/ReceiptUtils.ts
index 10355d63fcfa..5085f0e2384e 100644
--- a/src/libs/ReceiptUtils.ts
+++ b/src/libs/ReceiptUtils.ts
@@ -1,15 +1,12 @@
 import {Str} from 'expensify-common';
 import findLast from 'lodash/findLast';
 import type {OnyxEntry} from 'react-native-onyx';
-import type {TupleToUnion} from 'type-fest';
-import type {FileObject} from '@components/AttachmentModal';
 import CONST from '@src/CONST';
-import type {TranslationPaths} from '@src/languages/types';
 import ROUTES from '@src/ROUTES';
 import type {Transaction} from '@src/types/onyx';
 import type {ReceiptError, ReceiptSource} from '@src/types/onyx/Transaction';
-import {isLocalFile as isLocalFileFileUtils, splitExtensionFromFileName, validateImageForCorruption} from './fileDownload/FileUtils';
-import {hasReceipt, hasReceiptSource, isFetchingWaypointsFromServer} from './TransactionUtils';
+import * as FileUtils from './fileDownload/FileUtils';
+import * as TransactionUtils from './TransactionUtils';
 
 type ThumbnailAndImageURI = {
     image?: string;
@@ -30,10 +27,10 @@ type ThumbnailAndImageURI = {
  * @param receiptFileName
  */
 function getThumbnailAndImageURIs(transaction: OnyxEntry<Transaction>, receiptPath: ReceiptSource | null = null, receiptFileName: string | null = null): ThumbnailAndImageURI {
-    if (!hasReceipt(transaction) && !receiptPath && !receiptFileName) {
+    if (!TransactionUtils.hasReceipt(transaction) && !receiptPath && !receiptFileName) {
         return {isEmptyReceipt: true};
     }
-    if (isFetchingWaypointsFromServer(transaction)) {
+    if (TransactionUtils.isFetchingWaypointsFromServer(transaction)) {
         return {isThumbnail: true, isLocalFile: true};
     }
     // If there're errors, we need to display them in preview. We can store many files in errors, but we just need to get the last one
@@ -43,7 +40,7 @@ function getThumbnailAndImageURIs(transaction: OnyxEntry<Transaction>, receiptPa
     // filename of uploaded image or last part of remote URI
     const filename = errors?.filename ?? transaction?.filename ?? receiptFileName ?? '';
     const isReceiptImage = Str.isImage(filename);
-    const hasEReceipt = !hasReceiptSource(transaction) && transaction?.hasEReceipt;
+    const hasEReceipt = !TransactionUtils.hasReceiptSource(transaction) && transaction?.hasEReceipt;
     const isReceiptPDF = Str.isPDF(filename);
 
     if (hasEReceipt) {
@@ -63,60 +60,11 @@ function getThumbnailAndImageURIs(transaction: OnyxEntry<Transaction>, receiptPa
         return {thumbnail: `${path.substring(0, path.length - 4)}.jpg.1024.jpg`, image: path, filename};
     }
 
-    const isLocalFile = isLocalFileFileUtils(path);
-    const {fileExtension} = splitExtensionFromFileName(filename);
+    const isLocalFile = FileUtils.isLocalFile(path);
+    const {fileExtension} = FileUtils.splitExtensionFromFileName(filename);
     return {isThumbnail: true, fileExtension: Object.values(CONST.IOU.FILE_TYPES).find((type) => type === fileExtension), image: path, isLocalFile, filename};
 }
 
-type ValidateReceiptResult = {
-    isValid: boolean;
-    title?: TranslationPaths;
-    reason?: TranslationPaths;
-};
-/**
- * Validate a given receipt file for correctness and adherence to file constraints
- */
-function validateReceipt(file: FileObject): Promise<ValidateReceiptResult> {
-    return validateImageForCorruption(file)
-        .then(() => {
-            const {fileExtension} = splitExtensionFromFileName(file?.name ?? '');
-            const extension = fileExtension.toLowerCase() as TupleToUnion<typeof CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS>;
-
-            if (!CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes(extension)) {
-                return {
-                    isValid: false,
-                    title: 'attachmentPicker.wrongFileType' as TranslationPaths,
-                    reason: 'attachmentPicker.notAllowedExtension' as TranslationPaths,
-                };
-            }
-
-            if (!Str.isImage(file.name ?? '') && (file?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.RECEIPT_MAX_SIZE) {
-                return {
-                    isValid: false,
-                    title: 'attachmentPicker.attachmentTooLarge' as TranslationPaths,
-                    reason: 'attachmentPicker.sizeExceededWithLimit' as TranslationPaths,
-                };
-            }
-
-            if ((file?.size ?? 0) < CONST.API_ATTACHMENT_VALIDATIONS.MIN_SIZE) {
-                return {
-                    isValid: false,
-                    title: 'attachmentPicker.attachmentTooSmall' as TranslationPaths,
-                    reason: 'attachmentPicker.sizeNotMet' as TranslationPaths,
-                };
-            }
-
-            return {isValid: true};
-        })
-        .catch(() => {
-            return {
-                isValid: false,
-                title: 'attachmentPicker.attachmentError' as TranslationPaths,
-                reason: 'attachmentPicker.errorWhileSelectingCorruptedAttachment' as TranslationPaths,
-            };
-        });
-}
-
 // eslint-disable-next-line import/prefer-default-export
-export {getThumbnailAndImageURIs, validateReceipt};
+export {getThumbnailAndImageURIs};
 export type {ThumbnailAndImageURI};
diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts
index 799d6846cf16..b6ce81b0a3d4 100644
--- a/src/libs/actions/IOU.ts
+++ b/src/libs/actions/IOU.ts
@@ -3798,16 +3798,13 @@ function updateMoneyRequestDate(
 
 /** Updates the billable field of an expense */
 function updateMoneyRequestBillable(
-    transactionID: string | undefined,
-    transactionThreadReportID: string | undefined,
+    transactionID: string,
+    transactionThreadReportID: string,
     value: boolean,
     policy: OnyxEntry<OnyxTypes.Policy>,
     policyTagList: OnyxEntry<OnyxTypes.PolicyTagLists>,
     policyCategories: OnyxEntry<OnyxTypes.PolicyCategories>,
 ) {
-    if (!transactionID || !transactionThreadReportID) {
-        return;
-    }
     const transactionChanges: TransactionChanges = {
         billable: value,
     };
diff --git a/src/libs/actions/ReportActions.ts b/src/libs/actions/ReportActions.ts
index 272ce2c1465c..e8d7949464d8 100644
--- a/src/libs/actions/ReportActions.ts
+++ b/src/libs/actions/ReportActions.ts
@@ -4,21 +4,20 @@ import {getLinkedTransactionID, getReportAction, getReportActionMessage, isCreat
 import {getOriginalReportID} from '@libs/ReportUtils';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
-import type {Report} from '@src/types/onyx';
+import type * as OnyxTypes from '@src/types/onyx';
 import type ReportAction from '@src/types/onyx/ReportAction';
-import type {ReportActions} from '@src/types/onyx/ReportAction';
 import {deleteReport} from './Report';
 
 type IgnoreDirection = 'parent' | 'child';
 
-let allReportActions: OnyxCollection<ReportActions>;
+let allReportActions: OnyxCollection<OnyxTypes.ReportActions>;
 Onyx.connect({
     key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
     waitForCollectionCallback: true,
     callback: (value) => (allReportActions = value),
 });
 
-let allReports: OnyxCollection<Report>;
+let allReports: OnyxCollection<OnyxTypes.Report>;
 Onyx.connect({
     key: ONYXKEYS.COLLECTION.REPORT,
     waitForCollectionCallback: true,
diff --git a/src/libs/actions/Transaction.ts b/src/libs/actions/Transaction.ts
index beddbd587b02..d2f996c3e965 100644
--- a/src/libs/actions/Transaction.ts
+++ b/src/libs/actions/Transaction.ts
@@ -473,10 +473,7 @@ function abandonReviewDuplicateTransactions() {
     Onyx.set(ONYXKEYS.REVIEW_DUPLICATES, null);
 }
 
-function clearError(transactionID: string | undefined) {
-    if (!transactionID) {
-        return;
-    }
+function clearError(transactionID: string) {
     Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {errors: null, errorFields: {route: null, waypoints: null, routes: null}});
 }
 
diff --git a/src/pages/iou/ReceiptDropUI.tsx b/src/pages/iou/ReceiptDropUI.tsx
index d7a434fe70bb..db7ff0c6c57a 100644
--- a/src/pages/iou/ReceiptDropUI.tsx
+++ b/src/pages/iou/ReceiptDropUI.tsx
@@ -16,13 +16,13 @@ type ReceiptDropUIProps = {
     receiptImageTopPosition?: number;
 };
 
-function ReceiptDropUI({onDrop, receiptImageTopPosition}: ReceiptDropUIProps) {
+function ReceiptDropUI({onDrop, receiptImageTopPosition = 0}: ReceiptDropUIProps) {
     const styles = useThemeStyles();
     const {translate} = useLocalize();
     return (
         <DragAndDropConsumer onDrop={onDrop}>
             <View style={[styles.fileDropOverlay, styles.w100, styles.h100, styles.justifyContentCenter, styles.alignItemsCenter]}>
-                <View style={[receiptImageTopPosition ? styles.fileUploadImageWrapper(receiptImageTopPosition) : null]}>
+                <View style={styles.fileUploadImageWrapper(receiptImageTopPosition)}>
                     <ImageSVG
                         src={ReceiptUpload}
                         contentFit="contain"
diff --git a/src/pages/iou/SplitBillDetailsPage.tsx b/src/pages/iou/SplitBillDetailsPage.tsx
index 0797f5e925ab..b31fe7f71a6d 100644
--- a/src/pages/iou/SplitBillDetailsPage.tsx
+++ b/src/pages/iou/SplitBillDetailsPage.tsx
@@ -2,7 +2,6 @@ import React, {useCallback, useState} from 'react';
 import {View} from 'react-native';
 import {useOnyx} from 'react-native-onyx';
 import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
-import DragAndDropProvider from '@components/DragAndDrop/Provider';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
 import Icon from '@components/Icon';
 import * as Expensicons from '@components/Icon/Expensicons';
@@ -19,11 +18,11 @@ import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavig
 import type {SplitDetailsNavigatorParamList} from '@libs/Navigation/types';
 import {getParticipantsOption, getPolicyExpenseReportOption} from '@libs/OptionsListUtils';
 import {getOriginalMessage, isMoneyRequestAction} from '@libs/ReportActionsUtils';
-import type {OptionData} from '@libs/ReportUtils';
 import {getTransactionDetails, isPolicyExpenseChat} from '@libs/ReportUtils';
+import type {OptionData} from '@libs/ReportUtils';
 import {areRequiredFieldsEmpty, hasReceipt, isDistanceRequest, isReceiptBeingScanned} from '@libs/TransactionUtils';
-import type {WithReportAndReportActionOrNotFoundProps} from '@pages/home/report/withReportAndReportActionOrNotFound';
 import withReportAndReportActionOrNotFound from '@pages/home/report/withReportAndReportActionOrNotFound';
+import type {WithReportAndReportActionOrNotFoundProps} from '@pages/home/report/withReportAndReportActionOrNotFound';
 import variables from '@styles/variables';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
@@ -67,7 +66,6 @@ function SplitBillDetailsPage({route, report, reportAction}: SplitBillDetailsPag
     const hasSmartScanFailed = hasReceipt(transaction) && transaction?.receipt?.state === CONST.IOU.RECEIPT_STATE.SCANFAILED;
     const isEditingSplitBill = session?.accountID === actorAccountID && areRequiredFieldsEmpty(transaction);
     const [isConfirmed, setIsConfirmed] = useState(false);
-    const [isDraggingOver, setIsDraggingOver] = useState(false);
 
     const {
         amount: splitAmount,
@@ -85,69 +83,64 @@ function SplitBillDetailsPage({route, report, reportAction}: SplitBillDetailsPag
     }, [reportID, reportAction, draftTransaction, session?.accountID, session?.email]);
 
     return (
-        <ScreenWrapper
-            testID={SplitBillDetailsPage.displayName}
-            headerGapStyles={isDraggingOver ? [styles.isDraggingOver] : []}
-        >
+        <ScreenWrapper testID={SplitBillDetailsPage.displayName}>
             <FullPageNotFoundView shouldShow={!reportID || isEmptyObject(reportAction) || isEmptyObject(transaction)}>
-                <DragAndDropProvider setIsDraggingOver={setIsDraggingOver}>
-                    <HeaderWithBackButton
-                        title={translate('common.details')}
-                        onBackButtonPress={() => Navigation.goBack(route.params.backTo)}
-                    />
-                    <View style={[styles.containerWithSpaceBetween, styles.pointerEventsBoxNone]}>
-                        {isScanning && (
-                            <View style={[styles.ph5, styles.pb3, styles.borderBottom]}>
-                                <MoneyRequestHeaderStatusBar
-                                    icon={
-                                        <Icon
-                                            src={Expensicons.ReceiptScan}
-                                            height={variables.iconSizeSmall}
-                                            width={variables.iconSizeSmall}
-                                            fill={theme.icon}
-                                        />
-                                    }
-                                    description={translate('iou.receiptScanInProgressDescription')}
-                                    shouldStyleFlexGrow={false}
-                                />
-                            </View>
+                <HeaderWithBackButton
+                    title={translate('common.details')}
+                    onBackButtonPress={() => Navigation.goBack(route.params.backTo)}
+                />
+                <View style={[styles.containerWithSpaceBetween, styles.pointerEventsBoxNone]}>
+                    {isScanning && (
+                        <View style={[styles.ph5, styles.pb3, styles.borderBottom]}>
+                            <MoneyRequestHeaderStatusBar
+                                icon={
+                                    <Icon
+                                        src={Expensicons.ReceiptScan}
+                                        height={variables.iconSizeSmall}
+                                        width={variables.iconSizeSmall}
+                                        fill={theme.icon}
+                                    />
+                                }
+                                description={translate('iou.receiptScanInProgressDescription')}
+                                shouldStyleFlexGrow={false}
+                            />
+                        </View>
+                    )}
+                    <ImageBehaviorContextProvider shouldSetAspectRatioInStyle={!isDistanceRequest(transaction)}>
+                        {!!participants.length && (
+                            <MoneyRequestConfirmationList
+                                payeePersonalDetails={payeePersonalDetails}
+                                selectedParticipants={participantsExcludingPayee}
+                                iouAmount={splitAmount ?? 0}
+                                iouCurrencyCode={splitCurrency}
+                                iouComment={splitComment}
+                                iouCreated={splitCreated}
+                                shouldDisplayReceipt
+                                iouMerchant={splitMerchant}
+                                iouCategory={splitCategory}
+                                iouIsBillable={splitBillable}
+                                iouType={CONST.IOU.TYPE.SPLIT}
+                                isReadOnly={!isEditingSplitBill}
+                                shouldShowSmartScanFields
+                                receiptPath={transaction?.receipt?.source}
+                                receiptFilename={transaction?.filename}
+                                isEditingSplitBill={isEditingSplitBill}
+                                hasSmartScanFailed={hasSmartScanFailed}
+                                reportID={reportID}
+                                reportActionID={reportAction?.reportActionID}
+                                transaction={isEditingSplitBill && draftTransaction ? draftTransaction : transaction}
+                                onConfirm={onConfirm}
+                                isPolicyExpenseChat={isPolicyExpenseChat(report)}
+                                policyID={isPolicyExpenseChat(report) ? report?.policyID : undefined}
+                                action={isEditingSplitBill ? CONST.IOU.ACTION.EDIT : CONST.IOU.ACTION.CREATE}
+                                onToggleBillable={(billable) => {
+                                    setDraftSplitTransaction(transaction?.transactionID, {billable});
+                                }}
+                                isConfirmed={isConfirmed}
+                            />
                         )}
-                        <ImageBehaviorContextProvider shouldSetAspectRatioInStyle={!isDistanceRequest(transaction)}>
-                            {!!participants.length && (
-                                <MoneyRequestConfirmationList
-                                    payeePersonalDetails={payeePersonalDetails}
-                                    selectedParticipants={participantsExcludingPayee}
-                                    iouAmount={splitAmount ?? 0}
-                                    iouCurrencyCode={splitCurrency}
-                                    iouComment={splitComment}
-                                    iouCreated={splitCreated}
-                                    shouldDisplayReceipt
-                                    iouMerchant={splitMerchant}
-                                    iouCategory={splitCategory}
-                                    iouIsBillable={splitBillable}
-                                    iouType={CONST.IOU.TYPE.SPLIT}
-                                    isReadOnly={!isEditingSplitBill}
-                                    shouldShowSmartScanFields
-                                    receiptPath={transaction?.receipt?.source}
-                                    receiptFilename={transaction?.filename}
-                                    isEditingSplitBill={isEditingSplitBill}
-                                    hasSmartScanFailed={hasSmartScanFailed}
-                                    reportID={reportID}
-                                    reportActionID={reportAction?.reportActionID}
-                                    transaction={isEditingSplitBill && draftTransaction ? draftTransaction : transaction}
-                                    onConfirm={onConfirm}
-                                    isPolicyExpenseChat={isPolicyExpenseChat(report)}
-                                    policyID={isPolicyExpenseChat(report) ? report?.policyID : undefined}
-                                    action={isEditingSplitBill ? CONST.IOU.ACTION.EDIT : CONST.IOU.ACTION.CREATE}
-                                    onToggleBillable={(billable) => {
-                                        setDraftSplitTransaction(transaction?.transactionID, {billable});
-                                    }}
-                                    isConfirmed={isConfirmed}
-                                />
-                            )}
-                        </ImageBehaviorContextProvider>
-                    </View>
-                </DragAndDropProvider>
+                    </ImageBehaviorContextProvider>
+                </View>
             </FullPageNotFoundView>
         </ScreenWrapper>
     );
diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx
index 88b963cd0452..a54c882259c8 100644
--- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx
+++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx
@@ -2,7 +2,6 @@ import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
 import {View} from 'react-native';
 import type {OnyxEntry} from 'react-native-onyx';
 import {useOnyx} from 'react-native-onyx';
-import DragAndDropProvider from '@components/DragAndDrop/Provider';
 import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
 import HeaderWithBackButton from '@components/HeaderWithBackButton';
 import * as Expensicons from '@components/Icon/Expensicons';
@@ -126,7 +125,6 @@ function IOURequestStepConfirmation({
 
     const gpsRequired = transaction?.amount === 0 && iouType !== CONST.IOU.TYPE.SPLIT && receiptFile;
     const [isConfirmed, setIsConfirmed] = useState(false);
-    const [isDraggingOver, setIsDraggingOver] = useState(false);
 
     const headerTitle = useMemo(() => {
         if (isCategorizingTrackExpense) {
@@ -675,68 +673,65 @@ function IOURequestStepConfirmation({
         <ScreenWrapper
             shouldEnableMaxHeight={canUseTouchScreen()}
             testID={IOURequestStepConfirmation.displayName}
-            headerGapStyles={isDraggingOver ? [styles.isDraggingOver] : []}
         >
-            <DragAndDropProvider setIsDraggingOver={setIsDraggingOver}>
-                <View style={styles.flex1}>
-                    <HeaderWithBackButton
-                        title={headerTitle}
-                        onBackButtonPress={navigateBack}
-                        shouldShowThreeDotsButton={
-                            requestType === CONST.IOU.REQUEST_TYPE.MANUAL && (iouType === CONST.IOU.TYPE.SUBMIT || iouType === CONST.IOU.TYPE.TRACK) && !isMovingTransactionFromTrackExpense
-                        }
-                        threeDotsAnchorPosition={styles.threeDotsPopoverOffsetNoCloseButton(windowWidth)}
-                        threeDotsMenuItems={[
-                            {
-                                icon: Expensicons.Receipt,
-                                text: translate('receipt.addReceipt'),
-                                onSelected: navigateToAddReceipt,
-                            },
-                        ]}
-                    />
-                    {isLoading && <FullScreenLoadingIndicator />}
-                    {!!gpsRequired && (
-                        <LocationPermissionModal
-                            startPermissionFlow={startLocationPermissionFlow}
-                            resetPermissionFlow={() => setStartLocationPermissionFlow(false)}
-                            onGrant={() => createTransaction(selectedParticipantList, true)}
-                            onDeny={() => {
-                                updateLastLocationPermissionPrompt();
-                                createTransaction(selectedParticipantList, false);
-                            }}
-                        />
-                    )}
-                    <MoneyRequestConfirmationList
-                        transaction={transaction}
-                        selectedParticipants={participants}
-                        iouAmount={Math.abs(transaction?.amount ?? 0)}
-                        iouAttendees={transaction?.attendees ?? []}
-                        iouComment={transaction?.comment?.comment ?? ''}
-                        iouCurrencyCode={transaction?.currency}
-                        iouIsBillable={transaction?.billable}
-                        onToggleBillable={setBillable}
-                        iouCategory={transaction?.category}
-                        onConfirm={onConfirm}
-                        onSendMoney={sendMoney}
-                        receiptPath={receiptPath}
-                        receiptFilename={receiptFilename}
-                        iouType={iouType}
-                        reportID={reportID}
-                        isPolicyExpenseChat={isPolicyExpenseChat}
-                        policyID={getIOURequestPolicyID(transaction, report)}
-                        bankAccountRoute={getBankAccountRoute(report)}
-                        iouMerchant={transaction?.merchant}
-                        iouCreated={transaction?.created}
-                        isDistanceRequest={isDistanceRequest}
-                        isPerDiemRequest={isPerDiemRequest}
-                        shouldShowSmartScanFields={isMovingTransactionFromTrackExpense ? transaction?.amount !== 0 : requestType !== CONST.IOU.REQUEST_TYPE.SCAN}
-                        action={action}
-                        payeePersonalDetails={payeePersonalDetails}
-                        shouldPlaySound={iouType === CONST.IOU.TYPE.PAY}
-                        isConfirmed={isConfirmed}
+            <View style={styles.flex1}>
+                <HeaderWithBackButton
+                    title={headerTitle}
+                    onBackButtonPress={navigateBack}
+                    shouldShowThreeDotsButton={
+                        requestType === CONST.IOU.REQUEST_TYPE.MANUAL && (iouType === CONST.IOU.TYPE.SUBMIT || iouType === CONST.IOU.TYPE.TRACK) && !isMovingTransactionFromTrackExpense
+                    }
+                    threeDotsAnchorPosition={styles.threeDotsPopoverOffsetNoCloseButton(windowWidth)}
+                    threeDotsMenuItems={[
+                        {
+                            icon: Expensicons.Receipt,
+                            text: translate('receipt.addReceipt'),
+                            onSelected: navigateToAddReceipt,
+                        },
+                    ]}
+                />
+                {isLoading && <FullScreenLoadingIndicator />}
+                {!!gpsRequired && (
+                    <LocationPermissionModal
+                        startPermissionFlow={startLocationPermissionFlow}
+                        resetPermissionFlow={() => setStartLocationPermissionFlow(false)}
+                        onGrant={() => createTransaction(selectedParticipantList, true)}
+                        onDeny={() => {
+                            updateLastLocationPermissionPrompt();
+                            createTransaction(selectedParticipantList, false);
+                        }}
                     />
-                </View>
-            </DragAndDropProvider>
+                )}
+                <MoneyRequestConfirmationList
+                    transaction={transaction}
+                    selectedParticipants={participants}
+                    iouAmount={Math.abs(transaction?.amount ?? 0)}
+                    iouAttendees={transaction?.attendees ?? []}
+                    iouComment={transaction?.comment?.comment ?? ''}
+                    iouCurrencyCode={transaction?.currency}
+                    iouIsBillable={transaction?.billable}
+                    onToggleBillable={setBillable}
+                    iouCategory={transaction?.category}
+                    onConfirm={onConfirm}
+                    onSendMoney={sendMoney}
+                    receiptPath={receiptPath}
+                    receiptFilename={receiptFilename}
+                    iouType={iouType}
+                    reportID={reportID}
+                    isPolicyExpenseChat={isPolicyExpenseChat}
+                    policyID={getIOURequestPolicyID(transaction, report)}
+                    bankAccountRoute={getBankAccountRoute(report)}
+                    iouMerchant={transaction?.merchant}
+                    iouCreated={transaction?.created}
+                    isDistanceRequest={isDistanceRequest}
+                    isPerDiemRequest={isPerDiemRequest}
+                    shouldShowSmartScanFields={isMovingTransactionFromTrackExpense ? transaction?.amount !== 0 : requestType !== CONST.IOU.REQUEST_TYPE.SCAN}
+                    action={action}
+                    payeePersonalDetails={payeePersonalDetails}
+                    shouldPlaySound={iouType === CONST.IOU.TYPE.PAY}
+                    isConfirmed={isConfirmed}
+                />
+            </View>
         </ScreenWrapper>
     );
 }
diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx
index 1140f23011f5..ec32b709ad8f 100644
--- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx
+++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx
@@ -455,7 +455,7 @@ function IOURequestStepScan({
             return;
         }
 
-        // With the image size > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE, we use manipulateAsync to resize the image.
+        // With the image size > 24MB, we use manipulateAsync to resize the image.
         // It takes a long time so we should display a loading indicator while the resize image progresses.
         if (Str.isImage(originalFile.name ?? '') && (originalFile?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) {
             setIsLoadingReceipt(true);
diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx
index b0900d36965e..e31b13a4091e 100644
--- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx
+++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx
@@ -4,6 +4,7 @@ import React, {useCallback, useContext, useEffect, useMemo, useReducer, useRef,
 import {ActivityIndicator, PanResponder, PixelRatio, View} from 'react-native';
 import {useOnyx} from 'react-native-onyx';
 import type Webcam from 'react-webcam';
+import type {TupleToUnion} from 'type-fest';
 import Hand from '@assets/images/hand.svg';
 import ReceiptUpload from '@assets/images/receipt-upload.svg';
 import Shutter from '@assets/images/shutter.svg';
@@ -28,13 +29,12 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout';
 import useTheme from '@hooks/useTheme';
 import useThemeStyles from '@hooks/useThemeStyles';
 import {isMobile, isMobileWebKit} from '@libs/Browser';
-import {base64ToFile, resizeImageIfNeeded} from '@libs/fileDownload/FileUtils';
+import {base64ToFile, resizeImageIfNeeded, splitExtensionFromFileName, validateImageForCorruption} from '@libs/fileDownload/FileUtils';
 import getCurrentPosition from '@libs/getCurrentPosition';
 import {shouldStartLocationPermissionFlow} from '@libs/IOUUtils';
 import Log from '@libs/Log';
 import Navigation from '@libs/Navigation/Navigation';
 import {getParticipantsOption, getReportOption} from '@libs/OptionsListUtils';
-import {validateReceipt} from '@libs/ReceiptUtils';
 import {isArchivedReport, isPolicyExpenseChat} from '@libs/ReportUtils';
 import playSound, {SOUNDS} from '@libs/Sound';
 import {getDefaultTaxCode} from '@libs/TransactionUtils';
@@ -199,7 +199,7 @@ function IOURequestStepScan({
         // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
     }, [isTabActive]);
 
-    const hideReceiptModal = () => {
+    const hideRecieptModal = () => {
         setIsAttachmentInvalid(false);
     };
 
@@ -213,6 +213,36 @@ function IOURequestStepScan({
         setPdfFile(null);
     };
 
+    function validateReceipt(file: FileObject) {
+        return validateImageForCorruption(file)
+            .then(() => {
+                const {fileExtension} = splitExtensionFromFileName(file?.name ?? '');
+                if (
+                    !CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS.includes(
+                        fileExtension.toLowerCase() as TupleToUnion<typeof CONST.API_ATTACHMENT_VALIDATIONS.ALLOWED_RECEIPT_EXTENSIONS>,
+                    )
+                ) {
+                    setUploadReceiptError(true, 'attachmentPicker.wrongFileType', 'attachmentPicker.notAllowedExtension');
+                    return false;
+                }
+
+                if (!Str.isImage(file.name ?? '') && (file?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.RECEIPT_MAX_SIZE) {
+                    setUploadReceiptError(true, 'attachmentPicker.attachmentTooLarge', 'attachmentPicker.sizeExceededWithLimit');
+                    return false;
+                }
+
+                if ((file?.size ?? 0) < CONST.API_ATTACHMENT_VALIDATIONS.MIN_SIZE) {
+                    setUploadReceiptError(true, 'attachmentPicker.attachmentTooSmall', 'attachmentPicker.sizeNotMet');
+                    return false;
+                }
+                return true;
+            })
+            .catch(() => {
+                setUploadReceiptError(true, 'attachmentPicker.attachmentError', 'attachmentPicker.errorWhileSelectingCorruptedAttachment');
+                return false;
+            });
+    }
+
     const navigateBack = useCallback(() => {
         Navigation.goBack(backTo);
     }, [backTo]);
@@ -441,11 +471,8 @@ function IOURequestStepScan({
      * Sets the Receipt objects and navigates the user to the next page
      */
     const setReceiptAndNavigate = (originalFile: FileObject, isPdfValidated?: boolean) => {
-        validateReceipt(originalFile).then((result) => {
-            if (!result.isValid) {
-                if (result.title && result.reason) {
-                    setUploadReceiptError(true, result.title, result.reason);
-                }
+        validateReceipt(originalFile).then((isFileValid) => {
+            if (!isFileValid) {
                 return;
             }
 
@@ -455,7 +482,7 @@ function IOURequestStepScan({
                 return;
             }
 
-            // With the image size > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE, we use manipulateAsync to resize the image.
+            // With the image size > 24MB, we use manipulateAsync to resize the image.
             // It takes a long time so we should display a loading indicator while the resize image progresses.
             if (Str.isImage(originalFile.name ?? '') && (originalFile?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) {
                 setIsLoadingReceipt(true);
@@ -780,8 +807,8 @@ function IOURequestStepScan({
                         />
                         <ConfirmModal
                             title={attachmentInvalidReasonTitle ? translate(attachmentInvalidReasonTitle) : ''}
-                            onConfirm={hideReceiptModal}
-                            onCancel={hideReceiptModal}
+                            onConfirm={hideRecieptModal}
+                            onCancel={hideRecieptModal}
                             isVisible={isAttachmentInvalid}
                             prompt={getConfirmModalPrompt()}
                             confirmText={translate('common.close')}
