4 changed files with 188 additions and 146 deletions
@ -0,0 +1,38 @@ |
|||||
|
package pain |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
) |
||||
|
|
||||
|
type GrpHdr struct { |
||||
|
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 { |
||||
|
var err []string |
||||
|
if !SEPARegexps["MsgId"].MatchString(g.MessageId) { |
||||
|
err = append(err, "msgId did not match expected format") |
||||
|
} |
||||
|
if !SEPARegexps["CreDtTm"].MatchString(g.Timestamp) { |
||||
|
err = append(err, "timestamp did not match expected format") |
||||
|
} |
||||
|
if !SEPARegexps["NbOfTxs"].MatchString(g.NumTx) { |
||||
|
err = append(err, "numtx did not match expected format") |
||||
|
} |
||||
|
if !SEPARegexps["CtrlSum"].MatchString(g.Sum) { |
||||
|
err = append(err, "sum did not match expected format") |
||||
|
} |
||||
|
// Note: we assume g.InitiatingParty is initialized.
|
||||
|
if !SEPARegexps["Nm"].MatchString(g.InitiatingParty.Name) { |
||||
|
err = append(err, "initiating party's name did not match expected format") |
||||
|
} |
||||
|
|
||||
|
if len(err) > 0 { |
||||
|
return fmt.Errorf("group header not valid: %v", strings.Join(err, ", ")) |
||||
|
} |
||||
|
return nil |
||||
|
} |
||||
@ -0,0 +1,130 @@ |
|||||
|
package pain |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
) |
||||
|
|
||||
|
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"` |
||||
|
CreditorAgent CdtrAgt `xml:"CdtrAgt"` |
||||
|
SchemeId CdtrSchmeId `xml:"CdtrSchmeId"` |
||||
|
Transactions []DrctDbtTxInf `xml:"DrctDbtTxInf"` |
||||
|
} |
||||
|
|
||||
|
func (pmt *PmtInf) Valid() error { |
||||
|
var err []string |
||||
|
if !SEPARegexps["PmtInfId"].MatchString(pmt.Id) { |
||||
|
err = append(err, "payment info id does not match expected format") |
||||
|
} |
||||
|
if !SEPARegexps["PmtMtd"].MatchString(pmt.Method) { |
||||
|
err = append(err, "payment method does not match expected format") |
||||
|
} |
||||
|
if e := pmt.PaymentMeta.Valid(); e != nil { |
||||
|
err = append(err, fmt.Sprintf("payment meta not valid: %v", e)) |
||||
|
} |
||||
|
if !SEPARegexps["ReqdColltnDt"].MatchString(pmt.CollectionDate) { |
||||
|
err = append(err, "payment collection date does not match expected format") |
||||
|
} |
||||
|
if e := pmt.Creditor.Valid(); e != nil { |
||||
|
err = append(err, fmt.Sprintf("payment creditor not valid: %v", e)) |
||||
|
} |
||||
|
if e := pmt.CreditorAccount.Valid(); e != nil { |
||||
|
err = append(err, fmt.Sprintf("payment creditor account not valid: %v", e)) |
||||
|
} |
||||
|
if e := pmt.CreditorAgent.Valid(); e != nil { |
||||
|
err = append(err, fmt.Sprintf("payment creditor agent 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, ", ")) |
||||
|
} |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
type PmtTpInf struct { |
||||
|
ServiceLevel Code `xml:"SvcLvl"` |
||||
|
LocalInstrument Code `xml:"LclIntrm"` |
||||
|
SequenceType string `xml:"SeqTp"` |
||||
|
} |
||||
|
|
||||
|
type Cdtr struct { |
||||
|
Name string `xml:"Nm"` |
||||
|
PostalAddress PstlAddr `xml:"PstlAddr"` |
||||
|
} |
||||
|
|
||||
|
func (c *Cdtr) Valid() error { |
||||
|
var err []string |
||||
|
if !SEPARegexps["Nm"].MatchString(c.Name) { |
||||
|
err = append(err, "creditor name does not match format") |
||||
|
} |
||||
|
if e := c.PostalAddress.Valid(); e != nil { |
||||
|
err = append(err, fmt.Sprintf("creditor postal address not valid: %v", e)) |
||||
|
} |
||||
|
|
||||
|
if len(err) > 0 { |
||||
|
return fmt.Errorf("creditor (Nm: %q) not valid: %v", c.Name, strings.Join(err, ", ")) |
||||
|
} |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
type AdrLine string |
||||
|
type PstlAddr struct { |
||||
|
Country string `xml:"Ctry"` |
||||
|
AddressLines []AdrLine `xml:"AdrLine"` |
||||
|
} |
||||
|
|
||||
|
func (p *PstlAddr) Valid() error { |
||||
|
var err []string |
||||
|
if !SEPARegexps["Ctry"].MatchString(p.Country) { |
||||
|
err = append(err, "country does not match format") |
||||
|
} |
||||
|
if len(p.AddressLines) > 2 { |
||||
|
err = append(err, "expected at most 2 address lines") |
||||
|
} |
||||
|
for i, line := range p.AddressLines { |
||||
|
if !SEPARegexps["AdrLine"].MatchString(string(line)) { |
||||
|
err = append(err, fmt.Sprintf("address line %d (%q) does not match format", i, line)) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if len(err) > 0 { |
||||
|
return fmt.Errorf("address not valid: %v", strings.Join(err, ", ")) |
||||
|
} |
||||
|
|
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
type CdtrAgt struct { |
||||
|
InstitutionId FinInstnId `xml:"FinInstId"` |
||||
|
} |
||||
|
|
||||
|
func (c *CdtrAgt) Valid() error { |
||||
|
return c.InstituionId.Valid() |
||||
|
} |
||||
|
|
||||
|
type FinInstnId struct { |
||||
|
BIC string `xml:"BIC"` |
||||
|
} |
||||
|
|
||||
|
func (f *FinInstnId) Valid() error { |
||||
|
if !SEPARegexps["BIC"].MatchString(f.BIC) { |
||||
|
return fmt.Errorf("BIC not in expected format") |
||||
|
} |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
type CdtrSchmeId struct { |
||||
|
Id PartyIdSEPA3 `xml:"Id"` |
||||
|
} |
||||
|
|
||||
|
func (c *CdtrSchmeId) Valid() error { |
||||
|
return c.Id.Valid() |
||||
|
} |
||||
Loading…
Reference in new issue