public string AuthTransactionToIssuer(string json) { ContactCardOnlineAuthRequest request = ContactCardOnlineAuthRequest.FromJsonString(json); ContactCardOnlineAuthResponse response = new ContactCardOnlineAuthResponse(); try { EMVApproverResponse onlineResponse = GoOnline( new EMVApproverRequest() { EMV_Data = TLVasJSON.Convert(request.EMV_Data), }); response.AuthCode_8A = TLVasJSON.Convert(onlineResponse.AuthCode_8A); response.IssuerAuthData_91 = TLVasJSON.Convert(onlineResponse.IssuerAuthData_91); response.ResponseMessage = onlineResponse.ResponseMessage; if (onlineResponse.IsApproved) { response.Response = ContactCardOnlineAuthResponseEnum.Approved; } else { response.Response = ContactCardOnlineAuthResponseEnum.Declined; } return(JsonConvert.ToString(response.ToJsonString())); } catch (Exception ex) { response.Response = ContactCardOnlineAuthResponseEnum.UnableToGoOnline; Logger.Log("Unable to go online:" + ex.Message); return(JsonConvert.ToString(response.ToJsonString())); } }
private async Task CallTopUpWebService(string toAccountNumber, long?amount, string cvv, TLV emvData) { Device.BeginInvokeOnMainThread(() => { gridProgress.IsVisible = true; }); try { Proxies.DCEMVDemoServerClient client = SessionSingleton.GenDCEMVServerApiClient(); using (SessionSingleton.HttpClient) { CCTopUpTransaction tx = new CCTopUpTransaction() { Amount = amount.Value, CVV = cvv, EMV_Data = TLVasJSON.ToJSON(emvData), }; await client.TransactionTopupPostAsync(tx.ToJsonString()); } } catch (Exception ex) { throw ex; } finally { Device.BeginInvokeOnMainThread(() => { gridProgress.IsVisible = false; }); } }
public void TopUp(string json) { CCTopUpTransaction tx = CCTopUpTransaction.FromJsonString(json); if (tx.Amount == 0) { throw new ValidationException("Invalid Amount"); } if (string.IsNullOrEmpty(tx.CVV)) { throw new ValidationException("Invalid CVV"); } CCTopUpTransactionPM tpm = new CCTopUpTransactionPM() { Amount = tx.Amount, CVV = tx.CVV, EMV_Data = tx.EMV_Data }; TLV EMV_Data = TLVasJSON.FromJSON(tpm.EMV_Data); //TODO: only accept transactions from EMV cards, not DC EMV cards //TODO: reject contact transactions, with ARQC, contact would have already been online via //AuthTransactionToIssuer //contactless online //if (((EMV_Data.Children.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag).Value[0] & 0xC0) >> 6) == (byte)ACTypeEnum.ARQC) //{ // try // { // ApproverResponse onlineResponse = GoOnline( // new ApproverRequest() // { // EMV_Data = EMV_Data, // }); // if (!onlineResponse.IsApproved) // { // throw new ValidationException("Contactless Online Auth Declined"); // } // } // catch (Exception ex) // { // throw new ValidationException("Contactless Online Auth Declined, Unable to go online:" + ex.Message); // } //} bool isAccepted = AdviseTransactionToIssuer(); if (!isAccepted) { throw new ValidationException("Advice Message not accepted"); } _transactionRepository.AddTopUpTransaction(tpm, GetCurrentUserId()); }
private ApproverResponseBase DoEMVAuth(ApproverRequestBase requestIn) { try { EMVApproverRequest request = ((EMVApproverRequest)requestIn); DCEMVDemoServerClient client = SessionSingleton.GenDCEMVServerApiClient(); using (SessionSingleton.HttpClient) { ContactCardOnlineAuthRequest tx = new ContactCardOnlineAuthRequest() { EMV_Data = TLVasJSON.Convert(request.EMV_Data), }; string responseJson = ""; Task.Run(async() => { responseJson = await client.TransactionAuthtransactiontoissuerPostAsync(tx.ToJsonString()); }).Wait(); ContactCardOnlineAuthResponse response = ContactCardOnlineAuthResponse.FromJsonString(responseJson); EMVApproverResponse approverResponse = null; switch (response.Response) { case ContactCardOnlineAuthResponseEnum.Approved: case ContactCardOnlineAuthResponseEnum.Declined: approverResponse = new EMVApproverResponse(); approverResponse.AuthCode_8A = TLVasJSON.Convert(response.AuthCode_8A); approverResponse.IssuerAuthData_91 = TLVasJSON.Convert(response.IssuerAuthData_91); approverResponse.IsApproved = response.Response == ContactCardOnlineAuthResponseEnum.Approved ? true : false; approverResponse.ResponseMessage = response.ResponseMessage; break; case ContactCardOnlineAuthResponseEnum.UnableToGoOnline: break; } return(approverResponse); } } catch { return(null); } }
private async void EmvTxCtl_TxCompleted(object sender, EventArgs e) { try { if ((e as TxCompletedEventArgs).EMV_Data.IsPresent()) { TLV data = (e as TxCompletedEventArgs).EMV_Data.Get(); string emvData = TLVasJSON.ToJSON(data); string uid = Formatting.BcdToString(data.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag).Value); await RegisterCard(SessionSingleton.Account.AccountNumberId, uid); Device.BeginInvokeOnMainThread(() => { SessionSingleton.Account.Cards.Add(new Card() { CardSerialNumberId = uid, }); lblStatusCard.Text = string.Format("Card {0} linked", uid); UpdateView(CardAdminViewState.CardAddStatus); }); } else { lblStatusCard.Text = "Card not linked"; UpdateView(CardAdminViewState.CardAddStatus); } } catch (Exception ex) { Device.BeginInvokeOnMainThread(() => { UpdateView(CardAdminViewState.CardAddStatus); lblStatusCard.Text = ex.Message; }); } }
private async Task CallPosTransactWebService(string fromAccountNumber, string toAccountNumber, string cardSerialNumberFrom, string cardSerialNumberTo, long?amount, TransactionType transactionType, TLV emvData) { Device.BeginInvokeOnMainThread(() => { gridProgress.IsVisible = true; }); try { Proxies.DCEMVDemoServerClient client = SessionSingleton.GenDCEMVServerApiClient(); using (SessionSingleton.HttpClient) { POSTransaction posTx = new POSTransaction(); posTx.InvItems = ConvertLineItems(basketItems.ToList()); CardTransferTransaction tx = new CardTransferTransaction() { Amount = amount.Value, AccountFrom = fromAccountNumber, AccountTo = toAccountNumber, CardSerialFrom = cardSerialNumberFrom, CardSerialTo = cardSerialNumberTo, CardFromEMVData = TLVasJSON.ToJSON(emvData), }; await client.StoreSalebycardPostAsync(tx.ToJsonString(), posTx.ToJsonString()); } } catch (Exception ex) { throw ex; } finally { Device.BeginInvokeOnMainThread(() => { gridProgress.IsVisible = false; }); } }
public void CardTransfer(string json) { CardTransferTransaction tx = CardTransferTransaction.FromJsonString(json); if (tx.Amount == 0) { throw new ValidationException("Invalid Amount"); } TLV tlv = TLVasJSON.FromJSON(tx.CardFromEMVData); byte[] arpc = VerifyCardSignature(tlv); if (arpc == null) { throw new ValidationException("ARQC failure"); } //TODO: only accept transactions from DC EMV cards, not EMV cards switch (tx.TransactionType) { case TransactionType.SendMoneyFromAppToCard: if (!Validate.GuidValidation(tx.AccountFrom)) { throw new ValidationException("Invalid AccountNumberFrom"); } if (String.IsNullOrEmpty(tx.CardSerialTo)) { throw new ValidationException("Invalid CardSerialNumberTo"); } if (!String.IsNullOrEmpty(tx.AccountTo)) { throw new ValidationException("Invalid AccountNumberTo"); } if (!String.IsNullOrEmpty(tx.CardSerialFrom)) { throw new ValidationException("Invalid CardSerialNumberFrom"); } break; case TransactionType.SendMoneyFromCardToApp: if (!String.IsNullOrEmpty(tx.AccountFrom)) { throw new ValidationException("Invalid AccountNumberFrom"); } if (!String.IsNullOrEmpty(tx.CardSerialTo)) { throw new ValidationException("Invalid CardSerialNumberTo"); } if (!Validate.GuidValidation(tx.AccountTo)) { throw new ValidationException("Invalid AccountNumberTo"); } if (String.IsNullOrEmpty(tx.CardSerialFrom)) { throw new ValidationException("Invalid CardSerialNumberFrom"); } break; default: throw new ValidationException("Invalid transaction type: " + tx.TransactionType); } TransactionPM tpm = new TransactionPM() { Amount = tx.Amount, TransactionType = tx.TransactionType, AccountNumberIdFromRef = tx.AccountFrom, AccountNumberIdToRef = tx.AccountTo, CardSerialNumberIdFrom = tx.CardSerialFrom, CardSerialNumberIdTo = tx.CardSerialTo, CardFromEMVData = tx.CardFromEMVData }; _transactionRepository.AddCardBasedTransaction(tpm, GetCurrentUserId()); }
public void AddCardBasedPOSTransaction(string jsonTx, string jsonPosTx) { CardTransferTransaction transaction = CardTransferTransaction.FromJsonString(jsonTx); POSTransaction posDetail = POSTransaction.FromJsonString(jsonPosTx); if (transaction.Amount == 0) { throw new ValidationException("Invalid Amount"); } //TODO: make sure data in EMV matches duplicate data fields in transaction TLV tlv = TLVasJSON.FromJSON(transaction.CardFromEMVData); TLV _9F02 = tlv.Children.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag); long emvAmount = FormattingUtils.Formatting.BcdToLong(_9F02.Value); if (transaction.Amount != emvAmount) { throw new ValidationException("Invalid Amount: Card does not match Cryptogram"); } if (TransactionController.VerifyCardSignature(tlv) == null) { throw new ValidationException("Invalid Cryptogram"); } transaction.TransactionType = TransactionType.SendMoneyFromCardToApp; switch (transaction.TransactionType) { case TransactionType.SendMoneyFromCardToApp: if (!String.IsNullOrEmpty(transaction.AccountFrom)) { throw new ValidationException("Invalid AccountNumberFrom"); } if (!String.IsNullOrEmpty(transaction.CardSerialTo)) { throw new ValidationException("Invalid CardSerialNumberTo"); } if (!Validate.GuidValidation(transaction.AccountTo)) { throw new ValidationException("Invalid AccountNumberTo"); } if (String.IsNullOrEmpty(transaction.CardSerialFrom)) { throw new ValidationException("Invalid CardSerialNumberFrom"); } break; default: throw new ValidationException("Invalid transaction type: " + transaction.TransactionType); } if (posDetail.InvItems == null || posDetail.InvItems.Count == 0) { throw new ValidationException("Invalid items"); } TransactionPM txpm = new TransactionPM() { TransactionType = transaction.TransactionType, AccountNumberIdFromRef = transaction.AccountFrom, AccountNumberIdToRef = transaction.AccountTo, CardSerialNumberIdFrom = transaction.CardSerialFrom, CardSerialNumberIdTo = transaction.CardSerialTo, Amount = transaction.Amount, CardFromEMVData = transaction.CardFromEMVData, }; List <POSTransactionItemPM> items = new List <POSTransactionItemPM>(); posDetail.InvItems.ForEach(x => { POSTransactionItemPM tipm = new POSTransactionItemPM() { Amount = x.Amount, Name = x.Name, Quantity = x.Quantity, InventoryItemId = x.InventoryItemId, }; items.Add(tipm); }); POSTransactionPM posTxpm = new POSTransactionPM() { POSTransactionItems = items, }; _posRepository.AddPOSTransaction(txpm, posTxpm, GetCurrentUserId()); }
private async void Ta_ProcessCompleted(object sender, EventArgs e) { try { int?amount = Validate.AmountToCents(totalAmount.Total); TransactionType transactionType; string fromAccountNumber = ""; string cardSerialNumberFrom = ""; string toAccountNumber = ""; string cardSerialNumberTo = ""; TerminalProcessingOutcome tpo = (e as TerminalProcessingOutcomeEventArgs).TerminalProcessingOutcome; if (tpo == null)//error occurred, error displayed via Ta_ExceptionOccured { return; } if (tpo is EMVTerminalProcessingOutcome) { TLV dataRecord = ((EMVTerminalProcessingOutcome)tpo).DataRecord; TLV discretionaryData = ((EMVTerminalProcessingOutcome)tpo).DiscretionaryData; if (dataRecord != null) //error or decline { SetStatusLabel("Remove card"); if (discretionaryData != null) { dataRecord.Children.AddListToList(discretionaryData.Children); } string emvData = TLVasJSON.ToJSON(dataRecord); byte[] panBCD; TLV _5A = dataRecord.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag); if (_5A != null) { panBCD = _5A.Value; } else { TLV _57 = dataRecord.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); } switch (flowType) { case FlowType.SendMoneyFromCardToApp: toAccountNumber = SessionSingleton.Account.AccountNumberId; cardSerialNumberFrom = Formatting.BcdToString(panBCD); transactionType = TransactionType.SendMoneyFromCardToApp; break; default: throw new Exception("Unknown flow type:" + flowType); } try { await CallPosTransactWebService(fromAccountNumber, toAccountNumber, cardSerialNumberFrom, cardSerialNumberTo, amount, transactionType, emvData); Device.BeginInvokeOnMainThread(() => { lblTransactSummary.Text = "Transaction Completed Succesfully"; UpdateView(ViewState.Step3Summary); }); } catch (Exception ex) { Device.BeginInvokeOnMainThread(() => { lblTransactSummary.Text = "Declined, could not go online."; UpdateView(ViewState.Step3Summary); }); } } else { SetStatusLabel(string.Format("{0}\n{1}", tpo.UserInterfaceRequest.MessageIdentifier, tpo.UserInterfaceRequest.Status)); } } } catch (Exception ex) { Device.BeginInvokeOnMainThread(() => { lblTransactSummary.Text = ex.Message; UpdateView(ViewState.Step3Summary); }); } }