diff --git a/docs/reference/Translations/index.md b/docs/reference/Translations/index.md
index 8f5bd8835..d82084735 100644
--- a/docs/reference/Translations/index.md
+++ b/docs/reference/Translations/index.md
@@ -5074,9 +5074,6 @@ Translation keys for the `Payroll.PayrollOverview` i18n namespace.
| Property | Default value |
| ------ | ------ |
| `alerts` | |
-| `alerts.checkPaymentWarning_one` | `"You noted {{count}} employee who should be paid by check."` |
-| `alerts.checkPaymentWarning_other` | `"You noted {{count}} employees who should be paid by check."` |
-| `alerts.checkPaymentWarningDescription` | `"Employees with this payment method will need their checks delivered to them."` |
| `alerts.directDepositDeadline` | `"To pay your employees with direct deposit by {{payDate}}, you'll need to run payroll by {{time}} on {{date}}"` |
| `alerts.payrollNotCalculated` | `"Payroll is not calculated"` |
| `alerts.payrollProcessedMessage` | `"{{amount}} will be debited on {{date}}. Make sure you have these funds available."` |
diff --git a/docs/reference/payroll/blocks.md b/docs/reference/payroll/blocks.md
index 7198bae0d..0064b2d98 100644
--- a/docs/reference/payroll/blocks.md
+++ b/docs/reference/payroll/blocks.md
@@ -672,6 +672,13 @@ _Inherits `children`, `className`, `defaultValues`, `FallbackComponent`, `Loader
| `runPayroll/receipt/get` | User requested the payroll receipt | `{ payrollId }` |
| `runPayroll/pdfPaystub/viewed` | User opened an employee's paystub PDF | `{ employeeId }` |
| `payroll/wire/form/done` | Wire-in details were confirmed via the embedded wire form | Submit wire-in response |
+| `payroll/printChecks/start` | User opened the print-checks modal from the embedded print-checks banner | — |
+| `payroll/printChecks/generate/start` | User submitted the print-checks form | — |
+| `payroll/printChecks/generate/succeeded` | Printable checks finished generating | `{ documentUrl }` |
+| `payroll/printChecks/generate/failed` | The print-checks request was rejected or generation failed | `{ errorMessage }` |
+| `payroll/printChecks/retry` | User retried after a failed check generation | — |
+| `payroll/printChecks/cancel` | User cancelled the print-checks form | — |
+| `payroll/printChecks/close` | User closed the print-checks failure or summary screen | — |
diff --git a/src/components/Payroll/PayrollOverview/PayrollOverview.stories.tsx b/src/components/Payroll/PayrollOverview/PayrollOverview.stories.tsx
index 20834d568..6391e6eea 100644
--- a/src/components/Payroll/PayrollOverview/PayrollOverview.stories.tsx
+++ b/src/components/Payroll/PayrollOverview/PayrollOverview.stories.tsx
@@ -1357,3 +1357,112 @@ export const WithSkippedEmployee = () => {
/>
)
}
+
+const checkPaymentPayrollData = {
+ payrollDeadline: new Date('2025-09-24T23:00:00.000Z'),
+ checkDate: '2025-09-26',
+ processedDate: null,
+ calculatedAt: new Date('2025-09-15T16:25:07.000Z'),
+ uuid: 'payroll-uuid',
+ payrollUuid: 'payroll-uuid',
+ companyUuid: 'company-uuid',
+ offCycle: false,
+ external: false,
+ payPeriod: {
+ startDate: '2025-09-12',
+ endDate: '2025-09-18',
+ payScheduleUuid: 'schedule-uuid',
+ },
+ totals: {
+ companyDebit: '5000.00',
+ netPayDebit: '4000.00',
+ taxDebit: '1000.00',
+ reimbursementDebit: '0.00',
+ childSupportDebit: '0.00',
+ reimbursements: '0.00',
+ netPay: '4000.00',
+ grossPay: '5000.00',
+ employeeBonuses: '0.00',
+ employeeCommissions: '0.00',
+ employeeCashTips: '0.00',
+ employeePaycheckTips: '0.00',
+ additionalEarnings: '0.00',
+ ownersDraw: '0.00',
+ checkAmount: '1000.00',
+ employerTaxes: '500.00',
+ employeeTaxes: '500.00',
+ benefits: '0.00',
+ employeeBenefitsDeductions: '0.00',
+ imputedPay: '0.00',
+ deferredPayrollTaxes: '0.00',
+ otherDeductions: '0.00',
+ },
+ companyTaxes: [],
+ createdAt: new Date('2025-09-15T16:19:04.000Z'),
+ submissionBlockers: [],
+ partnerOwnedDisbursement: false,
+ employeeCompensations: [
+ {
+ employeeUuid: 'emp-check-1',
+ firstName: 'Isaiah',
+ lastName: 'Berlin',
+ excluded: false,
+ version: 'v1',
+ grossPay: '4000',
+ netPay: '3200',
+ checkAmount: '3200',
+ paymentMethod: 'Check' as const,
+ memo: null,
+ fixedCompensations: [],
+ hourlyCompensations: [
+ {
+ name: 'Regular Hours',
+ hours: '40.000',
+ amount: '4000.0',
+ jobUuid: 'job-1',
+ compensationMultiplier: 1,
+ flsaStatus: 'Nonexempt',
+ },
+ ],
+ paidTimeOff: [],
+ taxes: [
+ { name: 'Federal Income Tax', employer: false, amount: '80' },
+ { name: 'Federal Income Tax', employer: true, amount: '160' },
+ ],
+ benefits: [],
+ deductions: [],
+ },
+ ],
+}
+
+export const WithCheckPaymentEmployeeUnprocessed = () => {
+ return (
+
+ )
+}
+
+export const WithCheckPaymentEmployeeProcessed = () => {
+ return (
+
+ )
+}
diff --git a/src/components/Payroll/PayrollOverview/PayrollOverview.test.tsx b/src/components/Payroll/PayrollOverview/PayrollOverview.test.tsx
index 361fd9c7a..872b9a52a 100644
--- a/src/components/Payroll/PayrollOverview/PayrollOverview.test.tsx
+++ b/src/components/Payroll/PayrollOverview/PayrollOverview.test.tsx
@@ -311,3 +311,61 @@ describe('PayrollOverview calculatedAt guard', () => {
expect(screen.queryByText(/Review payroll/i)).toBeNull()
})
})
+
+describe('PayrollOverview print checks modal', () => {
+ beforeEach(() => {
+ vi.clearAllMocks()
+ mockPayrollData = {
+ ...basePayrollData,
+ employeeCompensations: [
+ {
+ employeeUuid: 'emp-check-1',
+ firstName: 'Isaiah',
+ lastName: 'Berlin',
+ excluded: false,
+ version: 'v1',
+ grossPay: '4000',
+ netPay: '3200',
+ checkAmount: '3200',
+ paymentMethod: 'Check',
+ memo: null,
+ fixedCompensations: [],
+ hourlyCompensations: [],
+ paidTimeOff: [],
+ taxes: [],
+ benefits: [],
+ deductions: [],
+ },
+ ],
+ }
+ mockIsFetching = false
+ })
+
+ it('hides the View and print checks button until the payroll is processed', async () => {
+ mockPayrollData = { ...mockPayrollData, processed: false }
+
+ renderWithProviders(
+ ,
+ )
+
+ expect(await screen.findByText(/noted 1 employee/i)).toBeInTheDocument()
+ expect(screen.queryByRole('button', { name: 'View and print checks' })).toBeNull()
+ })
+
+ it('opens the print checks modal from the alert once the payroll is processed', async () => {
+ const user = userEvent.setup()
+ mockPayrollData = {
+ ...mockPayrollData,
+ processed: true,
+ processingRequest: { status: 'submit_success', errors: [] },
+ }
+
+ renderWithProviders(
+ ,
+ )
+
+ await user.click(await screen.findByRole('button', { name: 'View and print checks' }))
+
+ expect(await screen.findByText('Choose check stock')).toBeInTheDocument()
+ })
+})
diff --git a/src/components/Payroll/PayrollOverview/PayrollOverview.tsx b/src/components/Payroll/PayrollOverview/PayrollOverview.tsx
index bf468c23f..46a5c4bd4 100644
--- a/src/components/Payroll/PayrollOverview/PayrollOverview.tsx
+++ b/src/components/Payroll/PayrollOverview/PayrollOverview.tsx
@@ -20,6 +20,7 @@ import {
type ConfirmWireDetailsComponentType,
} from '../ConfirmWireDetails/ConfirmWireDetails'
import { canCancelPayroll } from '../helpers'
+import { PrintChecks } from '../PrintChecks/PrintChecks'
import { PayrollOverviewPresentation } from './PayrollOverviewPresentation'
import { PayrollOverviewStatus } from './PayrollOverviewTypes'
import { useCompanyPaymentSpeed } from '@/hooks/useCompanyPaymentSpeed'
@@ -109,6 +110,13 @@ const findWireInRequestUuid = (
* | `runPayroll/receipt/get` | User requested the payroll receipt | `{ payrollId }` |
* | `runPayroll/pdfPaystub/viewed` | User opened an employee's paystub PDF | `{ employeeId }` |
* | `payroll/wire/form/done` | Wire-in details were confirmed via the embedded wire form | Submit wire-in response |
+ * | `payroll/printChecks/start` | User opened the print-checks modal from the embedded print-checks banner | — |
+ * | `payroll/printChecks/generate/start` | User submitted the print-checks form | — |
+ * | `payroll/printChecks/generate/succeeded` | Printable checks finished generating | `{ documentUrl }` |
+ * | `payroll/printChecks/generate/failed` | The print-checks request was rejected or generation failed | `{ errorMessage }` |
+ * | `payroll/printChecks/retry` | User retried after a failed check generation | — |
+ * | `payroll/printChecks/cancel` | User cancelled the print-checks form | — |
+ * | `payroll/printChecks/close` | User closed the print-checks failure or summary screen | — |
*
* @param props - See {@link PayrollOverviewProps}.
* @returns The payroll overview surface.
@@ -196,6 +204,10 @@ const Root = ({
/>
)
+ const printChecksBanner = (
+
+ )
+
useEffect(() => {
if (wireInRequest?.status === 'pending_review' && !showWireDetailsConfirmation) {
setShowWireDetailsConfirmation(true)
@@ -436,6 +448,7 @@ const Root = ({
setSelectedUnblockOptions(prev => ({ ...prev, [blockerType]: value }))
}}
wireInConfirmationRequest={wireInConfirmationRequest}
+ printChecksBanner={printChecksBanner}
withReimbursements={withReimbursements}
paymentSpeed={paymentSpeed}
pagination={pagination}
diff --git a/src/components/Payroll/PayrollOverview/PayrollOverviewPresentation.tsx b/src/components/Payroll/PayrollOverview/PayrollOverviewPresentation.tsx
index 2420743bf..29dfa7c42 100644
--- a/src/components/Payroll/PayrollOverview/PayrollOverviewPresentation.tsx
+++ b/src/components/Payroll/PayrollOverview/PayrollOverviewPresentation.tsx
@@ -32,7 +32,6 @@ import {
compensationTypeLabels,
FlsaStatus,
PAYROLL_RESOLVABLE_SUBMISSION_BLOCKER_TYPES,
- PAYMENT_METHODS,
} from '@/shared/constants'
import type { PaginationControlProps } from '@/components/Common/PaginationControl/PaginationControlTypes'
import DownloadIcon from '@/assets/icons/download-cloud.svg?react'
@@ -48,6 +47,7 @@ interface PayrollOverviewProps {
submissionBlockers?: PayrollSubmissionBlockerType[]
selectedUnblockOptions?: Record
wireInConfirmationRequest?: React.ReactNode
+ printChecksBanner?: React.ReactNode
pagination?: PaginationControlProps
onEdit: () => void
onSubmit: () => void
@@ -87,6 +87,7 @@ export const PayrollOverviewPresentation = ({
selectedUnblockOptions = {},
onUnblockOptionChange,
wireInConfirmationRequest,
+ printChecksBanner,
withReimbursements = true,
paymentSpeed,
pagination,
@@ -212,12 +213,6 @@ export const PayrollOverviewPresentation = ({
)
}
- const checkPaymentsCount =
- payrollData.employeeCompensations?.reduce(
- (acc, comp) =>
- !comp.excluded && comp.paymentMethod === PAYMENT_METHODS.check ? acc + 1 : acc,
- 0,
- ) ?? 0
const companyPaysColumns: Array<{
key: string
title: string
@@ -780,14 +775,7 @@ export const PayrollOverviewPresentation = ({
data={[{}]}
/>
)}
- {checkPaymentsCount > 0 && (
-
- {t('alerts.checkPaymentWarningDescription')}
-
- )}
+ {printChecksBanner}