public HttpResponseMessage SuccessPayment(Guid invoiceKey, Guid paymentKey, string token, string payerId)
        {
            var invoice = _merchelloContext.Services.InvoiceService.GetByKey(invoiceKey);
            var payment = _merchelloContext.Services.PaymentService.GetByKey(paymentKey);
            if (invoice == null || payment == null || String.IsNullOrEmpty(token) || String.IsNullOrEmpty(payerId))
            {
                var ex = new NullReferenceException(string.Format("Invalid argument exception. Arguments: invoiceKey={0}, paymentKey={1}, token={2}, payerId={3}.", invoiceKey, paymentKey, token, payerId));
                LogHelper.Error<PayPalApiController>("Payment is not authorized.", ex);
                throw ex;
            }

	        var providerKeyGuid = new Guid(Constants.PayPalPaymentGatewayProviderKey);
			var paymentGatewayMethod = _merchelloContext.Gateways.Payment
				.GetPaymentGatewayMethods()
				.First(item => item.PaymentMethod.ProviderKey == providerKeyGuid);
	        //var paymentGatewayMethod = _merchelloContext.Gateways.Payment.GetPaymentGatewayMethodByKey(providerKeyGuid);

            // Authorize
            var authorizeResult = _processor.AuthorizePayment(invoice, payment, token, payerId);
	        /*
			var authorizePaymentProcArgs = new ProcessorArgumentCollection();

	        authorizePaymentProcArgs[Constants.ProcessorArgumentsKeys.internalTokenKey] = token;
			authorizePaymentProcArgs[Constants.ProcessorArgumentsKeys.internalPayerIDKey] = payerId;
			authorizePaymentProcArgs[Constants.ProcessorArgumentsKeys.internalPaymentKeyKey] = payment.Key.ToString();

	        var authorizeResult = paymentGatewayMethod.AuthorizeCapturePayment(invoice, payment.Amount, authorizePaymentProcArgs);
            */
            _merchelloContext.Services.GatewayProviderService.Save(payment);
            if (!authorizeResult.Payment.Success)
            {
                LogHelper.Error<PayPalApiController>("Payment is not authorized.", authorizeResult.Payment.Exception);
				_merchelloContext.Services.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, "PayPal: request capture authorization error: " + authorizeResult.Payment.Exception.Message, 0);
                return ShowError(authorizeResult.Payment.Exception.Message);
            }
			_merchelloContext.Services.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "PayPal: capture authorized", 0);

			// The basket can be empty
            var customerContext = new Merchello.Web.CustomerContext(this.UmbracoContext);
            var currentCustomer = customerContext.CurrentCustomer;
	        if (currentCustomer != null) {
				var basket = Merchello.Web.Workflow.Basket.GetBasket(currentCustomer);
				basket.Empty();
	        }

            // Capture
            var captureResult = paymentGatewayMethod.CapturePayment(invoice, payment, payment.Amount, null);
            if (!captureResult.Payment.Success)
            {
                LogHelper.Error<PayPalApiController>("Payment is not captured.", captureResult.Payment.Exception);
                return ShowError(captureResult.Payment.Exception.Message);
            }

            // redirect to Site
			var returnUrl = payment.ExtendedData.GetValue(Constants.ExtendedDataKeys.ReturnUrl);
            var response = Request.CreateResponse(HttpStatusCode.Moved);
            response.Headers.Location = new Uri(returnUrl.Replace("%INVOICE%", invoice.Key.ToString().EncryptWithMachineKey()));
            return response;
        }
        public HttpResponseMessage SuccessPayment(Guid invoiceKey, Guid paymentKey, string token, string payerId)
        {
            var invoice = _merchelloContext.Services.InvoiceService.GetByKey(invoiceKey);
            var payment = _merchelloContext.Services.PaymentService.GetByKey(paymentKey);

            if (invoice == null || payment == null || String.IsNullOrEmpty(token) || String.IsNullOrEmpty(payerId))
            {
                var ex = new NullReferenceException(string.Format("Invalid argument exception. Arguments: invoiceKey={0}, paymentKey={1}, token={2}, payerId={3}.", invoiceKey, paymentKey, token, payerId));
                LogHelper.Error <PayPalApiController>("Payment is not authorized.", ex);
                throw ex;
            }

            var providerKeyGuid      = new Guid(Constants.PayPalPaymentGatewayProviderKey);
            var paymentGatewayMethod = _merchelloContext.Gateways.Payment
                                       .GetPaymentGatewayMethods()
                                       .First(item => item.PaymentMethod.ProviderKey == providerKeyGuid);
            //var paymentGatewayMethod = _merchelloContext.Gateways.Payment.GetPaymentGatewayMethodByKey(providerKeyGuid);

            // Authorize
            var authorizeResult = _processor.AuthorizePayment(invoice, payment, token, payerId);

            /*
             *      var authorizePaymentProcArgs = new ProcessorArgumentCollection();
             *
             * authorizePaymentProcArgs[Constants.ProcessorArgumentsKeys.internalTokenKey] = token;
             *      authorizePaymentProcArgs[Constants.ProcessorArgumentsKeys.internalPayerIDKey] = payerId;
             *      authorizePaymentProcArgs[Constants.ProcessorArgumentsKeys.internalPaymentKeyKey] = payment.Key.ToString();
             *
             * var authorizeResult = paymentGatewayMethod.AuthorizeCapturePayment(invoice, payment.Amount, authorizePaymentProcArgs);
             */
            _merchelloContext.Services.GatewayProviderService.Save(payment);
            if (!authorizeResult.Payment.Success)
            {
                LogHelper.Error <PayPalApiController>("Payment is not authorized.", authorizeResult.Payment.Exception);
                _merchelloContext.Services.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, "PayPal: request capture authorization error: " + authorizeResult.Payment.Exception.Message, 0);
                return(ShowError(authorizeResult.Payment.Exception.Message));
            }
            _merchelloContext.Services.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "PayPal: capture authorized", 0);

            // The basket can be empty
            var customerContext = new Merchello.Web.CustomerContext(this.UmbracoContext);
            var currentCustomer = customerContext.CurrentCustomer;

            if (currentCustomer != null)
            {
                var basket = Merchello.Web.Workflow.Basket.GetBasket(currentCustomer);
                basket.Empty();
            }

            // Capture
            decimal captureAmount;

            Decimal.TryParse(payment.ExtendedData.GetValue(Constants.ExtendedDataKeys.CaptureAmount), out captureAmount);
            if (captureAmount > 0)
            {
                var captureResult = paymentGatewayMethod.CapturePayment(invoice, payment, captureAmount, null);
                if (!captureResult.Payment.Success)
                {
                    LogHelper.Error <PayPalApiController>("Payment is not captured.", captureResult.Payment.Exception);
                    return(ShowError(captureResult.Payment.Exception.Message));
                }
            }

            // redirect to Site
            var returnUrl = payment.ExtendedData.GetValue(Constants.ExtendedDataKeys.ReturnUrl);
            var response  = Request.CreateResponse(HttpStatusCode.Moved);

            response.Headers.Location = new Uri(returnUrl.Replace("%INVOICE%", invoice.Key.ToString().EncryptWithMachineKey()));
            return(response);
        }