You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
3.8 KiB
147 lines
3.8 KiB
package sepa
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
SEPARegexps = map[string]*regexp.Regexp{
|
|
"MsgId": RestrictedIdentificationSEPA1,
|
|
"CreDtTm": ISODateTime,
|
|
"NbOfTxs": Max15NumericText,
|
|
"CtrlSum": RestrictedDecimalNumber,
|
|
"Nm": Max70Text,
|
|
"PmtInfId": RestrictedIdentificationSEPA1,
|
|
"PmtMtd": PaymentMethod2Code,
|
|
"PmtMetaSvcLvl": ServiceLevelSEPACode,
|
|
"PmtMetaLclInstrm": LocalInstrumentSEPACode,
|
|
"SeqTp": SequenceType1Code,
|
|
}
|
|
)
|
|
|
|
type PainXML struct {
|
|
GroupHeader GrpHdr `xml:"GrpHdr"`
|
|
PaymentInformation []PmtInf `xml:"PmtInf"`
|
|
TransactionInformation []TxInf `xml:"DrctDbtTxInf"`
|
|
}
|
|
|
|
func (p *PainXML) Valid() error {
|
|
var err []string
|
|
if e := p.GroupHeader.Valid(); e != nil {
|
|
err = append(err, fmt.Sprintf("%v", e))
|
|
}
|
|
if len(p.PaymentInformation) < 1 {
|
|
err = append(err, "no payment information")
|
|
}
|
|
if len(p.TransactionInformation) < 1 {
|
|
err = append(err, "no transaction information")
|
|
}
|
|
|
|
if len(err) > 0 {
|
|
return fmt.Errorf("pain XML not valid: %v", strings.Join(err, ", "))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type GrpHdr struct {
|
|
MessageId string `xml:"MsgId"`
|
|
Timestamp string `xml:"CreDtTm"`
|
|
NumTx string `xml:"NbOfTxs"`
|
|
Sum string `xml:"CtrlSum"`
|
|
InitiatingParty InitgPty `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")
|
|
}
|
|
// TODO
|
|
/*
|
|
if g.InitiatingParty == nil {
|
|
err = append(err, "no initiating party found")
|
|
} else {
|
|
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
|
|
}
|
|
|
|
type PmtInf struct {
|
|
Id string `xml:"PmtInfId"`
|
|
Method string `xml:"PmtMtd"`
|
|
PaymentMeta PmtTpInf `xml:"PmtTpInf"`
|
|
}
|
|
|
|
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 info id does not match expected format")
|
|
}
|
|
if e := pmt.PaymentMeta.Valid(); e != nil {
|
|
err = append(err, fmt.Sprintf("payment meta 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 Code struct {
|
|
Code string `xml:"Cd"`
|
|
}
|
|
|
|
func (meta *PmtTpInf) Valid() error {
|
|
var err []string
|
|
// TODO: check meta.ServiceLevel for nil
|
|
if !SEPARegexps["PmtMetaSvcLvl"].MatchString(meta.ServiceLevel.Code) {
|
|
err = append(err, "incorrect service level present (must be 'SEPA')")
|
|
}
|
|
// TODO: check meta.LocalInstrument for nil
|
|
if !SEPARegexps["PmtMetaLclInstrm"].MatchString(meta.LocalInstrument.Code) {
|
|
err = append(err, "incorrect local instrument present")
|
|
}
|
|
if !SEPARegexps["SeqTp"].MatchString(meta.SequenceType) {
|
|
err = append(err, "sequence type has incorrect format")
|
|
}
|
|
|
|
if len(err) > 0 {
|
|
return fmt.Errorf("payment meta not valid: %v", strings.Join(err, ", "))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type TxInf struct {
|
|
}
|
|
|
|
type InitgPty struct {
|
|
Name string `xml:"Nm"`
|
|
}
|
|
|