Skip to content

Commit

Permalink
More fields added.
Browse files Browse the repository at this point in the history
  • Loading branch information
xclud committed Jun 19, 2024
1 parent 510fd2d commit 3b5e73b
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 50 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
## 0.3.8

* More fields added.

## 0.3.7

* Pin Block, Card Entry Mode and POS Condition Code fields added.

## 0.3.6

* Data Element (DE) for field 48.
Expand Down
1 change: 0 additions & 1 deletion lib/pos.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import 'dart:convert';
import 'dart:typed_data';

import 'package:convert/convert.dart';
import 'package:iso9797/iso9797.dart' as iso9797;

part 'src/bitmap.dart';
part 'src/data_element.dart';
Expand Down
111 changes: 83 additions & 28 deletions lib/src/message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,8 @@ class Message {
final x = Message('0300');
final now = dateTime ?? DateTime.now().toLocal();

final am = amount.toString().padLeft(12, '0');
final amb = hex.decode(am);

x.processCode = 0x000000;
x.set(4, amb);
x.amount = amount;
x.dateTime = now;

x.posConditionCode = 0x14;
Expand Down Expand Up @@ -130,6 +127,27 @@ class Message {
/// Clones the message into a new instance.
Message clone() {
final copy = Message(mti);

final f52PinBlock = _f52PinBlock;

copy._f02Pan = _f02Pan;
copy._f03ProcessCode = _f03ProcessCode;
copy._f04Amount = _f04Amount;
copy._f11Stan = _f11Stan;
copy._f1213DateTime = _f1213DateTime;
copy._f22CardEntryMode = _f22CardEntryMode;
copy._f24Nii = _f24Nii;
copy._f25POSConditionCode = _f25POSConditionCode;
copy._f35Track2 = _f35Track2;
copy._f41TerminalId = _f41TerminalId;
copy._f42MerchantId = _f42MerchantId;
copy._f48DataElement = _f48DataElement;
copy._f49Currency = _f49Currency;
copy._f52PinBlock =
f52PinBlock == null ? null : Uint8List.fromList(f52PinBlock);
copy._mac = _mac;

copy._bmp.addAll(_bmp);
copy._data.addAll(_data);

return copy;
Expand Down Expand Up @@ -178,26 +196,25 @@ class Message {

/// Encodes a [Message] object to a [Uint8List]. Optionally adds MAC to the field 64.
Uint8List encode({Uint8List Function(List<int> message)? algorithm}) {
if (algorithm != null) {
final y = calcmac(algorithm);
final alg = algorithm;

mac = hex.encode(y).toUpperCase();
}
final fmac = alg != null ? calcmac(alg) : Uint8List(8);

final bdy = _body();
final bmp = _bitmap();
final mt = Uint8List.fromList(hex.decode(mti));

final xx = mt + bmp + bdy;
final xx = mt + bmp + bdy + fmac;
return Uint8List.fromList(xx);
}

String? _f02Pan;
int? _f03ProcessCode;
int? _f04Amount;
int? _f11Stan;
DateTime? _f1213DateTime;
int? _f22CardEntryMode;
String? _f24Nii;
int? _f24Nii;
int? _f25POSConditionCode;
String? _f35Track2;
String? _f41TerminalId;
Expand All @@ -206,7 +223,7 @@ class Message {
int? _f49Currency;

List<int>? _f52PinBlock;
String? _mac;
List<int>? _mac;

/// PAN, the Card Number.
/// Field 2.
Expand Down Expand Up @@ -252,6 +269,28 @@ class Message {
}
}

/// Amount.
/// Field 4.
///
/// Must be null or > 0.',
int? get amount => _f04Amount;
set amount(int? value) {
final v = value;

assert(
v == null || v > 0,
'Amout should be null or > 0.',
);

if (v == null) {
_bmp[4] = false;
_f04Amount = null;
} else {
_bmp[4] = true;
_f04Amount = value;
}
}

/// Stan.
/// Field 11.
///
Expand Down Expand Up @@ -302,7 +341,7 @@ class Message {

assert(
v == null || v > -1 || v < 0xffff,
'CardEntryMode should be null or between [0x00, 0xFFFF].',
'CardEntryMode should be null or between [0x0000, 0xFFFF].',
);

if (v == null) {
Expand All @@ -317,14 +356,14 @@ class Message {
/// NII.
/// Field 24.
///
/// Must be 4 characters.
String? get nii => _f24Nii;
set nii(String? value) {
/// Must be betweem [0x0000, 0xFFFF] characters.
int? get nii => _f24Nii;
set nii(int? value) {
final v = value;

assert(
v == null || v.length == 4,
'NII should be null or 4 characters long.',
v == null || v > -1 || v < 0xffff,
'NII should be null or between [0x0000, 0xFFFF].',
);

if (v == null) {
Expand Down Expand Up @@ -462,13 +501,13 @@ class Message {
/// Field 64 or 128.
///
/// Must be 16 characters.
String? get mac => _mac;
set mac(String? value) {
List<int>? get mac => _mac;
set mac(List<int>? value) {
final v = value;

assert(
v == null || v.length == 16,
'MAC should be null or 16 characters long.',
v == null || v.length == 8,
'MAC should be null or 8 bytes.',
);

if (v == null) {
Expand All @@ -484,7 +523,7 @@ class Message {
final bits = <List<int>>[];
final strBits = <String>[];

for (var i = 1; i <= 64; i++) {
for (var i = 1; i < 64; i++) {
if (i == 2) {
final p = pan;

Expand Down Expand Up @@ -514,6 +553,18 @@ class Message {
strBits.add(h3);
}

continue;
} else if (i == 4) {
final p = amount;

if (p != null) {
final amountPadded = amount.toString().padLeft(12, '0');
final amb = hex.decode(amountPadded);

bits.add(amb);
strBits.add(amountPadded);
}

continue;
} else if (i == 11) {
final p = stan;
Expand Down Expand Up @@ -591,10 +642,14 @@ class Message {
final p = _f24Nii;

if (p != null) {
final f2 = hex.decode(p);
bits.add(f2);
final bt = ByteData(2);
bt.setUint16(0, p, Endian.big);

strBits.add(p);
final f24 = bt.buffer.asUint8List();
final s24 = hex.encode(f24);

bits.add(f24);
strBits.add(s24);
}

continue;
Expand Down Expand Up @@ -670,8 +725,8 @@ class Message {
final p = mac;

if (p != null) {
bits.add(hex.decode(p));
strBits.add(p);
bits.add(p);
strBits.add(hex.encode(p));
}

continue;
Expand Down Expand Up @@ -726,7 +781,7 @@ class Message {
/// Calculates the MAC for current [Message].
Uint8List calcmac(Uint8List Function(List<int> message) algorithm) {
final c = clone();
c.mac = '0000000000000000';
c.mac = Uint8List(8);
final bmp = c._bitmap();
c.mac = null;

Expand Down
18 changes: 0 additions & 18 deletions lib/src/private.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,3 @@
part of '../pos.dart';

final _json = JsonEncoder.withIndent(' ');

/// Mac algorithm for 6th bit.
String iso9797MacAlgorithm3String(Uint8List key, Uint8List message) {
if (message.length % 8 != 0) {
final copyOfData = message.toList();
while (copyOfData.length % 8 != 0) {
copyOfData.add(0);
}

message = Uint8List.fromList(copyOfData);
}

final mac = iso9797.algorithm3(key, message, iso9797.PaddingMode.method1);
final macU = mac.map((e) => e.toRadixString(16)).join().toUpperCase();

final result = macU.codeUnits.take(8).map((e) => e.toRadixString(16)).join();
return result;
}
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
name: pos
description: Dart Implementation of the ISO-8583 banking protocol for Point of Sale (POS) Devices.
version: 0.3.7
version: 0.3.8
repository: https://github.com/xclud/dart_pos
homepage: https://pwa.ir

environment:
sdk: ">=2.12.0 <4.0.0"

dependencies:
iso9797: ^0.0.2
iso9797: ^0.0.5
convert: ^3.1.1

dev_dependencies:
Expand Down

0 comments on commit 3b5e73b

Please sign in to comment.