/// <summary>Asynchronous as long as we do not set TransactionTimeout to 0. So transaction is always in pending state after return.</summary> public void Authorize(AmazonPayClient client, ProcessPaymentResult result, List<string> errors, string orderReferenceId, decimal orderTotalAmount, string currencyCode, string orderGuid) { var request = new AuthorizeRequest(); request.SellerId = client.Settings.SellerId; request.AmazonOrderReferenceId = orderReferenceId; request.AuthorizationReferenceId = GetRandomId("Authorize"); request.CaptureNow = (client.Settings.TransactionType == AmazonPayTransactionType.AuthorizeAndCapture); //request.SellerAuthorizationNote = client.Settings.SellerNoteAuthorization.Truncate(256); request.AuthorizationAmount = new Price() { Amount = orderTotalAmount.ToString("0.00", CultureInfo.InvariantCulture), CurrencyCode = currencyCode ?? "EUR" }; var response = client.Service.Authorize(request); if (response != null && response.IsSetAuthorizeResult() && response.AuthorizeResult.IsSetAuthorizationDetails()) { var details = response.AuthorizeResult.AuthorizationDetails; result.AuthorizationTransactionId = details.AmazonAuthorizationId; result.AuthorizationTransactionCode = details.AuthorizationReferenceId; if (details.IsSetAuthorizationStatus()) { var status = details.AuthorizationStatus; if (status.IsSetState()) { result.AuthorizationTransactionResult = status.State.ToString(); } if (request.CaptureNow && details.IsSetIdList() && details.IdList.IsSetmember() && details.IdList.member.Count() > 0) { result.CaptureTransactionId = details.IdList.member[0]; } if (status.IsSetReasonCode()) { if (status.ReasonCode.IsCaseInsensitiveEqual("InvalidPaymentMethod") || status.ReasonCode.IsCaseInsensitiveEqual("AmazonRejected") || status.ReasonCode.IsCaseInsensitiveEqual("ProcessingFailure") || status.ReasonCode.IsCaseInsensitiveEqual("TransactionTimedOut") || status.ReasonCode.IsCaseInsensitiveEqual("TransactionTimeout")) { if (status.IsSetReasonDescription()) errors.Add("{0}: {1}".FormatWith(status.ReasonCode, status.ReasonDescription)); else errors.Add(status.ReasonCode); } } } } // The response to the Authorize call includes the AuthorizationStatus response element, which will be always be // set to Pending if you have selected the asynchronous mode of operation. result.NewPaymentStatus = Core.Domain.Payments.PaymentStatus.Pending; }
public void CloseOrderReference(AmazonPayClient client, string orderReferenceId) { var request = new CloseOrderReferenceRequest(); request.SellerId = client.Settings.SellerId; request.AmazonOrderReferenceId = orderReferenceId; var response = client.Service.CloseOrderReference(request); }
public OrderReferenceDetails SetOrderReferenceDetails(AmazonPayClient client, string orderReferenceId, decimal?orderTotalAmount, string currencyCode, string orderGuid = null, string storeName = null) { var request = new SetOrderReferenceDetailsRequest(); request.SellerId = client.Settings.SellerId; request.AmazonOrderReferenceId = orderReferenceId; var attributes = new OrderReferenceAttributes(); //attributes.SellerNote = client.Settings.SellerNoteOrderReference.Truncate(1024); attributes.PlatformId = AmazonPayCore.PlatformId; if (orderTotalAmount.HasValue) { attributes.OrderTotal = new OrderTotal() { Amount = orderTotalAmount.Value.ToString("0.00", CultureInfo.InvariantCulture), CurrencyCode = currencyCode }; } if (orderGuid.HasValue()) { attributes.SellerOrderAttributes = new SellerOrderAttributes() { SellerOrderId = orderGuid, StoreName = storeName }; } request.OrderReferenceAttributes = attributes; var response = client.Service.SetOrderReferenceDetails(request); if (response != null && response.IsSetSetOrderReferenceDetailsResult()) { var detailsResult = response.SetOrderReferenceDetailsResult; if (detailsResult.IsSetOrderReferenceDetails()) { return(detailsResult.OrderReferenceDetails); } } return(null); }
public OrderReferenceDetails SetOrderReferenceDetails(AmazonPayClient client, string orderReferenceId, string currencyCode, List <OrganizedShoppingCartItem> cart) { decimal orderTotalDiscountAmountBase = decimal.Zero; Discount orderTotalAppliedDiscount = null; List <AppliedGiftCard> appliedGiftCards = null; int redeemedRewardPoints = 0; decimal redeemedRewardPointsAmount = decimal.Zero; decimal?shoppingCartTotalBase = _orderTotalCalculationService.GetShoppingCartTotal(cart, out orderTotalDiscountAmountBase, out orderTotalAppliedDiscount, out appliedGiftCards, out redeemedRewardPoints, out redeemedRewardPointsAmount); if (shoppingCartTotalBase.HasValue) { return(SetOrderReferenceDetails(client, orderReferenceId, shoppingCartTotalBase, currencyCode)); } return(null); }
public string Refund(AmazonPayClient client, RefundPaymentRequest refund, RefundPaymentResult result) { result.NewPaymentStatus = refund.Order.PaymentStatus; string amazonRefundId = null; var currency = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId); var request = new RefundRequest(); request.SellerId = client.Settings.SellerId; request.AmazonCaptureId = refund.Order.CaptureTransactionId; request.RefundReferenceId = GetRandomId("Refund"); //request.SellerRefundNote = client.Settings.SellerNoteRefund.Truncate(255); request.RefundAmount = new Price() { Amount = refund.AmountToRefund.ToString("0.00", CultureInfo.InvariantCulture), CurrencyCode = currency.CurrencyCode }; var response = client.Service.Refund(request); if (response != null && response.IsSetRefundResult() && response.RefundResult.IsSetRefundDetails()) { var details = response.RefundResult.RefundDetails; amazonRefundId = details.AmazonRefundId; if (details.IsSetRefundStatus() && details.RefundStatus.IsSetState()) { if (refund.IsPartialRefund) { result.NewPaymentStatus = Core.Domain.Payments.PaymentStatus.PartiallyRefunded; } else { result.NewPaymentStatus = Core.Domain.Payments.PaymentStatus.Refunded; } } } return(amazonRefundId); }
public OrderReferenceDetails GetOrderReferenceDetails(AmazonPayClient client, string orderReferenceId, string addressConsentToken = null) { var request = new GetOrderReferenceDetailsRequest(); request.SellerId = client.Settings.SellerId; request.AmazonOrderReferenceId = orderReferenceId; request.AddressConsentToken = addressConsentToken; var response = client.Service.GetOrderReferenceDetails(request); if (response != null && response.IsSetGetOrderReferenceDetailsResult()) { var detailsResult = response.GetOrderReferenceDetailsResult; if (detailsResult.IsSetOrderReferenceDetails()) { return(detailsResult.OrderReferenceDetails); } } return(null); }
public void Capture(AmazonPayClient client, CapturePaymentRequest capture, CapturePaymentResult result) { result.NewPaymentStatus = capture.Order.PaymentStatus; var request = new CaptureRequest(); var currency = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId); request.SellerId = client.Settings.SellerId; request.AmazonAuthorizationId = capture.Order.AuthorizationTransactionId; request.CaptureReferenceId = GetRandomId("Capture"); //request.SellerCaptureNote = client.Settings.SellerNoteCapture.Truncate(255); request.CaptureAmount = new Price() { Amount = capture.Order.OrderTotal.ToString("0.00", CultureInfo.InvariantCulture), CurrencyCode = currency.CurrencyCode }; var response = client.Service.Capture(request); if (response != null && response.IsSetCaptureResult() && response.CaptureResult.IsSetCaptureDetails()) { var details = response.CaptureResult.CaptureDetails; result.CaptureTransactionId = details.AmazonCaptureId; if (details.IsSetCaptureStatus() && details.CaptureStatus.IsSetState()) { result.CaptureTransactionResult = details.CaptureStatus.State.ToString().Grow(details.CaptureStatus.ReasonCode, " "); if (details.CaptureStatus.State == PaymentStatus.COMPLETED) { result.NewPaymentStatus = Core.Domain.Payments.PaymentStatus.Paid; } } } }
public OrderReferenceDetails GetOrderReferenceDetails(AmazonPayClient client, string orderReferenceId, string addressConsentToken = null) { var request = new GetOrderReferenceDetailsRequest(); request.SellerId = client.Settings.SellerId; request.AmazonOrderReferenceId = orderReferenceId; request.AddressConsentToken = addressConsentToken; var response = client.Service.GetOrderReferenceDetails(request); if (response != null && response.IsSetGetOrderReferenceDetailsResult()) { var detailsResult = response.GetOrderReferenceDetailsResult; if (detailsResult.IsSetOrderReferenceDetails()) return detailsResult.OrderReferenceDetails; } return null; }
public AuthorizationDetails GetAuthorizationDetails(AmazonPayClient client, string authorizationId, out AmazonPayApiData data) { data = new AmazonPayApiData(); AuthorizationDetails details = null; var request = new GetAuthorizationDetailsRequest(); request.SellerId = client.Settings.SellerId; request.AmazonAuthorizationId = authorizationId; var response = client.Service.GetAuthorizationDetails(request); if (response.IsSetGetAuthorizationDetailsResult()) { var result = response.GetAuthorizationDetailsResult; if (result != null && result.IsSetAuthorizationDetails()) details = result.AuthorizationDetails; } try { data.MessageType = "GetAuthorizationDetails"; if (response.IsSetResponseMetadata() && response.ResponseMetadata.IsSetRequestId()) data.MessageId = response.ResponseMetadata.RequestId; if (details != null) { if (details.IsSetAmazonAuthorizationId()) data.AuthorizationId = details.AmazonAuthorizationId; if (details.IsSetAuthorizationReferenceId()) data.ReferenceId = details.AuthorizationReferenceId; if (details.IsSetIdList() && details.IdList.IsSetmember()) data.CaptureId = (details.IdList.member != null && details.IdList.member.Count > 0 ? details.IdList.member[0] : null); if (details.IsSetAuthorizationFee()) data.Fee = new AmazonPayApiPrice(details.AuthorizationFee.Amount, details.AuthorizationFee.CurrencyCode); if (details.IsSetAuthorizationAmount()) data.AuthorizedAmount = new AmazonPayApiPrice(details.AuthorizationAmount.Amount, details.AuthorizationAmount.CurrencyCode); if (details.IsSetCapturedAmount()) data.CapturedAmount = new AmazonPayApiPrice(details.CapturedAmount.Amount, details.CapturedAmount.CurrencyCode); if (details.IsSetCaptureNow()) data.CaptureNow = details.CaptureNow; if (details.IsSetCreationTimestamp()) data.Creation = details.CreationTimestamp; if (details.IsSetExpirationTimestamp()) data.Expiration = details.ExpirationTimestamp; if (details.IsSetAuthorizationStatus()) { data.ReasonCode = details.AuthorizationStatus.ReasonCode; data.ReasonDescription = details.AuthorizationStatus.ReasonDescription; data.State = details.AuthorizationStatus.State.ToString(); data.StateLastUpdate = details.AuthorizationStatus.LastUpdateTimestamp; } } } catch (Exception exc) { exc.Dump(); } return details; }
/// <summary>Confirm an order reference informs Amazon that the buyer has placed the order.</summary> public void ConfirmOrderReference(AmazonPayClient client, string orderReferenceId) { var request = new ConfirmOrderReferenceRequest(); request.SellerId = client.Settings.SellerId; request.AmazonOrderReferenceId = orderReferenceId; var response = client.Service.ConfirmOrderReference(request); }
public CapturePaymentResult Capture(CapturePaymentRequest request) { var result = new CapturePaymentResult() { NewPaymentStatus = request.Order.PaymentStatus }; try { var settings = _services.Settings.LoadSetting<AmazonPaySettings>(request.Order.StoreId); var client = new AmazonPayClient(settings); _api.Capture(client, request, result); } catch (OffAmazonPaymentsServiceException exc) { LogAmazonError(exc, errors: result.Errors); } catch (Exception exc) { LogError(exc, errors: result.Errors); } return result; }
private void ProcessAuthorizationResult(AmazonPayClient client, Order order, AmazonPayApiData data, OffAmazonPaymentsService.Model.AuthorizationDetails details) { string formattedAddress; var orderAttribute = DeserializeOrderAttribute(order); if (!orderAttribute.IsBillingAddressApplied) { if (_api.FulfillBillingAddress(client.Settings, order, details, out formattedAddress)) { AddOrderNote(client.Settings, order, AmazonPayOrderNote.BillingAddressApplied, formattedAddress); orderAttribute.IsBillingAddressApplied = true; SerializeOrderAttribute(orderAttribute, order); } else if (formattedAddress.HasValue()) { AddOrderNote(client.Settings, order, AmazonPayOrderNote.BillingAddressCountryNotAllowed, formattedAddress); orderAttribute.IsBillingAddressApplied = true; SerializeOrderAttribute(orderAttribute, order); } } if (data.State.IsCaseInsensitiveEqual("Pending")) return; string newResult = data.State.Grow(data.ReasonCode, " "); if (_orderProcessingService.CanMarkOrderAsAuthorized(order)) { _orderProcessingService.MarkAsAuthorized(order); } if (data.State.IsCaseInsensitiveEqual("Closed") && data.ReasonCode.IsCaseInsensitiveEqual("OrderReferenceCanceled") && _orderProcessingService.CanVoidOffline(order)) { _orderProcessingService.VoidOffline(order); // cancelation at amazon seller central } if (!newResult.IsCaseInsensitiveEqual(order.AuthorizationTransactionResult)) { order.AuthorizationTransactionResult = newResult; if (order.CaptureTransactionId.IsNullOrEmpty() && data.CaptureId.HasValue()) order.CaptureTransactionId = data.CaptureId; // captured at amazon seller central _orderService.UpdateOrder(order); AddOrderNote(client.Settings, order, AmazonPayOrderNote.AmazonMessageProcessed, _api.ToInfoString(data)); } }
public RefundPaymentResult Refund(RefundPaymentRequest request) { var result = new RefundPaymentResult() { NewPaymentStatus = request.Order.PaymentStatus }; try { var settings = _services.Settings.LoadSetting<AmazonPaySettings>(request.Order.StoreId); var client = new AmazonPayClient(settings); string amazonRefundId = _api.Refund(client, request, result); if (amazonRefundId.HasValue() && request.Order.Id != 0) { _genericAttributeService.InsertAttribute(new GenericAttribute() { EntityId = request.Order.Id, KeyGroup = "Order", Key = AmazonPayCore.AmazonPayRefundIdKey, Value = amazonRefundId, StoreId = request.Order.StoreId }); } } catch (OffAmazonPaymentsServiceException exc) { LogAmazonError(exc, errors: result.Errors); } catch (Exception exc) { LogError(exc, errors: result.Errors); } return result; }
public AmazonPayViewModel ProcessPluginRequest(AmazonPayRequestType type, TempDataDictionary tempData, string orderReferenceId = null) { var model = new AmazonPayViewModel(); model.Type = type; try { var store = _services.StoreContext.CurrentStore; var customer = _services.WorkContext.CurrentCustomer; var cart = customer.GetCartItems(ShoppingCartType.ShoppingCart, store.Id); if (type == AmazonPayRequestType.LoginHandler) { if (string.IsNullOrWhiteSpace(orderReferenceId)) { LogError(null, T("Plugins.Payments.AmazonPay.MissingOrderReferenceId"), null, true); model.Result = AmazonPayResultType.Redirect; return model; } if (cart.Count <= 0 || !IsActive(store.Id)) { model.Result = AmazonPayResultType.Redirect; return model; } if (customer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed) { model.Result = AmazonPayResultType.Unauthorized; return model; } var checkoutState = _httpContext.GetCheckoutState(); if (checkoutState == null) { Logger.InsertLog(LogLevel.Warning, "Checkout state is null in AmazonPayService.ValidateAndInitiateCheckout!"); model.Result = AmazonPayResultType.Redirect; return model; } var state = new AmazonPayCheckoutState() { OrderReferenceId = orderReferenceId }; if (checkoutState.CustomProperties.ContainsKey(AmazonPayCore.AmazonPayCheckoutStateKey)) checkoutState.CustomProperties[AmazonPayCore.AmazonPayCheckoutStateKey] = state; else checkoutState.CustomProperties.Add(AmazonPayCore.AmazonPayCheckoutStateKey, state); //_httpContext.Session.SafeSet(AmazonPayCore.AmazonPayCheckoutStateKey, state); model.RedirectAction = "Index"; model.RedirectController = "Checkout"; model.Result = AmazonPayResultType.Redirect; return model; } else if (type == AmazonPayRequestType.ShoppingCart || type == AmazonPayRequestType.MiniShoppingCart) { if (cart.Count <= 0 || !IsActive(store.Id)) { model.Result = AmazonPayResultType.None; return model; } string storeLocation = _services.WebHelper.GetStoreLocation(store.SslEnabled); model.LoginHandlerUrl = "{0}Plugins/SmartStore.AmazonPay/AmazonPayShoppingCart/LoginHandler".FormatWith(storeLocation); } else { if (!_httpContext.HasAmazonPayState() || cart.Count <= 0) { model.Result = AmazonPayResultType.Redirect; return model; } if (customer.IsGuest() && !_orderSettings.AnonymousCheckoutAllowed) { model.Result = AmazonPayResultType.Unauthorized; return model; } var state = _httpContext.GetAmazonPayState(_services.Localization); model.OrderReferenceId = state.OrderReferenceId; //model.IsOrderConfirmed = state.IsOrderConfirmed; } var currency = _services.WorkContext.WorkingCurrency; var settings = _services.Settings.LoadSetting<AmazonPaySettings>(store.Id); model.SellerId = settings.SellerId; model.ClientId = settings.AccessKey; model.IsShippable = cart.RequiresShipping(); model.IsRecurring = cart.IsRecurring(); model.WidgetUrl = settings.GetWidgetUrl(); model.ButtonUrl = settings.GetButtonUrl(type); model.AddressWidgetWidth = Math.Max(settings.AddressWidgetWidth, 200); model.AddressWidgetHeight = Math.Max(settings.AddressWidgetHeight, 228); model.PaymentWidgetWidth = Math.Max(settings.PaymentWidgetWidth, 200); model.PaymentWidgetHeight = Math.Max(settings.PaymentWidgetHeight, 228); if (type == AmazonPayRequestType.MiniShoppingCart) { if (!settings.ShowButtonInMiniShoppingCart) { model.Result = AmazonPayResultType.None; return model; } } else if (type == AmazonPayRequestType.Address) { if (!model.IsShippable) { model.RedirectAction = "ShippingMethod"; model.RedirectController = "Checkout"; model.Result = AmazonPayResultType.Redirect; return model; } var shippingToCountryNotAllowed = tempData[AmazonPayCore.SystemName + "ShippingToCountryNotAllowed"]; if (shippingToCountryNotAllowed != null && true == (bool)shippingToCountryNotAllowed) model.Warning = T("Plugins.Payments.AmazonPay.ShippingToCountryNotAllowed"); } else if (type == AmazonPayRequestType.ShippingMethod) { model.RedirectAction = model.RedirectController = ""; if (model.IsShippable) { var client = new AmazonPayClient(settings); var details = _api.GetOrderReferenceDetails(client, model.OrderReferenceId); if (_api.FindAndApplyAddress(details, customer, model.IsShippable, true)) { _customerService.UpdateCustomer(customer); model.Result = AmazonPayResultType.None; return model; } else { tempData[AmazonPayCore.SystemName + "ShippingToCountryNotAllowed"] = true; model.RedirectAction = "ShippingAddress"; model.RedirectController = "Checkout"; model.Result = AmazonPayResultType.Redirect; return model; } } } else if (type == AmazonPayRequestType.Payment) { if (_rewardPointsSettings.Enabled && !model.IsRecurring) { int rewardPointsBalance = customer.GetRewardPointsBalance(); decimal rewardPointsAmountBase = _orderTotalCalculationService.ConvertRewardPointsToAmount(rewardPointsBalance); decimal rewardPointsAmount = _currencyService.ConvertFromPrimaryStoreCurrency(rewardPointsAmountBase, currency); if (rewardPointsAmount > decimal.Zero) { model.DisplayRewardPoints = true; model.RewardPointsAmount = _priceFormatter.FormatPrice(rewardPointsAmount, true, false); model.RewardPointsBalance = rewardPointsBalance; } } _genericAttributeService.SaveAttribute<string>(customer, SystemCustomerAttributeNames.SelectedPaymentMethod, AmazonPayCore.SystemName, store.Id); var client = new AmazonPayClient(settings); var details = _api.SetOrderReferenceDetails(client, model.OrderReferenceId, GetOrderTotal(), currency.CurrencyCode); // this is ugly... var paymentRequest = _httpContext.Session["OrderPaymentInfo"] as ProcessPaymentRequest; if (paymentRequest == null) { _httpContext.Session["OrderPaymentInfo"] = new ProcessPaymentRequest(); } } else if (type == AmazonPayRequestType.OrderReviewData) { if (model.IsShippable) { var shippingOption = customer.GetAttribute<ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, store.Id); if (shippingOption != null) model.ShippingMethod = shippingOption.Name; } } } catch (OffAmazonPaymentsServiceException exc) { LogAmazonError(exc, notify: true); } catch (Exception exc) { LogError(exc, notify: true); } return model; }
public ProcessPaymentResult ProcessPayment(ProcessPaymentRequest request) { // initiate Amazon payment. We do not add errors to request.Errors cause of asynchronous processing. var result = new ProcessPaymentResult(); var errors = new List<string>(); bool informCustomerAboutErrors = false; bool informCustomerAddErrors = false; try { var orderGuid = request.OrderGuid.ToString(); var store = _storeService.GetStoreById(request.StoreId); var currency = _services.WorkContext.WorkingCurrency; var settings = _services.Settings.LoadSetting<AmazonPaySettings>(store.Id); var state = _httpContext.GetAmazonPayState(_services.Localization); var client = new AmazonPayClient(settings); informCustomerAboutErrors = settings.InformCustomerAboutErrors; informCustomerAddErrors = settings.InformCustomerAddErrors; _api.Authorize(client, result, errors, state.OrderReferenceId, request.OrderTotal, currency.CurrencyCode, orderGuid); } catch (OffAmazonPaymentsServiceException exc) { LogAmazonError(exc, errors: errors); } catch (Exception exc) { LogError(exc, errors: errors); } if (informCustomerAboutErrors && errors != null && errors.Count > 0) { // customer needs to be informed of an amazon error here. hooking OrderPlaced.CustomerNotification won't work // cause of asynchronous processing. solution: we add a customer order note that is also send as an email. var state = new AmazonPayActionState() { OrderGuid = request.OrderGuid }; if (informCustomerAddErrors) { state.Errors = new List<string>(); state.Errors.AddRange(errors); } AsyncRunner.Run((container, x) => { var obj = x as AmazonPayActionState; container.Resolve<IAmazonPayService>().AddCustomerOrderNoteLoop(obj); }, state, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default); } return result; }
public void ProcessIpn(HttpRequestBase request) { try { var data = _api.ParseNotification(request); var order = FindOrder(data); if (order == null || !IsActive(order.StoreId)) return; var client = new AmazonPayClient(_services.Settings.LoadSetting<AmazonPaySettings>(order.StoreId)); if (client.Settings.DataFetching != AmazonPayDataFetchingType.Ipn) return; if (data.MessageType.IsCaseInsensitiveEqual("AuthorizationNotification")) { ProcessAuthorizationResult(client, order, data, null); return; } else if (data.MessageType.IsCaseInsensitiveEqual("CaptureNotification")) { ProcessCaptureResult(client, order, data); return; } else if (data.MessageType.IsCaseInsensitiveEqual("RefundNotification")) { ProcessRefundResult(client, order, data); return; } } catch (OffAmazonPaymentsServiceException exc) { LogAmazonError(exc); } catch (Exception exc) { LogError(exc); } }
public PreProcessPaymentResult PreProcessPayment(ProcessPaymentRequest request) { // fulfill the Amazon checkout var result = new PreProcessPaymentResult(); try { var orderGuid = request.OrderGuid.ToString(); var store = _storeService.GetStoreById(request.StoreId); var customer = _customerService.GetCustomerById(request.CustomerId); var currency = _services.WorkContext.WorkingCurrency; var settings = _services.Settings.LoadSetting<AmazonPaySettings>(store.Id); var state = _httpContext.GetAmazonPayState(_services.Localization); var client = new AmazonPayClient(settings); if (!IsActive(store.Id, true)) { //_httpContext.ResetCheckoutState(); result.AddError(T("Plugins.Payments.AmazonPay.PaymentMethodNotActive", store.Name)); return result; } var preConfirmDetails = _api.SetOrderReferenceDetails(client, state.OrderReferenceId, request.OrderTotal, currency.CurrencyCode, orderGuid, store.Name); _api.GetConstraints(preConfirmDetails, result.Errors); if (!result.Success) return result; _api.ConfirmOrderReference(client, state.OrderReferenceId); // address and payment cannot be changed if order is in open state, amazon widgets then might show an error. //state.IsOrderConfirmed = true; var cart = customer.GetCartItems(ShoppingCartType.ShoppingCart, store.Id); var isShippable = cart.RequiresShipping(); // note: billing address is only available after authorization is in a non-pending and non-declined state. var details = _api.GetOrderReferenceDetails(client, state.OrderReferenceId); _api.FindAndApplyAddress(details, customer, isShippable, false); if (details.IsSetBuyer() && details.Buyer.IsSetEmail() && settings.CanSaveEmailAndPhone(customer.Email)) { customer.Email = details.Buyer.Email; } _customerService.UpdateCustomer(customer); if (details.IsSetBuyer() && details.Buyer.IsSetPhone() && settings.CanSaveEmailAndPhone(customer.GetAttribute<string>(SystemCustomerAttributeNames.Phone, store.Id))) { _genericAttributeService.SaveAttribute<string>(customer, SystemCustomerAttributeNames.Phone, details.Buyer.Phone); } } catch (OffAmazonPaymentsServiceException exc) { LogAmazonError(exc, errors: result.Errors); } catch (Exception exc) { LogError(exc, errors: result.Errors); } return result; }
public void DataPollingTaskProcess() { try { // ignore cancelled and completed (paid and shipped) orders. ignore old orders too. var data = new AmazonPayApiData(); int pollingMaxOrderCreationDays = _services.Settings.GetSettingByKey<int>("AmazonPaySettings.PollingMaxOrderCreationDays", 31); var isTooOld = DateTime.UtcNow.AddDays(-(pollingMaxOrderCreationDays)); var query = from x in _orderRepository.Table where x.PaymentMethodSystemName == AmazonPayCore.SystemName && x.CreatedOnUtc > isTooOld && !x.Deleted && x.OrderStatusId < (int)OrderStatus.Complete && x.PaymentStatusId != (int)PaymentStatus.Voided orderby x.Id descending select x; var orders = query.ToList(); //"- start polling {0} orders".FormatWith(orders.Count).Dump(); foreach (var order in orders) { try { var client = new AmazonPayClient(_services.Settings.LoadSetting<AmazonPaySettings>(order.StoreId)); if (client.Settings.DataFetching == AmazonPayDataFetchingType.Polling) { if (order.AuthorizationTransactionId.HasValue()) { var details = _api.GetAuthorizationDetails(client, order.AuthorizationTransactionId, out data); ProcessAuthorizationResult(client, order, data, details); } if (order.CaptureTransactionId.HasValue()) { if (_orderProcessingService.CanMarkOrderAsPaid(order) || _orderProcessingService.CanVoidOffline(order) || _orderProcessingService.CanRefundOffline(order) || _orderProcessingService.CanPartiallyRefundOffline(order, 0.01M)) { var details = _api.GetCaptureDetails(client, order.CaptureTransactionId, out data); ProcessCaptureResult(client, order, data); if (_orderProcessingService.CanRefundOffline(order) || _orderProcessingService.CanPartiallyRefundOffline(order, 0.01M)) { // note status polling: we cannot use GetRefundDetails to reflect refund(s) made at Amazon seller central cause we // do not have any refund-id and there is no api endpoint that serves them. so we only can process CaptureDetails.RefundedAmount. ProcessRefundResult(client, order, data); } } } } } catch (OffAmazonPaymentsServiceException exc) { LogAmazonError(exc); } catch (Exception exc) { LogError(exc); } } } catch (OffAmazonPaymentsServiceException exc) { LogAmazonError(exc); } catch (Exception exc) { LogError(exc); } }
public RefundDetails GetRefundDetails(AmazonPayClient client, string refundId, out AmazonPayApiData data) { data = new AmazonPayApiData(); RefundDetails details = null; var request = new GetRefundDetailsRequest(); request.SellerId = client.Settings.SellerId; request.AmazonRefundId = refundId; var response = client.Service.GetRefundDetails(request); if (response != null && response.IsSetGetRefundDetailsResult()) { var result = response.GetRefundDetailsResult; if (result != null && result.IsSetRefundDetails()) details = result.RefundDetails; } try { data.MessageType = "GetRefundDetails"; if (response.IsSetResponseMetadata() && response.ResponseMetadata.IsSetRequestId()) data.MessageId = response.ResponseMetadata.RequestId; if (details != null) { if (details.IsSetAmazonRefundId()) data.RefundId = details.AmazonRefundId; if (details.IsSetRefundReferenceId()) data.ReferenceId = details.RefundReferenceId; if (details.IsSetFeeRefunded()) data.Fee = new AmazonPayApiPrice(details.FeeRefunded.Amount, details.FeeRefunded.CurrencyCode); if (details.IsSetRefundAmount()) data.RefundedAmount = new AmazonPayApiPrice(details.RefundAmount.Amount, details.RefundAmount.CurrencyCode); if (details.IsSetCreationTimestamp()) data.Creation = details.CreationTimestamp; if (details.IsSetRefundStatus()) { data.ReasonCode = details.RefundStatus.ReasonCode; data.ReasonDescription = details.RefundStatus.ReasonDescription; data.State = details.RefundStatus.State.ToString(); data.StateLastUpdate = details.RefundStatus.LastUpdateTimestamp; } } } catch (Exception exc) { exc.Dump(); } return details; }
public string Refund(AmazonPayClient client, RefundPaymentRequest refund, RefundPaymentResult result) { result.NewPaymentStatus = refund.Order.PaymentStatus; string amazonRefundId = null; var request = new RefundRequest(); request.SellerId = client.Settings.SellerId; request.AmazonCaptureId = refund.Order.CaptureTransactionId; request.RefundReferenceId = GetRandomId("Refund"); //request.SellerRefundNote = client.Settings.SellerNoteRefund.Truncate(255); request.RefundAmount = new Price() { Amount = refund.AmountToRefund.ToString("0.00", CultureInfo.InvariantCulture), CurrencyCode = refund.Order.CustomerCurrencyCode ?? "EUR" }; var response = client.Service.Refund(request); if (response != null && response.IsSetRefundResult() && response.RefundResult.IsSetRefundDetails()) { var details = response.RefundResult.RefundDetails; amazonRefundId = details.AmazonRefundId; if (details.IsSetRefundStatus() && details.RefundStatus.IsSetState()) { if (refund.IsPartialRefund) result.NewPaymentStatus = Core.Domain.Payments.PaymentStatus.PartiallyRefunded; else result.NewPaymentStatus = Core.Domain.Payments.PaymentStatus.Refunded; } } return amazonRefundId; }
public VoidPaymentResult Void(VoidPaymentRequest request) { var result = new VoidPaymentResult() { NewPaymentStatus = request.Order.PaymentStatus }; // redundant... cause payment infrastructure hides "void" and displays "refund" instead. //if (request.Order.PaymentStatus == PaymentStatus.Paid) //{ // var refundRequest = new RefundPaymentRequest() // { // Order = request.Order, // IsPartialRefund = false, // AmountToRefund = request.Order.OrderTotal // }; // var refundResult = Refund(refundRequest); // result.Errors.AddRange(refundResult.Errors); // return result; //} try { if (request.Order.PaymentStatus == PaymentStatus.Pending || request.Order.PaymentStatus == PaymentStatus.Authorized) { var settings = _services.Settings.LoadSetting<AmazonPaySettings>(request.Order.StoreId); var client = new AmazonPayClient(settings); var orderAttribute = DeserializeOrderAttribute(request.Order); _api.CancelOrderReference(client, orderAttribute.OrderReferenceId); } } catch (OffAmazonPaymentsServiceException exc) { LogAmazonError(exc, errors: result.Errors); } catch (Exception exc) { LogError(exc, errors: result.Errors); } return result; }
public OrderReferenceDetails SetOrderReferenceDetails(AmazonPayClient client, string orderReferenceId, decimal? orderTotalAmount, string currencyCode, string orderGuid = null, string storeName = null) { var request = new SetOrderReferenceDetailsRequest(); request.SellerId = client.Settings.SellerId; request.AmazonOrderReferenceId = orderReferenceId; var attributes = new OrderReferenceAttributes(); //attributes.SellerNote = client.Settings.SellerNoteOrderReference.Truncate(1024); attributes.PlatformId = AmazonPayCore.PlatformId; if (orderTotalAmount.HasValue) { attributes.OrderTotal = new OrderTotal() { Amount = orderTotalAmount.Value.ToString("0.00", CultureInfo.InvariantCulture), CurrencyCode = currencyCode }; } if (orderGuid.HasValue()) { attributes.SellerOrderAttributes = new SellerOrderAttributes() { SellerOrderId = orderGuid, StoreName = storeName }; } request.OrderReferenceAttributes = attributes; var response = client.Service.SetOrderReferenceDetails(request); if (response != null && response.IsSetSetOrderReferenceDetailsResult()) { var detailsResult = response.SetOrderReferenceDetailsResult; if (detailsResult.IsSetOrderReferenceDetails()) return detailsResult.OrderReferenceDetails; } return null; }
private void ProcessCaptureResult(AmazonPayClient client, Order order, AmazonPayApiData data) { if (data.State.IsCaseInsensitiveEqual("Pending")) return; string newResult = data.State.Grow(data.ReasonCode, " "); if (data.State.IsCaseInsensitiveEqual("Completed") && _orderProcessingService.CanMarkOrderAsPaid(order)) { _orderProcessingService.MarkOrderAsPaid(order); CloseOrderReference(client.Settings, order); } else if (data.State.IsCaseInsensitiveEqual("Declined") && _orderProcessingService.CanVoidOffline(order)) { if (!GetAuthorizationState(client, order.AuthorizationTransactionId).IsCaseInsensitiveEqual("Open")) { _orderProcessingService.VoidOffline(order); } } if (!newResult.IsCaseInsensitiveEqual(order.CaptureTransactionResult)) { order.CaptureTransactionResult = newResult; _orderService.UpdateOrder(order); AddOrderNote(client.Settings, order, AmazonPayOrderNote.AmazonMessageProcessed, _api.ToInfoString(data)); } }
public AuthorizationDetails GetAuthorizationDetails(AmazonPayClient client, string authorizationId, out AmazonPayApiData data) { data = new AmazonPayApiData(); AuthorizationDetails details = null; var request = new GetAuthorizationDetailsRequest(); request.SellerId = client.Settings.SellerId; request.AmazonAuthorizationId = authorizationId; var response = client.Service.GetAuthorizationDetails(request); if (response.IsSetGetAuthorizationDetailsResult()) { var result = response.GetAuthorizationDetailsResult; if (result != null && result.IsSetAuthorizationDetails()) { details = result.AuthorizationDetails; } } try { data.MessageType = "GetAuthorizationDetails"; if (response.IsSetResponseMetadata() && response.ResponseMetadata.IsSetRequestId()) { data.MessageId = response.ResponseMetadata.RequestId; } if (details != null) { if (details.IsSetAmazonAuthorizationId()) { data.AuthorizationId = details.AmazonAuthorizationId; } if (details.IsSetAuthorizationReferenceId()) { data.ReferenceId = details.AuthorizationReferenceId; } if (details.IsSetIdList() && details.IdList.IsSetmember()) { data.CaptureId = (details.IdList.member != null && details.IdList.member.Count > 0 ? details.IdList.member[0] : null); } if (details.IsSetAuthorizationFee()) { data.Fee = new AmazonPayApiPrice(details.AuthorizationFee.Amount, details.AuthorizationFee.CurrencyCode); } if (details.IsSetAuthorizationAmount()) { data.AuthorizedAmount = new AmazonPayApiPrice(details.AuthorizationAmount.Amount, details.AuthorizationAmount.CurrencyCode); } if (details.IsSetCapturedAmount()) { data.CapturedAmount = new AmazonPayApiPrice(details.CapturedAmount.Amount, details.CapturedAmount.CurrencyCode); } if (details.IsSetCaptureNow()) { data.CaptureNow = details.CaptureNow; } if (details.IsSetCreationTimestamp()) { data.Creation = details.CreationTimestamp; } if (details.IsSetExpirationTimestamp()) { data.Expiration = details.ExpirationTimestamp; } if (details.IsSetAuthorizationStatus()) { data.ReasonCode = details.AuthorizationStatus.ReasonCode; data.ReasonDescription = details.AuthorizationStatus.ReasonDescription; data.State = details.AuthorizationStatus.State.ToString(); data.StateLastUpdate = details.AuthorizationStatus.LastUpdateTimestamp; } } } catch (Exception exc) { exc.Dump(); } return(details); }
private string GetAuthorizationState(AmazonPayClient client, string authorizationId) { try { if (authorizationId.HasValue()) { AmazonPayApiData data; if (_api.GetAuthorizationDetails(client, authorizationId, out data) != null) return data.State; } } catch (OffAmazonPaymentsServiceException exc) { LogAmazonError(exc); } catch (Exception exc) { LogError(exc); } return null; }
private void CloseOrderReference(AmazonPaySettings settings, Order order) { // You can still perform captures against any open authorizations, but you cannot create any new authorizations on the // Order Reference object. You can still execute refunds against the Order Reference object. try { var client = new AmazonPayClient(settings); var orderAttribute = DeserializeOrderAttribute(order); _api.CloseOrderReference(client, orderAttribute.OrderReferenceId); } catch (OffAmazonPaymentsServiceException exc) { LogAmazonError(exc); } catch (Exception exc) { LogError(exc); } }
private void ProcessRefundResult(AmazonPayClient client, Order order, AmazonPayApiData data) { if (data.State.IsCaseInsensitiveEqual("Pending")) return; if (data.RefundedAmount != null && data.RefundedAmount.Amount != 0.0) // totally refunded amount { // we could only process it once cause otherwise order.RefundedAmount would getting wrong. if (order.RefundedAmount == decimal.Zero) { decimal refundAmount = Convert.ToDecimal(data.RefundedAmount.Amount); decimal receivable = order.OrderTotal - refundAmount; if (receivable <= decimal.Zero) { if (_orderProcessingService.CanRefundOffline(order)) { _orderProcessingService.RefundOffline(order); if (client.Settings.DataFetching == AmazonPayDataFetchingType.Polling) AddOrderNote(client.Settings, order, AmazonPayOrderNote.AmazonMessageProcessed, _api.ToInfoString(data)); } } else { if (_orderProcessingService.CanPartiallyRefundOffline(order, refundAmount)) { _orderProcessingService.PartiallyRefundOffline(order, refundAmount); if (client.Settings.DataFetching == AmazonPayDataFetchingType.Polling) AddOrderNote(client.Settings, order, AmazonPayOrderNote.AmazonMessageProcessed, _api.ToInfoString(data)); } } } } if (client.Settings.DataFetching == AmazonPayDataFetchingType.Ipn) AddOrderNote(client.Settings, order, AmazonPayOrderNote.AmazonMessageProcessed, _api.ToInfoString(data)); }
/// <summary>Asynchronous as long as we do not set TransactionTimeout to 0. So transaction is always in pending state after return.</summary> public void Authorize(AmazonPayClient client, ProcessPaymentResult result, List <string> errors, string orderReferenceId, decimal orderTotalAmount, string currencyCode, string orderGuid) { var request = new AuthorizeRequest(); request.SellerId = client.Settings.SellerId; request.AmazonOrderReferenceId = orderReferenceId; request.AuthorizationReferenceId = GetRandomId("Authorize"); request.CaptureNow = (client.Settings.TransactionType == AmazonPayTransactionType.AuthorizeAndCapture); //request.SellerAuthorizationNote = client.Settings.SellerNoteAuthorization.Truncate(256); request.AuthorizationAmount = new Price() { Amount = orderTotalAmount.ToString("0.00", CultureInfo.InvariantCulture), CurrencyCode = currencyCode ?? "EUR" }; var response = client.Service.Authorize(request); if (response != null && response.IsSetAuthorizeResult() && response.AuthorizeResult.IsSetAuthorizationDetails()) { var details = response.AuthorizeResult.AuthorizationDetails; result.AuthorizationTransactionId = details.AmazonAuthorizationId; result.AuthorizationTransactionCode = details.AuthorizationReferenceId; if (details.IsSetAuthorizationStatus()) { var status = details.AuthorizationStatus; if (status.IsSetState()) { result.AuthorizationTransactionResult = status.State.ToString(); } if (request.CaptureNow && details.IsSetIdList() && details.IdList.IsSetmember() && details.IdList.member.Count() > 0) { result.CaptureTransactionId = details.IdList.member[0]; } if (status.IsSetReasonCode()) { if (status.ReasonCode.IsCaseInsensitiveEqual("InvalidPaymentMethod") || status.ReasonCode.IsCaseInsensitiveEqual("AmazonRejected") || status.ReasonCode.IsCaseInsensitiveEqual("ProcessingFailure") || status.ReasonCode.IsCaseInsensitiveEqual("TransactionTimedOut") || status.ReasonCode.IsCaseInsensitiveEqual("TransactionTimeout")) { if (status.IsSetReasonDescription()) { errors.Add("{0}: {1}".FormatWith(status.ReasonCode, status.ReasonDescription)); } else { errors.Add(status.ReasonCode); } } } } } // The response to the Authorize call includes the AuthorizationStatus response element, which will be always be // set to Pending if you have selected the asynchronous mode of operation. result.NewPaymentStatus = Core.Domain.Payments.PaymentStatus.Pending; }
public OrderReferenceDetails SetOrderReferenceDetails(AmazonPayClient client, string orderReferenceId, Customer customer, List<OrganizedShoppingCartItem> cart) { decimal orderTotalDiscountAmountBase = decimal.Zero; Discount orderTotalAppliedDiscount = null; List<AppliedGiftCard> appliedGiftCards = null; int redeemedRewardPoints = 0; decimal redeemedRewardPointsAmount = decimal.Zero; decimal? shoppingCartTotalBase = _orderTotalCalculationService.GetShoppingCartTotal(cart, out orderTotalDiscountAmountBase, out orderTotalAppliedDiscount, out appliedGiftCards, out redeemedRewardPoints, out redeemedRewardPointsAmount); if (shoppingCartTotalBase.HasValue) { var currency = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId); return SetOrderReferenceDetails(client, orderReferenceId, shoppingCartTotalBase, currency.CurrencyCode); } return null; }
public RefundDetails GetRefundDetails(AmazonPayClient client, string refundId, out AmazonPayApiData data) { data = new AmazonPayApiData(); RefundDetails details = null; var request = new GetRefundDetailsRequest(); request.SellerId = client.Settings.SellerId; request.AmazonRefundId = refundId; var response = client.Service.GetRefundDetails(request); if (response != null && response.IsSetGetRefundDetailsResult()) { var result = response.GetRefundDetailsResult; if (result != null && result.IsSetRefundDetails()) { details = result.RefundDetails; } } try { data.MessageType = "GetRefundDetails"; if (response.IsSetResponseMetadata() && response.ResponseMetadata.IsSetRequestId()) { data.MessageId = response.ResponseMetadata.RequestId; } if (details != null) { if (details.IsSetAmazonRefundId()) { data.RefundId = details.AmazonRefundId; } if (details.IsSetRefundReferenceId()) { data.ReferenceId = details.RefundReferenceId; } if (details.IsSetFeeRefunded()) { data.Fee = new AmazonPayApiPrice(details.FeeRefunded.Amount, details.FeeRefunded.CurrencyCode); } if (details.IsSetRefundAmount()) { data.RefundedAmount = new AmazonPayApiPrice(details.RefundAmount.Amount, details.RefundAmount.CurrencyCode); } if (details.IsSetCreationTimestamp()) { data.Creation = details.CreationTimestamp; } if (details.IsSetRefundStatus()) { data.ReasonCode = details.RefundStatus.ReasonCode; data.ReasonDescription = details.RefundStatus.ReasonDescription; data.State = details.RefundStatus.State.ToString(); data.StateLastUpdate = details.RefundStatus.LastUpdateTimestamp; } } } catch (Exception exc) { exc.Dump(); } return(details); }
public void Capture(AmazonPayClient client, CapturePaymentRequest capture, CapturePaymentResult result) { result.NewPaymentStatus = capture.Order.PaymentStatus; var request = new CaptureRequest(); request.SellerId = client.Settings.SellerId; request.AmazonAuthorizationId = capture.Order.AuthorizationTransactionId; request.CaptureReferenceId = GetRandomId("Capture"); //request.SellerCaptureNote = client.Settings.SellerNoteCapture.Truncate(255); request.CaptureAmount = new Price() { Amount = capture.Order.OrderTotal.ToString("0.00", CultureInfo.InvariantCulture), CurrencyCode = capture.Order.CustomerCurrencyCode ?? "EUR" }; var response = client.Service.Capture(request); if (response != null && response.IsSetCaptureResult() && response.CaptureResult.IsSetCaptureDetails()) { var details = response.CaptureResult.CaptureDetails; result.CaptureTransactionId = details.AmazonCaptureId; if (details.IsSetCaptureStatus() && details.CaptureStatus.IsSetState()) { result.CaptureTransactionResult = details.CaptureStatus.State.ToString().Grow(details.CaptureStatus.ReasonCode, " "); if (details.CaptureStatus.State == PaymentStatus.COMPLETED) result.NewPaymentStatus = Core.Domain.Payments.PaymentStatus.Paid; } } }