From da5db648832bce13934a392eaadec07797aba816 Mon Sep 17 00:00:00 2001 From: Gerdriaan Mulder Date: Sun, 5 Jan 2020 21:32:50 +0100 Subject: [PATCH] Add SchmeId validations --- pain.go | 101 +++++++++++++++++++++++++++++++++++++++++++------ pain_regexp.go | 3 +- 2 files changed, 91 insertions(+), 13 deletions(-) diff --git a/pain.go b/pain.go index aa6a34c..2819250 100644 --- a/pain.go +++ b/pain.go @@ -18,6 +18,7 @@ var ( "PmtMtd": PaymentMethod2Code, "PmtMetaSvcLvl": ServiceLevelSEPACode, "PmtMetaLclInstrm": LocalInstrumentSEPACode, + "Id": RestrictedPersonIdentifierSEPA, "SeqTp": SequenceType1Code, "IBAN": IBAN2007Identifier, } @@ -49,11 +50,11 @@ func (p *PainXML) Valid() error { } type GrpHdr struct { - MessageId string `xml:"MsgId"` - Timestamp string `xml:"CreDtTm"` - NumTx string `xml:"NbOfTxs"` - Sum string `xml:"CtrlSum"` - InitiatingParty InitgPty `xml:"InitgPty"` + MessageId string `xml:"MsgId"` + Timestamp string `xml:"CreDtTm"` + NumTx string `xml:"NbOfTxs"` + Sum string `xml:"CtrlSum"` + InitiatingParty PartyIdSEPA1 `xml:"InitgPty"` } func (g *GrpHdr) Valid() error { @@ -82,12 +83,14 @@ func (g *GrpHdr) Valid() error { } type PmtInf struct { - Id string `xml:"PmtInfId"` - Method string `xml:"PmtMtd"` - PaymentMeta PmtTpInf `xml:"PmtTpInf"` - CollectionDate string `xml:"ReqdColltnDt"` - Creditor Cdtr `xml:"Cdtr"` - CreditorAccount CdtrAcct `xml:"CdtrAcct"` + Id string `xml:"PmtInfId"` + Method string `xml:"PmtMtd"` + PaymentMeta PmtTpInf `xml:"PmtTpInf"` + CollectionDate string `xml:"ReqdColltnDt"` + Creditor Cdtr `xml:"Cdtr"` + CreditorAccount CdtrAcct `xml:"CdtrAcct"` + CreditorAgent CdtrAgt `xml:"CdtrAgt"` + SchemeId CdtrSchmeId `xml:"CdtrSchmeId"` } func (pmt *PmtInf) Valid() error { @@ -110,6 +113,9 @@ func (pmt *PmtInf) Valid() error { if e := pmt.CreditorAccount.Valid(); e != nil { err = append(err, fmt.Sprintf("payment creditor account not valid: %v", e)) } + if e := pmt.SchemeId.Valid(); e != nil { + err = append(err, fmt.Sprintf("payment scheme id not valid: %v", e)) + } if len(err) > 0 { return fmt.Errorf("payment info (Id: %q) not valid: %v", pmt.Id, strings.Join(err, ", ")) @@ -143,6 +149,22 @@ func (c *Cdtr) Valid() error { return nil } +type CdtrAgt struct { + InstitutionId FinInstnId `xml:"FinInstId"` +} + +type FinInstnId struct { + BIC string `xml:"BIC"` +} + +type CdtrSchmeId struct { + Id PartyIdSEPA3 `xml:"Id"` +} + +func (c *CdtrSchmeId) Valid() error { + return c.Id.Valid() +} + type PstlAddr struct { Country string `xml:"Ctry"` AddressLines []AdrLine `xml:"AdrLine"` @@ -220,7 +242,62 @@ func (meta *PmtTpInf) Valid() error { type TxInf struct { } -type InitgPty struct { +type PartySEPA2 struct { + PrivateId PersonIdSEPA2 `xml:"PrvtId"` +} + +func (p *PartySEPA2) Valid() error { + return p.PrivateId.Valid() +} + +type PartyIdSEPA1 struct { Name string `xml:"Nm"` // We do not implement the "Id" element from "PartyIdentificationSEPA1" } + +type PartyIdSEPA3 struct { + Id PartySEPA2 `xml:"Id"` +} + +func (p *PartyIdSEPA3) Valid() error { + return p.Id.Valid() +} + +type PersonIdSEPA2 struct { + Other RestrictedPersonIdSEPA `xml:"Othr"` +} + +func (p *PersonIdSEPA2) Valid() error { + return p.Other.Valid() +} + +type RestrictedPersonIdSEPA struct { + Id string `xml:"Id"` // RestrictedPersonIdentifierSEPA + SchemeName RestrictedPersonIdSchemeNameSEPA `xml:"SchmeNm"` +} + +func (r *RestrictedPersonIdSEPA) Valid() error { + var err []string + if !SEPARegexps["Id"].MatchString(r.Id) { + err = append(err, "id of RestrictedPersonIdSEPA does not match format") + } + if e := r.SchemeName.Valid(); e != nil { + err = append(err, fmt.Sprintf("SchemeName not valid: %v", e)) + } + + if len(err) > 0 { + return fmt.Errorf("restricted person id SEPA not valid: %v", strings.Join(err, ", ")) + } + return nil +} + +type RestrictedPersonIdSchemeNameSEPA struct { + Party string `xml:"Prty"` // IdentificationSchemeNameSEPA +} + +func (r *RestrictedPersonIdSchemeNameSEPA) Valid() error { + if r.Party != "SEPA" { + return fmt.Errorf("party should be 'SEPA', got %v", r.Party) + } + return nil +} diff --git a/pain_regexp.go b/pain_regexp.go index d19d4d4..09be71a 100644 --- a/pain_regexp.go +++ b/pain_regexp.go @@ -17,5 +17,6 @@ var ( PaymentMethod2Code = regexp.MustCompile(`DD`) LocalInstrumentSEPACode = regexp.MustCompile(`CORE|B2B`) - IBAN2007Identifier = regexp.MustCompile(`[A-Z]{2,2}[0-9]{2,2}[a-zA-Z0-9]{1,30}`) + IBAN2007Identifier = regexp.MustCompile(`[A-Z]{2,2}[0-9]{2,2}[a-zA-Z0-9]{1,30}`) + RestrictedPersonIdentifierSEPA = regexp.MustCompile(`[a-zA-Z]{2,2}[0-9]{2,2}([A-Za-z0-9]|[\+|\?|/|\-|:|\(|\)|\.|,|']){3,3}([A-Za-z0-9]|[\+|\?|/|\-|:|\(|\)|\.|,|']){1,28}`) )