public async Task CreateRefundRequest_RequiresPaymentPlanToken()
        {
            using (var client = TestUtils.GetMockClient())
            {
                var refundRef = System.Guid.NewGuid().ToString();
                var request   = new LatitudePayCreateRefundRequest()
                {
                    Amount           = new LatitudePayMoney(10M, LatitudePayCurrencies.NewZealandDollars),
                    IdempotencyKey   = refundRef,
                    Reference        = refundRef,
                    PaymentPlanToken = System.Guid.NewGuid().ToString()
                };
                request.PaymentPlanToken = null;

                // Test for null
                try
                {
                    var refundResponse = await client.CreateRefundAsync(request);

                    Assert.Fail("ArgumentNullException expected");
                }
                catch (ArgumentNullException ane)
                {
                    Assert.AreEqual("request." + nameof(request.PaymentPlanToken), ane.ParamName);
                }

                //Test for empty
                try
                {
                    request.PaymentPlanToken = String.Empty;
                    var refundResponse = await client.CreateRefundAsync(request);

                    Assert.Fail("ArgumentException expected");
                }
                catch (ArgumentException ane)
                {
                    Assert.AreEqual("request." + nameof(request.PaymentPlanToken), ane.ParamName);
                }

                // Test for whitespace only
                try
                {
                    request.PaymentPlanToken = "  \t";
                    var refundResponse = await client.CreateRefundAsync(request);

                    Assert.Fail("ArgumentException expected");
                }
                catch (ArgumentException ane)
                {
                    Assert.AreEqual("request." + nameof(request.PaymentPlanToken), ane.ParamName);
                }
            }
        }
        internal static HttpResponseMessage CreateRefund(LatitudePayCreateRefundRequest request)
        {
            if (!String.IsNullOrWhiteSpace(request.IdempotencyKey))
            {
                var existingRequest = (from r in _Refunds where request.IdempotencyKey == r.InitialRequest.IdempotencyKey select r).FirstOrDefault();
                if (existingRequest != null)
                {
                    return(ToJsonHttpResponse(existingRequest.InitialResponseStatus, existingRequest.InitialResponse));
                }
            }

            var existingPayment = (from p in _Payments where request.IdempotencyKey == p.InitialRequest.IdempotencyKey select p).FirstOrDefault();

            if (existingPayment == null)
            {
                return(ToJsonHttpResponse(HttpStatusCode.NotFound, new { error = "Payment plan not found." }));
            }

            if (request.Amount.Amount > existingPayment.InitialRequest.TotalAmount.Amount)
            {
                return(ToJsonHttpResponse(HttpStatusCode.NotFound, new { error = "Refund is more than payment amount." }));
            }

            var token           = System.Guid.NewGuid().ToString();
            var responseContent = new LatitudePayCreateRefundResponse()
            {
                CommissionAmount = 0M,
                RefundDate       = DateTimeOffset.Now.DateTime,
                RefundId         = System.Guid.NewGuid().ToString(),
                Reference        = request.Reference
            };

            var mockRefund = new MockLatitudePayRefund()
            {
                InitialResponseStatus = HttpStatusCode.OK,
                InitialRequest        = request,
                InitiallyReceivedAt   = DateTimeOffset.Now,
                InitialResponse       = responseContent,
            };

            _Refunds.Add(mockRefund);

            return(ToJsonHttpResponse(mockRefund.InitialResponseStatus, mockRefund.InitialResponse));
        }
        public async Task CreateRefundRequest_RequiresPositiveAmount()
        {
            using (var client = TestUtils.GetMockClient())
            {
                var refundRef = System.Guid.NewGuid().ToString();
                var request   = new LatitudePayCreateRefundRequest()
                {
                    Amount           = new LatitudePayMoney(10M, LatitudePayCurrencies.NewZealandDollars),
                    IdempotencyKey   = refundRef,
                    Reference        = refundRef,
                    PaymentPlanToken = System.Guid.NewGuid().ToString()
                };
                request.Amount = new LatitudePayMoney(0M, LatitudePayCurrencies.NewZealandDollars);

                // Test for zero
                try
                {
                    var refundResponse = await client.CreateRefundAsync(request);

                    Assert.Fail("ArgumentOutOfRangeException expected");
                }
                catch (ArgumentOutOfRangeException aore)
                {
                    Assert.AreEqual("request." + nameof(request.Amount), aore.ParamName);
                }

                //Test for negative
                try
                {
                    request.Amount = new LatitudePayMoney(-10M, LatitudePayCurrencies.NewZealandDollars);
                    var refundResponse = await client.CreateRefundAsync(request);

                    Assert.Fail("ArgumentOutOfRangeException expected");
                }
                catch (ArgumentOutOfRangeException aore)
                {
                    Assert.AreEqual("request." + nameof(request.Amount), aore.ParamName);
                }
            }
        }
        public async Task Refund()
        {
            using (var client = TestUtils.GetMockClient())
            {
                var request = new LatitudePayCreatePosPurchaseRequest()
                {
                    Reference      = "TBR-" + System.Guid.NewGuid().ToString(),
                    BillingAddress = new LatitudePayAddress()
                    {
                        AddressLine1 = "124 Fifth Avenue",
                        Suburb       = "Auckland",
                        CityTown     = "Auckland",
                        State        = "Auckland",
                        Postcode     = "1010",
                        CountryCode  = "NZ"
                    },
                    ShippingAddress = new LatitudePayAddress()
                    {
                        AddressLine1 = "124 Fifth Avenue",
                        Suburb       = "Auckland",
                        CityTown     = "Auckland",
                        State        = "Auckland",
                        Postcode     = "1010",
                        CountryCode  = "NZ"
                    },
                    Customer = new LatitudePayCustomer()
                    {
                        Address = new LatitudePayAddress()
                        {
                            AddressLine1 = "124 Fifth Avenue",
                            Suburb       = "Auckland",
                            CityTown     = "Auckland",
                            State        = "Auckland",
                            Postcode     = "1010",
                            CountryCode  = "NZ"
                        },
                        FirstName    = "John",
                        Surname      = "Doe",
                        MobileNumber = Environment.GetEnvironmentVariable("LatitudePay_TestMobileNumber")
                    },
                    Products = new List <LatitudePayProduct>()
                    {
                        new LatitudePayProduct()
                        {
                            Name        = "Tennis Ball Multipack",
                            Price       = new LatitudePayMoney(30, "NZD"),
                            Sku         = "abc123",
                            Quantity    = 1,
                            TaxIncluded = true
                        }
                    },
                    ShippingLines = new List <LatitiudePayShippingLine>()
                    {
                        new LatitiudePayShippingLine()
                        {
                            Carrier = "NZ Post",
                            Price   = new LatitudePayMoney(5.5M, "NZD")
                        }
                    },
                    TaxAmount   = new LatitudePayMoney(5.325M, "NZD"),
                    TotalAmount = new LatitudePayMoney(35.5M, "NZD"),
                    ReturnUrls  = new LatitudePayReturnUrls()
                    {
                        SuccessUrl  = new Uri("http://genoapay.com/success"),
                        FailUrl     = new Uri("http://genoapay.com/fail"),
                        CallbackUrl = new Uri("http://genoapay.com/fail-safe-callback")
                    }
                };

                var purchaseResponse = await client.CreatePosPurchaseAsync(request);

                Assert.IsNotNull(purchaseResponse);
                Assert.IsFalse(String.IsNullOrWhiteSpace(purchaseResponse.Token));
                Assert.IsNotNull(purchaseResponse.StatusUrl);

                //Wait until payment enters final status
                var statusRequest = new LatitudePayPurchaseStatusRequest()
                {
                    PaymentPlanToken = purchaseResponse.Token
                };
                var finalStatus = false;
                LatitudePayPurchaseStatusResponse paymentStatus;
                while (!finalStatus)
                {
                    await Task.Delay(5000).ConfigureAwait(false);

                    paymentStatus = await client.GetPurchaseStatusAsync(statusRequest).ConfigureAwait(false);

                    finalStatus = !String.Equals(paymentStatus.Status, LatitudePayConstants.StatusPending, StringComparison.OrdinalIgnoreCase);
                }

                var refundRequest = new LatitudePayCreateRefundRequest()
                {
                    PaymentPlanToken = purchaseResponse.Token, Amount = request.TotalAmount, Reason = "Test refund", Reference = System.Guid.NewGuid().ToString()
                };
                var refundResponse = await client.CreateRefundAsync(refundRequest);

                Assert.IsNotNull(refundResponse);
                Assert.IsFalse(String.IsNullOrEmpty(refundResponse.RefundId));
                Assert.IsFalse(String.IsNullOrEmpty(refundResponse.Reference));
            }
        }