Browse Source

PAIN structs ready for minimum required XML

master
Gerdriaan Mulder 6 years ago
parent
commit
d7f295d37d
  1. 1
      pain/group_header.go
  2. 25
      pain/pain.go
  3. 8
      pain/pain_regexp.go
  4. 11
      pain/payment_information.go
  5. 130
      pain/payment_information_transactions.go

1
pain/group_header.go

@ -2,6 +2,7 @@ package pain
import (
"fmt"
"strings"
)
type GrpHdr struct {

25
pain/pain.go

@ -2,7 +2,6 @@ package pain
import (
"fmt"
"regexp"
"strings"
)
@ -31,30 +30,10 @@ func (p *PainXML) 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 CdtrAcct struct {
Id IBAN `xml:"Id"`
}
type IBAN struct {
IBAN string `xml:"IBAN"`
}
func (c *CdtrAcct) Valid() error {
if e := c.Id.Valid(); e != nil {
return fmt.Errorf("creditor account id not valid: %v", e)
@ -62,6 +41,10 @@ func (c *CdtrAcct) Valid() error {
return nil
}
type IBAN struct {
IBAN string `xml:"IBAN"`
}
func (i *IBAN) Valid() error {
if !SEPARegexps["IBAN"].MatchString(i.IBAN) {
return fmt.Errorf("IBAN does not match format")

8
pain/pain_regexp.go

@ -11,6 +11,7 @@ var (
Max15NumericText = regexp.MustCompile(`[0-9]{1,15}`)
RestrictedDecimalNumber = regexp.MustCompile(`[+-]?\d+\.\d\d`)
Max70Text = regexp.MustCompile(`.{1,70}`)
Max140Text = regexp.MustCompile(`.{1,140}`)
ServiceLevelSEPACode = regexp.MustCompile(`SEPA`)
SequenceType1Code = regexp.MustCompile(`FRST|RCUR|FNAL|OOFF`)
@ -27,11 +28,13 @@ var (
"BIC": BICIdentifier,
"CreDtTm": ISODateTime,
"CtrlSum": RestrictedDecimalNumber,
"EndToEndId": RestrictionIdentificationSEPA1,
"EndToEndId": RestrictedIdentificationSEPA1,
"IBAN": IBAN2007Identifier,
"Id": RestrictedPersonIdentifierSEPA,
"InstrId": RestrictionIdentificationSEPA1,
"InstrId": RestrictedIdentificationSEPA1,
"InstdAmt": RestrictedDecimalNumber, // Note: this is for the value
"MsgId": RestrictedIdentificationSEPA1,
"MndtId": RestrictedIdentificationSEPA2,
"NbOfTxs": Max15NumericText,
"Nm": Max70Text,
"PmtInfId": RestrictedIdentificationSEPA1,
@ -40,5 +43,6 @@ var (
"PmtMtd": PaymentMethod2Code,
"ReqdColltnDt": ISODateTime,
"SeqTp": SequenceType1Code,
"Ustrd": Max140Text,
}
)

11
pain/payment_information.go

@ -2,6 +2,7 @@ package pain
import (
"fmt"
"strings"
)
type PmtInf struct {
@ -56,8 +57,8 @@ type PmtTpInf struct {
}
type Cdtr struct {
Name string `xml:"Nm"`
PostalAddress PstlAddr `xml:"PstlAddr"`
Name string `xml:"Nm"`
PostalAddress PstlAdr `xml:"PstlAdr"`
}
func (c *Cdtr) Valid() error {
@ -76,12 +77,12 @@ func (c *Cdtr) Valid() error {
}
type AdrLine string
type PstlAddr struct {
type PstlAdr struct {
Country string `xml:"Ctry"`
AddressLines []AdrLine `xml:"AdrLine"`
}
func (p *PstlAddr) Valid() error {
func (p *PstlAdr) Valid() error {
var err []string
if !SEPARegexps["Ctry"].MatchString(p.Country) {
err = append(err, "country does not match format")
@ -107,7 +108,7 @@ type CdtrAgt struct {
}
func (c *CdtrAgt) Valid() error {
return c.InstituionId.Valid()
return c.InstitutionId.Valid()
}
type FinInstnId struct {

130
pain/payment_information_transactions.go

@ -6,8 +6,40 @@ import (
)
type DrctDbtTxInf struct {
Id PaymentId `xml:"PmtId"`
Amount CurrencyWithAmount `xml:"InstdAmt"`
Id PaymentId `xml:"PmtId"`
Amount CurrencyWithAmount `xml:"InstdAmt"`
Transaction DrctDbtTx `xml:"DrctDbtTx"`
Agent DbtrAgt `xml:"DbtrAgt"`
Debtor Dbtr `xml:"Dbtr"`
Account DbtrAcct `xml:"DbtrAcct"`
Info RmtInf `xml:"RmtInf"`
}
func (d *DrctDbtTxInf) Valid() error {
var err []string
if e := d.Id.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if e := d.Amount.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if e := d.Transaction.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if e := d.Agent.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if e := d.Debtor.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if e := d.Account.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if len(err) > 0 {
return fmt.Errorf("direct debit transaction information not valid: %v", strings.Join(err, ", "))
}
return nil
}
type CurrencyWithAmount struct {
@ -15,6 +47,21 @@ type CurrencyWithAmount struct {
Value string `xml:",innerxml"`
}
func (c *CurrencyWithAmount) Valid() error {
var err []string
if c.Currency != "EUR" {
err = append(err, "expected Ccy EUR")
}
if !SEPARegexps["InstdAmnt"].MatchString(c.Value) {
err = append(err, "value does not match format")
}
if len(err) > 0 {
return fmt.Errorf("currency with amount not valid: %v", strings.Join(err, ", "))
}
return nil
}
type PaymentId struct {
InstrumentId string `xml:"InstrId"`
EndToEndId string `xml:"EndToEndId"`
@ -34,3 +81,82 @@ func (p *PaymentId) Valid() error {
}
return nil
}
type MndtRltdInf struct {
Id string `xml:"MndtId"`
SignatureDate string `xml:"DtOfSgntr"`
IsAmended bool `xml:"AmdmntInd"`
//AmdmntInfDtls is optional
//ElctrncSgntr is optional
}
func (m *MndtRltdInf) Valid() error {
var err []string
if !SEPARegexps["MndtId"].MatchString(m.Id) {
err = append(err, "mandate id does not match format")
}
if !SEPARegexps["DtOfSgntr"].MatchString(m.SignatureDate) {
err = append(err, "date of signature does not match format")
}
if len(err) > 0 {
return fmt.Errorf("mandate related information is not valid: %v", strings.Join(err, ", "))
}
return nil
}
type DrctDbtTx struct {
MandateRelatedInfo MndtRltdInf `xml:"MndtRltdInf"`
//CdtrSchemeId is optional
}
func (d *DrctDbtTx) Valid() error {
return d.MandateRelatedInfo.Valid()
}
type DbtrAgt struct {
InstitutionId FinInstnId `xml:"FinInstId"`
}
func (d *DbtrAgt) Valid() error {
return d.InstitutionId.Valid()
}
type Dbtr struct {
Name string `xml:"Nm"`
Address PstlAdr `xml:"PstlAdr"`
}
func (d *Dbtr) Valid() error {
var err []string
if !SEPARegexps["Nm"].MatchString(d.Name) {
err = append(err, "name does not match format")
}
if e := d.Address.Valid(); e != nil {
err = append(err, fmt.Sprintf("%v", e))
}
if len(err) > 0 {
return fmt.Errorf("dbtr not valid: %v", strings.Join(err, ", "))
}
return nil
}
type DbtrAcct struct {
Id IBAN `xml:"IBAN"`
}
func (d *DbtrAcct) Valid() error {
return d.Id.Valid()
}
type RmtInf struct {
Value string `xml:"Ustrd"`
}
func (r *RmtInf) Valid() error {
if !SEPARegexps["Ustrd"].MatchString(r.Value) {
return fmt.Errorf("remittance information does not match format")
}
return nil
}

Loading…
Cancel
Save