/// <summary> /// This method allows you void an authorized but not captured payment. In this case a Void button will be visible on the /// order details page in admin area. Note that an order should be authorized and SupportVoid property should return true. /// </summary> /// <param name="voidPaymentRequest">Request</param> /// <returns>Result</returns> public VoidPaymentResult Void(VoidPaymentRequest voidPaymentRequest) { var result = new VoidPaymentResult(); Order order = voidPaymentRequest.Order; if (int.TryParse(order.AuthorizationTransactionId, out int transactionNumber)) { PayexInterface payex = GetPayexInterface(); CancelResult cancelResult = payex.Cancel(transactionNumber).GetAwaiter().GetResult(); if (cancelResult.IsRequestSuccessful) { result.NewPaymentStatus = PaymentStatus.Voided; } else { result.AddError(cancelResult.GetErrorDescription()); } } else { result.AddError( string.Format( "The order did not contain a valid TransactionNumber in the AuthorizationTransactionId field ('{0}').", order.AuthorizationTransactionId)); } return(result); }
internal Task <CompleteResult> Complete(string orderRef) { PayexInterface payex = GetPayexInterface(); var result = payex.Complete(orderRef); return(result); }
/// <summary> /// This method allows you make a refund. In this case a Refund button will be visible on the order details page in admin /// area. Note that an order should be paid, and SupportRefund or SupportPartiallyRefund property should return true. /// </summary> /// <param name="refundPaymentRequest">Request</param> /// <returns>Result</returns> public RefundPaymentResult Refund(RefundPaymentRequest refundPaymentRequest) { var result = new RefundPaymentResult(); Order order = refundPaymentRequest.Order; if (int.TryParse(order.CaptureTransactionId, out int transactionNumber)) { decimal amount = Math.Round(refundPaymentRequest.AmountToRefund, 2); PayexInterface payex = GetPayexInterface(); CreditResult creditResult = payex.Credit(transactionNumber, amount, order.OrderGuid.ToString()) .GetAwaiter().GetResult(); if (creditResult.IsRequestSuccessful) { // NOTE: We should save the transaction id for the refund, but no field is available in order. // Add order note var note = new StringBuilder(); note.AppendLine("PayEx: Credit succeeded"); note.AppendLine(string.Format("Credited amount: {0:n2}", amount)); note.AppendLine("TransactionNumber: " + creditResult.TransactionNumber); note.AppendLine("TransactionStatus: " + creditResult.TransactionStatus); order.OrderNotes.Add( new OrderNote { Note = note.ToString(), DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(order); // Set new payment status if (refundPaymentRequest.IsPartialRefund && refundPaymentRequest.AmountToRefund + order.RefundedAmount < order.OrderTotal) { result.NewPaymentStatus = PaymentStatus.PartiallyRefunded; } else { result.NewPaymentStatus = PaymentStatus.Refunded; } } else { result.AddError(creditResult.GetErrorDescription()); } } else { result.AddError( string.Format( "The order did not contain a valid TransactionNumber in the AuthorizationTransactionId field ('{0}').", order.AuthorizationTransactionId)); } return(result); }
/// <summary> /// Some payment gateways allow you to authorize payments before they're captured. It allows store owners to review order /// details before the payment is actually done. /// </summary> /// <param name="capturePaymentRequest">Capture payment request</param> /// <returns>Capture payment result</returns> public CapturePaymentResult Capture(CapturePaymentRequest capturePaymentRequest) { var result = new CapturePaymentResult(); Order order = capturePaymentRequest.Order; if (int.TryParse(order.AuthorizationTransactionId, out int transactionNumber)) { decimal amount = Math.Round(order.OrderTotal, 2); PayexInterface payex = GetPayexInterface(); CaptureResult captureResult = payex.Capture(transactionNumber, amount, order.OrderGuid.ToString()) .GetAwaiter().GetResult(); result.CaptureTransactionResult = captureResult.ErrorCode; result.CaptureTransactionId = captureResult.TransactionNumber; if (captureResult.IsTransactionSuccessful) { result.NewPaymentStatus = PaymentStatus.Paid; // Add order note var note = new StringBuilder(); note.AppendLine("PayEx: Capture succeeded"); note.AppendLine(string.Format("Amount: {0:n2}", amount)); note.AppendLine("TransactionNumber: " + captureResult.TransactionNumber); note.AppendLine("TransactionStatus: " + captureResult.TransactionStatus); order.OrderNotes.Add( new OrderNote { Note = note.ToString(), DisplayToCustomer = false, CreatedOnUtc = DateTime.UtcNow }); _orderService.UpdateOrder(order); } else { result.AddError(captureResult.GetErrorDescription()); } } else { result.Errors.Add( string.Format( "The order did not contain a valid TransactionNumber in the AuthorizationTransactionId field ('{0}').", order.AuthorizationTransactionId)); } return(result); }
private PayexInterface GetPayexInterface() { PayexAccount account; if (_payExPaymentSettings.AccountNumber > 0) { account = new PayexAccount(_payExPaymentSettings.AccountNumber, _payExPaymentSettings.EncryptionKey); } else { account = new PayexAccount(TestAccount, TestEncryptionKey); } PayexInterface payex = new PayexInterface(account); payex.UseTestEnvironment = _payExPaymentSettings.UseTestEnvironment || _payExPaymentSettings.AccountNumber <= 0; return(payex); }
private async Task <bool> AddOrderLine( PayexInterface payex, string orderRef, string itemNumber, string itemDescription, int quantity, decimal amount) { if (string.IsNullOrEmpty(itemNumber)) { return(true); // Skip } BaseResult lineResult = await payex.AddSingleOrderLine( new AddSingleOrderLineRequest { OrderRef = orderRef, ItemNumber = itemNumber, ItemDescription1 = itemDescription, Quantity = quantity, Amount = amount, }); return(lineResult.IsRequestSuccessful); }
/// <summary> /// Post process payment (used by payment gateways that require redirecting to a third-party URL) /// </summary> /// <param name="postProcessPaymentRequest">Payment info required for an order processing</param> public void PostProcessPayment(PostProcessPaymentRequest postProcessPaymentRequest) { Order order = postProcessPaymentRequest.Order; // Make sure order is not already paid or authorized if (order.PaymentStatus == PaymentStatus.Paid || order.PaymentStatus == PaymentStatus.Authorized) { return; } string currencyCode = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId).CurrencyCode; string description = string.Format("{0} - Order", _storeContext.CurrentStore.Name); string userAgent; if (_httpContextAccessor.HttpContext.Request != null) { userAgent = _httpContextAccessor.HttpContext.Request.Headers["User-Agent"].ToString(); } else { userAgent = null; } string returnUrl = _webHelper.GetStoreLocation(false) + "Plugins/PaymentPayEx/Complete"; string cancelUrl = _webHelper.GetStoreLocation(false) + "Plugins/PaymentPayEx/CancelOrder?id=" + order.Id; PayexInterface payex = GetPayexInterface(); string agreementRef = null; // If the customer wishes to save his payment details, we make an agreement. // This should be saved later in the complete operation, if it occurs. agreementRef = TryGetAgreementRef(_paymentService.DeserializeCustomValues(order)); if (agreementRef == "new") { CreateAgreementRequest agreementRequest = new CreateAgreementRequest { PurchaseOperation = GetPurchaseOperation(), MerchantRef = order.OrderGuid.ToString(), MaxAmount = _payExPaymentSettings.AgreementMaxAmount, Description = description, }; CreateAgreementResult agreementResult = payex.CreateAgreement(agreementRequest).GetAwaiter().GetResult(); if (agreementResult.IsRequestSuccessful) { agreementRef = agreementResult.AgreementRef; } else { _logger.Error( string.Format("PayEx: CreateAgreement (for AutoPay) failed for order {0}.", order.Id), new NopException(agreementResult.GetErrorDescription()), order.Customer); } } // Initialize the purchase and get the redirect URL InitializeRequest request = new InitializeRequest { PurchaseOperation = GetPurchaseOperation(), Amount = order.OrderTotal, CurrencyCode = currencyCode, OrderID = order.OrderGuid.ToString(), ProductNumber = "ncOrder", Description = description, AgreementRef = agreementRef, //VatPercent = 100M * order.OrderTax / order.OrderTotal, ClientIPAddress = order.CustomerIp, UserAgent = userAgent, ReturnURL = returnUrl, CancelUrl = cancelUrl, View = PaymentView, ClientLanguage = _workContext.WorkingLanguage?.LanguageCulture, }; BeforeInitialize(postProcessPaymentRequest, request); InitializeResult result = payex.Initialize(request).GetAwaiter().GetResult(); if (result.IsRequestSuccessful) { // Save OrderRef in case TransactionCallback fails or is implemented externally. order.AuthorizationTransactionCode = result.OrderRef; _orderService.UpdateOrder(order); if (_payExPaymentSettings.PassProductNamesAndTotals) { AddOrderLines(payex, result.OrderRef, order); } // Redirect to PayEx _httpContextAccessor.HttpContext.Response.Redirect(result.RedirectUrl); } else { throw new NopException(result.GetErrorDescription()); } }
/// <summary> /// This method is always invoked right before a customer places an order. /// Use it when you need to process a payment before an order is stored into database. /// For example, capture or authorize credit card. Usually this method is used when a customer /// is not redirected to third-party site for completing a payment and all payments /// are handled on your site (for example, PayPal Direct). /// </summary> /// <param name="processPaymentRequest">Payment info required for an order processing</param> /// <returns>Process payment result</returns> public ProcessPaymentResult ProcessPayment(ProcessPaymentRequest processPaymentRequest) { var result = new ProcessPaymentResult(); result.NewPaymentStatus = PaymentStatus.Pending; // Use an existing agreement to make the payment, if the customer chose this option. if (!processPaymentRequest.CustomValues.TryGetValue(AgreementRefKey, out object agreementRefObject) || agreementRefObject == null) { return(result); } var agreementRef = TryGetAgreementRef(processPaymentRequest.CustomValues); if (!string.IsNullOrEmpty(agreementRef) && agreementRef != "new") { string currencyCode = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId) .CurrencyCode; string description = string.Format("{0} - Order", _storeContext.CurrentStore.Name); AutoPayRequest request = new AutoPayRequest { PurchaseOperation = GetPurchaseOperation(), Amount = processPaymentRequest.OrderTotal, CurrencyCode = currencyCode, OrderID = processPaymentRequest.OrderGuid.ToString(), ProductNumber = "ncOrder", Description = description, AgreementRef = agreementRef, }; PayexInterface payex = GetPayexInterface(); AutoPayResult autopayResult = payex.AutoPay(request).GetAwaiter().GetResult(); // Check result and set new payment status if (autopayResult.IsTransactionSuccessful) { result.SubscriptionTransactionId = agreementRef; if (autopayResult.TransactionStatus.Value == Enumerations.TransactionStatusCode.Authorize) { result.NewPaymentStatus = PaymentStatus.Authorized; result.AuthorizationTransactionId = autopayResult.TransactionNumber; result.AuthorizationTransactionResult = autopayResult.ErrorCode; } else if (autopayResult.TransactionStatus.Value == Enumerations.TransactionStatusCode.Sale) { result.NewPaymentStatus = PaymentStatus.Paid; result.CaptureTransactionId = autopayResult.TransactionNumber; result.CaptureTransactionResult = autopayResult.ErrorCode; } } else { _logger.Error( string.Format("PayEx: AutoPay failed for order {0}.", processPaymentRequest.OrderGuid), new NopException(autopayResult.GetErrorDescription())); } } return(result); }
private void AddOrderLines(PayexInterface payex, string orderRef, Order order) { //get the items in the cart decimal cartTotal = decimal.Zero; var cartItems = order.OrderItems; int itemIndex = 1; foreach (var item in cartItems) { AddOrderLine( payex, orderRef, item.Product.Sku ?? string.Format("{0}", itemIndex++), item.Product.Name, item.Quantity, item.PriceInclTax) .GetAwaiter().GetResult(); cartTotal += item.PriceInclTax; } //the checkout attributes that have a value and send them to PayEx as items to be paid for var caValues = _checkoutAttributeParser.ParseCheckoutAttributeValues(order.CheckoutAttributesXml); foreach (var val in caValues) { var caPriceInclTax = _taxService.GetCheckoutAttributePrice(val, true, order.Customer); CheckoutAttribute ca = val.CheckoutAttribute; if (caPriceInclTax > decimal.Zero && ca != null) //if it has a price { AddOrderLine(payex, orderRef, string.Format("{0}", itemIndex++), ca.Name, 1, caPriceInclTax) .GetAwaiter().GetResult(); cartTotal += caPriceInclTax; } } //order totals //shipping var orderShippingInclTax = order.OrderShippingInclTax; if (orderShippingInclTax > decimal.Zero) { AddOrderLine( payex, orderRef, string.Format("{0}", itemIndex++), _localizationService.GetResource("Order.Shipping"), 1, orderShippingInclTax) .GetAwaiter().GetResult(); cartTotal += orderShippingInclTax; } //payment method additional fee var paymentMethodAdditionalFeeInclTax = order.PaymentMethodAdditionalFeeInclTax; if (paymentMethodAdditionalFeeInclTax > decimal.Zero) { AddOrderLine( payex, orderRef, string.Format("{0}", itemIndex++), _localizationService.GetResource("Order.PaymentMethodAdditionalFee"), 1, paymentMethodAdditionalFeeInclTax) .GetAwaiter().GetResult(); cartTotal += paymentMethodAdditionalFeeInclTax; } if (cartTotal > order.OrderTotal) { /* Take the difference between what the order total is and what it should be and use that as the "discount". * The difference equals the amount of the gift card and/or reward points used. */ decimal discountTotal = cartTotal - order.OrderTotal; //gift card or rewared point amount applied to cart in nopCommerce AddOrderLine( payex, orderRef, string.Format("{0}", itemIndex++), _localizationService.GetResource("Admin.Orders.Products.Discount"), 1, -discountTotal) .GetAwaiter().GetResult(); } }