Skip to main content
Connect your New Expensify workspace to NetSuite for comprehensive expense management with advanced features including custom fields, subsidiaries, and multi-entity support.

Setup

1

Navigate to Accounting

Go to Workspace Settings > Accounting and select NetSuite
2

Choose Connection Type

Select whether to create a new connection or reuse an existing one
3

Enter Token Credentials

Provide your NetSuite token ID, token secret, consumer key, and consumer secret
4

Select Subsidiary

Choose which NetSuite subsidiary to connect (if applicable)
5

Configure Settings

Set up import and export preferences

Connection Management

NetSuite supports reusing connections across multiple workspaces:
// Source: src/components/ConnectToNetSuiteFlow/index.tsx
function ConnectToNetSuiteFlow({policyID}: ConnectToNetSuiteFlowProps) {
    const hasPoliciesConnectedToNetSuite = !!getAdminPoliciesConnectedToNetSuite()?.length;
    const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`);
    const shouldGoToCredentialsPage = isAuthenticationError(policy, CONST.POLICY.CONNECTIONS.NAME.NETSUITE);

    const connectionOptions = [
        {
            icon: icons.LinkCopy,
            text: translate('workspace.common.createNewConnection'),
            onSelected: () => {
                Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_TOKEN_INPUT.getRoute(policyID));
            },
        },
        {
            icon: icons.Copy,
            text: translate('workspace.common.reuseExistingConnection'),
            onSelected: () => {
                Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_EXISTING_CONNECTIONS.getRoute(policyID));
            },
        },
    ];

    useEffect(() => {
        if (shouldGoToCredentialsPage || !hasPoliciesConnectedToNetSuite) {
            Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_TOKEN_INPUT.getRoute(policyID));
            return;
        }
        setIsReuseConnectionsPopoverOpen(true);
    }, []);
}
Connection Reuse: If you’ve already connected a NetSuite account, you can reuse those credentials for additional workspaces without re-entering token information.

Import Settings

NetSuite offers comprehensive import configuration:
// Source: src/pages/workspace/accounting/netsuite/import/NetSuiteImportPage.tsx
const config = policy?.connections?.netsuite?.options?.config;
const {subsidiaryList} = policy?.connections?.netsuite?.options?.data ?? {};
const selectedSubsidiary = useMemo(
  () => (subsidiaryList ?? []).find((subsidiary) => subsidiary.internalID === config?.subsidiaryID),
  [subsidiaryList, config?.subsidiaryID]
);

Expense Categories

Expense categories are always imported and cannot be disabled. They form the foundation of expense categorization.
// Source: src/pages/workspace/accounting/netsuite/import/NetSuiteImportPage.tsx
<ToggleSettingOptionRow
    title={translate('workspace.netsuite.import.expenseCategories')}
    subtitle={translate('workspace.netsuite.import.expenseCategoriesDescription')}
    shouldPlaceSubtitleBelowSwitch
    isActive
    disabled
    switchAccessibilityLabel={translate('workspace.netsuite.import.expenseCategories')}
    onToggle={() => {}}
/>

Import Fields

Configure how NetSuite fields are imported:
// Source: src/pages/workspace/accounting/netsuite/import/NetSuiteImportPage.tsx
{CONST.NETSUITE_CONFIG.IMPORT_FIELDS.map((importField) => (
    <MenuItemWithTopDescription
        description={translate(`workspace.netsuite.import.importFields.${importField}.title`)}
        title={translate(`workspace.accounting.importTypes.${
            config?.syncOptions?.mapping?.[importField] ?? CONST.INTEGRATION_ENTITY_MAP_TYPES.NETSUITE_DEFAULT
        }`)}
        shouldShowRightIcon
        onPress={() => {
            Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_IMPORT_MAPPING.getRoute(policyID, importField));
        }}
    />
))}
Import fields include:
  • Departments: Organizational departments
  • Classes: Classification codes
  • Locations: Physical or logical locations
  • Projects: Project tracking
  • Vendors: Supplier information
Each field can be imported as:
  • Tags: For expense-level categorization
  • Report Fields: For report-level categorization
  • Not Imported: Skip the field

Customers or Jobs

Import NetSuite customers and jobs with advanced options:
// Source: src/pages/workspace/accounting/netsuite/import/NetSuiteImportPage.tsx
<MenuItemWithTopDescription
    description={translate(`workspace.netsuite.import.customersOrJobs.title`)}
    title={getCustomersOrJobsLabelNetSuite(policy, translate)}
    shouldShowRightIcon
    numberOfLinesTitle={2}
    onPress={() => {
        Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_IMPORT_CUSTOMERS_OR_PROJECTS.getRoute(policyID));
    }}
/>
  • Import customers only
  • Import jobs only
  • Import both customers and jobs
  • Enable cross-subsidiary customers

Tax

For supported subsidiaries, enable tax import:
// Source: src/pages/workspace/accounting/netsuite/import/NetSuiteImportPage.tsx
{canUseTaxNetSuite(isBetaEnabled(CONST.BETAS.NETSUITE_USA_TAX), selectedSubsidiary?.country) && (
    <ToggleSettingOptionRow
        title={translate('common.tax')}
        subtitle={translate('workspace.netsuite.import.importTaxDescription')}
        shouldPlaceSubtitleBelowSwitch
        isActive={config?.syncOptions?.syncTax ?? false}
        switchAccessibilityLabel={translate('common.tax')}
        onToggle={(isEnabled: boolean) => {
            updateNetSuiteSyncTaxConfiguration(policyID, isEnabled);
        }}
    />
)}
Tax import is only available for specific subsidiary countries and requires beta feature access.

Custom Fields

NetSuite supports importing custom fields:
// Source: src/pages/workspace/accounting/netsuite/import/NetSuiteImportPage.tsx
{Object.values(CONST.NETSUITE_CONFIG.IMPORT_CUSTOM_FIELDS).map((importField) => {
    const settings = getImportCustomFieldsSettings(importField, config);
    return (
        <MenuItemWithTopDescription
            title={getNetSuiteImportCustomFieldLabel(policy, importField, translate, localeCompare)}
            description={translate(`workspace.netsuite.import.importCustomFields.${importField}.title`)}
            shouldShowRightIcon
            onPress={() => {
                Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_IMPORT_CUSTOM_FIELD_MAPPING.getRoute(policyID, importField));
            }}
        />
    );
})}
Custom field types:
  • Custom Segments: NetSuite custom segments
  • Custom Lists: Custom list fields
  • Transaction Fields: Custom transaction body fields
1

Add Custom Field

Navigate to Import > Custom Fields and click Add
2

Choose Field Type

Select Custom Segment, Custom List, or Transaction Field
3

Enter Field Details

Provide the script ID, internal ID, and display name
4

Configure Mapping

Choose how the field maps to Expensify (tags or report fields)

Export Settings

Configure how expenses export to NetSuite:

Preferred Exporter

Select the workspace admin who exports expenses.

Export Date

Choose the date for NetSuite transactions:
  • Date Created: Expense creation date
  • Date Exported: Export date
  • Date Submitted: Report submission date

Reimbursable Expenses

Export out-of-pocket expenses as:
  • Expense Reports: Standard expense reports
  • Vendor Bills: Accounts payable bills
  • Journal Entries: Accounting journal entries

Non-Reimbursable Expenses

Export company card expenses as:
  • Expense Reports: Company expense reports
  • Vendor Bills: Non-reimbursable bills
  • Journal Entries: Direct journal entries

Vendors

Map Expensify users to NetSuite vendors for automated vendor selection on exports.

Advanced Settings

Enable automatic syncing to keep NetSuite and Expensify data synchronized:
  • Sync frequency configuration
  • Error handling and notifications
  • Manual sync override
Connect multiple NetSuite subsidiaries:
  • Separate connections per subsidiary
  • Cross-subsidiary customer access
  • Subsidiary-specific configurations
Advanced custom segment configuration:
  • Segment script IDs and internal IDs
  • Hierarchical segment structures
  • Segment value mapping

Subsidiary Configuration

When connecting to NetSuite with multiple subsidiaries:
  1. Select Primary Subsidiary: Choose the main subsidiary for this workspace
  2. Configure Import Settings: Set up which data to import from the selected subsidiary
  3. Cross-Subsidiary Options: Enable cross-subsidiary customers if needed

Authentication

NetSuite uses token-based authentication (TBA):
1

Generate Tokens in NetSuite

In NetSuite, go to Setup > Users/Roles > Access Tokens and generate a new token
2

Note Token Credentials

Save the Token ID and Token Secret
3

Get Consumer Key/Secret

Obtain your Consumer Key and Consumer Secret from your NetSuite integration record
4

Enter in Expensify

Input all four credentials in the NetSuite connection flow
Security Best Practice: Store NetSuite tokens securely. Never share token credentials or commit them to version control.

Troubleshooting

If you see authentication errors:
  • Verify all four token credentials are correct
  • Ensure the NetSuite user has proper permissions
  • Check that token-based authentication is enabled in NetSuite
  • Confirm the integration record is active
For subsidiary-related problems:
  • Verify you have access to the selected subsidiary
  • Check subsidiary-specific permissions
  • Ensure cross-subsidiary features are enabled if needed
If custom fields aren’t syncing:
  • Verify script IDs and internal IDs are correct
  • Check that custom fields are active in NetSuite
  • Ensure proper permissions for custom field access

Best Practices

  1. Test with Sandbox: Use a NetSuite sandbox account for initial setup and testing
  2. Document Custom Fields: Keep a record of custom field script IDs and mappings
  3. Regular Token Rotation: Periodically regenerate NetSuite tokens for security
  4. Monitor Sync Status: Check the connection page regularly for errors
  5. Subsidiary Planning: Plan subsidiary structure before connecting multiple entities

Support

For NetSuite integration support:
  • Contact Expensify Concierge for connection assistance
  • Refer to NetSuite documentation for platform-specific requirements
  • Work with your NetSuite administrator for permissions and token generation

Build docs developers (and LLMs) love