diff --git a/src/CONST.js b/src/CONST.js
index 19a7bdf92f08..a32ad3121da9 100755
--- a/src/CONST.js
+++ b/src/CONST.js
@@ -271,6 +271,7 @@ const CONST = {
     KEYBOARD_TYPE: {
         NUMERIC: 'numeric',
         PHONE_PAD: 'phone-pad',
+        NUMBER_PAD: 'number-pad',
     },
 
     ATTACHMENT_PICKER_TYPE: {
@@ -443,7 +444,7 @@ const CONST = {
         NUMBER: /^[0-9]+$/,
         CARD_NUMBER: /^[0-9]{15,16}$/,
         CARD_SECURITY_CODE: /^[0-9]{3,4}$/,
-        CARD_EXPIRATION_DATE: /(0[1-9]|10|11|12)\/20[0-9]{2}$/,
+        CARD_EXPIRATION_DATE: /^(0[1-9]|1[0-2])([^0-9])?([0-9]{4}|([0-9]{2}))$/,
         PAYPAL_ME_USERNAME: /^[a-zA-Z0-9]+$/,
 
         // Adapted from: https://gist.github.com/dperini/729294
diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js
index 4317a9ac6be1..ece47440dabe 100755
--- a/src/ONYXKEYS.js
+++ b/src/ONYXKEYS.js
@@ -137,4 +137,7 @@ export default {
 
     // Set when we are loading payment methods
     IS_LOADING_PAYMENT_METHODS: 'isLoadingPaymentMethods',
+
+    // Stores values for the add debit card form
+    ADD_DEBIT_CARD_FORM: 'addDebitCardForm',
 };
diff --git a/src/components/FormAlertWithSubmitButton.js b/src/components/FormAlertWithSubmitButton.js
index 0bd2659eb32e..077814e11f2c 100644
--- a/src/components/FormAlertWithSubmitButton.js
+++ b/src/components/FormAlertWithSubmitButton.js
@@ -37,6 +37,9 @@ const propTypes = {
     /** Styles for container element */
     containerStyles: PropTypes.arrayOf(PropTypes.object),
 
+    /** Is the button in a loading state */
+    isLoading: PropTypes.bool,
+
     ...withLocalizePropTypes,
 };
 
@@ -45,6 +48,7 @@ const defaultProps = {
     isDisabled: false,
     isMessageHtml: false,
     containerStyles: [],
+    isLoading: false,
 };
 
 const FormAlertWithSubmitButton = ({
@@ -57,6 +61,7 @@ const FormAlertWithSubmitButton = ({
     message,
     isMessageHtml,
     containerStyles,
+    isLoading,
 }) => {
     /**
      * @returns {React.Component}
@@ -114,6 +119,7 @@ const FormAlertWithSubmitButton = ({
                 text={buttonText}
                 onPress={onSubmit}
                 isDisabled={isDisabled}
+                isLoading={isLoading}
             />
         </View>
     );
diff --git a/src/languages/en.js b/src/languages/en.js
index bde22d3861bd..097d9bb5724c 100755
--- a/src/languages/en.js
+++ b/src/languages/en.js
@@ -84,6 +84,8 @@ export default {
         confirm: 'Confirm',
         reset: 'Reset',
         done: 'Done',
+        debitCard: 'Debit card',
+        payPalMe: 'PayPal.me/',
     },
     attachmentPicker: {
         cameraPermissionRequired: 'Camera permission required',
@@ -279,7 +281,6 @@ export default {
     },
     addPayPalMePage: {
         enterYourUsernameToGetPaidViaPayPal: 'Enter your username to get paid back via PayPal.',
-        payPalMe: 'PayPal.me/',
         yourPayPalUsername: 'Your PayPal username',
         addPayPalAccount: 'Add PayPal account',
         editPayPalAccount: 'Update PayPal account',
@@ -287,24 +288,22 @@ export default {
         formatError: 'Invalid PayPal.me username',
     },
     addDebitCardPage: {
-        addADebitCard: 'Add a Debit Card',
-        nameOnCard: 'Name on Card',
-        debitCardNumber: 'Debit Card Number',
-        expiration: 'Expiration',
-        expirationDate: 'MM/YYYY',
+        addADebitCard: 'Add a debit card',
+        nameOnCard: 'Name on card',
+        debitCardNumber: 'Debit card number',
+        expiration: 'Expiration date',
+        expirationDate: 'MM/YY',
         cvv: 'CVV',
-        billingAddress: 'Billing Address',
-        streetAddress: 'Street Address',
-        cityName: 'City Name',
-        expensifyTermsOfService: 'Expensify Terms Of Service',
+        billingAddress: 'Billing address',
+        expensifyTermsOfService: 'Expensify Terms of Service',
         growlMessageOnSave: 'Your debit card was successfully added',
         error: {
-            invalidName: 'Please add a valid name',
-            zipCode: 'Please enter a valid zip code',
+            invalidName: 'Please enter a valid name',
+            addressZipCode: 'Please enter a valid zip code',
             debitCardNumber: 'Please enter a valid debit card number',
             expirationDate: 'Please enter a valid expiration date',
             securityCode: 'Please enter a valid security code',
-            address: 'Please enter a valid billing address',
+            addressStreet: 'Please enter a valid billing address that is not a PO Box',
             addressState: 'Please select a state',
             addressCity: 'Please enter a city',
             acceptedTerms: 'You must accept the Terms of Service to continue',
diff --git a/src/languages/es.js b/src/languages/es.js
index b46ff9ae7e50..37eb855bbf3c 100644
--- a/src/languages/es.js
+++ b/src/languages/es.js
@@ -84,6 +84,8 @@ export default {
         confirm: 'Confirmar',
         reset: 'Restablecer',
         done: 'Listo',
+        debitCard: 'Tarjeta de débito',
+        payPalMe: 'PayPal.me/',
     },
     attachmentPicker: {
         cameraPermissionRequired: 'Se necesita permiso para usar la cámara',
@@ -279,7 +281,6 @@ export default {
     },
     addPayPalMePage: {
         enterYourUsernameToGetPaidViaPayPal: 'Escribe tu nombre de usuario para que otros puedan pagarte a través de PayPal.',
-        payPalMe: 'PayPal.me/',
         yourPayPalUsername: 'Tu usuario de PayPal',
         addPayPalAccount: 'Agregar cuenta de PayPal',
         growlMessageOnSave: 'Su nombre de usuario de PayPal se agregó correctamente',
@@ -290,21 +291,19 @@ export default {
         addADebitCard: 'Agregar una tarjeta de débito',
         nameOnCard: 'Nombre en la tarjeta',
         debitCardNumber: 'Numero de la tarjeta de débito',
-        expiration: 'Vencimiento',
+        expiration: 'Fecha de vencimiento',
         expirationDate: 'MM/AA',
         cvv: 'CVV',
-        billingAddress: 'Dirección de Envio',
-        streetAddress: 'Dirección',
-        cityName: 'Nombre de la ciudad',
+        billingAddress: 'Dirección de envio',
         expensifyTermsOfService: 'Expensify Términos de servicio',
         growlMessageOnSave: 'Su tarteja de débito se agregó correctamente',
         error: {
-            invalidName: 'Por favor agregue un nombre válido',
-            zipCode: 'Por favor ingrese un código postal válido',
+            invalidName: 'Por favor ingrese un nombre válido',
+            addressZipCode: 'Por favor ingrese un código postal válido',
             debitCardNumber: 'Ingrese un número de tarjeta de débito válido',
             expirationDate: 'Por favor introduzca una fecha de vencimiento válida',
             securityCode: 'Ingrese un código de seguridad válido',
-            address: 'Ingrese una dirección de facturación válida',
+            addressStreet: 'Ingrese una dirección de facturación válida que no sea un apartado postal',
             addressState: 'Por favor seleccione un estado',
             addressCity: 'Por favor ingrese una ciudad',
             acceptedTerms: 'Debes aceptar los Términos de servicio para continuar',
diff --git a/src/libs/CardUtils.js b/src/libs/CardUtils.js
new file mode 100644
index 000000000000..5b7a0d3ec7fc
--- /dev/null
+++ b/src/libs/CardUtils.js
@@ -0,0 +1,39 @@
+/**
+ * Returns the masked card number (ex: 4242XXXXXXXX4242)
+ *
+ * @param {String} cardNumber
+ * @return {Boolean}
+ */
+function maskCardNumber(cardNumber) {
+    const firstFour = cardNumber.substring(0, 4);
+    const lastFour = cardNumber.substring(cardNumber.length - 4);
+
+    return `${firstFour}${'X'.repeat(cardNumber.length - 8)}${lastFour}`;
+}
+
+/**
+ * @param {String} expirationDateString - string in MM/YYYY, MM/YY, MMYY, or MMYYYY format
+ * @returns {String}
+ */
+function getMonthFromExpirationDateString(expirationDateString) {
+    return expirationDateString.substr(0, 2);
+}
+
+/**
+ * @param {String} expirationDateString - string in MMYY or MMYYYY format, with any non-number separator
+ * @returns {String}
+ */
+function getYearFromExpirationDateString(expirationDateString) {
+    const stringContainsNumbersOnly = /^\d+$/.test(expirationDateString);
+    const cardYear = stringContainsNumbersOnly
+        ? expirationDateString.substr(2)
+        : expirationDateString.substr(3);
+
+    return cardYear.length === 2 ? `20${cardYear}` : cardYear;
+}
+
+export {
+    maskCardNumber,
+    getMonthFromExpirationDateString,
+    getYearFromExpirationDateString,
+};
diff --git a/src/libs/ValidationUtils.js b/src/libs/ValidationUtils.js
index 2de72b331023..13d1c2501321 100644
--- a/src/libs/ValidationUtils.js
+++ b/src/libs/ValidationUtils.js
@@ -1,7 +1,7 @@
 import moment from 'moment';
 import _ from 'underscore';
 import CONST from '../CONST';
-
+import {getMonthFromExpirationDateString, getYearFromExpirationDateString} from './CardUtils';
 
 /**
  * Implements the Luhn Algorithm, a checksum formula used to validate credit card
@@ -76,14 +76,23 @@ function isRequiredFulfilled(value) {
 }
 
 /**
- * Validates that this is a valid expiration date
- * in the MM/YY or MM/YYYY format
+ * Validates that this is a valid expiration date. Supports the following formats:
+ * 1. MM/YY
+ * 2. MM/YYYY
+ * 3. MMYY
+ * 4. MMYYYY
  *
  * @param {String} string
  * @returns {Boolean}
  */
 function isValidExpirationDate(string) {
-    return CONST.REGEX.CARD_EXPIRATION_DATE.test(string);
+    if (!CONST.REGEX.CARD_EXPIRATION_DATE.test(string)) {
+        return false;
+    }
+
+    // Use the last of the month to check if the expiration date is in the future or not
+    const expirationDate = `${getYearFromExpirationDateString(string)}-${getMonthFromExpirationDateString(string)}-01`;
+    return moment(expirationDate).endOf('month').isAfter(moment());
 }
 
 /**
diff --git a/src/libs/actions/PaymentMethods.js b/src/libs/actions/PaymentMethods.js
index d9467327244d..f8b6cacedf4f 100644
--- a/src/libs/actions/PaymentMethods.js
+++ b/src/libs/actions/PaymentMethods.js
@@ -7,7 +7,7 @@ import ROUTES from '../../ROUTES';
 import Growl from '../Growl';
 import {translateLocal} from '../translate';
 import Navigation from '../Navigation/Navigation';
-import {maskCardNumber} from '../cardUtils';
+import {maskCardNumber, getMonthFromExpirationDateString, getYearFromExpirationDateString} from '../CardUtils';
 
 /**
  * Calls the API to get the user's bankAccountList, cardList, wallet, and payPalMe
@@ -41,18 +41,20 @@ function getPaymentMethods() {
  * @param {Object} params
  */
 function addBillingCard(params) {
-    const cardYear = params.expirationDate.substr(3);
-    const cardMonth = params.expirationDate.substr(0, 2);
+    const cardMonth = getMonthFromExpirationDateString(params.expirationDate);
+    const cardYear = getYearFromExpirationDateString(params.expirationDate);
 
+    Onyx.merge(ONYXKEYS.ADD_DEBIT_CARD_FORM, {submitting: true});
     API.AddBillingCard({
         cardNumber: params.cardNumber,
         cardYear,
         cardMonth,
         cardCVV: params.securityCode,
         addressName: params.nameOnCard,
-        addressZip: params.zipCode,
+        addressZip: params.addressZipCode,
         currency: CONST.CURRENCY.USD,
     }).then(((response) => {
+        let errorMessage = '';
         if (response.jsonCode === 200) {
             const cardObject = {
                 additionalData: {
@@ -60,9 +62,9 @@ function addBillingCard(params) {
                     isP2PDebitCard: true,
                 },
                 addressName: params.nameOnCard,
-                addressState: params.selectedState,
-                addressStreet: params.billingAddress,
-                addressZip: params.zipCode,
+                addressState: params.addressState,
+                addressStreet: params.addressStreet,
+                addressZip: params.addressZipCode,
                 cardMonth,
                 cardNumber: maskCardNumber(params.cardNumber),
                 cardYear,
@@ -73,12 +75,28 @@ function addBillingCard(params) {
             Growl.show(translateLocal('addDebitCardPage.growlMessageOnSave'), CONST.GROWL.SUCCESS, 3000);
             Navigation.navigate(ROUTES.SETTINGS_PAYMENTS);
         } else {
-            Growl.error(translateLocal('addDebitCardPage.error.genericFailureMessage', 3000));
+            errorMessage = response.message ? response.message : translateLocal('addDebitCardPage.error.genericFailureMessage');
         }
+
+        Onyx.merge(ONYXKEYS.ADD_DEBIT_CARD_FORM, {
+            submitting: false,
+            error: errorMessage,
+        });
     }));
 }
 
+/**
+ * Resets the values for the add debit card form back to their initial states
+ */
+function clearDebitCardFormErrorAndSubmit() {
+    Onyx.set(ONYXKEYS.ADD_DEBIT_CARD_FORM, {
+        submitting: false,
+        error: '',
+    });
+}
+
 export {
     getPaymentMethods,
     addBillingCard,
+    clearDebitCardFormErrorAndSubmit,
 };
diff --git a/src/libs/cardUtils.js b/src/libs/cardUtils.js
deleted file mode 100644
index a3bc8a9fcf75..000000000000
--- a/src/libs/cardUtils.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * Returns the masked card number (ex: 4242XXXXXXXX4242)
- *
- * @param {String} cardNumber
- * @return {Boolean}
- */
-function maskCardNumber(cardNumber) {
-    const firstFour = cardNumber.substring(0, 4);
-    const lastFour = cardNumber.substring(cardNumber.length - 4);
-
-    return `${firstFour}${'X'.repeat(cardNumber.length - 8)}${lastFour}`;
-}
-
-export {
-    // eslint-disable-next-line import/prefer-default-export
-    maskCardNumber,
-};
diff --git a/src/pages/EnablePayments/AdditionalDetailsStep.js b/src/pages/EnablePayments/AdditionalDetailsStep.js
index bf943b4966fb..12e47d568587 100644
--- a/src/pages/EnablePayments/AdditionalDetailsStep.js
+++ b/src/pages/EnablePayments/AdditionalDetailsStep.js
@@ -89,7 +89,7 @@ class AdditionalDetailsStep extends React.Component {
                 label: props.translate('common.ssnLast4'),
                 fieldName: 'ssn',
                 maxLength: 4,
-                keyboardType: 'number-pad',
+                keyboardType: CONST.KEYBOARD_TYPE.NUMBER_PAD,
             },
         ];
 
diff --git a/src/pages/ReimbursementAccount/BankAccountStep.js b/src/pages/ReimbursementAccount/BankAccountStep.js
index ae24c6fa3192..d302ead8dca5 100644
--- a/src/pages/ReimbursementAccount/BankAccountStep.js
+++ b/src/pages/ReimbursementAccount/BankAccountStep.js
@@ -263,7 +263,7 @@ class BankAccountStep extends React.Component {
                         />
                         <ExpensiTextInput
                             label={this.props.translate('bankAccount.routingNumber')}
-                            keyboardType="number-pad"
+                            keyboardType={CONST.KEYBOARD_TYPE.NUMBER_PAD}
                             value={this.state.routingNumber}
                             onChangeText={value => this.clearErrorAndSetValue('routingNumber', value)}
                             disabled={shouldDisableInputs}
@@ -272,7 +272,7 @@ class BankAccountStep extends React.Component {
                         <ExpensiTextInput
                             containerStyles={[styles.mt4]}
                             label={this.props.translate('bankAccount.accountNumber')}
-                            keyboardType="number-pad"
+                            keyboardType={CONST.KEYBOARD_TYPE.NUMBER_PAD}
                             value={this.state.accountNumber}
                             onChangeText={value => this.clearErrorAndSetValue('accountNumber', value)}
                             disabled={shouldDisableInputs}
diff --git a/src/pages/settings/Payments/AddDebitCardPage.js b/src/pages/settings/Payments/AddDebitCardPage.js
index f56801066e85..476d609b1d05 100644
--- a/src/pages/settings/Payments/AddDebitCardPage.js
+++ b/src/pages/settings/Payments/AddDebitCardPage.js
@@ -3,31 +3,48 @@ import {
     View,
     ScrollView,
 } from 'react-native';
+import lodashGet from 'lodash/get';
+import _ from 'underscore';
+import {withOnyx} from 'react-native-onyx';
+import PropTypes from 'prop-types';
 import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton';
 import Navigation from '../../../libs/Navigation/Navigation';
 import ScreenWrapper from '../../../components/ScreenWrapper';
-import TextInputWithLabel from '../../../components/TextInputWithLabel';
 import styles from '../../../styles/styles';
-import StatePicker from '../../../components/StatePicker';
 import Text from '../../../components/Text';
 import TextLink from '../../../components/TextLink';
 import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
-import {addBillingCard} from '../../../libs/actions/PaymentMethods';
-import Button from '../../../components/Button';
+import {addBillingCard, clearDebitCardFormErrorAndSubmit} from '../../../libs/actions/PaymentMethods';
 import KeyboardAvoidingView from '../../../components/KeyboardAvoidingView';
-import FixedFooter from '../../../components/FixedFooter';
-import Growl from '../../../libs/Growl';
 import {
     isValidAddress, isValidExpirationDate, isValidZipCode, isValidDebitCard, isValidSecurityCode,
 } from '../../../libs/ValidationUtils';
 import CheckboxWithLabel from '../../../components/CheckboxWithLabel';
+import ExpensiTextInput from '../../../components/ExpensiTextInput';
+import CONST from '../../../CONST';
+import FormAlertWithSubmitButton from '../../../components/FormAlertWithSubmitButton';
+import ONYXKEYS from '../../../ONYXKEYS';
+import compose from '../../../libs/compose';
+import AddressSearch from '../../../components/AddressSearch';
 
 const propTypes = {
+    addDebitCardForm: PropTypes.shape({
+        /** Error message from API call */
+        error: PropTypes.string,
+
+        /** Whether or not the form is submitting */
+        submitting: PropTypes.bool,
+    }),
+
     /* Onyx Props */
     ...withLocalizePropTypes,
 };
 
 const defaultProps = {
+    addDebitCardForm: {
+        error: '',
+        submitting: false,
+    },
 };
 
 class DebitCardPage extends Component {
@@ -39,97 +56,121 @@ class DebitCardPage extends Component {
             cardNumber: '',
             expirationDate: '',
             securityCode: '',
-            billingAddress: '',
-            city: '',
-            selectedState: '',
-            zipCode: '',
+            addressStreet: '',
+            addressState: '',
+            addressZipCode: '',
             acceptedTerms: false,
-            isAddingCard: false,
+            errors: {},
+            shouldShowAlertPrompt: false,
+        };
+
+        this.requiredFields = [
+            'nameOnCard',
+            'cardNumber',
+            'expirationDate',
+            'securityCode',
+            'addressStreet',
+            'addressState',
+            'addressZipCode',
+            'acceptedTerms',
+        ];
+
+        // Map a field to the key of the error's translation
+        this.errorTranslationKeys = {
+            nameOnCard: 'addDebitCardPage.error.invalidName',
+            cardNumber: 'addDebitCardPage.error.debitCardNumber',
+            expirationDate: 'addDebitCardPage.error.expirationDate',
+            securityCode: 'addDebitCardPage.error.securityCode',
+            addressStreet: 'addDebitCardPage.error.addressStreet',
+            addressState: 'addDebitCardPage.error.addressState',
+            addressZipCode: 'addDebitCardPage.error.addressZipCode',
+            acceptedTerms: 'addDebitCardPage.error.acceptedTerms',
         };
 
-        this.toggleTermsOfService = this.toggleTermsOfService.bind(this);
-        this.handleExpirationInput = this.handleExpirationInput.bind(this);
-        this.handleCardNumberInput = this.handleCardNumberInput.bind(this);
         this.submit = this.submit.bind(this);
+        this.clearErrorAndSetValue = this.clearErrorAndSetValue.bind(this);
+        this.getErrorText = this.getErrorText.bind(this);
+    }
+
+    /**
+     * Make sure we reset the onyx values so old errors don't show if this form is displayed later
+     */
+    componentWillUnmount() {
+        clearDebitCardFormErrorAndSubmit();
+    }
+
+    /**
+     * @param {String} inputKey
+     * @returns {String}
+     */
+    getErrorText(inputKey) {
+        if (!lodashGet(this.state.errors, inputKey, false)) {
+            return '';
+        }
+
+        return this.props.translate(this.errorTranslationKeys[inputKey]);
     }
 
     /**
      * @returns {Boolean}
      */
     validate() {
-        if (this.state.nameOnCard === '') {
-            Growl.error(this.props.translate('addDebitCardPage.error.invalidName'));
-            return false;
+        const errors = {};
+        if (_.isEmpty(this.state.nameOnCard.trim())) {
+            errors.nameOnCard = true;
         }
 
         if (!isValidDebitCard(this.state.cardNumber.replace(/ /g, ''))) {
-            Growl.error(this.props.translate('addDebitCardPage.error.debitCardNumber'));
-            return false;
+            errors.cardNumber = true;
         }
 
         if (!isValidExpirationDate(this.state.expirationDate)) {
-            Growl.error(this.props.translate('addDebitCardPage.error.expirationDate'));
-            return false;
+            errors.expirationDate = true;
         }
 
         if (!isValidSecurityCode(this.state.securityCode)) {
-            Growl.error(this.props.translate('addDebitCardPage.error.securityCode'));
-            return false;
-        }
-
-        if (!isValidAddress(this.state.billingAddress)) {
-            Growl.error(this.props.translate('addDebitCardPage.error.address'));
-            return false;
-        }
-
-        if (this.state.city === '') {
-            Growl.error(this.props.translate('addDebitCardPage.error.addressCity'));
-            return false;
+            errors.securityCode = true;
         }
 
-        if (this.state.selectedState === '') {
-            Growl.error(this.props.translate('addDebitCardPage.error.addressState'));
-            return false;
-        }
-
-        if (!isValidZipCode(this.state.zipCode)) {
-            Growl.error(this.props.translate('addDebitCardPage.error.zipCode'));
-            return false;
+        if (!isValidAddress(this.state.addressStreet)
+            || !this.state.addressState
+            || !isValidZipCode(this.state.addressZipCode)) {
+            errors.addressStreet = true;
         }
 
         if (!this.state.acceptedTerms) {
-            Growl.error(this.props.translate('addDebitCardPage.error.acceptedTerms'));
-            return false;
+            errors.acceptedTerms = true;
         }
 
-        return true;
+        const hasErrors = _.size(errors) > 0;
+        this.setState({
+            errors,
+            shouldShowAlertPrompt: hasErrors,
+        });
+        return !hasErrors;
     }
 
     submit() {
         if (!this.validate()) {
             return;
         }
-        this.setState({isAddingCard: true});
         addBillingCard(this.state);
     }
 
-    toggleTermsOfService() {
-        this.setState(prevState => ({acceptedTerms: !prevState.acceptedTerms}));
-    }
-
-    handleExpirationInput(expirationDate) {
-        let newExpirationDate = expirationDate;
-        const isErasing = expirationDate.length < this.state.expirationDate.length;
-        if (expirationDate.length === 2 && !isErasing) {
-            newExpirationDate = `${expirationDate}/`;
-        }
-        this.setState({expirationDate: newExpirationDate});
-    }
-
-    handleCardNumberInput(newCardNumber) {
-        if (/^[0-9]{0,16}$/.test(newCardNumber)) {
-            this.setState({cardNumber: newCardNumber});
-        }
+    /**
+     * Clear the error associated to inputKey if found and store the inputKey new value in the state.
+     *
+     * @param {String} inputKey
+     * @param {String} value
+     */
+    clearErrorAndSetValue(inputKey, value) {
+        this.setState(prevState => ({
+            [inputKey]: value,
+            errors: {
+                ...prevState.errors,
+                [inputKey]: false,
+            },
+        }));
     }
 
     render() {
@@ -138,97 +179,101 @@ class DebitCardPage extends Component {
                 <KeyboardAvoidingView>
                     <HeaderWithCloseButton
                         title={this.props.translate('addDebitCardPage.addADebitCard')}
+                        shouldShowBackButton
+                        onBackButtonPress={() => Navigation.goBack()}
                         onCloseButtonPress={() => Navigation.dismissModal(true)}
                     />
-                    <ScrollView style={styles.flex1} contentContainerStyle={styles.p5}>
-                        <TextInputWithLabel
-                            label={this.props.translate('addDebitCardPage.nameOnCard')}
-                            placeholder={this.props.translate('addDebitCardPage.nameOnCard')}
-                            containerStyles={[styles.flex1, styles.mb2]}
-                            onChangeText={nameOnCard => this.setState({nameOnCard})}
-                            value={this.state.nameOnCard}
-                        />
-                        <TextInputWithLabel
-                            label={this.props.translate('addDebitCardPage.debitCardNumber')}
-                            placeholder={this.props.translate('addDebitCardPage.debitCardNumber')}
-                            keyboardType="number-pad"
-                            containerStyles={[styles.flex1, styles.mb2]}
-                            onChangeText={cardNumber => this.handleCardNumberInput(cardNumber)}
-                            value={this.state.cardNumber}
-                        />
-                        <View style={[styles.flexRow, styles.mb2]}>
-                            <TextInputWithLabel
-                                label={this.props.translate('addDebitCardPage.expiration')}
-                                placeholder={this.props.translate('addDebitCardPage.expirationDate')}
-                                keyboardType="number-pad"
-                                containerStyles={[styles.flex2, styles.mr4]}
-                                onChangeText={expirationDate => this.handleExpirationInput(expirationDate)}
-                                value={this.state.expirationDate}
+                    <ScrollView
+                        style={[styles.w100, styles.flex1]}
+                        contentContainerStyle={styles.flexGrow1}
+                        keyboardShouldPersistTaps="handled"
+                        ref={el => this.form = el}
+                    >
+                        <View style={[styles.mh5, styles.mb5]}>
+                            <ExpensiTextInput
+                                label={this.props.translate('addDebitCardPage.nameOnCard')}
+                                onChangeText={nameOnCard => this.clearErrorAndSetValue('nameOnCard', nameOnCard)}
+                                value={this.state.nameOnCard}
+                                errorText={this.getErrorText('nameOnCard')}
                             />
-                            <TextInputWithLabel
-                                label={this.props.translate('addDebitCardPage.cvv')}
-                                placeholder="123"
-                                keyboardType="number-pad"
-                                containerStyles={[styles.flex2]}
-                                onChangeText={securityCode => this.setState({securityCode})}
-                                value={this.state.securityCode}
+                            <ExpensiTextInput
+                                label={this.props.translate('addDebitCardPage.debitCardNumber')}
+                                containerStyles={[styles.mt4]}
+                                onChangeText={cardNumber => this.clearErrorAndSetValue('cardNumber', cardNumber)}
+                                value={this.state.cardNumber}
+                                errorText={this.getErrorText('cardNumber')}
+                                keyboardType={CONST.KEYBOARD_TYPE.NUMBER_PAD}
                             />
-                        </View>
-                        <TextInputWithLabel
-                            label={this.props.translate('addDebitCardPage.billingAddress')}
-                            placeholder={this.props.translate('addDebitCardPage.streetAddress')}
-                            containerStyles={[styles.flex1, styles.mb2]}
-                            onChangeText={billingAddress => this.setState({billingAddress})}
-                            value={this.state.billingAddress}
-                        />
-                        <TextInputWithLabel
-                            label={this.props.translate('common.city')}
-                            placeholder={this.props.translate('addDebitCardPage.cityName')}
-                            containerStyles={[styles.flex1, styles.mb2]}
-                            onChangeText={city => this.setState({city})}
-                            value={this.state.city}
-                        />
-                        <View style={[styles.flexRow, styles.mb6]}>
-                            <View style={[styles.flex2, styles.mr4]}>
-                                <Text style={[styles.mb1, styles.formLabel]}>
-                                    {this.props.translate('common.state')}
-                                </Text>
-                                <StatePicker
-                                    onChange={state => this.setState({selectedState: state})}
-                                    value={this.state.selectedState}
-                                />
+                            <View style={[styles.flexRow, styles.mt4]}>
+                                <View style={[styles.flex1, styles.mr2]}>
+                                    <ExpensiTextInput
+                                        label={this.props.translate('addDebitCardPage.expiration')}
+                                        placeholder={this.props.translate('addDebitCardPage.expirationDate')}
+                                        onChangeText={expirationDate => this.clearErrorAndSetValue('expirationDate', expirationDate)}
+                                        value={this.state.expirationDate}
+                                        errorText={this.getErrorText('expirationDate')}
+                                        keyboardType={CONST.KEYBOARD_TYPE.PHONE_PAD}
+                                        translateX={-10}
+                                    />
+                                </View>
+                                <View style={[styles.flex1]}>
+                                    <ExpensiTextInput
+                                        label={this.props.translate('addDebitCardPage.cvv')}
+                                        onChangeText={securityCode => this.clearErrorAndSetValue('securityCode', securityCode)}
+                                        value={this.state.securityCode}
+                                        errorText={this.getErrorText('securityCode')}
+                                        translateX={-10}
+                                    />
+                                </View>
                             </View>
-                            <TextInputWithLabel
-                                label={this.props.translate('common.zip')}
-                                placeholder={this.props.translate('common.zip')}
-                                containerStyles={[styles.flex2]}
-                                onChangeText={zipCode => this.setState({zipCode})}
-                                value={this.state.zipCode}
+                            <AddressSearch
+                                label={this.props.translate('addDebitCardPage.billingAddress')}
+                                containerStyles={[styles.mt4]}
+                                value={this.state.addressStreet}
+                                onChangeText={(fieldName, value) => this.clearErrorAndSetValue(fieldName, value)}
+                                errorText={this.getErrorText('addressStreet')}
+                            />
+                            <CheckboxWithLabel
+                                isChecked={this.state.acceptedTerms}
+                                onPress={() => {
+                                    this.setState(prevState => ({
+                                        acceptedTerms: !prevState.acceptedTerms,
+                                        errors: {
+                                            ...prevState.errors,
+                                            acceptedTerms: false,
+                                        },
+                                    }));
+                                }}
+                                LabelComponent={() => (
+                                    <>
+                                        <Text>{`${this.props.translate('common.iAcceptThe')}`}</Text>
+                                        <TextLink href="https://use.expensify.com/terms">
+                                            {`${this.props.translate('addDebitCardPage.expensifyTermsOfService')}`}
+                                        </TextLink>
+                                    </>
+                                )}
+                                style={[styles.mt4, styles.mb4]}
+                                errorText={this.getErrorText('acceptedTerms')}
+                                hasError={Boolean(this.state.errors.acceptedTerms)}
                             />
                         </View>
-                        <CheckboxWithLabel
-                            isChecked={this.state.acceptedTerms}
-                            onPress={this.toggleTermsOfService}
-                            LabelComponent={() => (
-                                <Text>
-                                    {`${this.props.translate('common.iAcceptThe')} `}
-                                    <TextLink href="https://use.expensify.com/terms">
-                                        {`${this.props.translate('addDebitCardPage.expensifyTermsOfService')}`}
-                                    </TextLink>
+                        {!_.isEmpty(this.props.addDebitCardForm.error) && (
+                            <View style={[styles.mh5, styles.mb5]}>
+                                <Text style={[styles.formError]}>
+                                    {this.props.addDebitCardForm.error}
                                 </Text>
-                            )}
+                            </View>
+                        )}
+                        <FormAlertWithSubmitButton
+                            isAlertVisible={this.state.shouldShowAlertPrompt}
+                            buttonText={this.props.translate('common.save')}
+                            onSubmit={this.submit}
+                            onFixTheErrorsLinkPressed={() => {
+                                this.form.scrollTo({y: 0, animated: true});
+                            }}
+                            isLoading={this.props.addDebitCardForm.submitting}
                         />
                     </ScrollView>
-                    <FixedFooter>
-                        <Button
-                            success
-                            onPress={this.submit}
-                            style={[styles.w100]}
-                            text={this.props.translate('common.save')}
-                            isLoading={this.state.isAddingCard}
-                            pressOnEnter
-                        />
-                    </FixedFooter>
                 </KeyboardAvoidingView>
             </ScreenWrapper>
         );
@@ -238,4 +283,11 @@ class DebitCardPage extends Component {
 DebitCardPage.propTypes = propTypes;
 DebitCardPage.defaultProps = defaultProps;
 
-export default withLocalize(DebitCardPage);
+export default compose(
+    withOnyx({
+        addDebitCardForm: {
+            key: ONYXKEYS.ADD_DEBIT_CARD_FORM,
+        },
+    }),
+    withLocalize,
+)(DebitCardPage);
diff --git a/src/pages/settings/Payments/AddPayPalMePage.js b/src/pages/settings/Payments/AddPayPalMePage.js
index edfa0c8858af..4b1cb1e0a937 100644
--- a/src/pages/settings/Payments/AddPayPalMePage.js
+++ b/src/pages/settings/Payments/AddPayPalMePage.js
@@ -86,7 +86,7 @@ class AddPayPalMePage extends React.Component {
                                 {this.props.translate('addPayPalMePage.enterYourUsernameToGetPaidViaPayPal')}
                             </Text>
                             <ExpensiTextInput
-                                label={this.props.translate('addPayPalMePage.payPalMe')}
+                                label={this.props.translate('common.payPalMe')}
                                 autoCompleteType="off"
                                 autoCorrect={false}
                                 value={this.state.payPalMeUsername}
diff --git a/src/pages/settings/Payments/PaymentsPage.js b/src/pages/settings/Payments/PaymentsPage.js
index 9ef9e2234d03..4e8c5a5e2ec9 100644
--- a/src/pages/settings/Payments/PaymentsPage.js
+++ b/src/pages/settings/Payments/PaymentsPage.js
@@ -139,12 +139,12 @@ class PaymentsPage extends React.Component {
                         }}
                     >
                         <MenuItem
-                            title="PayPal.me"
+                            title={this.props.translate('common.payPalMe')}
                             icon={PayPal}
                             onPress={() => this.addPaymentMethodTypePressed(PAYPAL)}
                         />
                         <MenuItem
-                            title="Debit Card"
+                            title={this.props.translate('common.debitCard')}
                             icon={CreditCard}
                             onPress={() => this.addPaymentMethodTypePressed(DEBIT_CARD)}
                         />
diff --git a/tests/unit/CardUtilsTest.js b/tests/unit/CardUtilsTest.js
new file mode 100644
index 000000000000..ac2c4345b389
--- /dev/null
+++ b/tests/unit/CardUtilsTest.js
@@ -0,0 +1,42 @@
+const cardUtils = require('../../src/libs/CardUtils');
+
+const shortDate = '0924';
+const shortDateSlashed = '09/24';
+const shortDateHyphen = '09-24';
+const longDate = '092024';
+const longDateSlashed = '09/2024';
+const longDateHyphen = '09-2024';
+const expectedMonth = '09';
+const expectedYear = '2024';
+
+describe('CardUtils', () => {
+    it('Test MM/YYYY format for getting expirationDate month and year', () => {
+        expect(cardUtils.getMonthFromExpirationDateString(longDateSlashed)).toBe(expectedMonth);
+        expect(cardUtils.getYearFromExpirationDateString(longDateSlashed)).toBe(expectedYear);
+    });
+
+    it('Test MM-YYYY format for getting expirationDate month and year', () => {
+        expect(cardUtils.getMonthFromExpirationDateString(longDateHyphen)).toBe(expectedMonth);
+        expect(cardUtils.getYearFromExpirationDateString(longDateHyphen)).toBe(expectedYear);
+    });
+
+    it('Test MMYYYY format for getting expirationDate month and year', () => {
+        expect(cardUtils.getMonthFromExpirationDateString(longDate)).toBe(expectedMonth);
+        expect(cardUtils.getYearFromExpirationDateString(longDate)).toBe(expectedYear);
+    });
+
+    it('Test MM/YY format for getting expirationDate month and year', () => {
+        expect(cardUtils.getMonthFromExpirationDateString(shortDateSlashed)).toBe(expectedMonth);
+        expect(cardUtils.getYearFromExpirationDateString(shortDateSlashed)).toBe(expectedYear);
+    });
+
+    it('Test MM-YY format for getting expirationDate month and year', () => {
+        expect(cardUtils.getMonthFromExpirationDateString(shortDateHyphen)).toBe(expectedMonth);
+        expect(cardUtils.getYearFromExpirationDateString(shortDateHyphen)).toBe(expectedYear);
+    });
+
+    it('Test MMYY format for getting expirationDate month and year', () => {
+        expect(cardUtils.getMonthFromExpirationDateString(shortDate)).toBe(expectedMonth);
+        expect(cardUtils.getYearFromExpirationDateString(shortDate)).toBe(expectedYear);
+    });
+});