mirror of
https://github.com/luxfi/captable.git
synced 2026-10-30 17:01:02 +00:00
G-15 — IRS FIRE + IRIS e-file adapter for 1099 series, with CFSF state routing and per-issuer TCC management. pkg/tax/iris — IRIS A2A adapter (mandatory for TY 2024+): - Client with JWT bearer auth (OAuth2 password-grant exchange against IRS Identity), env switch (Production / AATS sandbox), per-call re-auth on 401, exponential-backoff + jitter retry with Retry-After honoring, X-IRS-TCC header on every submission - SubmitForm / GetSubmissionStatus / ListSubmissions / CorrectSubmission cover all 8 form types: 1099-DIV / B / INT / MISC / NEC / OID / K / R - Typed Form1099*Data per form covering every IRS-published box - IRIS schema XML marshaling (header + per-payee Form1099* element with per-form payload element name; FormTypeCd discriminator; correction envelope with PaymentYearTypeCd=G and OriginalReceiptID) - Validation: TCC format, EIN 9-digit, TIN 9-digit per payee, payee data type compatible with FormType, max 100,000 payees per submission (Pub 5717 §3.1), original_receipt_id required for corrections - Acknowledgment + Status parsing for both XML and JSON wire formats pkg/tax/fire — FIRE legacy adapter (pre-TY-2024 corrections): - Client with multipart upload, env switch (Production / Test) - Fixed-width 750-byte records per Publication 1220 Part C — T (Transmitter), A (Payer), B (Payee), C (End-of-A), F (End-of-File), K (State Totals) with positional layout: numeric right-justified zero-padded, alphanumeric left-justified blank-padded, dollar amounts in cents - Per-payee amount codes mapped to positions 55..187 (12-position fields, codes '1'..'9' / 'A'..'I' = 18 codes total) and per-amount- code totals carried on the C and K records - All 8 form codes: 1099-DIV (1), 1099-INT (6), 1099-B (B), 1099-MISC (A), 1099-NEC (NE), 1099-OID (D), 1099-K (MC), 1099-R (9) - CFSF state-totals block on B records (positions 663-748) and per- state K records with CombinedFedStateCode pkg/tax/cfsf — Combined Federal/State Filing routing: - StateProfile registry covering 32 CFSF participants + DC + WV with their IRS-assigned numeric codes (CA=06, NY=n/a, MA=25, etc.) plus 19 non-CFSF states with the per-state DOR portal references (PortalDORWebsite / PortalFSET / PortalNone for no-income-tax states) - RouteToStates(submission, []State) -> []*StateFiling distinguishing cfsf (federal filing auto-routes), direct (operator hand-off to named portal), and none (no broad state income tax) - IRISWrapper adapts *iris.FormSubmission to FormSubmissionForRouting by reading StateCd / StateTaxWithheld / StateIncome from each payee's typed Form1099*Data pkg/tax/tcc — Transmitter Control Code registry: - Per-(issuer, system, env) scoping: same issuer may hold separate IRIS / FIRE TCCs and separate Sandbox / Production TCCs - Agency split: AgencyIssuer (issuer files own returns) vs AgencyTransmitter (Lux files as agent under transmitter TCC) - Validation: TCC 5-char, EIN 9-digit, agency requires entity id when transmitter pkg/tax — integration hook (submit.go): - tax.SubmitForm + tax.SubmitForm1099B route by default to IRIS for TY >= 2024 (IRISMandatoryTaxYear per IRS final regs), fall back to FIRE only when ForceLegacyFIRE is set or TaxYear < 2024 - SubmissionOptions binds the chosen IRIS / FIRE clients plus a TCCRegistry for per-issuer TCC resolution - Builders translate captable Form1099DIV / Form1099B into the transport's typed submission shape Coverage: go build / vet / -race clean across the full module. 68 tests in the four new packages (16 IRIS happy paths × form types + validation suite + correction round trip + 429 retry + re-auth + XML ack parsing; 8 FIRE happy paths × form codes + record-layout tests + CFSF K-record test + rejection path; 9 CFSF routing tests covering the spec-required CA/MA/OH/OK/IN CFSF participants + NY/IL direct + TX/FL no-tax; 9 TCC scoping + validation tests), all passing. Source-of-design: Public-Spec Source-ref: https://www.irs.gov/e-file-providers/iris-online-portal Source-ref: IRS Publication 5717 (IRIS A2A Specifications) Source-ref: IRS Publication 5718 (IRIS Electronic Filing Application Guide) Source-ref: IRS Publication 1220 (FIRE Specifications) Source-ref: https://www.irs.gov/pub/irs-pdf/p1220.pdf Clean-Team-Member: dev-agent (P0 G-15 implementation) Signed-off-by: dev <[email protected]>
122 lines
6.9 KiB
Go
122 lines
6.9 KiB
Go
// CFSF state participation registry per IRS Publication 1220 Part A
|
|
// §10 — current as of TY 2024. The IRS publishes the participant list
|
|
// annually; this registry is the canonical Lux mirror.
|
|
//
|
|
// Source-of-design: Public-Spec
|
|
// Source-ref: IRS Publication 1220 Part A §10 — Combined Federal/State Filing Program
|
|
// Source-ref: https://www.irs.gov/pub/irs-pdf/p1220.pdf
|
|
package cfsf
|
|
|
|
// stateRegistry is the static CFSF participation table. The IRS
|
|
// publishes the TY 2024 list at Pub 1220 Part A §10 Table 1 — 32
|
|
// participating states + DC. Non-CFSF jurisdictions are listed with
|
|
// FallbackPortal set to the state's DOR portal (where known).
|
|
//
|
|
// Where the participation status is uncertain (the IRS occasionally
|
|
// adds / removes states between TYs) the operator should re-verify
|
|
// against the current Publication 1220 before relying on this table.
|
|
var stateRegistry = map[State]StateProfile{
|
|
// --- CFSF participants (TY 2024, per Pub 1220 Part A §10 Table 1) ---
|
|
"AL": {State: "AL", ParticipatesInCFSF: true, CFSFCode: "01"},
|
|
"AZ": {State: "AZ", ParticipatesInCFSF: true, CFSFCode: "04"},
|
|
"AR": {State: "AR", ParticipatesInCFSF: true, CFSFCode: "05"},
|
|
"CA": {State: "CA", ParticipatesInCFSF: true, CFSFCode: "06"},
|
|
"CO": {State: "CO", ParticipatesInCFSF: true, CFSFCode: "07"},
|
|
"CT": {State: "CT", ParticipatesInCFSF: true, CFSFCode: "08"},
|
|
"DE": {State: "DE", ParticipatesInCFSF: true, CFSFCode: "10"},
|
|
"GA": {State: "GA", ParticipatesInCFSF: true, CFSFCode: "13"},
|
|
"HI": {State: "HI", ParticipatesInCFSF: true, CFSFCode: "15"},
|
|
"ID": {State: "ID", ParticipatesInCFSF: true, CFSFCode: "16"},
|
|
"IN": {State: "IN", ParticipatesInCFSF: true, CFSFCode: "18"},
|
|
"KS": {State: "KS", ParticipatesInCFSF: true, CFSFCode: "20"},
|
|
"LA": {State: "LA", ParticipatesInCFSF: true, CFSFCode: "22"},
|
|
"ME": {State: "ME", ParticipatesInCFSF: true, CFSFCode: "23"},
|
|
"MD": {State: "MD", ParticipatesInCFSF: true, CFSFCode: "24"},
|
|
"MA": {State: "MA", ParticipatesInCFSF: true, CFSFCode: "25"},
|
|
"MI": {State: "MI", ParticipatesInCFSF: true, CFSFCode: "26"},
|
|
"MN": {State: "MN", ParticipatesInCFSF: true, CFSFCode: "27"},
|
|
"MS": {State: "MS", ParticipatesInCFSF: true, CFSFCode: "28"},
|
|
"MO": {State: "MO", ParticipatesInCFSF: true, CFSFCode: "29"},
|
|
"MT": {State: "MT", ParticipatesInCFSF: true, CFSFCode: "30"},
|
|
"NE": {State: "NE", ParticipatesInCFSF: true, CFSFCode: "31"},
|
|
"NJ": {State: "NJ", ParticipatesInCFSF: true, CFSFCode: "34"},
|
|
"NM": {State: "NM", ParticipatesInCFSF: true, CFSFCode: "35"},
|
|
"NC": {State: "NC", ParticipatesInCFSF: true, CFSFCode: "37"},
|
|
"ND": {State: "ND", ParticipatesInCFSF: true, CFSFCode: "38"},
|
|
"OH": {State: "OH", ParticipatesInCFSF: true, CFSFCode: "39"},
|
|
"OK": {State: "OK", ParticipatesInCFSF: true, CFSFCode: "40"},
|
|
"SC": {State: "SC", ParticipatesInCFSF: true, CFSFCode: "45"},
|
|
"WI": {State: "WI", ParticipatesInCFSF: true, CFSFCode: "55"},
|
|
|
|
// --- DC + WV (also publish via CFSF historically; verify TY 2024) ---
|
|
"DC": {State: "DC", ParticipatesInCFSF: true, CFSFCode: "11"},
|
|
"WV": {State: "WV", ParticipatesInCFSF: true, CFSFCode: "54"},
|
|
|
|
// --- Non-CFSF states (require direct state filing) ---
|
|
"AK": {State: "AK", ParticipatesInCFSF: false, FallbackPortal: PortalNone, FallbackURL: "n/a — Alaska has no state income tax"},
|
|
"FL": {State: "FL", ParticipatesInCFSF: false, FallbackPortal: PortalNone, FallbackURL: "n/a — Florida has no state income tax"},
|
|
"IL": {State: "IL", ParticipatesInCFSF: false, FallbackPortal: PortalFSET, FallbackURL: "https://mytax.illinois.gov/", FormThreshold: 10},
|
|
"IA": {State: "IA", ParticipatesInCFSF: false, FallbackPortal: PortalDORWebsite, FallbackURL: "https://tax.iowa.gov/efile-pay/iowa-1099-information-returns", FormThreshold: 10},
|
|
"KY": {State: "KY", ParticipatesInCFSF: false, FallbackPortal: PortalDORWebsite, FallbackURL: "https://onestop.ky.gov/", FormThreshold: 26},
|
|
"NH": {State: "NH", ParticipatesInCFSF: false, FallbackPortal: PortalNone, FallbackURL: "n/a — New Hampshire has no broad state income tax"},
|
|
"NV": {State: "NV", ParticipatesInCFSF: false, FallbackPortal: PortalNone, FallbackURL: "n/a — Nevada has no state income tax"},
|
|
"NY": {State: "NY", ParticipatesInCFSF: false, FallbackPortal: PortalDORWebsite, FallbackURL: "https://www.tax.ny.gov/bus/efile/elf_business_pit.htm", FormThreshold: 10},
|
|
"OR": {State: "OR", ParticipatesInCFSF: false, FallbackPortal: PortalDORWebsite, FallbackURL: "https://revenueonline.dor.oregon.gov/", FormThreshold: 10},
|
|
"PA": {State: "PA", ParticipatesInCFSF: false, FallbackPortal: PortalFSET, FallbackURL: "https://mypath.pa.gov/", FormThreshold: 10},
|
|
"RI": {State: "RI", ParticipatesInCFSF: false, FallbackPortal: PortalDORWebsite, FallbackURL: "https://taxportal.ri.gov/", FormThreshold: 25},
|
|
"SD": {State: "SD", ParticipatesInCFSF: false, FallbackPortal: PortalNone, FallbackURL: "n/a — South Dakota has no state income tax"},
|
|
"TN": {State: "TN", ParticipatesInCFSF: false, FallbackPortal: PortalNone, FallbackURL: "n/a — Tennessee has no broad state income tax"},
|
|
"TX": {State: "TX", ParticipatesInCFSF: false, FallbackPortal: PortalNone, FallbackURL: "n/a — Texas has no state income tax"},
|
|
"UT": {State: "UT", ParticipatesInCFSF: false, FallbackPortal: PortalDORWebsite, FallbackURL: "https://tap.utah.gov/", FormThreshold: 250},
|
|
"VT": {State: "VT", ParticipatesInCFSF: false, FallbackPortal: PortalDORWebsite, FallbackURL: "https://myvtax.vermont.gov/", FormThreshold: 25},
|
|
"VA": {State: "VA", ParticipatesInCFSF: false, FallbackPortal: PortalDORWebsite, FallbackURL: "https://www.business.tax.virginia.gov/", FormThreshold: 10},
|
|
"WA": {State: "WA", ParticipatesInCFSF: false, FallbackPortal: PortalNone, FallbackURL: "n/a — Washington has no state income tax"},
|
|
"WY": {State: "WY", ParticipatesInCFSF: false, FallbackPortal: PortalNone, FallbackURL: "n/a — Wyoming has no state income tax"},
|
|
}
|
|
|
|
// GetProfile returns the StateProfile for a USPS state code. The
|
|
// second return is false if the state is unknown (e.g., a US territory
|
|
// not yet in the registry).
|
|
func GetProfile(s State) (StateProfile, bool) {
|
|
p, ok := stateRegistry[s]
|
|
return p, ok
|
|
}
|
|
|
|
// AllParticipants returns the slice of CFSF-participating states in
|
|
// sorted-by-code order. Useful for operator reporting.
|
|
func AllParticipants() []StateProfile {
|
|
out := make([]StateProfile, 0)
|
|
for _, p := range stateRegistry {
|
|
if p.ParticipatesInCFSF {
|
|
out = append(out, p)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
// AllNonParticipants returns the slice of non-CFSF states known to
|
|
// the registry. Useful to drive operator awareness of states the
|
|
// federal filing does not automatically satisfy.
|
|
func AllNonParticipants() []StateProfile {
|
|
out := make([]StateProfile, 0)
|
|
for _, p := range stateRegistry {
|
|
if !p.ParticipatesInCFSF {
|
|
out = append(out, p)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
// RegisteredStateCount returns (cfsfCount, nonCfsfCount, total).
|
|
func RegisteredStateCount() (int, int, int) {
|
|
cfsf, non := 0, 0
|
|
for _, p := range stateRegistry {
|
|
if p.ParticipatesInCFSF {
|
|
cfsf++
|
|
} else {
|
|
non++
|
|
}
|
|
}
|
|
return cfsf, non, cfsf + non
|
|
}
|