Skip to content

Commit 2aa783c

Browse files
author
Thiago Zilli
committed
Refactor Pix options and payload generation
- annotate EMV tags and add BACEN GUI constant - overhaul Options API: compact functional setters/getters, rename additional field, introduce Merchant type - simplify New to use stored params on Pix - unify TLV creation with tlv helper, rebuild GenPayload, centralize CRC calculation/replacement, adjust MAI/additional data generation - move Validates to validates.go and add stricter checks (name/city length, dynamic URL must use HTTPS) - update tests to reflect API and behavior changes
1 parent c165908 commit 2aa783c

File tree

6 files changed

+178
-437
lines changed

6 files changed

+178
-437
lines changed

pix/const.go

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
package pix
22

3+
// EMV schema tags (BACEN Pix)
34
const (
4-
//EmvSchema
5-
TAG_INIT = "00"
6-
TAG_INIT_METHOD = "01"
7-
TAG_MAI = "26"
8-
TAG_MCC = "52"
9-
TAG_TRANSACTION_CURRENCY = "53"
10-
TAG_TRANSACTION_AMOUNT = "54"
11-
TAG_COUNTRY_CODE = "58"
12-
TAG_MERCHANT_NAME = "59"
13-
TAG_MERCHANT_CITY = "60"
14-
TAG_ADDITIONAL_DATA = "62"
15-
TAG_CRC = "63"
5+
TAG_INIT = "00" // Payload Format Indicator
6+
TAG_INIT_METHOD = "01" // Point of Initiation Method
7+
TAG_MAI = "26" // Merchant Account Information
8+
TAG_MCC = "52" // Merchant Category Code
9+
TAG_TRANSACTION_CURRENCY = "53" // Transaction Currency
10+
TAG_TRANSACTION_AMOUNT = "54" // Transaction Amount
11+
TAG_COUNTRY_CODE = "58" // Country Code
12+
TAG_MERCHANT_NAME = "59" // Merchant Name
13+
TAG_MERCHANT_CITY = "60" // Merchant City
14+
TAG_ADDITIONAL_DATA = "62" // Additional Data Field Template
15+
TAG_CRC = "63" // CRC16 Checksum
1616

17-
//EmvAdditionalDataSchema
17+
// Additional Data Template
1818
TAG_TXID = "05"
1919

20-
//EmvMaiSchema
20+
// Merchant Account Info subtags
2121
TAG_MAI_GUI = "00"
2222
TAG_MAI_PIXKEY = "01"
2323
TAG_MAI_INFO_ADD = "02"
2424
TAG_MAI_URL = "25"
25-
BC_GUI = "br.gov.bcb.pix"
25+
26+
// BACEN domain for Pix
27+
BC_GUI = "br.gov.bcb.pix"
2628
)

pix/options.go

Lines changed: 52 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,77 @@
11
package pix
22

3+
// PixKind defines if the QR Code is static or dynamic.
34
type PixKind int
45

56
const (
67
STATIC PixKind = iota
78
DYNAMIC
89
)
910

