import {z} from 'zod' export type APIClientID = string; export type APISecret = string; export type UserToken = string; export type NewUserID = string; export type CreditPayrollIncomeGetRequestOptions = {item_ids?: Array | undefined}; export type CreditPayrollIncomeGetRequest = {client_id?: APIClientID | undefined, secret?: APISecret | undefined, user_token?: UserToken | undefined, user_id?: NewUserID | undefined, options?: CreditPayrollIncomeGetRequestOptions | undefined}; export type CreateApiCreditPayrollIncomeGetArgs = {body: CreditPayrollIncomeGetRequest}; export type CreateApiCreditPayrollIncomeGetOptions = {baseUrl?: string | undefined, clientId?: string | undefined, secret?: string | undefined, plaidVersion?: string | undefined, fetch?: typeof fetch | undefined}; export const itemId = z.string(); export const payrollIncomeRateOfPay = z.object({pay_rate: z.string().nullable().optional(), pay_amount: z.number().nullable().optional()}).and(z.record(z.string(), z.unknown())); export const payrollIncomeAccountData = z.object({account_id: z.string().nullable(), rate_of_pay: payrollIncomeRateOfPay, pay_frequency: z.string().nullable()}).and(z.record(z.string(), z.unknown())).nullable(); export const payStubDeductionsBreakdown = z.object({current_amount: z.number().nullable(), description: z.string().nullable(), iso_currency_code: z.string().nullable(), unofficial_currency_code: z.string().nullable(), ytd_amount: z.number().nullable()}).and(z.record(z.string(), z.unknown())); export const payStubDeductionsTotal = z.object({current_amount: z.number().nullable(), iso_currency_code: z.string().nullable(), unofficial_currency_code: z.string().nullable(), ytd_amount: z.number().nullable()}).and(z.record(z.string(), z.unknown())); export const creditPayStubDeductions = z.object({breakdown: z.array(payStubDeductionsBreakdown), total: payStubDeductionsTotal}).and(z.record(z.string(), z.unknown())); export const creditDocumentType = z.string().nullable(); export const creditDocumentMetadata = z.object({name: z.string(), document_type: creditDocumentType, download_url: z.string().nullable(), status: z.string().nullable(), page_count: z.number().int().nullable().optional(), error_message: z.string().nullable().optional()}).and(z.record(z.string(), z.unknown())); export const payStubEarningsBreakdownCanonicalDescription = z.string().nullable(); export const payStubEarningsBreakdown = z.object({canonical_description: payStubEarningsBreakdownCanonicalDescription, current_amount: z.number().nullable(), description: z.string().nullable(), hours: z.number().nullable(), iso_currency_code: z.string().nullable(), rate: z.number().nullable(), unofficial_currency_code: z.string().nullable(), ytd_amount: z.number().nullable()}).and(z.record(z.string(), z.unknown())); export const payStubEarningsTotal = z.object({current_amount: z.number().nullable(), hours: z.number().nullable(), iso_currency_code: z.string().nullable(), unofficial_currency_code: z.string().nullable(), ytd_amount: z.number().nullable()}).and(z.record(z.string(), z.unknown())); export const creditPayStubEarnings = z.object({breakdown: z.array(payStubEarningsBreakdown), total: payStubEarningsTotal}).and(z.record(z.string(), z.unknown())); export const creditPayStubAddress = z.object({city: z.string().nullable(), country: z.string().nullable(), postal_code: z.string().nullable(), region: z.string().nullable(), street: z.string().nullable()}).and(z.record(z.string(), z.unknown())); export const payStubTaxpayerID = z.object({id_type: z.string().nullable(), id_mask: z.string().nullable()}).and(z.record(z.string(), z.unknown())); export const creditPayStubEmployee = z.object({address: creditPayStubAddress, name: z.string().nullable(), marital_status: z.string().nullable(), taxpayer_id: payStubTaxpayerID}).and(z.record(z.string(), z.unknown())); export const creditPayStubEmployer = z.object({address: creditPayStubAddress, name: z.string().nullable()}).and(z.record(z.string(), z.unknown())); export const creditPayStubNetPay = z.object({current_amount: z.number().nullable(), description: z.string().nullable(), iso_currency_code: z.string().nullable(), unofficial_currency_code: z.string().nullable(), ytd_amount: z.number().nullable()}).and(z.record(z.string(), z.unknown())); export const payStubDistributionBreakdown = z.object({account_name: z.string().nullable(), bank_name: z.string().nullable(), current_amount: z.number().nullable(), iso_currency_code: z.string().nullable(), mask: z.string().nullable(), type: z.string().nullable(), unofficial_currency_code: z.string().nullable()}).and(z.record(z.string(), z.unknown())); export const creditPayStubPayBasisType = z.enum(["SALARY", "HOURLY", "COMMISSION"]); export const payStubPayPeriodDetails = z.object({pay_amount: z.number().nullable(), distribution_breakdown: z.array(payStubDistributionBreakdown), end_date: z.string().nullable(), gross_earnings: z.number().nullable(), iso_currency_code: z.string().nullable(), pay_date: z.string().nullable(), pay_frequency: z.string().nullable(), pay_basis: creditPayStubPayBasisType.optional(), start_date: z.string().nullable(), unofficial_currency_code: z.string().nullable()}).and(z.record(z.string(), z.unknown())); export const creditPayStub = z.object({deductions: creditPayStubDeductions, document_id: z.string().nullable(), document_metadata: creditDocumentMetadata, earnings: creditPayStubEarnings, employee: creditPayStubEmployee, employer: creditPayStubEmployer, net_pay: creditPayStubNetPay, pay_period_details: payStubPayPeriodDetails}).and(z.record(z.string(), z.unknown())); export const w2Box12 = z.object({code: z.string().nullable().optional(), amount: z.string().nullable().optional()}).and(z.record(z.string(), z.unknown())); export const w2StateAndLocalWages = z.object({state: z.string().nullable().optional(), employer_state_id_number: z.string().nullable().optional(), state_wages_tips: z.string().nullable().optional(), state_income_tax: z.string().nullable().optional(), local_wages_tips: z.string().nullable().optional(), local_income_tax: z.string().nullable().optional(), locality_name: z.string().nullable().optional()}).and(z.record(z.string(), z.unknown())); export const creditW2 = z.object({document_metadata: creditDocumentMetadata, document_id: z.string(), employer: creditPayStubEmployer, employee: creditPayStubEmployee, tax_year: z.string().nullable(), employer_id_number: z.string().nullable(), wages_tips_other_comp: z.string().nullable(), federal_income_tax_withheld: z.string().nullable(), social_security_wages: z.string().nullable(), social_security_tax_withheld: z.string().nullable(), medicare_wages_and_tips: z.string().nullable(), medicare_tax_withheld: z.string().nullable(), social_security_tips: z.string().nullable(), allocated_tips: z.string().nullable(), box_9: z.string().nullable(), dependent_care_benefits: z.string().nullable(), nonqualified_plans: z.string().nullable(), box_12: z.array(w2Box12), statutory_employee: z.string().nullable(), retirement_plan: z.string().nullable(), third_party_sick_pay: z.string().nullable(), other: z.string().nullable(), state_and_local_wages: z.array(w2StateAndLocalWages)}).and(z.record(z.string(), z.unknown())); export const form1099Type = z.enum(["FORM_1099_TYPE_UNKNOWN", "FORM_1099_TYPE_MISC", "FORM_1099_TYPE_K"]); export const credit1099Recipient = z.object({address: creditPayStubAddress.optional(), name: z.string().nullable().optional(), tin: z.string().nullable().optional(), account_number: z.string().nullable().optional(), facta_filing_requirement: z.string().nullable().optional(), second_tin_exists: z.string().nullable().optional()}).and(z.record(z.string(), z.unknown())); export const credit1099Payer = z.object({address: creditPayStubAddress.optional(), name: z.string().nullable().optional(), tin: z.string().nullable().optional(), telephone_number: z.string().nullable().optional()}).and(z.record(z.string(), z.unknown())); export const credit1099Filer = z.object({address: creditPayStubAddress.optional(), name: z.string().nullable().optional(), tin: z.string().nullable().optional(), type: z.string().nullable().optional()}).and(z.record(z.string(), z.unknown())); export const credit1099 = z.object({document_id: z.string().nullable(), document_metadata: creditDocumentMetadata.optional(), form_1099_type: form1099Type.optional(), recipient: credit1099Recipient.optional(), payer: credit1099Payer.optional(), filer: credit1099Filer.optional(), tax_year: z.string().nullable().optional(), rents: z.number().nullable().optional(), royalties: z.number().nullable().optional(), other_income: z.number().nullable().optional(), federal_income_tax_withheld: z.number().nullable().optional(), fishing_boat_proceeds: z.number().nullable().optional(), medical_and_healthcare_payments: z.number().nullable().optional(), nonemployee_compensation: z.number().nullable().optional(), substitute_payments_in_lieu_of_dividends_or_interest: z.number().nullable().optional(), payer_made_direct_sales_of_5000_or_more_of_consumer_products_to_buyer: z.string().nullable().optional(), crop_insurance_proceeds: z.number().nullable().optional(), excess_golden_parachute_payments: z.number().nullable().optional(), gross_proceeds_paid_to_an_attorney: z.number().nullable().optional(), section_409a_deferrals: z.number().nullable().optional(), section_409a_income: z.number().nullable().optional(), state_tax_withheld: z.number().nullable().optional(), state_tax_withheld_lower: z.number().nullable().optional(), payer_state_number: z.string().nullable().optional(), payer_state_number_lower: z.string().nullable().optional(), state_income: z.number().nullable().optional(), state_income_lower: z.number().nullable().optional(), transactions_reported: z.string().nullable().optional(), pse_name: z.string().nullable().optional(), pse_telephone_number: z.string().nullable().optional(), gross_amount: z.number().nullable().optional(), card_not_present_transaction: z.number().nullable().optional(), merchant_category_code: z.string().nullable().optional(), number_of_payment_transactions: z.string().nullable().optional(), january_amount: z.number().nullable().optional(), february_amount: z.number().nullable().optional(), march_amount: z.number().nullable().optional(), april_amount: z.number().nullable().optional(), may_amount: z.number().nullable().optional(), june_amount: z.number().nullable().optional(), july_amount: z.number().nullable().optional(), august_amount: z.number().nullable().optional(), september_amount: z.number().nullable().optional(), october_amount: z.number().nullable().optional(), november_amount: z.number().nullable().optional(), december_amount: z.number().nullable().optional(), primary_state: z.string().nullable().optional(), secondary_state: z.string().nullable().optional(), primary_state_id: z.string().nullable().optional(), secondary_state_id: z.string().nullable().optional(), primary_state_income_tax: z.number().nullable().optional(), secondary_state_income_tax: z.number().nullable().optional()}).and(z.record(z.string(), z.unknown())); export const creditI20Student = z.object({given_name: z.string().nullable().optional(), surname_primary_name: z.string().nullable().optional(), passport_name: z.string().nullable().optional(), preferred_name: z.string().nullable().optional(), school_name: z.string().nullable().optional(), program_start_date: z.string().nullable().optional(), program_end_date: z.string().nullable().optional()}).and(z.record(z.string(), z.unknown())); export const creditI20 = z.object({document_id: z.string().nullable().optional(), document_metadata: creditDocumentMetadata.optional(), student: creditI20Student.optional(), personal_funds: z.number().nullable().optional(), on_campus_employment: z.number().nullable().optional(), funds_from_this_school: z.number().nullable().optional(), students_funding_total: z.number().nullable().optional(), funds_from_another_source: z.number().nullable().optional(), estimated_average_costs_total: z.number().nullable().optional(), estimated_average_living_expenses: z.number().nullable().optional(), students_funding_period_months: z.number().int().nullable().optional(), estimated_average_costs_period_months: z.number().int().nullable().optional()}).and(z.record(z.string(), z.unknown())); export const payrollIncomeObject = z.object({account_id: z.string().nullable(), pay_stubs: z.array(creditPayStub), w2s: z.array(creditW2), form1099s: z.array(credit1099), i20s: z.array(creditI20)}).and(z.record(z.string(), z.unknown())); export const payrollItemStatus = z.object({processing_status: z.string().nullable().optional()}).and(z.record(z.string(), z.unknown())).nullable(); export const payrollItem = z.object({item_id: itemId, institution_id: z.string(), institution_name: z.string(), accounts: z.array(payrollIncomeAccountData), payroll_income: z.array(payrollIncomeObject), status: payrollItemStatus, updated_at: z.string().nullable()}); export const plaidErrorType = z.enum(["INVALID_REQUEST", "INVALID_RESULT", "INVALID_INPUT", "INSTITUTION_ERROR", "RATE_LIMIT_EXCEEDED", "API_ERROR", "ITEM_ERROR", "ASSET_REPORT_ERROR", "BASE_REPORT_ERROR", "RECAPTCHA_ERROR", "OAUTH_ERROR", "PAYMENT_ERROR", "BANK_TRANSFER_ERROR", "INCOME_VERIFICATION_ERROR", "MICRODEPOSITS_ERROR", "SANDBOX_ERROR", "PARTNER_ERROR", "SIGNAL_ERROR", "TRANSACTIONS_ERROR", "TRANSACTION_ERROR", "TRANSFER_ERROR", "CHECK_REPORT_ERROR", "CONSUMER_REPORT_ERROR", "USER_ERROR", "IDEMPOTENCY_ERROR", "ASSETS_ERROR", "CRA_MONITORING_ERROR", "CREDIT_PROFILE_REPORT_ERROR", "ENCOMPASS_ERROR", "ENRICH_ERROR", "FRAUD_INSIGHTS_ERROR", "FREDDIE_MAC_ERROR", "LINK_DELIVERY_ERROR", "PROFILE_ERROR", "RECURRING_TRANSACTIONS_ERROR", "STATEMENTS_ERROR", "TRANSFER_RECURRING_ERROR", "TRANSFER_REFUND_ERROR", "CRA_REPORT_ERROR", "CRA_PARTNER_INSIGHTS_ERROR"]); export const plaidError = z.object({error_type: plaidErrorType, error_code: z.string(), error_code_reason: z.string().nullable().optional(), error_message: z.string(), display_message: z.string().nullable(), request_id: z.string().optional(), causes: z.array(z.unknown()).optional(), status: z.number().int().nullable().optional(), documentation_url: z.string().optional(), suggested_action: z.string().nullable().optional(), required_account_subtypes: z.array(z.string()).optional(), provided_account_subtypes: z.array(z.string()).optional()}).and(z.record(z.string(), z.unknown())).nullable(); export const requestID = z.string(); export const creditPayrollIncomeGetResponse = z.object({items: z.array(payrollItem), error: plaidError.optional(), request_id: requestID}).and(z.record(z.string(), z.unknown())); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Retrieve a user's payroll information * * POST /credit/payroll_income/get */ export const createApiCreditPayrollIncomeGet = async (args: CreateApiCreditPayrollIncomeGetArgs, options?: CreateApiCreditPayrollIncomeGetOptions) => { const {baseUrl = "https://production.plaid.com", fetch: fetchFn = fetch, clientId, secret, plaidVersion} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (clientId !== undefined) headers.set("PLAID-CLIENT-ID", clientId) if (secret !== undefined) headers.set("PLAID-SECRET", secret) if (plaidVersion !== undefined) headers.set("Plaid-Version", plaidVersion) const url = `${baseUrl.replace(/\/+$/, '')}/credit/payroll_income/get${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(creditPayrollIncomeGetResponse, await res.json()) };