doSale method
Future<Map<String, dynamic> >
doSale({
- required BuildContext context,
- required double amount,
- String? traceNO,
override
transaction do sale
Implementation
@override
Future<Map<String, dynamic>> doSale({
required BuildContext context,
required double amount,
String? traceNO,
}) async {
NavigatorState navigator = Navigator.of(context);
String traceNumber = traceNO ?? await traceNo();
String amountStr = amount.toStringAsFixed(2);
Map<String, dynamic> cardRet =
await cardRead(amount: amountStr, tranType: 1, traceNo: traceNumber);
if (cardRet["code"] == 0) {
String? emv = cardRet["emv"];
String? track2 = cardRet["track2"];
int? detectType = cardRet["detect_type"];
if (emv != null && track2 != null) {
DataInitRet? initData = await _storage.initData;
DownloadKeyRet? keyRet = await _storage.downloadKey;
String tdk = "${keyRet?.tdk}";
String tpk = "${keyRet?.tpk}";
String merchantName = initData?.merchantName ?? "";
String terminalId = initData?.terminalId ?? "";
String merchantId = initData?.merchantId ?? "";
String netEncKey = DtbLinkCrypto.decrypt("${initData?.netEncKey}");
// PIN required condition
String? encryptedPin;
if (detectType == 3 || amount > 50000.0) {
final result = await navigator.push(
MaterialPageRoute(
builder: (context) => PinCodeScreen(
amount: amount,
onConfirm: (pinCode) {
navigator.pop({
"result": true,
"pin": pinCode,
});
},
onCancel: () {
navigator.pop({
"result": false,
});
},
),
),
);
if (result != null && result["result"] == true) {
encryptedPin = result["pin"];
} else {
return {
"status_code": "ng",
"msg": Msg(code: "126", body: "ПИН боловсруулахад алдаа гарлаа.")
.toJson(),
};
}
}
final saleBuildResp = await _doSaleBuild(
entryMode: detectType == 3 ? "chip" : "",
amount: amountStr,
traceNo: traceNumber,
track2: track2,
emv: emv,
tdk: tdk,
tpk: tpk,
terminalId: terminalId,
merchantId: merchantId,
merchantName: merchantName,
netEncKey: netEncKey,
pin: encryptedPin ?? "",
);
if (saleBuildResp["status_code"] == "ng") {
return saleBuildResp;
}
String dbRefNo = saleBuildResp["db_ref_no"];
Map<String, dynamic> bodySale = {
"db_ref_no": dbRefNo,
"service_data": saleBuildResp["service_data"],
"terminal_id": saleBuildResp["terminal_id"],
};
String entryMode = '${saleBuildResp["entry_mode"]}';
String entryModeText = '${saleBuildResp["entry_mode_text"]}';
String reqID = "";
ApiResponse<EncApiRet> apiResp = await DtbLinkNet.instance.request(
method: Method.post,
path: "/v1/sale",
prefix: "sale tran",
body: json.encode(bodySale),
onRespHeader: (Map<String, String> headers) {
reqID = headers["request-id"] ?? reqID;
},
fromJson: (dynamic ret) => EncApiRet.fromJson(ret),
timeOut: const Duration(seconds: 20),
);
if (apiResp.statusCode == "ng") {
return apiResp.toJson();
}
EncApiRet? encApiRet = apiResp.ret;
final parseSaleResp = await _saleParse(
isoData: "${encApiRet?.isoData}",
track2: track2,
tdk: tdk,
netEncKey: netEncKey,
);
parseSaleResp.putIfAbsent("request_id", () => reqID);
parseSaleResp.putIfAbsent(
"db_ref_no", () => saleBuildResp["db_ref_no"]);
if (parseSaleResp["resp_code"] == "000") {}
final f55 = parseSaleResp["f55"];
if (f55 != null && f55.isNotEmpty) {
final respF55 = await _finishTran(f55);
_log('respF55: $respF55');
}
String dayTime = tranDateFormatter.format(DateTime.now());
final regParse = await _registerTran(
operation: "SALE",
reqId: reqID,
amountStr: amountStr,
traceNo: traceNumber,
dbRefNo: dbRefNo,
entryMode: entryMode,
entryModeText: entryModeText,
terminalId: terminalId,
merchantId: merchantId,
merchantName: merchantName,
netEncKey: netEncKey,
dayTime: dayTime,
parseMap: parseSaleResp,
);
_log('regParse: $regParse');
await _apiComplete(
traceNo: traceNumber,
dbRefNo: dbRefNo,
terminalId: terminalId,
netEncKey: netEncKey,
);
return {"status_code": "ok", "ret": parseSaleResp};
} else {
cardRet.putIfAbsent("msg", () => "Card not read");
return cardRet;
}
} else {
cardRet.putIfAbsent("msg", () => "Card not read");
return cardRet;
}
}