Closed Juniornewxt closed 1 year ago
Hey @Juniornewxt , here is how it can work:
spec := &MessageSpec{
Fields: map[int]field.Field{
0: field.NewString(&field.Spec{
Length: 4,
Description: "Message Type Indicator",
Enc: encoding.ASCII,
Pref: prefix.ASCII.Fixed,
}),
1: field.NewBitmap(&field.Spec{
Description: "Bitmap",
Enc: encoding.Binary,
Pref: prefix.ASCII.Fixed,
}),
2: field.NewString(&field.Spec{
Length: 19,
Description: "Primary Account Number",
Enc: encoding.ASCII,
Pref: prefix.ASCII.LL,
}),
// TLV
55: field.NewComposite(&field.Spec{
Length: 999,
Description: "ICC Data – EMV Having Multiple Tags",
Pref: prefix.ASCII.LLL,
Tag: &field.TagSpec{
Enc: encoding.BerTLVTag,
Sort: sort.StringsByHex,
},
Subfields: map[string]field.Field{
"9A": field.NewString(&field.Spec{
Description: "Transaction Date",
Enc: encoding.Binary,
Pref: prefix.BerTLV,
}),
"9F02": field.NewString(&field.Spec{
Description: "Amount, Authorized (Numeric)",
Enc: encoding.Binary,
Pref: prefix.BerTLV,
}),
},
}),
},
}
type TestISOF55Data struct {
F9A *field.String
F9F02 *field.String
}
type TestISOData struct {
F2 *field.String
F55 *TestISOF55Data
}
message := NewMessage(spec)
err := message.Marshal(&TestISOData{
F2: field.NewStringValue("4276555555555555"),
F55: &TestISOF55Data{
F9A: field.NewStringValue("210720"),
F9F02: field.NewStringValue("000000000501"),
},
})
// handle err
feel free to re-open the ticket if it doesn't work for you or if you have other questions!
Ok friend, yes, I think I understand, I thought there was another way to do it so I don't have to change a lot of my already done code :) Tks my friend.
You don't have to change a lot of your code, because:
message.Marshal
- it can partially set fields. So, you don't have to define a type for the whole message. You can only define a struct for field55 and its subfields like this:type TestISOF55Data struct {
F9A *field.String
F9F02 *field.String
}
// you can define struct with only one field and populate message with its data
type PartialData struct {
F55 *TestISOF55Data
}
// will update/set only F55 and F9A and F9F02 in the message, the rest of the fields will stay untouched
err := message.Marshal(&PartialData{
F55: &TestISOF55Data{
F9A: field.NewStringValue("210720"),
F9F02: field.NewStringValue("000000000501"),
},
})
message.BinaryField(55, val)
Here is the code:
f55Spec := field.NewComposite(&field.Spec{
Length: 999,
Description: "ICC Data – EMV Having Multiple Tags",
Pref: prefix.ASCII.LLL,
Tag: &field.TagSpec{
Enc: encoding.BerTLVTag,
Sort: sort.StringsByHex,
},
Subfields: map[string]field.Field{
"9A": field.NewString(&field.Spec{
Description: "Transaction Date",
Enc: encoding.Binary,
Pref: prefix.BerTLV,
}),
"9F02": field.NewString(&field.Spec{
Description: "Amount, Authorized (Numeric)",
Enc: encoding.Binary,
Pref: prefix.BerTLV,
}),
},
})
// we can create composite filed like this
f55 := field.NewComposite(f55Spec)
type TestISOF55Data struct {
F9A *field.String
F9F02 *field.String
}
// and set value only of this field
err := f55.Marshal(&TestISOF55Data{
F9A: field.NewStringValue("210720"),
F9F02: field.NewStringValue("000000000501"),
})
// handle err
// get binary value of the field
rawValue, err := f55.Pack()
// handle err
// use message method to set field value
err = message.BinaryField(55, rawValue)
// handle er
Now I got it, but I'm testing it for a local flag here that is very similar to Visa, it doesn't seem to me that the bit55 formatted correctly, because I can't find the size of the field in the message, see that it says Visa:
This field 55 VSDC chip data usage contains three subfields after the length subfield. Positions: 1 2–3 4–255 Subfield 1: length Subfield 2: dataset ID Subfield 3: dataset length Subfield 4: Chip Card TLV data elements Tag Length Value Tag Length Value
TLV1 TLVN
Byte 1 Byte 2 Byte 3–4 Byte 5–256 Length Subfield: This is a one-byte binary subfield that contains the number of bytes in this field after the length subfield. Position 1, Dataset ID: This is a one-byte binary identifier given to each dataset. The identifier is hexadecimal 01. Positions 2–3, Dataset Length: This is a 2-byte binary subfield that contains the total length of all TLV elements that follow.
That will take more time for me to check and come up with a code example :(
Created sample code with above spec
Hello friends, I was reading the code, but I didn't find a practical way to generate the bit55 ISO, can you help me?
How would it look in the example below?
"9A" = 220911 "9F02" = 000000000001
...... func NewSpec() *iso8583.MessageSpec { return &iso8583.MessageSpec{ Fields: map[int]field.Field{ 0: field.NewString(&field.Spec{ Length: 4, Description: "MTI", Enc: encoding.Binary, Pref: prefix.ASCII.Fixed, }), 1: field.NewBitmap(&field.Spec{ Description: "Bitmap", Enc: encoding.BytesToASCIIHex, Pref: prefix.Hex.Fixed, }), 2: field.NewString(&field.Spec{ Length: 16, Description: "PAN ", Enc: encoding.ASCII, Pref: prefix.ASCII.LL, }), 55: field.NewComposite(&field.Spec{ Length: 999, Description: "ICC Data – EMV Having Multiple Tags", Pref: prefix.ASCII.LLL, Tag: &field.TagSpec{ Enc: encoding.BerTLVTag, Sort: sort.StringsByHex, }, Subfields: map[string]field.Field{ "9A": field.NewString(&field.Spec{ Description: "Transaction Date", Enc: encoding.Binary, Pref: prefix.BerTLV, }), "9F02": field.NewString(&field.Spec{ Description: "Amount, Authorized (Numeric)", Enc: encoding.Binary, Pref: prefix.BerTLV, }), }, }), .............. message.Field(2, "4116090000000000") message.Field(55, "220911000000000001") ............. Tks !