public override PaymentStepResult Process(IPayment payment, IOrderForm orderForm, IOrderGroup orderGroup, IShipment shipment) { var paymentStepResult = new PaymentStepResult(); if (payment.TransactionType == TransactionType.Void.ToString()) { try { var orderId = orderGroup.Properties[Constants.SwedbankPayOrderIdField]?.ToString(); var previousPayment = orderForm.Payments.FirstOrDefault(x => x.IsSwedbankPayPayment()); //If payed by swish, do a reversal if (previousPayment != null && previousPayment.TransactionType == TransactionType.Sale.ToString() && !string.IsNullOrWhiteSpace(orderId)) { var paymentOrder = AsyncHelper.RunSync(() => SwedbankPayClient.PaymentOrders.Get(new Uri(orderId, UriKind.Relative))); if (paymentOrder.Operations.Reverse == null) { paymentStepResult.Message = "Reversal is not a valid operation"; AddNoteAndSaveChanges(orderGroup, payment.TransactionType, $"{paymentStepResult.Message}"); } else { var reversalRequest = _requestFactory.GetReversalRequest(payment, orderForm.GetAllLineItems(), _market, shipment, description: "Cancelling purchase order"); var reversalResponse = AsyncHelper.RunSync(() => paymentOrder.Operations.Reverse(reversalRequest)); if (reversalResponse.Reversal.Transaction.Type == Sdk.TransactionType.Reversal) { payment.Status = PaymentStatus.Processed.ToString(); AddNoteAndSaveChanges(orderGroup, payment.TransactionType, $"Refunded {payment.Amount}"); paymentStepResult.Status = true; return(paymentStepResult); } else { paymentStepResult.Message = "Error when executing reversal"; AddNoteAndSaveChanges(orderGroup, payment.TransactionType, $"Error occurred {paymentStepResult.Message}"); } } } else if (!string.IsNullOrWhiteSpace(orderId)) { var paymentOrder = AsyncHelper.RunSync(() => SwedbankPayClient.PaymentOrders.Get(new Uri(orderId, UriKind.Relative))); if (paymentOrder.Operations.Cancel == null) { AddNoteAndSaveChanges(orderGroup, payment.TransactionType, $"Cancel is not possible on this order {orderId}"); return(paymentStepResult); } var cancelRequest = _requestFactory.GetCancelRequest(); var cancelResponse = AsyncHelper.RunSync(() => paymentOrder.Operations.Cancel(cancelRequest)); if (cancelResponse.Cancellation.Transaction.Type == Sdk.TransactionType.Cancellation && cancelResponse.Cancellation.Transaction.State.Equals(State.Completed)) { payment.Status = PaymentStatus.Processed.ToString(); payment.TransactionID = cancelResponse.Cancellation.Transaction.Number; payment.ProviderTransactionID = cancelResponse.Cancellation.Transaction.Id.ToString(); AddNoteAndSaveChanges(orderGroup, payment.TransactionType, "Order cancelled at SwedbankPay"); return(paymentStepResult); } } return(paymentStepResult); } catch (Exception ex) { payment.Status = PaymentStatus.Failed.ToString(); paymentStepResult.Message = ex.Message; AddNoteAndSaveChanges(orderGroup, payment.TransactionType, $"Error occurred {ex.Message}"); Logger.Error(ex.Message, ex); } } if (Successor != null) { return(Successor.Process(payment, orderForm, orderGroup, shipment)); } return(paymentStepResult); }
public Document CreateDocumentForPreAuthenticateRequest(IPayment payment, IOrderForm orderForm, Currency orderGroupCurrency) { var dataCashReference = payment.Properties[DataCashPaymentGateway.DataCashReferencePropertyName] as string; var merchantReference = payment.Properties[DataCashPaymentGateway.DataCashMerchantReferencePropertyName] as string; var requestDoc = CreateDocument(); requestDoc.set("Request.Transaction.TxnDetails.merchantreference", merchantReference); requestDoc.set("Request.Transaction.TxnDetails.amount", payment.Amount.ToString("0.##")); requestDoc.set("Request.Transaction.CardTxn.method", "pre"); requestDoc.setWithAttributes("Request.Transaction.CardTxn.card_details", dataCashReference, new Hashtable() { { "type", "from_hps" } }); // 3rd Man Service requestDoc.setWithAttributes("Request.Transaction.TxnDetails.The3rdMan", string.Empty, new Hashtable() { { "type", "realtime" } }); // Customer Information requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.CustomerInformation.customer_reference", DateTime.Now.Ticks.ToString()); requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.CustomerInformation.forename", payment.BillingAddress.FirstName); requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.CustomerInformation.surname", payment.BillingAddress.LastName); requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.CustomerInformation.telephone", payment.BillingAddress.DaytimePhoneNumber); requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.CustomerInformation.email", payment.BillingAddress.Email); // for realtime fraud check requests requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.CustomerInformation.mobile_telephone_number", payment.BillingAddress.DaytimePhoneNumber); requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.CustomerInformation.ip_address", Utilities.GetIPAddress(HttpContext.Current.Request)); // Delivery address var shippingAddress = orderForm.Shipments.First().ShippingAddress; requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.DeliveryAddress.street_address_1", shippingAddress.Line1); requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.DeliveryAddress.street_address_2", shippingAddress.Line2); requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.DeliveryAddress.city", shippingAddress.City); requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.DeliveryAddress.country", CountryCodes.GetNumericCountryCode(shippingAddress.CountryCode)); requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.DeliveryAddress.postcode", shippingAddress.PostalCode); // Billing address var billingAddress = payment.BillingAddress; requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.BillingAddress.street_address_1", billingAddress.Line1); requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.BillingAddress.street_address_2", billingAddress.Line2); requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.BillingAddress.city", billingAddress.City); requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.BillingAddress.country", CountryCodes.GetNumericCountryCode(billingAddress.CountryCode)); requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.BillingAddress.postcode", billingAddress.PostalCode); // Order information var allLineItems = orderForm.GetAllLineItems().ToList(); requestDoc.setWithAttributes("Request.Transaction.TxnDetails.The3rdMan.OrderInformation.Products", string.Empty, new Hashtable() { { "count", allLineItems.Count.ToString() } }); foreach (var xmlElement in CreateProductXmFromLineItems(requestDoc, allLineItems, orderGroupCurrency)) { requestDoc.setXmlElement("Request.Transaction.TxnDetails.The3rdMan.OrderInformation.Products.Product", xmlElement); } requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.http_header_fields", GetHeaders()); // Register the consumer associated with this transaction for the consumer product requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.register_consumer_watch", "true"); // Uncomment this line if you are using full account, since 3rd man fraud checking is not available for test account //requestDoc.set("Request.Transaction.TxnDetails.The3rdMan.Realtime.real_time_sha1", HashCode(merchantReference)); return(requestDoc); }
/* RewardDescription is "checking" whether the promotion was fulfilled (or not, or partially), * ...which items the promotion was applied to... * ...the fake-cart is taken care of) * PromotionProcessorBase has one abstract method to be implemented, Evaluate. * ...the method is supplied with a PromotionData, and a PromotionProcessorContext object * ...that contains information about the current order/fakeCart. */ protected override RewardDescription Evaluate( // note: it's OrderForm now... MyPercentagePromotion promotionData // the model --> look in the UI to see the properties , PromotionProcessorContext context) { /* A reward description contains information about if and how a reward is applied. * ...some properties are: * - A list of redemption descriptions, one for each of the maximum amount of redemptions * ...that could be applied to the current order. * This does not have to take redemption limits into consideration, that is handled by the * promotion engine. * - A reward type. Depending on the type, the promotion value is read from the properties * UnitDiscount, Percentage or Quantity. * - A status flag. Indicates if a promotion is not, partially, or fully fulfilled. * - A saved amount. The amount by which this reward reduces the order cost. * Is set by the promotion engine; should not be set in the promotion processor*/ IOrderForm orderForm = context.OrderForm; // OrderForm now pops in with the context //context. // lots of things IEnumerable <ILineItem> lineItemsCheck = orderForm.GetAllLineItems(); IEnumerable <ILineItem> lineItems = GetLineItems(context.OrderForm); #region Just Checking //var e = _contentLoader.Get<EntryContentBase>(item0); //should check if it's applicable... at all //var li = _orderFactory.Service.CreateLineItem(e.Code); //li.Quantity = 1; //li.PlacedPrice = 15; //orderForm.Shipments.First().LineItems.Add(li); #endregion // GetFulfillmentStatus - extension method FulfillmentStatus status = promotionData.MinNumberOfItems.GetFulfillmentStatus( orderForm, _targetEvaluator, _fulfillmentEvaluator); List <RewardDescription> rewardDescriptions = new List <RewardDescription>(); List <RedemptionDescription> redemptionDescriptions = new List <RedemptionDescription>(); #region NewStuff // The below does not see the cart, it's for landing pages for the Promotion itself (rendering) PromotionItems promoItems = GetPromotionItems(promotionData); // gets null var condition = promotionData.PercentageDiscount; // ...in the model var targets = promotionData.DiscountTargets; // get one in any case, points to what's at "promo" var skuCodes = _targetEvaluator.GetApplicableCodes( lineItems, targets.Items, targets.MatchRecursive); // get one if kicked in, 0 if not var fulfillmentStatus = _fulfillmentEvaluator.GetStatusForBuyQuantityPromotion( skuCodes , lineItems , promotionData.MinNumberOfItems.RequiredQuantity , promotionData.PartialFulfillmentNumberOfItems); // Just checking // The promotion engine creates a "price matrix" for all items in the order form. // OrderFormPriceMatrix, is accessible through the EntryPrices property // of the PromotionProcessorContext object. // PromotionProcessorContext is passed to the Evaluate method as one of the arguments. // ...the matrix holds "codes" and quantity // The second ExtractEntries call starts to receive entries where the first call ended. // ... makes it easy to create several redemptions by calling ExtractEntries in a loop, // ... and create one RedemptionDescription inside the loop. // The price matrix has one public method (ExtractEntries) // ... two overloads, both overloads takes entry codes and quantity as parameters. // ... one contains an action for getting the entries in a specific order. // ... if no specific order is specified, MostExpensiveFirst is used. var affectedEntries = context.EntryPrices.ExtractEntries( skuCodes, 1); // get one if it kicks in, null if not if (affectedEntries != null) { IEnumerable <PriceEntry> priceEntries = affectedEntries.PriceEntries; foreach (var item in priceEntries) { var qty = item.Quantity; var price = item.Price; var calc = item.CalculatedTotal; // involves the Qty var actuals = item.ActualTotal; // includes rounding } } // could have a look here switch (fulfillmentStatus) { case FulfillmentStatus.NotFulfilled: break; case FulfillmentStatus.PartiallyFulfilled: break; case FulfillmentStatus.Fulfilled: break; case FulfillmentStatus.CouponCodeRequired: break; case FulfillmentStatus.Excluded: break; case FulfillmentStatus.VisitorGroupRequired: break; case FulfillmentStatus.RedemptionLimitReached: break; case FulfillmentStatus.NoMoneySaved: break; case FulfillmentStatus.InvalidCoupon: break; case FulfillmentStatus.InvalidCombination: break; case FulfillmentStatus.MissingVisitorGroup: break; case FulfillmentStatus.NoRedemptionRemaining: break; case FulfillmentStatus.Ineffective: break; default: break; } // ... an extension method return(RewardDescription.CreatePercentageReward( fulfillmentStatus , GetRedemptions(skuCodes, promotionData, context) , promotionData , promotionData.PercentageDiscount.Percentage //, fulfillmentStatus.GetRewardDescriptionText() , fulfillmentStatus.GetRewardDescriptionText() + " : " + promotionData.Description + " : " )); #endregion #region Older stuff and debug - no show #region Older not in use //RewardDescription rewardDescription = new RewardDescription(); //var codes = _targetEvaluator.GetApplicableCodes(lineItems,) //_fulfillmentEvaluator.GetStatusForBuyQuantityPromotion( // ) #endregion // new stuff #region Previous version //if (status.HasFlag(FulfillmentStatus.Fulfilled)) //{ // return RewardDescription.CreateMoneyOrPercentageRewardDescription( // status, // redemptionDescriptions, // promotionData, // promotionData.PercentageDiscount, // context.OrderGroup.Currency, // "Custom promotion fulfilled"); // should have a more flexible way... GetDescription() //} //else //{ // return RewardDescription.CreateNotFulfilledDescription( // promotionData, FulfillmentStatus.NotFulfilled); //} #endregion #region Debug //RedemptionDescription rFirst; //redemptionDescriptions.Add(CreateRedemptionDescriptionText(orderForm)); // below "if-construct" is for debug //if (promotionData.PercentageDiscount <= 0) // ... return "sorry, no discount" //{ // return RewardDescription.CreatePercentageReward( // FulfillmentStatus.NotFulfilled, // redemptionDescriptions, // promotionData, // 0, // CreateRewardDescriptionText(redemptionDescriptions.First(), FulfillmentStatus.NotFulfilled, promotionData)); // /*RewardDescription.CreateMoneyOrPercentageRewardDescription(FulfillmentStatus.NotFulfilled,r,promotionData,null);*/ //} //IEnumerable<ContentReference> targetItems = promotionData.DiscountTargets.Items.ToList(); // set by the Promo-UI //bool matchRecursive = true; // walking down the catalog hierarchy //var lineItems = GetLineItems(orderForm); // "GetLineItems" - in the base class (PromotionProcessorBase) //var affectedItems = _targetEvaluator.GetApplicableItems(lineItems, targetItems, matchRecursive); // in CollectionTargetEvaluator //var affectedItems = _targetEvaluator.GetApplicableCodes(orderForm.GetAllLineItems(), targetItems, false); // small class --> just to get the status by the settings //var status = FulfillmentEvaluator.GetStatusForBuyQuantityPromotion(affectedItems.Select(x => x.LineItem) // , promotionData.MinNumberOfItems, promotionData.PartialFulfillmentNumberOfItems); // in the model //var s = FulfillmentEvaluator. //FulfillmentEvaluator ff = new FulfillmentEvaluator(); //if (rewardDescriptions.Any()) //{ // return rewardDescriptions.First(); //} //else //{ // return null; //} /*return RewardDescription.CreateMoneyOrPercentageRewardDescription( * status, * affectedItems, * promotionData, * promotionData.PercentageDiscount, * GetRewardDescriptionText(affectedItems, status, promotionData));*/ #endregion #endregion } // end RewardDescription
protected override Money CalculateSubtotal(IOrderForm orderForm, Currency currency) { var result = orderForm.GetAllLineItems().Where(x => !x.IsGift).Sum(lineItem => _lineItemCalculator.GetDiscountedPrice(lineItem, currency).Amount); return new Money(result, currency); }