10-
func (pix PixKind) String() string {
11-
return [...]string{"STATIC", "DYNAMIC"}[pix]
11+
func (k PixKind) String() string {
12+
switch k {
13+
case STATIC:
14+
return "STATIC"
15+
case DYNAMIC:
16+
return "DYNAMIC"
17+
default:
18+
return "UNKNOWN"
19+
}
1220
}
1321

22+
// Options pattern for configuring Pix parameters.
1423
type Options func(o *OptionsParams) error
1524

25+
type Merchant struct {
26+
name string
27+
city string
28+
}
29+
1630
type OptionsParams struct {
1731
txId string
1832
pixKey string
1933
description string
2034
amount string
21-
aditionalInfo string
35+
additional string
2236
merchant Merchant
2337
kind PixKind
2438
url string
2539
qrcodeContent string
2640
qrcodeSize int
2741
}
2842

29-
type Merchant struct {
30-
name string
31-
city string
32-
}
33-
34-
func OptQRCodeSize(value int) Options {
35-
return func(o *OptionsParams) error {
36-
o.qrcodeSize = value
37-
return nil
38-
}
39-
}
40-
41-
func OptUrl(value string) Options {
42-
return func(o *OptionsParams) error {
43-
o.url = value
44-
return nil
45-
}
46-
}
47-
48-
func OptAditionalInfo(value string) Options {
49-
return func(o *OptionsParams) error {
50-
o.aditionalInfo = value
51-
return nil
52-
}
53-
}
54-
55-
func OptKind(kind PixKind) Options {
56-
return func(o *OptionsParams) error {
57-
o.kind = kind
58-
return nil
59-
}
60-
}
61-
62-
func OptTxId(id string) Options {
63-
return func(o *OptionsParams) error {
64-
o.txId = id
65-
return nil
66-
}
67-
}
68-
69-
func OptPixKey(pixkey string) Options {
70-
return func(o *OptionsParams) error {
71-
o.pixKey = pixkey
72-
return nil
73-
}
74-
}
75-
76-
func OptDescription(desc string) Options {
77-
return func(o *OptionsParams) error {
78-
o.description = desc
79-
return nil
80-
}
81-
}
82-
83-
func OptMerchantName(name string) Options {
84-
return func(o *OptionsParams) error {
85-
o.merchant.name = name
86-
return nil
87-
}
88-
}
89-
90-
func OptMerchantCity(city string) Options {
91-
return func(o *OptionsParams) error {
92-
o.merchant.city = city
93-
return nil
94-
}
95-
}
96-
97-
func OptAmount(amount string) Options {
98-
return func(o *OptionsParams) error {
99-
o.amount = amount
100-
return nil
101-
}
102-
}
103-
104-
// ------------- getters
105-
106-
func (o *OptionsParams) GetTxId() string {
107-
return o.txId
108-
}
109-
110-
func (o *OptionsParams) GetPixKey() string {
111-
return o.pixKey
112-
}
113-
114-
func (o *OptionsParams) GetDescription() string {
115-
return o.description
116-
}
117-
118-
func (o *OptionsParams) GetMerchantName() string {
119-
return o.merchant.name
120-
}
121-
122-
func (o *OptionsParams) GetMerchantCity() string {
123-
return o.merchant.city
124-
}
125-
126-
func (o *OptionsParams) GetAmount() string {
127-
return o.amount
128-
}
129-
130-
func (o *OptionsParams) GetKind() PixKind {
131-
return o.kind
132-
}
133-
134-
func (o *OptionsParams) GetAditionalInfo() string {
135-
return o.aditionalInfo
136-
}
137-
138-
func (o *OptionsParams) GetUrl() string {
139-
return o.url
140-
}
141-
142-
func (o *OptionsParams) GetQRCodeSize() int {
143-
return o.qrcodeSize
144-
}
145-
146-
func (o *OptionsParams) GetQRCodeContent() string {
147-
return o.qrcodeContent
148-
}
149-
150-
// ------------- setters
151-
152-
func (o *OptionsParams) SetQRCodeContent(value string) {
153-
o.qrcodeContent = value
154-
}
43+
// Functional options (setters)
44+
func OptQRCodeSize(v int) Options {
45+
return func(o *OptionsParams) error { o.qrcodeSize = v; return nil }
46+
}
47+
func OptUrl(v string) Options { return func(o *OptionsParams) error { o.url = v; return nil } }
48+
func OptAdditionalInfo(v string) Options {
49+
return func(o *OptionsParams) error { o.additional = v; return nil }
50+
}
51+
func OptKind(k PixKind) Options { return func(o *OptionsParams) error { o.kind = k; return nil } }
52+
func OptTxId(v string) Options { return func(o *OptionsParams) error { o.txId = v; return nil } }
53+
func OptPixKey(v string) Options { return func(o *OptionsParams) error { o.pixKey = v; return nil } }
54+
func OptDescription(v string) Options {
55+
return func(o *OptionsParams) error { o.description = v; return nil }
56+
}
57+
func OptMerchantName(v string) Options {
58+
return func(o *OptionsParams) error { o.merchant.name = v; return nil }
59+
}
60+
func OptMerchantCity(v string) Options {
61+
return func(o *OptionsParams) error { o.merchant.city = v; return nil }
62+
}
63+
func OptAmount(v string) Options { return func(o *OptionsParams) error { o.amount = v; return nil } }
64+
func (o *OptionsParams) SetQRCodeContent(v string) { o.qrcodeContent = v }
65+
66+
// Getters
67+
func (o *OptionsParams) GetTxId() string { return o.txId }
68+
func (o *OptionsParams) GetPixKey() string { return o.pixKey }
69+
func (o *OptionsParams) GetDescription() string { return o.description }
70+
func (o *OptionsParams) GetMerchantName() string { return o.merchant.name }
71+
func (o *OptionsParams) GetMerchantCity() string { return o.merchant.city }
72+
func (o *OptionsParams) GetAmount() string { return o.amount }
73+
func (o *OptionsParams) GetKind() PixKind { return o.kind }
74+
func (o *OptionsParams) GetAdditionalInfo() string { return o.additional }
75+
func (o *OptionsParams) GetUrl() string { return o.url }
76+
func (o *OptionsParams) GetQRCodeSize() int { return o.qrcodeSize }
77+
func (o *OptionsParams) GetQRCodeContent() string { return o.qrcodeContent }

pix/options_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func TestOptions(t *testing.T) {
3030
}{
3131
{OptQRCodeSize(256), func() interface{} { return params.GetQRCodeSize() }, 256},
3232
{OptUrl("https://example.com"), func() interface{} { return params.GetUrl() }, "https://example.com"},
33-
{OptAditionalInfo("Additional Info"), func() interface{} { return params.GetAditionalInfo() }, "Additional Info"},
33+
{OptAdditionalInfo("Additional Info"), func() interface{} { return params.GetAdditionalInfo() }, "Additional Info"},
3434
{OptKind(DYNAMIC), func() interface{} { return params.GetKind() }, DYNAMIC},
3535
{OptTxId("Transaction123"), func() interface{} { return params.GetTxId() }, "Transaction123"},
3636
{OptPixKey("123456"), func() interface{} { return params.GetPixKey() }, "123456"},

0 commit comments

Comments
 (0)