public static string BuildQRCodeValue(long amount, string accountToPresent, string trackingId) { try { QRDEList listIn = new QRDEList(); listIn.AddToList(QRDE.Create(EMVQRTagsEnum.PAYLOAD_FORMAT_INDICATOR_00, "01")); listIn.AddToList(QRDE.Create(EMVQRTagsEnum.POINT_OF_INITIATION_METHOD_01, "12")); QRDE _26 = QRDE.Create(EMVQRTagsEnum.MERCHANT_ACCOUNT_INFORMATION_TEMPLATE_26); QRDE.Create(EMVQRTagsEnum.GLOBALLY_UNIQUE_IDENTIFIER_00, accountToPresent, _26); EMVQRTagsEnum.CreateUnknown(TagId._05, trackingId, _26); //tracking id listIn.AddToList(_26); //listIn.AddToList(QRDE.Create(EMVQRTagsEnum.MERCHANT_CATEGORY_CODE_52, "4111")); //listIn.AddToList(QRDE.Create(EMVQRTagsEnum.COUNTRY_CODE_58, "CN")); listIn.AddToList(QRDE.Create(EMVQRTagsEnum.TRANSACTION_AMOUNT_54, Convert.ToString(amount))); //listIn.AddToList(QRDE.Create(EMVQRTagsEnum.TRANSACTION_CURRENCY_53, "156")); listIn.AddToList(QRDE.Create(EMVQRTagsEnum.CRC_63, "0000")); return(listIn.Serialize()); } catch (Exception ex) { Logger.Log(ex.Message); return(string.Empty); } }
public void StartTransactionRequest(ref TransactionRequest tr, string barcodeValue) { //unpack barcode QRDEList listOut = new QRDEList(); listOut.Deserialize(barcodeValue); int depth = 0; Logger.Log("Barcode Scanned:"); Logger.Log(listOut.ToPrintString(ref depth)); long amount = Convert.ToInt64(listOut.Get(EMVQRTagsEnum.TRANSACTION_AMOUNT_54.Tag).Value); long amountOther = 0; tr = new TransactionRequest(amount + amountOther, amountOther, TransactionTypeEnum.PurchaseGoodsAndServices); EMVTerminalProcessingOutcome processingOutcome = new EMVTerminalProcessingOutcome() { NextProcessState = EMVTerminalPreProcessingStateEnum.EndProcess, UIRequestOnOutcomePresent = false, UIRequestOnRestartPresent = false, QRData = listOut, }; OnProcessCompleted(processingOutcome); }
public void StartTransactionRequest(TransactionRequest tr, string barcodeValue) { //add tracking id QRDEList listOut = new QRDEList(); listOut.Deserialize(barcodeValue); int depth = 0; Logger.Log("Barcode Presented:"); Logger.Log(listOut.ToPrintString(ref depth)); EMVTerminalProcessingOutcome processingOutcome = new EMVTerminalProcessingOutcome() { NextProcessState = EMVTerminalPreProcessingStateEnum.EndProcess, UIRequestOnOutcomePresent = false, UIRequestOnRestartPresent = false, QRData = listOut, }; OnProcessCompleted(processingOutcome); }
private async void EmvTxCtl_TxCompleted(object sender, EventArgs e) { try { TransactionType transactionType; string fromAccountNumber = ""; string cardSerialNumberFrom = ""; string toAccountNumber = ""; string cardSerialNumberTo = ""; if ((e as TxCompletedEventArgs).EMV_Data.IsPresent()) { if ((e as TxCompletedEventArgs).TxResult == TxResult.Approved || (e as TxCompletedEventArgs).TxResult == TxResult.ContactlessOnline) { TLV data = (e as TxCompletedEventArgs).EMV_Data.Get(); byte[] panBCD; TLV _5A = data.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag); if (_5A != null) { panBCD = _5A.Value; } else { TLV _57 = data.Children.Get(EMVTagsEnum.TRACK_2_EQUIVALENT_DATA_57_KRN.Tag); if (_57 == null) { throw new Exception("No PAN found"); } String panString = Formatting.ByteArrayToHexString(_57.Value); panBCD = Formatting.StringToBcd(panString.Split('D')[0], false); } TLV _9F02 = data.Children.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag); if (_9F02 == null) { throw new Exception("No Amount found"); } long amount = Formatting.BcdToLong(_9F02.Value); switch (flowType) { case FlowType.SendMoneyFromCardToApp: toAccountNumber = SessionSingleton.Account.AccountNumberId; cardSerialNumberFrom = Formatting.BcdToString(panBCD); transactionType = TransactionType.SendMoneyFromCardToApp; break; case FlowType.SendMoneyFromAppToCard: fromAccountNumber = SessionSingleton.Account.AccountNumberId; cardSerialNumberTo = Formatting.BcdToString(panBCD); transactionType = TransactionType.SendMoneyFromAppToCard; break; default: throw new Exception("Unknown flow type:" + flowType); } try { await CallTransactByCardWebService(fromAccountNumber, toAccountNumber, cardSerialNumberFrom, cardSerialNumberTo, amount, transactionType, data); Device.BeginInvokeOnMainThread(() => { lblTransactSummary.Text = "Transaction Completed Succesfully"; UpdateView(ViewState.StepSummary); }); } catch { Device.BeginInvokeOnMainThread(() => { lblTransactSummary.Text = "Declined, could not go online."; UpdateView(ViewState.StepSummary); }); } } else { Device.BeginInvokeOnMainThread(() => { lblTransactSummary.Text = (e as TxCompletedEventArgs).TxResult.ToString(); UpdateView(ViewState.StepSummary); }); } } else if ((e as TxCompletedEventArgs).QR_Data.IsPresent()) { QRDEList data = (e as TxCompletedEventArgs).QR_Data.Get(); QRDE _26 = data.Get(EMVQRTagsEnum.MERCHANT_ACCOUNT_INFORMATION_TEMPLATE_26.Tag); QRDE _54 = data.Get(EMVQRTagsEnum.TRANSACTION_AMOUNT_54.Tag); QRDE gui = _26.Children.Get(EMVQRTagsEnum.GLOBALLY_UNIQUE_IDENTIFIER_00.Tag); QRDE tracking = _26.Children.Get(TagId._05); long amount = Convert.ToInt64(_54.Value); if ((e as TxCompletedEventArgs).TxResult == TxResult.QRCodeScanned) { switch (flowType) { case FlowType.SendMoneyFromCardToApp: throw new Exception("Invalid flow type for Scanned QR code"); case FlowType.SendMoneyFromAppToCard: fromAccountNumber = SessionSingleton.Account.AccountNumberId; toAccountNumber = gui.Value; transactionType = TransactionType.SendMoneyFromAppToCard; break; default: throw new Exception("Unknown flow type:" + flowType); } try { await CallTransactByQRCodeWebService(fromAccountNumber, toAccountNumber, amount, tracking.Value); Device.BeginInvokeOnMainThread(() => { lblTransactSummary.Text = "Transaction Completed Succesfully"; UpdateView(ViewState.StepSummary); }); } catch (Exception ex) { Device.BeginInvokeOnMainThread(() => { lblTransactSummary.Text = "Declined, could not go online."; UpdateView(ViewState.StepSummary); }); } } else if ((e as TxCompletedEventArgs).TxResult == TxResult.QRCodeToPoll) { switch (flowType) { case FlowType.SendMoneyFromCardToApp: break; case FlowType.SendMoneyFromAppToCard: throw new Exception("Invalid flow type for QR code"); default: throw new Exception("Unknown flow type:" + flowType); } try { bool success = await CallTransactGetStateWebService(tracking.Value); //bool success = await CallTransactGetStateWebService("929fa290b20647988f72f2ca762bc3e7"); if (success) { Device.BeginInvokeOnMainThread(() => { lblTransactSummary.Text = "Transaction Approved"; UpdateView(ViewState.StepSummary); }); } else { Device.BeginInvokeOnMainThread(() => { App.Current.MainPage.DisplayAlert("Info", "Transaction not found, try again if you believe the transaction was approved", "OK"); }); } } catch { Device.BeginInvokeOnMainThread(() => { App.Current.MainPage.DisplayAlert("Info", "Unknown, there is no connectivity to the server, try again if you believe the tx was approved", "OK"); }); } } else { Device.BeginInvokeOnMainThread(() => { lblTransactSummary.Text = (e as TxCompletedEventArgs).TxResult.ToString(); UpdateView(ViewState.StepSummary); }); } } else { Device.BeginInvokeOnMainThread(() => { lblTransactSummary.Text = "Declined"; UpdateView(ViewState.StepSummary); }); } } catch (Exception ex) { Device.BeginInvokeOnMainThread(() => { lblTransactSummary.Text = ex.Message; UpdateView(ViewState.StepSummary); }); } }
private void ProcessCompletion(TerminalProcessingOutcomeEventArgs e, InterFaceType interFaceType) { TLV data = null; TLV discretionaryData = null; QRDEList qrData = null; try { long?amount = Convert.ToInt64(totalAmount.Total); TerminalProcessingOutcome tpo = e.TerminalProcessingOutcome; if (tpo == null)//error occurred, error displayed via Ta_ExceptionOccured { return; } if (tpo is EMVTerminalProcessingOutcome) { data = ((EMVTerminalProcessingOutcome)tpo).DataRecord; discretionaryData = ((EMVTerminalProcessingOutcome)tpo).DiscretionaryData; qrData = ((EMVTerminalProcessingOutcome)tpo).QRData; if (data != null) //error { SetStatusLabel(new UIMessageEventArgs(MessageIdentifiersEnum.RemoveCard, StatusEnum.EndProcessing), interFaceType); //may be a contactless magstripe transaction if (data.Children.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag) == null) { txResult = TxResult.ContactlessMagOnline; } else { if (((data.Children.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag).Value[0] & 0xC0) >> 6) == (byte)ACTypeEnum.ARQC) { if (interFaceType == InterFaceType.Contact) { throw new EMVProtocolException("Invalid state for contact, gen ac 2 returned arqc?"); } CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(data.Children.Get(EMVTagsEnum.CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN.Tag)); if (cvmr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline) { ContactlessApp_PinRequest(data.Children); } txResult = TxResult.ContactlessOnline; } if (((data.Children.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag).Value[0] & 0xC0) >> 6) == (byte)ACTypeEnum.TC) { txResult = TxResult.Approved; } if (((data.Children.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag).Value[0] & 0xC0) >> 6) == (byte)ACTypeEnum.AAC) { txResult = TxResult.Declined; } } } else if (qrData != null) { if (interFaceType == InterFaceType.QRCodeScanned) { txResult = TxResult.QRCodeScanned; } else if (interFaceType == InterFaceType.QRCodeToPoll) { txResult = TxResult.QRCodeToPoll; } } else { txResult = TxResult.Declined; } SetTxFinalResultLabel(txResult.ToString()); } else { SetStatusLabel(new UIMessageEventArgs(tpo.UserInterfaceRequest.MessageIdentifier, tpo.UserInterfaceRequest.Status), interFaceType); } } catch (Exception ex) { Device.BeginInvokeOnMainThread(() => { UIMessageEventArgs ui = new UIMessageEventArgs(MessageIdentifiersEnum.TryAgain, StatusEnum.ProcessingError) { AdditionalMessage = ex.Message }; SetStatusLabel(ui, interFaceType); }); } finally { StopContactPaymentApp(); StopContactlessPaymentApp(); StopQRCodePollPaymentApp(); #region Merge EMV Lists if (discretionaryData != null) { if (data != null) { data.Children.AddListToList(discretionaryData.Children); } } #endregion TxCompleted?.Invoke(this, new TxCompletedEventArgs(txResult, interFaceType, Optional <TLV> .Create(data), Optional <QRDEList> .Create(qrData))); } }