protected virtual ShetabPaymentStep2 endPayment(string code, string status)
        {
            var result = new ShetabPaymentStep2 <ParsianBankTranStatus>();

            result.BankType = this.BankType;

            string authority = code;
            long   auth;

            if (!long.TryParse(authority, out auth))
            {
                result.Status = (int)ParsianBankTranStatus.InvalidBankStep2Code;
            }
            else if (!PaymentSucceeded(status))
            {
                result.Status = status;
            }
            else
            {
                var  pec       = new ir.shaparak.pec.EShopService();
                byte pecStatus = 0;
                long invoice   = 0;

                pec.PaymentEnquiry(Config.Credentials.Pin, auth, ref pecStatus, ref invoice);

                result.Query     = auth;
                result.Code      = invoice;
                result.Status    = pecStatus;
                result.Succeeded = (PaymentStep2Succeeded(pecStatus) && auth != -1);
            }

            return(result);
        }
        protected virtual Task <ShetabPaymentStep2> endPaymentAsync(string code, string status, CancellationToken cancellation)
        {
            var tcs = new TaskCompletionSource <ShetabPaymentStep2>();

            try
            {
                var pec = new ir.shaparak.pec.EShopService();

                pec.PaymentEnquiryCompleted += new PaymentEnquiryCompletedEventHandler((sender, args) =>
                {
                    if (args.Error != null)
                    {
                        tcs.TrySetException(args.Error);
                    }
                    else
                    if (!args.Cancelled)
                    {
                        try
                        {
                            var result = new ShetabPaymentStep2 <ParsianBankTranStatus>();

                            result.Query     = (long)args.UserState;
                            result.Code      = args.invoiceNumber;
                            result.Status    = args.status;
                            result.Succeeded = (PaymentStep2Succeeded(args.status) && result.Query != -1);
                            result.BankType  = this.BankType;

                            tcs.SetResult(result);
                        }
                        catch (Exception ex)
                        {
                            tcs.TrySetException(ex);
                        }
                    }
                    else
                    {
                        tcs.SetCanceled();
                    }

                    pec.Dispose();
                });

                string authority = code;
                long   auth;
                byte   pecStatus = 0;
                long   invoice   = 0;

                if (!long.TryParse(authority, out auth))
                {
                    var result = new ShetabPaymentStep2 <ParsianBankTranStatus>();

                    result.Query     = auth;
                    result.Status    = (int)ParsianBankTranStatus.InvalidBankStep2Code;
                    result.Succeeded = false;
                    result.BankType  = this.BankType;

                    tcs.SetResult(result);
                }
                else if (!PaymentSucceeded(status))
                {
                    var result = new ShetabPaymentStep2 <ParsianBankTranStatus>();

                    result.Query     = auth;
                    result.Status    = status;
                    result.Succeeded = false;
                    result.BankType  = this.BankType;

                    tcs.SetResult(result);
                }
                else
                {
                    cancellation.Register(() => pec.CancelAsync(auth));

                    pec.PaymentEnquiryAsync(Config.Credentials.Pin, auth, pecStatus, invoice, auth);
                }
            }
            catch (Exception e)
            {
                tcs.SetException(e);
            }

            return(tcs.Task);
        }