예제 #1
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
                });
            }
        }
예제 #5
0
        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)));
            }
        }