protected override IPaymentResult PerformProcessPayment(SalePreparationBase preparation, IPaymentMethod paymentMethod) { // We have to use the CheckoutConfirmationModel in this implementation. If this were to be used // outside of a demo, you could consider writing your own base controller that inherits directly from // Merchello.Web.Mvc.PaymentMethodUiController<TModel> and complete the transaction there in which case the // BazaarPaymentMethodFormControllerBase would be a good example. var form = UmbracoContext.HttpContext.Request.Form; var DebitOrderNumber = form.Get("DebitOrderNumber"); if (string.IsNullOrEmpty(DebitOrderNumber)) { var invalidData = new InvalidDataException("The Purchase Order Number cannot be an empty string"); return new PaymentResult(Attempt<IPayment>.Fail(invalidData), null, false); } // You need a ProcessorArgumentCollection for this transaction to store the payment method nonce // The braintree package includes an extension method off of the ProcessorArgumentCollection - SetPaymentMethodNonce([nonce]); var args = new ProcessorArgumentCollection(); args.SetDebitOrderNumber(DebitOrderNumber); // We will want this to be an Authorize(paymentMethod.Key, args); // -- Also in a real world situation you would want to validate the PO number somehow. return preparation.AuthorizePayment(paymentMethod.Key, args); }
/// <summary> /// Does the actual work of authorizing and capturing a payment /// </summary> /// <param name="invoice">The <see cref="IInvoice"/></param> /// <param name="amount">The amount to capture</param> /// <param name="args">Any arguments required to process the payment.</param> /// <returns>The <see cref="IPaymentResult"/></returns> protected override IPaymentResult PerformAuthorizeCapturePayment(IInvoice invoice, decimal amount, ProcessorArgumentCollection args) { var payment = GatewayProviderService.CreatePayment(PaymentMethodType.PurchaseOrder, amount, PaymentMethod.Key); payment.CustomerKey = invoice.CustomerKey; payment.PaymentMethodName = PaymentMethod.Name; payment.ReferenceNumber = PaymentMethod.PaymentCode + "-" + invoice.PrefixedInvoiceNumber(); payment.Collected = true; payment.Authorized = true; var po = args.AsPurchaseOrderFormData(); if (string.IsNullOrEmpty(po.PurchaseOrderNumber)) { return new PaymentResult(Attempt<IPayment>.Fail(payment, new Exception("Error Purchase Order Number is empty")), invoice, false); } invoice.PoNumber = po.PurchaseOrderNumber; MerchelloContext.Current.Services.InvoiceService.Save(invoice); GatewayProviderService.Save(payment); GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "Cash payment", amount); return new PaymentResult(Attempt<IPayment>.Succeed(payment), invoice, CalculateTotalOwed(invoice).CompareTo(amount) <= 0); }
/// <summary> /// Does the actual work capturing a payment /// </summary> /// <param name="invoice">The <see cref="IInvoice"/></param> /// <param name="payment">The previously Authorize payment to be captured</param> /// <param name="amount">The amount to capture</param> /// <param name="args">Any arguments required to process the payment.</param> /// <returns>The <see cref="IPaymentResult"/></returns> protected override IPaymentResult PerformCapturePayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args) { var result = _processor.PriorAuthorizeCapturePayment(invoice, payment); GatewayProviderService.Save(payment); if (!result.Payment.Success) { GatewayProviderService.ApplyPaymentToInvoice( payment.Key, invoice.Key, AppliedPaymentType.Denied, result.Payment.Exception.Message, 0); } else { GatewayProviderService.ApplyPaymentToInvoice( payment.Key, invoice.Key, AppliedPaymentType.Debit, payment.ExtendedData.GetValue(Constants.ExtendedDataKeys.CaptureTransactionResult), amount); } return result; }
/// <summary> /// Does the actual work of creating and processing the payment /// </summary> /// <param name="invoice">The <see cref="IInvoice"/></param> /// <param name="args">Any arguments required to process the payment.</param> /// <returns>The <see cref="IPaymentResult"/></returns> protected override IPaymentResult PerformAuthorizePayment(IInvoice invoice, ProcessorArgumentCollection args) { var po = args.AsPurchaseOrderFormData(); var payment = GatewayProviderService.CreatePayment(PaymentMethodType.PurchaseOrder, invoice.Total, PaymentMethod.Key); payment.CustomerKey = invoice.CustomerKey; payment.PaymentMethodName = PaymentMethod.Name; payment.ReferenceNumber = PaymentMethod.PaymentCode + "-" + invoice.PrefixedInvoiceNumber(); payment.Collected = false; payment.Authorized = true; if (string.IsNullOrEmpty(po.PurchaseOrderNumber)) { return new PaymentResult(Attempt<IPayment>.Fail(payment, new Exception("Error Purchase Order Number is empty")), invoice, false); } invoice.PoNumber = po.PurchaseOrderNumber; MerchelloContext.Current.Services.InvoiceService.Save(invoice); GatewayProviderService.Save(payment); // In this case, we want to do our own Apply Payment operation as the amount has not been collected - // so we create an applied payment with a 0 amount. Once the payment has been "collected", another Applied Payment record will // be created showing the full amount and the invoice status will be set to Paid. GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, string.Format("To show promise of a {0} payment", PaymentMethod.Name), 0); //// If this were using a service we might want to store some of the transaction data in the ExtendedData for record ////payment.ExtendData return new PaymentResult(Attempt.Succeed(payment), invoice, false); }
/// <summary> /// Processes the Authorize and AuthorizeAndCapture transactions /// </summary> /// <param name="invoice">The <see cref="IInvoice"/> to be paid</param> /// <param name="payment">The <see cref="IPayment"/> record</param> /// <param name="args"></param> /// <returns>The <see cref="IPaymentResult"/></returns> public IPaymentResult ProcessPayment(IInvoice invoice, IPayment payment, ProcessorArgumentCollection args) { var setExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType { ReturnURL = String.Format("{0}/App_Plugins/Merchello.PayPal/PayPalExpressCheckout.html?InvoiceKey={1}&PaymentKey={2}&PaymentMethodKey={3}", GetWebsiteUrl(), invoice.Key, payment.Key, payment.PaymentMethodKey), CancelURL = "http://localhost/cancel", PaymentDetails = new List<PaymentDetailsType> { GetPaymentDetails(invoice) } }; var setExpressCheckout = new SetExpressCheckoutReq(); var setExpressCheckoutRequest = new SetExpressCheckoutRequestType(setExpressCheckoutRequestDetails); setExpressCheckout.SetExpressCheckoutRequest = setExpressCheckoutRequest; var config = new Dictionary<string, string> { {"mode", "sandbox"}, {"account1.apiUsername", _settings.ApiUsername}, {"account1.apiPassword", _settings.ApiPassword}, {"account1.apiSignature", _settings.ApiSignature} }; var service = new PayPalAPIInterfaceServiceService(config); var responseSetExpressCheckoutResponseType = service.SetExpressCheckout(setExpressCheckout); // If this were using a service we might want to store some of the transaction data in the ExtendedData for record payment.ExtendedData.SetValue("RedirectUrl", "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=" + responseSetExpressCheckoutResponseType.Token); return new PaymentResult(Attempt<IPayment>.Succeed(payment), invoice, false); }
public IPaymentResult InitializePayment(IInvoice invoice, IPayment payment, ProcessorArgumentCollection args) { string postUrl = GetPostUrl(invoice, payment); payment.ExtendedData.SetValue("RedirectUrl", postUrl); HttpContext.Current.Response.Redirect(postUrl); return new PaymentResult(Attempt<IPayment>.Succeed(payment), invoice, true); }
/// <summary> /// Performs the actual work of authorizing and capturing a payment. /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="amount"> /// The amount. /// </param> /// <param name="args"> /// The args. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> /// <remarks> /// This is a transaction with SubmitForSettlement = true /// </remarks> protected override IPaymentResult PerformAuthorizeCapturePayment(IInvoice invoice, decimal amount, ProcessorArgumentCollection args) { var paymentMethodNonce = args.GetPaymentMethodNonce(); if (string.IsNullOrEmpty(paymentMethodNonce)) { var error = new InvalidOperationException("No payment method nonce was found in the ProcessorArgumentCollection"); LogHelper.Debug<BraintreeStandardTransactionPaymentGatewayMethod>(error.Message); return new PaymentResult(Attempt<IPayment>.Fail(error), invoice, false); } // TODO this is a total last minute hack var email = string.Empty; if (args.ContainsKey("customerEmail")) email = args["customerEmail"]; var attempt = this.ProcessPayment(invoice, TransactionOption.SubmitForSettlement, invoice.Total, paymentMethodNonce, email); var payment = attempt.Payment.Result; this.GatewayProviderService.Save(payment); if (!attempt.Payment.Success) { this.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, attempt.Payment.Exception.Message, 0); } else { this.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "Braintree PayPal one time transaction - authorized and captured", amount); } return attempt; }
/// <summary> /// Does the actual work of authorizing the payment /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="args"> /// The args. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> protected override IPaymentResult PerformAuthorizePayment(IInvoice invoice, ProcessorArgumentCollection args) { // The Provider settings if (BraintreeApiService.BraintreeProviderSettings.DefaultTransactionOption == TransactionOption.SubmitForSettlement) { return this.PerformAuthorizeCapturePayment(invoice, invoice.Total, args); } var paymentMethodNonce = args.GetPaymentMethodNonce(); if (string.IsNullOrEmpty(paymentMethodNonce)) { var error = new InvalidOperationException("No payment method nonce was found in the ProcessorArgumentCollection"); LogHelper.Debug<BraintreeStandardTransactionPaymentGatewayMethod>(error.Message); return new PaymentResult(Attempt<IPayment>.Fail(error), invoice, false); } var attempt = ProcessPayment(invoice, TransactionOption.Authorize, invoice.Total, paymentMethodNonce); var payment = attempt.Payment.Result; GatewayProviderService.Save(payment); if (!attempt.Payment.Success) { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, attempt.Payment.Exception.Message, 0); } else { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "To show record of Braintree Authorization", 0); } return attempt; }
protected override IPaymentResult PerformCapturePayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args) { var token = args["token"]; var payerId = args["PayerID"]; var result = _processor.ComplitePayment(invoice, payment, token, payerId); GatewayProviderService.Save(payment); // TODO GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "Cash payment", payment.Amount); /* if (!result.Payment.Success) { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, result.Payment.Exception.Message, 0); } else { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, payment.ExtendedData.GetValue(Constants.ExtendedDataKeys.CaptureTransactionResult), amount); } */ return result; }
/// <summary> /// Performs the actual work of authorizing and capturing a payment. /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="amount"> /// The amount. /// </param> /// <param name="args"> /// The args. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> /// <remarks> /// This is a transaction with SubmitForSettlement = true /// </remarks> protected override IPaymentResult PerformAuthorizeCapturePayment(IInvoice invoice, decimal amount, ProcessorArgumentCollection args) { var paymentMethodNonce = args.GetPaymentMethodNonce(); if (string.IsNullOrEmpty(paymentMethodNonce)) { var error = new InvalidOperationException("No payment method nonce was found in the ProcessorArgumentCollection"); LogHelper.Debug<BraintreeSimpleTransactionPaymentGatewayMethod>(error.Message); return new PaymentResult(Attempt<IPayment>.Fail(error), invoice, false); } var attempt = ProcessPayment(invoice, TransactionOption.Authorize, invoice.Total, paymentMethodNonce); var payment = attempt.Payment.Result; GatewayProviderService.Save(payment); if (!attempt.Payment.Success) { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, attempt.Payment.Exception.Message, 0); } else { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "Braintree transaction - authorized and captured", amount); } return attempt; }
private IPaymentResult ProcessPayment(IInvoice invoice, TransactionMode transactionMode, decimal amount, ProcessorArgumentCollection args) { var cc = args.AsCreditCardFormData(); var payment = GatewayProviderService.CreatePayment(PaymentMethodType.CreditCard, invoice.Total, PaymentMethod.Key); payment.CustomerKey = invoice.CustomerKey; payment.Authorized = false; payment.Collected = false; payment.PaymentMethodName = string.Format("{0} Stripe Credit Card", cc.CreditCardType); payment.ExtendedData.SetValue(Constants.ExtendedDataKeys.CcLastFour, cc.CardNumber.Substring(cc.CardNumber.Length - 4, 4).EncryptWithMachineKey()); var result = _processor.ProcessPayment(invoice, payment, transactionMode, amount, cc); GatewayProviderService.Save(payment); if (!result.Payment.Success) { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, result.Payment.Exception.Message, 0); } else { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, //payment.ExtendedData.GetValue(Constants.ExtendedDataKeys.AuthorizationTransactionResult) + (transactionMode == TransactionMode.AuthorizeAndCapture ? string.Empty : " to show record of Authorization"), transactionMode == TransactionMode.AuthorizeAndCapture ? invoice.Total : 0); } return result; }
protected override IPaymentResult PerformCapturePayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args) { var payedTotalList = invoice.AppliedPayments().Select(item => item.Amount).ToList(); var payedTotal = (payedTotalList.Count == 0 ? 0 : payedTotalList.Aggregate((a, b) => a + b)); var isPartialPayment = amount + payedTotal < invoice.Total; var result = _processor.CapturePayment(invoice, payment, amount, isPartialPayment); //GatewayProviderService.Save(payment); if (!result.Payment.Success) { //payment.VoidPayment(invoice, payment.PaymentMethodKey.Value); GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, "PayPal: request capture error: " + result.Payment.Exception.Message, 0); } else { GatewayProviderService.Save(payment); GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "PayPal: captured", amount); //GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, payment.ExtendedData.GetValue(Constants.ExtendedDataKeys.CaptureTransactionResult), amount); } return result; }
/// <summary> /// Authorizes and Captures a Payment /// </summary> /// <param name="invoice">The <see cref="IInvoice"/></param> /// <param name="paymentGatewayMethod">The <see cref="IPaymentMethod"/></param> /// <param name="args">Additional arguements required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> public static IPaymentResult AuthorizeCapturePayment(this IInvoice invoice, IPaymentGatewayMethod paymentGatewayMethod, ProcessorArgumentCollection args) { Mandate.ParameterNotNull(paymentGatewayMethod, "paymentGatewayMethod"); return paymentGatewayMethod.AuthorizeCapturePayment(invoice, invoice.Total, args); }
private IPaymentResult ProcessPayment(IInvoice invoice, TransactionMode transactionMode, decimal amount, ProcessorArgumentCollection args) { var po = args.AsPurchaseOrderFormData(); var payment = GatewayProviderService.CreatePayment(PaymentMethodType.PurchaseOrder, invoice.Total, PaymentMethod.Key); payment.CustomerKey = invoice.CustomerKey; payment.Authorized = false; payment.Collected = false; payment.PaymentMethodName = "Purchase Order"; var result = _processor.ProcessPayment(invoice, payment, amount, po); GatewayProviderService.Save(payment); if (!result.Payment.Success) { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, result.Payment.Exception.Message, 0); } else { MerchelloContext.Current.Services.InvoiceService.Save(invoice, false); GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, payment.ExtendedData.GetValue(Constants.ExtendedDataKeys.AuthorizationTransactionResult) + (transactionMode == TransactionMode.AuthorizeAndCapture ? string.Empty : " to show record of Authorization"), transactionMode == TransactionMode.AuthorizeAndCapture ? invoice.Total : 0); } return result; }
/// <summary> /// Attempts to authorize a payment /// </summary> /// <param name="paymentGatewayMethod">The <see cref="IPaymentGatewayMethod"/> to use in processing the payment</param> /// <param name="args">Additional arguments required by the payment processor</param> /// <returns>The <see cref="IPaymentResult"/></returns> public override IPaymentResult AuthorizePayment(IPaymentGatewayMethod paymentGatewayMethod, ProcessorArgumentCollection args) { var result = base.AuthorizePayment(paymentGatewayMethod, args); if (result.Payment.Success) Customer.Basket().Empty(); return result; }
protected override IPaymentResult PerformCapturePayment(global::Merchello.Core.Models.IInvoice invoice, global::Merchello.Core.Models.IPayment payment, decimal amount, ProcessorArgumentCollection args) { payment.Collected = true; payment.Authorized = true; GatewayProviderService.Save(payment); GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, string.Format("To show promise of a {0} payment", PaymentMethod.Name), amount); return _processor.CapturePayment(invoice, payment, amount, false); }
/// <summary> /// Overrides the AuthorizePayment. /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="args"> /// The args. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> /// <exception cref="InvalidOperationException"> /// Throws an exception if this method is called. /// </exception> public override IPaymentResult AuthorizePayment(IInvoice invoice, ProcessorArgumentCollection args) { var invalidOp = new InvalidOperationException( "Braintree PayPal authorize transaction is not supported. Use AuthorizeCapture Payment"); LogHelper.Error<PayPalVaultTransactionPaymentGatewayMethod>("Authorize method not supported.", invalidOp); throw invalidOp; }
// AuthorizeCapturePayment will save the invoice with an Invoice Number. private IPaymentResult ProcessPayment(SalePreparationBase preparation, IPaymentMethod paymentMethod, string paymentMethodNonce) { // You need a ProcessorArgumentCollection for this transaction to store the payment method nonce // The braintree package includes an extension method off of the ProcessorArgumentCollection - SetPaymentMethodNonce([nonce]); var args = new ProcessorArgumentCollection(); args.SetPaymentMethodNonce(paymentMethodNonce); // We will want this to be an AuthorizeCapture(paymentMethod.Key, args); return preparation.AuthorizeCapturePayment(paymentMethod.Key, args); }
public ActionResult Callback(string id) { var checkSum = Request.Headers["QuickPay-Checksum-SHA256"]; // Get the Payload data var req = Request.InputStream; req.Seek(0, SeekOrigin.Begin); var json = new StreamReader(req).ReadToEnd(); LogHelper.Info<CallbackController>(() => "[BODY] : " + json); var gateway = MerchelloContext.Current.Gateways.Payment.GetProviderByKey(Guid.Parse(Constants.ProviderId)); var gatewaySettings = gateway.ExtendedData.GetProviderSettings(); var compute = Sign(json, gatewaySettings.PrivateKey); // Private Key for the Payment Window! Not the API key. if (!checkSum.Equals(compute)) { LogHelper.Warn<CallbackController>("Checksum did not compute : " + checkSum + "\r\n" + json); throw new Exception("MD5 Check does not compute"); } QuickPayResponseModel callbackInput; try { callbackInput = JsonConvert.DeserializeObject<QuickPayResponseModel>(json); } catch (Exception ex) { LogHelper.Error<CallbackController>("Unable to deserialize json from QuickPay callback", ex); return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } if (!callbackInput.Accepted) { LogHelper.Info<CallbackController>("Payment not accepted by QuickPay"); return Content("Payment not accepted by QuickPay"); } if (callbackInput.Order_Id.StartsWith("test_")) { LogHelper.Warn<CallbackController>("QuickPay is in test mode. The payment provider is unable to identify the invoice to apply the payment to, since the order_id was returned as " + callbackInput.Order_Id); return Content("QuickPay Test Mode Detected"); } var invoiceNumber = int.Parse(callbackInput.Order_Id); var invoice = MerchelloContext.Current.Services.InvoiceService.GetByInvoiceNumber(invoiceNumber); var paymentGatewayMethod = MerchelloContext.Current.Gateways.Payment.GetPaymentGatewayMethods().Single(x => x.PaymentMethod.ProviderKey == Guid.Parse(Constants.ProviderId)); var args = new ProcessorArgumentCollection(); args.Add(Constants.ExtendedDataKeys.PaymentCurrency, callbackInput.Currency); args.Add(Constants.ExtendedDataKeys.PaymentAmount, callbackInput.Operations.Where(x => !x.Pending).Sum(x => x.Amount).ToString("F0")); args.Add(Constants.ExtendedDataKeys.QuickpayPaymentId, callbackInput.Id.ToString("F0")); var paymentResult = invoice.AuthorizePayment(paymentGatewayMethod, args); Notification.Trigger("OrderConfirmation", paymentResult, new[] { invoice.BillToEmail }); return Content("Hello QuickPay"); }
/// <summary> /// Payment methods derived from <see cref="RedirectPaymentMethodBase"/> cannot implement <see cref="PerformAuthorizeCapturePayment(IInvoice, decimal, ProcessorArgumentCollection)"/>. /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="amount"> /// The amount. /// </param> /// <param name="args"> /// The args. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> /// <exception cref="InvalidOperationException"> /// Throws an exception if this method is invoked. /// </exception> protected override IPaymentResult PerformAuthorizeCapturePayment(IInvoice invoice, decimal amount, ProcessorArgumentCollection args) { var logData = MultiLogger.GetBaseLoggingData(); logData.AddCategory("Payment"); logData.AddCategory("Redirect"); var invalidOp = new InvalidOperationException("Payment Providers that require redirection cannot perform Authorize & Capture operations."); MultiLogHelper.Error<RedirectPaymentMethodBase>("Cannot perform authorize and capture operation", invalidOp, logData); throw invalidOp; }
/// <summary> /// Does the actual work of capturing a payment /// </summary> /// <param name="invoice">The <see cref="IInvoice"/></param> /// <param name="payment"></param> /// <param name="amount"></param> /// <param name="args">Any arguments required to process the payment. (Maybe a username, password or some Api Key)</param> /// <returns>The <see cref="IPaymentResult"/></returns> protected override IPaymentResult PerformCapturePayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args) { payment.Amount += amount; payment.Collected = true; payment.Authorized = true; GatewayProviderService.Save(payment); var appliedPayment = GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "Cash payment", amount); return new PaymentResult(Attempt<IPayment>.Succeed(payment), invoice, invoice.Total == amount); }
protected override IPaymentResult PerformAuthorizeCapturePayment(IInvoice invoice, decimal amount, ProcessorArgumentCollection args) { var payment = GatewayProviderService.CreatePayment(PaymentMethodType.Cash, amount, PaymentMethod.Key); payment.PaymentMethodName = PaymentMethod.Name + " " + PaymentMethod.PaymentCode; payment.ReferenceNumber = PaymentMethod.PaymentCode + "-" + invoice.PrefixedInvoiceNumber(); payment.Collected = true; payment.Authorized = true; GatewayProviderService.Save(payment); var appliedPayment = GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "Cash payment", amount); return new PaymentResult(Attempt<IPayment>.Succeed(payment), invoice, invoice.Total == amount); }
private IPaymentResult ProcessPayment(IInvoice invoice, ProcessorArgumentCollection args) { var payment = GatewayProviderService.CreatePayment(PaymentMethodType.Cash, invoice.Total, PaymentMethod.Key); payment.CustomerKey = invoice.CustomerKey; payment.Authorized = false; payment.Collected = false; payment.PaymentMethodName = "PayPal"; GatewayProviderService.Save(payment); var result = _processor.ProcessPayment(invoice, payment, args); GatewayProviderService.Save(payment); GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, string.Format("To show promise of a {0} payment", PaymentMethod.Name), 0); return result; }
/// <summary> /// The perform authorize payment. /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="args"> /// The args. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> protected override IPaymentResult PerformAuthorizePayment(IInvoice invoice, ProcessorArgumentCollection args) { var payment = GatewayProviderService.CreatePayment(PaymentMethodType.CreditCard, invoice.Total, PaymentMethod.Key); payment.CustomerKey = invoice.CustomerKey; payment.PaymentMethodName = PaymentMethod.Name; payment.ReferenceNumber = PaymentMethod.PaymentCode + "-" + invoice.PrefixedInvoiceNumber(); payment.Collected = false; payment.Authorized = true; GatewayProviderService.Save(payment); // In this case, we want to do our own Apply Payment operation as the amount has not been collected - // so we create an applied payment with a 0 amount. Once the payment has been "collected", another Applied Payment record will // be created showing the full amount and the invoice status will be set to Paid. GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, string.Format("To show promise of a {0} payment", PaymentMethod.Name), 0); return new PaymentResult(Attempt.Succeed(payment), invoice, false); }
/// <summary> /// The perform authorize capture payment. /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="amount"> /// The amount. /// </param> /// <param name="args"> /// The args. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> protected override IPaymentResult PerformAuthorizeCapturePayment(IInvoice invoice, decimal amount, ProcessorArgumentCollection args) { var paymentMethodToken = args.GetPaymentMethodToken(); if (string.IsNullOrEmpty(paymentMethodToken)) { var error = new InvalidOperationException("No payment method token was found in the ProcessorArgumentCollection"); LogHelper.Debug<BraintreeStandardTransactionPaymentGatewayMethod>(error.Message); return new PaymentResult(Attempt<IPayment>.Fail(error), invoice, false); } var attempt = this.ProcessPayment(invoice, TransactionOption.SubmitForSettlement, invoice.Total, paymentMethodToken); var payment = attempt.Payment.Result; this.GatewayProviderService.Save(payment); if (!attempt.Payment.Success) { this.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, attempt.Payment.Exception.Message, 0); } else { var customerKey = invoice.CustomerKey.GetValueOrDefault(); var last4 = string.Empty; if (!Guid.Empty.Equals(customerKey)) { var customer = this.BraintreeApiService.Customer.GetBraintreeCustomer(customerKey); if (customer.CreditCards.Any()) { var cc = customer.CreditCards.FirstOrDefault(x => x.Token == paymentMethodToken); if (cc != null) { last4 += " - " + cc.CardType + " " + cc.LastFour; } } } this.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, this.PaymentLineAuthorizeCaptureDescription + " " + last4, payment.Amount); } return attempt; }
/// <summary> /// Authorizes and Captures a Payment /// </summary> /// <param name="paymentGatewayMethod">The <see cref="IPaymentMethod"/></param> /// <param name="args">Additional arguments required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> public override IPaymentResult AuthorizeCapturePayment(IPaymentGatewayMethod paymentGatewayMethod, ProcessorArgumentCollection args) { Mandate.ParameterNotNull(paymentGatewayMethod, "paymentGatewayMethod"); if (!this.IsReadyToInvoice()) return new PaymentResult(Attempt<IPayment>.Fail(new InvalidOperationException("SalesPreparation is not ready to invoice")), null, false); // invoice var invoice = this.PrepareInvoice(this.InvoiceBuilder); this.Context.Services.InvoiceService.Save(invoice); var result = invoice.AuthorizeCapturePayment(paymentGatewayMethod, args); if (result.Payment.Success && this.Context.Settings.EmptyBasketOnPaymentSuccess) this.Context.Customer.Basket().Empty(); this.OnFinalizing(result); return result; }
private IPaymentResult InitializePayment(IInvoice invoice, ProcessorArgumentCollection args) { var payment = GatewayProviderService.CreatePayment(PaymentMethodType.CreditCard, invoice.Total, PaymentMethod.Key); payment.CustomerKey = invoice.CustomerKey; payment.Authorized = false; payment.Collected = false; payment.PaymentMethodName = "SagePay"; GatewayProviderService.Save(payment); var result = ((SagePayFormPaymentProcessor)_processor).InitializePayment(invoice, payment, args); if (!result.Payment.Success) { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, "SagePay: request initialization error: " + result.Payment.Exception.Message, 0); } else { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "SagePay: initialized", 0); } return result; }
/// <summary> /// Authorizes and Captures a Payment /// </summary> /// <param name="invoice">The invoice to be payed</param> /// <param name="amount">The amount of the payment to the invoice</param> /// <param name="args">Additional arguements required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> public IPaymentResult AuthorizeCapturePayment(IInvoice invoice, decimal amount, ProcessorArgumentCollection args) { Mandate.ParameterNotNull(invoice, "invoice"); // persist the invoice if (!invoice.HasIdentity) GatewayProviderService.Save(invoice); // authorize and capture the payment var response = PerformAuthorizeCapturePayment(invoice, amount, args); if (!response.Payment.Success) return response; AssertPaymentApplied(response, invoice); AssertInvoiceStatus(invoice); // Check configuration for override on ApproveOrderCreation if (!response.ApproveOrderCreation) ((PaymentResult)response).ApproveOrderCreation = MerchelloConfiguration.Current.AlwaysApproveOrderCreation; // give response return response; }
/// <summary> /// Performs the actual work of capturing the payment. /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="payment"> /// The payment. /// </param> /// <param name="amount"> /// The amount. /// </param> /// <param name="args"> /// The args. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> protected override IPaymentResult PerformCapturePayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args) { var transaction = payment.ExtendedData.GetBraintreeTransaction(); if (transaction == null) { var error = new NullReferenceException("Braintree transaction could not be found and/or deserialized from payment extended data collection"); return new PaymentResult(Attempt<IPayment>.Fail(payment, error), invoice, false); } var attempt = BraintreeApiService.Transaction.SubmitForSettlement(transaction.Id); if (!attempt.IsSuccess()) { var error = new BraintreeApiException(attempt.Errors, attempt.Message); GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, error.Message, 0); return new PaymentResult(Attempt<IPayment>.Fail(payment, error), invoice, false); } payment.Collected = true; this.GatewayProviderService.Save(payment); this.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, attempt.Message, amount); return new PaymentResult(Attempt<IPayment>.Succeed(payment), invoice, true); }
/// <summary> /// Performs the AuthorizePayment operation. /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="args"> /// The <see cref="ProcessorArgumentCollection"/>. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> /// <remarks> /// For the ExpressCheckout there is not technically an "Authorize" but we use this to start the checkout process and to /// mark intent to pay before redirecting the customer to PayPal. e.g. This method is called after the customer has /// clicked the Pay button, we then save the invoice and "Authorize" a payment setting the invoice status to Unpaid before redirecting. /// IN this way, we have both an Invoice and a Payment (denoting the redirect). When the customer completes the purchase on PayPal sites /// the payment will be used to perform a capture and the invoice status will be changed to Paid. In the event the customer cancels, /// the invoice will either be voided or deleted depending on the configured setting. /// Events are included in the controller handling the response to allow developers to override success and cancel redirect URLs. /// </remarks> protected override IPaymentResult PerformAuthorizePayment(IInvoice invoice, ProcessorArgumentCollection args) { var payment = GatewayProviderService.CreatePayment(PaymentMethodType.Redirect, invoice.Total, PaymentMethod.Key); payment.CustomerKey = invoice.CustomerKey; payment.PaymentMethodName = PaymentMethod.Name; payment.ReferenceNumber = PaymentMethod.PaymentCode + "-" + invoice.PrefixedInvoiceNumber(); payment.Collected = false; payment.Authorized = false; // this is technically not the authorization. We'll mark this in a later step. // Have to save here to generate the payment key GatewayProviderService.Save(payment); // Now we want to get things setup for the ExpressCheckout var record = this._paypalApiService.ExpressCheckout.SetExpressCheckout(invoice, payment); payment.SavePayPalTransactionRecord(record); // Have to save here to persist the record so it can be used in later processing. GatewayProviderService.Save(payment); // In this case, we want to do our own Apply Payment operation as the amount has not been collected - // so we create an applied payment with a 0 amount. Once the payment has been "collected", another Applied Payment record will // be created showing the full amount and the invoice status will be set to Paid. GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, string.Format("To show promise of a {0} payment via PayPal Express Checkout", PaymentMethod.Name), 0); // if the ACK was success return a success IPaymentResult if (record.Success) { return new PaymentResult(Attempt<IPayment>.Succeed(payment), invoice, false, record.SetExpressCheckout.RedirectUrl); } // In the case of a failure, package up the exception so we can bubble it up. var ex = new PayPalApiException("PayPal Checkout Express initial response ACK was not Success"); if (record.SetExpressCheckout.ErrorTypes.Any()) ex.ErrorTypes = record.SetExpressCheckout.ErrorTypes; return new PaymentResult(Attempt<IPayment>.Fail(payment, ex), invoice, false); }
/// <summary> /// Does the actual work of refunding the payment /// </summary> /// <param name="invoice">The invoice to be the payment was applied</param> /// <param name="payment">The payment to be refunded</param> /// <param name="amount">The amount of the payment to be refunded</param> /// <param name="args">Additional arguments required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> protected abstract IPaymentResult PerformRefundPayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args);
/// <summary> /// Does the actual work of authorizing and capturing a payment /// </summary> /// <param name="invoice">The <see cref="IInvoice"/></param> /// <param name="amount">The amount to capture</param> /// <param name="args">Any arguments required to process the payment.</param> /// <returns>The <see cref="IPaymentResult"/></returns> protected override IPaymentResult PerformAuthorizeCapturePayment(IInvoice invoice, decimal amount, ProcessorArgumentCollection args) { return(ProcessPayment(invoice, TransactionMode.AuthorizeAndCapture, amount, args)); }
/// <summary> /// The perform authorize payment. /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="args"> /// The args. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> protected override IPaymentResult PerformAuthorizePayment(IInvoice invoice, ProcessorArgumentCollection args) { throw new NotImplementedException(); }
/// <summary> /// Performs the actual work of performing the refund. /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="payment"> /// The payment. /// </param> /// <param name="amount"> /// The amount. /// </param> /// <param name="args"> /// The args. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> protected override IPaymentResult PerformRefundPayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args) { var transaction = payment.ExtendedData.GetBraintreeTransaction(); if (transaction == null) { var error = new NullReferenceException("Braintree transaction could not be found and/or deserialized from payment extended data collection"); return(new PaymentResult(Attempt <IPayment> .Fail(payment, error), invoice, false)); } var attempt = BraintreeApiService.Transaction.Refund(transaction.Id, amount); if (!attempt.IsSuccess()) { var error = new BraintreeApiException(attempt.Errors, attempt.Message); GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Refund, error.Message, 0); return(new PaymentResult(Attempt <IPayment> .Fail(payment, error), invoice, false)); } payment.Amount = payment.Amount - amount; if (payment.Amount != 0) { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "To show partial payment remaining after refund", payment.Amount); } GatewayProviderService.Save(payment); return(new PaymentResult(Attempt <IPayment> .Succeed(payment), invoice, false)); }
private PaymentDetailsType CreatePayPalPaymentDetails(IInvoice invoice, ProcessorArgumentCollection args = null) { string articleBySkuPath = args.GetArticleBySkuPath(_settings.ArticleBySkuPath.IsEmpty() ? null : GetWebsiteUrl() + _settings.ArticleBySkuPath); var currencyCodeType = PayPalCurrency(invoice.CurrencyCode()); var currencyDecimals = CurrencyDecimals(currencyCodeType); decimal itemTotal = 0; decimal taxTotal = 0; decimal shippingTotal = 0; AddressType shipAddress = null; var paymentDetailItems = new List <PaymentDetailsItemType>(); foreach (var item in invoice.Items) { if (item.LineItemTfKey == Merchello.Core.Constants.TypeFieldKeys.LineItem.TaxKey) { taxTotal = item.TotalPrice; } else if (item.LineItemTfKey == Merchello.Core.Constants.TypeFieldKeys.LineItem.ShippingKey) { shippingTotal = item.TotalPrice; var address = item.ExtendedData.GetAddress(Merchello.Core.AddressType.Shipping); if (address != null) { shipAddress = new AddressType() { Name = address.Name, Street1 = address.Address1, Street2 = address.Address2, PostalCode = address.PostalCode, CityName = address.Locality, StateOrProvince = address.Region, CountryName = address.Country().Name, Country = (CountryCodeType)Enum.Parse(typeof(CountryCodeType), address.Country().CountryCode, true), Phone = address.Phone }; } } else { var paymentItem = new PaymentDetailsItemType { Name = item.Name, ItemURL = (articleBySkuPath.IsEmpty() ? null : articleBySkuPath + item.Sku), Amount = new BasicAmountType(currencyCodeType, PriceToString(item.Price, currencyDecimals)), Quantity = item.Quantity, }; paymentDetailItems.Add(paymentItem); itemTotal += item.TotalPrice; } } var paymentDetails = new PaymentDetailsType { PaymentDetailsItem = paymentDetailItems, ItemTotal = new BasicAmountType(currencyCodeType, PriceToString(itemTotal, currencyDecimals)), TaxTotal = new BasicAmountType(currencyCodeType, PriceToString(taxTotal, currencyDecimals)), ShippingTotal = new BasicAmountType(currencyCodeType, PriceToString(shippingTotal, currencyDecimals)), OrderTotal = new BasicAmountType(currencyCodeType, PriceToString(itemTotal + taxTotal + shippingTotal, currencyDecimals)), PaymentAction = PaymentActionCodeType.ORDER, InvoiceID = invoice.InvoiceNumberPrefix + invoice.InvoiceNumber.ToString("0"), SellerDetails = new SellerDetailsType { PayPalAccountID = _settings.AccountId }, PaymentRequestID = "PaymentRequest", ShipToAddress = shipAddress, NotifyURL = "http://IPNhost" }; return(paymentDetails); }
/// <summary> /// Processes the Authorize and AuthorizeAndCapture transactions /// </summary> /// <param name="invoice">The <see cref="IInvoice"/> to be paid</param> /// <param name="payment">The <see cref="IPayment"/> record</param> /// <param name="args"></param> /// <returns>The <see cref="IPaymentResult"/></returns> public IPaymentResult InitializePayment(IInvoice invoice, IPayment payment, ProcessorArgumentCollection args) { var setExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType(); Func <string, string> adjustUrl = (url) => { if (!url.StartsWith("http")) { url = GetWebsiteUrl() + (url[0] == '/' ? "" : "/") + url; } url = url.Replace("{invoiceKey}", invoice.Key.ToString(), StringComparison.InvariantCultureIgnoreCase); url = url.Replace("{paymentKey}", payment.Key.ToString(), StringComparison.InvariantCultureIgnoreCase); url = url.Replace("{paymentMethodKey}", payment.PaymentMethodKey.ToString(), StringComparison.InvariantCultureIgnoreCase); return(url); }; // Save ReturnUrl and CancelUrl in ExtendedData. // They will be usefull in PayPalApiController. var returnUrl = args.GetReturnUrl(); if (returnUrl.IsEmpty()) { returnUrl = _settings.ReturnUrl; } if (returnUrl.IsEmpty()) { returnUrl = "/"; } returnUrl = adjustUrl(returnUrl); payment.ExtendedData.SetValue(Constants.ExtendedDataKeys.ReturnUrl, returnUrl); var cancelUrl = args.GetCancelUrl(); if (cancelUrl.IsEmpty()) { cancelUrl = _settings.CancelUrl; } if (cancelUrl.IsEmpty()) { cancelUrl = "/"; } cancelUrl = adjustUrl(cancelUrl); payment.ExtendedData.SetValue(Constants.ExtendedDataKeys.CancelUrl, cancelUrl); // Set ReturnUrl and CancelUrl of PayPal request to PayPalApiController. setExpressCheckoutRequestDetails.ReturnURL = adjustUrl("/umbraco/MerchelloPayPal/PayPalApi/SuccessPayment?InvoiceKey={invoiceKey}&PaymentKey={paymentKey}"); setExpressCheckoutRequestDetails.CancelURL = adjustUrl("/umbraco/MerchelloPayPal/PayPalApi/AbortPayment?InvoiceKey={invoiceKey}&PaymentKey={paymentKey}"); //setExpressCheckoutRequestDetails.OrderDescription = "#" + invoice.InvoiceNumber; setExpressCheckoutRequestDetails.PaymentDetails = new List <PaymentDetailsType> { CreatePayPalPaymentDetails(invoice, args) }; var setExpressCheckout = new SetExpressCheckoutReq() { SetExpressCheckoutRequest = new SetExpressCheckoutRequestType(setExpressCheckoutRequestDetails) }; try { var response = GetPayPalService().SetExpressCheckout(setExpressCheckout); if (response.Ack != AckCodeType.SUCCESS && response.Ack != AckCodeType.SUCCESSWITHWARNING) { return(new PaymentResult(Attempt <IPayment> .Fail(payment, CreateErrorResult(response.Errors)), invoice, false)); } var redirectUrl = string.Format("https://www.{0}paypal.com/cgi-bin/webscr?cmd=_express-checkout&token={1}", (_settings.LiveMode ? "" : "sandbox."), response.Token); payment.ExtendedData.SetValue("RedirectUrl", redirectUrl); return(new PaymentResult(Attempt <IPayment> .Succeed(payment), invoice, true)); } catch (Exception ex) { return(new PaymentResult(Attempt <IPayment> .Fail(payment, ex), invoice, true)); } }
/// <summary> /// Captures a payment for the <see cref="IInvoice"/> /// </summary> /// <param name="invoice">The invoice to be paid</param> /// <param name="payment">The payment to capture</param> /// <param name="amount">The amount of the payment to be captured</param> /// <param name="args">Additional arguments required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> public virtual IPaymentResult CapturePayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args) { Mandate.ParameterNotNull(invoice, "invoice"); var operationData = new PaymentOperationData() { Invoice = invoice, Payment = payment, Amount = amount, ProcessorArgumentCollection = args }; Capturing.RaiseEvent(new SaveEventArgs <PaymentOperationData>(operationData), this); // persist the invoice if (!invoice.HasIdentity) { GatewayProviderService.Save(invoice); } var response = PerformCapturePayment(invoice, payment, amount, args); //((PaymentResult)response).ApproveOrderCreation = this.EnsureApproveOrderCreation(response, invoice); // Special case where the order has already been created due to configuration override. if (invoice.Orders.Any() && response.ApproveOrderCreation) { ((PaymentResult)response).ApproveOrderCreation = false; } CaptureAttempted.RaiseEvent(new PaymentAttemptEventArgs <IPaymentResult>(response), this); if (!response.Payment.Success) { return(response); } AssertPaymentApplied(response, invoice); AssertInvoiceStatus(invoice); // give response return(response); }
/// <summary> /// Refunds a payment /// </summary> /// <param name="invoice">The invoice to be the payment was applied</param> /// <param name="payment">The payment to be refunded</param> /// <param name="amount">The amount to be refunded</param> /// <param name="args">Additional arguments required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> public virtual IPaymentResult RefundPayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args) { Mandate.ParameterNotNull(invoice, "invoice"); if (!invoice.HasIdentity) { return(new PaymentResult(Attempt <IPayment> .Fail(new InvalidOperationException("Cannot refund a payment on an invoice that cannot have payments")), invoice, false)); } var operationData = new PaymentOperationData() { Invoice = invoice, Payment = payment, Amount = amount, ProcessorArgumentCollection = args }; Refunding.RaiseEvent(new SaveEventArgs <PaymentOperationData>(operationData), this); var response = PerformRefundPayment(invoice, payment, amount, args); RefundAttempted.RaiseEvent(new PaymentAttemptEventArgs <IPaymentResult>(response), this); if (!response.Payment.Success) { return(response); } AssertInvoiceStatus(invoice); // Force the ApproveOrderCreation to false if (response.ApproveOrderCreation) { ((PaymentResult)response).ApproveOrderCreation = false; } // give response return(response); }
/// <summary> /// Voids a payment /// </summary> /// <param name="invoice">The invoice associated with the payment to be voided</param> /// <param name="payment">The payment to be voided</param> /// <param name="args">Additional arguments required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> public virtual IPaymentResult VoidPayment(IInvoice invoice, IPayment payment, ProcessorArgumentCollection args) { Mandate.ParameterNotNull(invoice, "invoice"); if (!invoice.HasIdentity) { return(new PaymentResult(Attempt <IPayment> .Fail(new InvalidOperationException("Cannot void a payment on an invoice that cannot have payments")), invoice, false)); } var operationData = new PaymentOperationData() { Invoice = invoice, Payment = payment, ProcessorArgumentCollection = args }; Voiding.RaiseEvent(new SaveEventArgs <PaymentOperationData>(operationData), this); var response = PerformVoidPayment(invoice, payment, args); VoidAttempted.RaiseEvent(new PaymentAttemptEventArgs <IPaymentResult>(response), this); if (!response.Payment.Success) { return(response); } var appliedPayments = payment.AppliedPayments().Where(x => x.TransactionType != AppliedPaymentType.Void); foreach (var appliedPayment in appliedPayments) { appliedPayment.TransactionType = AppliedPaymentType.Void; appliedPayment.Amount = 0; GatewayProviderService.Save(appliedPayment); } // Assert the payment has been voided if (!payment.Voided) { payment.Voided = true; GatewayProviderService.Save(payment); } AssertInvoiceStatus(invoice); // Force the ApproveOrderCreation to false if (response.ApproveOrderCreation) { ((PaymentResult)response).ApproveOrderCreation = false; } // give response return(response); }
private static string ArgValue(this ProcessorArgumentCollection args, string key) { return(args.ContainsKey(key) ? args[key] : string.Empty); }
/// <summary> /// Does the actual work of creating and authorizing the payment /// </summary> /// <param name="invoice">The <see cref="IInvoice"/></param> /// <param name="args">Any arguments required to process the payment. (Maybe a username, password or some API Key)</param> /// <returns>The <see cref="IPaymentResult"/></returns> protected abstract IPaymentResult PerformAuthorizePayment(IInvoice invoice, ProcessorArgumentCollection args);
/// <summary> /// Does the actual work of creating and processing the payment /// </summary> /// <param name="invoice">The <see cref="IInvoice"/></param> /// <param name="args">Any arguments required to process the payment.</param> /// <returns>The <see cref="IPaymentResult"/></returns> protected override IPaymentResult PerformAuthorizePayment(IInvoice invoice, ProcessorArgumentCollection args) { return(ProcessPayment(invoice, TransactionMode.Authorize, invoice.Total, args)); }
/// <summary> /// Doe the actual work of Authorizes and Captures a Payment /// </summary> /// <param name="invoice">The invoice to be paid</param> /// <param name="amount">The amount of the payment to the invoice</param> /// <param name="args">Additional arguments required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> protected abstract IPaymentResult PerformAuthorizeCapturePayment(IInvoice invoice, decimal amount, ProcessorArgumentCollection args);
/// <summary> /// Authorizes and Captures a Payment /// </summary> /// <param name="paymentMethodKey">The <see cref="IPaymentMethod"/> key</param> /// <param name="args">Additional arguments required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> public virtual IPaymentResult AuthorizeCapturePayment(Guid paymentMethodKey, ProcessorArgumentCollection args) { var paymentMethod = _merchelloContext.Gateways.Payment.GetPaymentGatewayMethods().FirstOrDefault(x => x.PaymentMethod.Key.Equals(paymentMethodKey)); return(AuthorizeCapturePayment(paymentMethod, args)); }
/// <summary> /// Authorizes and Captures a Payment /// </summary> /// <param name="paymentGatewayMethod">The <see cref="IPaymentMethod"/></param> /// <param name="args">Additional arguments required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> public virtual IPaymentResult AuthorizeCapturePayment(IPaymentGatewayMethod paymentGatewayMethod, ProcessorArgumentCollection args) { Mandate.ParameterNotNull(paymentGatewayMethod, "paymentGatewayMethod"); if (!IsReadyToInvoice()) { return(new PaymentResult(Attempt <IPayment> .Fail(new InvalidOperationException("SalesPreparation is not ready to invoice")), null, false)); } // invoice var invoice = PrepareInvoice(new InvoiceBuilderChain(this)); MerchelloContext.Services.InvoiceService.Save(invoice); var result = invoice.AuthorizeCapturePayment(paymentGatewayMethod, args); Finalizing.RaiseEvent(new SalesPreparationEventArgs <IPaymentResult>(result), this); return(result); }
/// <summary> /// Authorizes and Captures a Payment /// </summary> /// <param name="invoice">The invoice to be paid</param> /// <param name="amount">The amount of the payment to the invoice</param> /// <param name="args">Additional arguments required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> public virtual IPaymentResult AuthorizeCapturePayment(IInvoice invoice, decimal amount, ProcessorArgumentCollection args) { Mandate.ParameterNotNull(invoice, "invoice"); var operationData = new PaymentOperationData() { Invoice = invoice, Amount = amount, ProcessorArgumentCollection = args }; Capturing.RaiseEvent(new SaveEventArgs <PaymentOperationData>(operationData), this); // persist the invoice if (!invoice.HasIdentity) { GatewayProviderService.Save(invoice); } // authorize and capture the payment var response = PerformAuthorizeCapturePayment(invoice, amount, args); //((PaymentResult)response).ApproveOrderCreation = this.EnsureApproveOrderCreation(response, invoice); AuthorizeCaptureAttempted.RaiseEvent(new PaymentAttemptEventArgs <IPaymentResult>(response), this); if (!response.Payment.Success) { return(response); } AssertPaymentApplied(response, invoice); AssertInvoiceStatus(invoice); // Check configuration for override on ApproveOrderCreation if (!response.ApproveOrderCreation) { ((PaymentResult)response).ApproveOrderCreation = MerchelloConfiguration.Current.AlwaysApproveOrderCreation; } // give response return(response); }
protected override IPaymentResult PerformVoidPayment(IInvoice invoice, IPayment payment, ProcessorArgumentCollection args) { throw new System.NotImplementedException(); }
protected override IPaymentResult PerformAuthorizeCapturePayment(IInvoice invoice, decimal amount, ProcessorArgumentCollection args) { throw new System.NotImplementedException(); }
/// <summary> /// Performs the actual work of capturing the payment. /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="payment"> /// The payment. /// </param> /// <param name="amount"> /// The amount. /// </param> /// <param name="args"> /// The args. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> protected override IPaymentResult PerformCapturePayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args) { var transaction = payment.ExtendedData.GetBraintreeTransaction(); if (transaction == null) { var error = new NullReferenceException("Braintree transaction could not be found and/or deserialized from payment extended data collection"); return(new PaymentResult(Attempt <IPayment> .Fail(payment, error), invoice, false)); } var attempt = BraintreeApiService.Transaction.SubmitForSettlement(transaction.Id); if (!attempt.IsSuccess()) { var error = new BraintreeApiException(attempt.Errors, attempt.Message); GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, error.Message, 0); return(new PaymentResult(Attempt <IPayment> .Fail(payment, error), invoice, false)); } payment.Collected = true; this.GatewayProviderService.Save(payment); this.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, attempt.Message, amount); return(new PaymentResult(Attempt <IPayment> .Succeed(payment), invoice, true)); }
/// <summary> /// The perform authorize capture payment. /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="amount"> /// The amount. /// </param> /// <param name="args"> /// The args. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> protected override IPaymentResult PerformAuthorizeCapturePayment(IInvoice invoice, decimal amount, ProcessorArgumentCollection args) { var payment = GatewayProviderService.CreatePayment(PaymentMethodType.Cash, amount, PaymentMethod.Key); payment.CustomerKey = invoice.CustomerKey; payment.PaymentMethodName = PaymentMethod.Name + " " + PaymentMethod.PaymentCode; payment.ReferenceNumber = PaymentMethod.PaymentCode + "-" + invoice.PrefixedInvoiceNumber(); payment.Collected = true; payment.Authorized = true; GatewayProviderService.Save(payment); GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "Cash payment", amount); return(new PaymentResult(Attempt <IPayment> .Succeed(payment), invoice, CalculateTotalOwed(invoice).CompareTo(amount) <= 0)); }
/// <summary> /// Performs the actual work of authorizing and capturing a payment. /// </summary> /// <param name="invoice"> /// The invoice. /// </param> /// <param name="amount"> /// The amount. /// </param> /// <param name="args"> /// The args. /// </param> /// <returns> /// The <see cref="IPaymentResult"/>. /// </returns> /// <remarks> /// This is a transaction with SubmitForSettlement = true /// </remarks> protected override IPaymentResult PerformAuthorizeCapturePayment(IInvoice invoice, decimal amount, ProcessorArgumentCollection args) { var paymentMethodNonce = args.GetPaymentMethodNonce(); if (string.IsNullOrEmpty(paymentMethodNonce)) { var error = new InvalidOperationException("No payment method nonce was found in the ProcessorArgumentCollection"); LogHelper.Debug <BraintreeStandardTransactionPaymentGatewayMethod>(error.Message); return(new PaymentResult(Attempt <IPayment> .Fail(error), invoice, false)); } // TODO this is a total last minute hack var email = string.Empty; if (args.ContainsKey("customerEmail")) { email = args["customerEmail"]; } var attempt = this.ProcessPayment(invoice, TransactionOption.SubmitForSettlement, invoice.Total, paymentMethodNonce, email); var payment = attempt.Payment.Result; this.GatewayProviderService.Save(payment); if (!attempt.Payment.Success) { this.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, attempt.Payment.Exception.Message, 0); } else { this.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "Braintree PayPal one time transaction - authorized and captured", amount); } return(attempt); }
/// <summary> /// Does the actual work of voiding a payment /// </summary> /// <param name="invoice">The invoice to which the payment is associated</param> /// <param name="payment">The payment to be voided</param> /// <param name="args">Additional arguements required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> protected override IPaymentResult PerformVoidPayment(IInvoice invoice, IPayment payment, ProcessorArgumentCollection args) { foreach (var applied in payment.AppliedPayments()) { applied.TransactionType = AppliedPaymentType.Void; applied.Amount = 0; applied.Description += " - **Void**"; GatewayProviderService.Save(applied); } payment.Voided = true; GatewayProviderService.Save(payment); return(new PaymentResult(Attempt <IPayment> .Succeed(payment), invoice, false)); }
/// <summary> /// Does the actual work capturing a payment /// </summary> /// <param name="invoice">The <see cref="IInvoice"/></param> /// <param name="payment">The previously Authorize payment to be captured</param> /// <param name="amount">The amount to capture</param> /// <param name="args">Any arguments required to process the payment.</param> /// <returns>The <see cref="IPaymentResult"/></returns> protected override IPaymentResult PerformCapturePayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args) { var result = _processor.PriorAuthorizeCapturePayment(invoice, payment); GatewayProviderService.Save(payment); if (!result.Payment.Success) { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, result.Payment.Exception.Message, 0); } else { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, payment.ExtendedData.GetValue(Constants.ExtendedDataKeys.CaptureTransactionResult), amount); } return(result); }
/// <summary> /// Does the actual work of refunding the payment /// </summary> /// <param name="invoice">The invoice to be the payment was applied</param> /// <param name="payment">The payment to be refunded</param> /// <param name="amount">The amount of the payment to be refunded</param> /// <param name="args">Additional arguements required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> protected override IPaymentResult PerformRefundPayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args) { foreach (var applied in payment.AppliedPayments()) { applied.TransactionType = AppliedPaymentType.Refund; applied.Amount = 0; applied.Description += " - Refunded"; GatewayProviderService.Save(applied); } payment.Amount = payment.Amount - amount; if (payment.Amount != 0) { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "To show partial payment remaining after refund", payment.Amount); } GatewayProviderService.Save(payment); return(new PaymentResult(Attempt <IPayment> .Succeed(payment), invoice, false)); }
private IPaymentResult ProcessPayment(IInvoice invoice, TransactionMode transactionMode, decimal amount, ProcessorArgumentCollection args) { var cc = args.AsCreditCardFormData(); var payment = GatewayProviderService.CreatePayment(PaymentMethodType.CreditCard, invoice.Total, PaymentMethod.Key); payment.CustomerKey = invoice.CustomerKey; payment.Authorized = false; payment.Collected = false; payment.PaymentMethodName = string.Format("{0} Authorize.Net Credit Card", cc.CreditCardType); payment.ExtendedData.SetValue(Constants.ExtendedDataKeys.CcLastFour, cc.CardNumber.Substring(cc.CardNumber.Length - 4, 4).EncryptWithMachineKey()); var result = _processor.ProcessPayment(invoice, payment, transactionMode, amount, cc); GatewayProviderService.Save(payment); if (!result.Payment.Success) { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, result.Payment.Exception.Message, 0); } else { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, payment.ExtendedData.GetValue(Constants.ExtendedDataKeys.AuthorizationTransactionResult) + (transactionMode == TransactionMode.AuthorizeAndCapture ? string.Empty : " to show record of Authorization"), transactionMode == TransactionMode.AuthorizeAndCapture ? invoice.Total : 0); } return(result); }
/// <summary> /// Does the actual work of capturing a payment /// </summary> /// <param name="invoice">The <see cref="IInvoice"/></param> /// <param name="payment">the <see cref="IPayment"/></param> /// <param name="amount">The amount</param> /// <param name="args">Any arguments required to process the payment. (Maybe a username, password or some Api Key)</param> /// <returns>The <see cref="IPaymentResult"/></returns> protected override IPaymentResult PerformCapturePayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args) { payment.Collected = true; payment.Authorized = true; GatewayProviderService.Save(payment); GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "Cash payment", amount); return(new PaymentResult(Attempt <IPayment> .Succeed(payment), invoice, CalculateTotalOwed(invoice).CompareTo(amount) <= 0)); }
/// <summary> /// Does the actual work capturing a payment /// </summary> /// <param name="invoice">The <see cref="IInvoice"/></param> /// <param name="payment">The previously Authorize payment to be captured</param> /// <param name="amount">The amount to capture</param> /// <param name="args">Any arguments required to process the payment.</param> /// <returns>The <see cref="IPaymentResult"/></returns> protected override IPaymentResult PerformCapturePayment(IInvoice invoice, IPayment payment, decimal amount, ProcessorArgumentCollection args) { var payedTotalList = invoice.AppliedPayments().Select(item => item.Amount).ToList(); var payedTotal = (payedTotalList.Count == 0 ? 0 : payedTotalList.Aggregate((a, b) => a + b)); var isPartialPayment = amount + payedTotal < invoice.Total; var result = _processor.CapturePayment(invoice, payment, amount, isPartialPayment); //GatewayProviderService.Save(payment); if (!result.Payment.Success) { //payment.VoidPayment(invoice, payment.PaymentMethodKey.Value); GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, "Sagepay: request capture error: " + result.Payment.Exception.Message, 0); } else { GatewayProviderService.Save(payment); GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "Sagepay: captured", amount); //GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, payment.ExtendedData.GetValue(Constants.ExtendedDataKeys.CaptureTransactionResult), amount); } return(result); }
/// <summary> /// Does the actual work of voiding a payment /// </summary> /// <param name="invoice">The invoice to which the payment is associated</param> /// <param name="payment">The payment to be voided</param> /// <param name="args">Additional arguments required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> protected abstract IPaymentResult PerformVoidPayment(IInvoice invoice, IPayment payment, ProcessorArgumentCollection args);
/// <summary> /// Does the actual work of creating and processing the payment /// </summary> /// <param name="invoice">The <see cref="IInvoice"/></param> /// <param name="args">Any arguments required to process the payment.</param> /// <returns>The <see cref="IPaymentResult"/></returns> protected override IPaymentResult PerformAuthorizePayment(IInvoice invoice, ProcessorArgumentCollection args) { return(InitializePayment(invoice, args)); }
/// <summary> /// Does the actual work of voiding a payment /// </summary> /// <param name="invoice">The invoice to which the payment is associated</param> /// <param name="payment">The payment to be voided</param> /// <param name="args">Additional arguements required by the payment processor</param> /// <returns>A <see cref="IPaymentResult"/></returns> protected override IPaymentResult PerformVoidPayment(IInvoice invoice, IPayment payment, ProcessorArgumentCollection args) { var result = _processor.VoidPayment(invoice, payment); if (!result.Payment.Success) { GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, result.Payment.Exception.Message, 0); return(result); } // use the overloaded AppliedPayments method here for testing if we don't have // a MerchelloContext foreach (var applied in payment.AppliedPayments(GatewayProviderService)) { applied.TransactionType = AppliedPaymentType.Refund; applied.Amount = 0; applied.Description += " - **Void**"; GatewayProviderService.Save(applied); } payment.Voided = true; GatewayProviderService.Save(payment); return(new PaymentResult(Attempt <IPayment> .Succeed(payment), invoice, false)); }