public TxCompletedEventArgs(TxResult txResult, InterFaceType interFaceType, Optional <TLV> emvData, Optional <QRDEList> qr_Data) { TxResult = txResult; InterFaceType = interFaceType; EMV_Data = emvData; QR_Data = qr_Data; }
private void cmdCancelTx_Clicked(object sender, EventArgs e) { Stop(); txResult = TxResult.Cancelled; SetTxFinalResultLabel(""); SetStatusLabel(new UIMessageEventArgs(MessageIdentifiersEnum.ClearDisplay, StatusEnum.EndProcessing), InterFaceType.Cancelled); TxCompleted?.Invoke(this, new TxCompletedEventArgs(txResult, InterFaceType.Cancelled, Optional <TLV> .CreateEmpty(), Optional <QRDEList> .CreateEmpty())); }
private void Start() { txResult = TxResult.Error; cancellationTokenForStatusMessage = new CancellationTokenSource(); //txtPin.Text = ""; txtPin.Text = "4315"; StartStatusMessageProcessor(); StartContactPaymentApp(contactDeviceId); StartContactlessPaymentApp(contactlessDeviceId); UpdateView(ViewState.Step2TapCard);//call after TransactionRequest is created }
private static NodeEffect[] ParseEffects(Tx tx, AffectedNode[] affectedNodes, string account, TxResult result) { if (affectedNodes == null || affectedNodes.Length == 0) { return(null); } var effects = new List <NodeEffect>(); foreach (var an in affectedNodes) { var diffType = an.DiffType; var node = an.CreatedNode ?? an.DeletedNode ?? an.ModifiedNode; var fieldsSet = new FieldsSet(node.FinalFields, node.PreviousFields, node.NewFields); NodeEffect nodeEffect = null; //TODO now only get offer related effects, need to process other entry type if (node.LedgerEntryType == "Offer") { // for new and cancelled offers var sell = fieldsSet.Flags == (long)LedgerOfferFlags.Sell; OfferEffect offerEffect = null; // current account offer if (fieldsSet.Account == account) { // 1. offer_partially_funded var seq = fieldsSet.Sequence; if (diffType == DiffType.ModifiedNode || (diffType == DiffType.DeletedNode && node.PreviousFields != null && node.PreviousFields.TakerGets != null && !IsAmountZero(node.FinalFields.TakerGets))) { var partiallyFoundedEffect = new OfferPartiallyFundedEffect(); offerEffect = partiallyFoundedEffect; partiallyFoundedEffect.Seq = seq; partiallyFoundedEffect.CounterParty = new CounterParty { Account = tx.Account, Seq = tx.Sequence, Hash = tx.Hash }; if (diffType == DiffType.DeletedNode) { partiallyFoundedEffect.Cancelled = true; } else { // TODO no need partially funded must remains offers partiallyFoundedEffect.Remaining = !IsAmountZero(fieldsSet.TakerGets); } var gets = fieldsSet.TakerGets; var pays = fieldsSet.TakerPays; partiallyFoundedEffect.Gets = gets; partiallyFoundedEffect.Pays = pays; partiallyFoundedEffect.Got = AmountSubtract(node.PreviousFields.TakerPays, pays); partiallyFoundedEffect.Paid = AmountSubtract(node.PreviousFields.TakerGets, gets); partiallyFoundedEffect.Type = sell ? OfferEffectType.Sold : OfferEffectType.Bought; } else { // offer_funded, offer_created or offer_cancelled offer effect var effect = diffType == DiffType.CreatedNode ? EffectType.OfferCreated : (node.PreviousFields != null && node.PreviousFields.TakerPays != null ? EffectType.OfferFunded : EffectType.OfferCancelled); switch (effect) { // 2. offer_funded case EffectType.OfferFunded: var fundedfEffect = new OfferFundedEffect(); fundedfEffect.Seq = seq; offerEffect = fundedfEffect; fundedfEffect.CounterParty = new CounterParty { Account = tx.Account, Seq = tx.Sequence, Hash = tx.Hash }; fundedfEffect.Got = AmountSubtract(node.PreviousFields.TakerPays, fieldsSet.TakerPays); fundedfEffect.Paid = AmountSubtract(node.PreviousFields.TakerGets, fieldsSet.TakerGets); fundedfEffect.Type = sell ? OfferEffectType.Sold : OfferEffectType.Bought; break; // 3. offer_created case EffectType.OfferCreated: var createdEffect = new OfferCreatedEffect(); createdEffect.Seq = seq; offerEffect = createdEffect; createdEffect.Gets = fieldsSet.TakerGets; createdEffect.Pays = fieldsSet.TakerPays; createdEffect.Type = sell ? OfferEffectType.Sell : OfferEffectType.Buy; break; // 4. offer_cancelled case EffectType.OfferCancelled: var cancelledEffect = new OfferCancelledEffect(); cancelledEffect.Seq = seq; offerEffect = cancelledEffect; cancelledEffect.Gets = fieldsSet.TakerGets; cancelledEffect.Pays = fieldsSet.TakerPays; cancelledEffect.Type = sell ? OfferEffectType.Sell : OfferEffectType.Buy; // collect data for cancel transaction type if (result.Type == TxResultType.OfferCancel) { var cancelResult = result as OfferCancelTxResult; cancelResult.Gets = cancelledEffect.Gets; cancelResult.Pays = cancelledEffect.Pays; } break; } } } // 5. offer_bought else if (tx.Account == account && node.PreviousFields != null) { var boughtEffect = new OfferBoughtEffect(); offerEffect = boughtEffect; boughtEffect.CounterParty = new CounterParty { Account = fieldsSet.Account, Seq = fieldsSet.Sequence, Hash = node.PreviousTxnID ?? fieldsSet.PreviousTxnID }; boughtEffect.Paid = AmountSubtract(node.PreviousFields.TakerPays, fieldsSet.TakerPays); boughtEffect.Got = AmountSubtract(node.PreviousFields.TakerGets, fieldsSet.TakerGets); boughtEffect.Type = sell ? OfferEffectType.Bought : OfferEffectType.Sold; } // add price if (offerEffect != null && offerEffect.GotOrPays != null && offerEffect.PaidOrGets != null) { var created = offerEffect.Effect == EffectType.OfferCreated && offerEffect.Type == OfferEffectType.Buy; var funded = offerEffect.Effect == EffectType.OfferFunded && offerEffect.Type == OfferEffectType.Bought; var cancelled = offerEffect.Effect == EffectType.OfferCancelled && offerEffect.Type == OfferEffectType.Buy; var bought = offerEffect.Effect == EffectType.OfferBought && offerEffect.Type == OfferEffectType.Bought; var partially_funded = offerEffect.Effect == EffectType.OfferPartiallyFunded && offerEffect.Type == OfferEffectType.Bought; var offerFunded = created || funded || cancelled || bought || partially_funded; offerEffect.Price = GetPrice(offerEffect.GotOrPays, offerEffect.PaidOrGets, offerFunded); } nodeEffect = offerEffect; } else if (node.LedgerEntryType == "AccountRoot") { if (result.Type == TxResultType.OfferEffect) { if (fieldsSet.RegularKey == account) { var regularKeyEffect = new SetRegularKeyEffect(); nodeEffect = regularKeyEffect; regularKeyEffect.Type = "null"; regularKeyEffect.Account = fieldsSet.Account; regularKeyEffect.RegularKey = account; } } } if (nodeEffect != null) { effects.Add(nodeEffect); if (diffType == DiffType.DeletedNode && nodeEffect.Effect != EffectType.OfferBought) { nodeEffect.Deleted = true; } } } return(effects.ToArray()); }
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))); } }