public ActionResult PaymentInfo() { var model = new PaymentInfoModel { //whether current customer is guest IsGuest = _workContext.CurrentCustomer.IsGuest(), //get postal code from the billing address or from the shipping one PostalCode = _workContext.CurrentCustomer.BillingAddress?.ZipPostalCode ?? _workContext.CurrentCustomer.ShippingAddress?.ZipPostalCode }; //whether customer already has stored cards var customerId = _workContext.CurrentCustomer.GetAttribute <string>(SquarePaymentDefaults.CustomerIdAttribute); var customer = _squarePaymentManager.GetCustomer(customerId); if (customer?.Cards != null) { var cardNumberMask = _localizationService.GetResource("Plugins.Payments.Square.Fields.StoredCard.Mask"); model.StoredCards = customer.Cards.Select(card => new SelectListItem { Text = string.Format(cardNumberMask, card.Last4), Value = card.Id }).ToList(); } //add the special item for 'select card' with value 0 if (model.StoredCards.Any()) { var selectCardText = _localizationService.GetResource("Plugins.Payments.Square.Fields.StoredCard.SelectCard"); model.StoredCards.Insert(0, new SelectListItem { Text = selectCardText, Value = "0" }); } return(View("~/Plugins/Payments.Square/Views/PaymentInfo.cshtml", model)); }
/// <summary> /// Invoke view component /// </summary> /// <param name="widgetZone">Widget zone name</param> /// <param name="additionalData">Additional data</param> /// <returns>View component result</returns> public IViewComponentResult Invoke(string widgetZone, object additionalData) { var model = new PaymentInfoModel { //whether current customer is guest IsGuest = _workContext.CurrentCustomer.IsGuest(), //get postal code from the billing address or from the shipping one PostalCode = _workContext.CurrentCustomer.BillingAddress?.ZipPostalCode ?? _workContext.CurrentCustomer.ShippingAddress?.ZipPostalCode }; //whether customer already has stored cards var customerId = _genericAttributeService .GetAttribute <string>(_workContext.CurrentCustomer, SquarePaymentDefaults.CustomerIdAttribute) ?? string.Empty; var customer = _squarePaymentManager.GetCustomer(customerId); if (customer?.Cards != null) { var cardNumberMask = _localizationService.GetResource("Plugins.Payments.Square.Fields.StoredCard.Mask"); model.StoredCards = customer.Cards .Select(card => new SelectListItem { Text = string.Format(cardNumberMask, card.Last4), Value = card.Id }) .ToList(); } //add the special item for 'select card' with empty GUID value if (model.StoredCards.Any()) { var selectCardText = _localizationService.GetResource("Plugins.Payments.Square.Fields.StoredCard.SelectCard"); model.StoredCards.Insert(0, new SelectListItem { Text = selectCardText, Value = Guid.Empty.ToString() }); } //set verfication details if (_squarePaymentSettings.Use3ds) { var cart = _shoppingCartService.GetShoppingCart(_workContext.CurrentCustomer, ShoppingCartType.ShoppingCart, _storeContext.CurrentStore.Id); model.OrderTotal = _orderTotalCalculationService.GetShoppingCartTotal(cart, false, false) ?? decimal.Zero; var currency = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId); model.Currency = currency?.CurrencyCode; model.BillingFirstName = _workContext.CurrentCustomer.BillingAddress?.FirstName; model.BillingLastName = _workContext.CurrentCustomer.BillingAddress?.LastName; model.BillingEmail = _workContext.CurrentCustomer.BillingAddress?.Email; model.BillingCountry = _workContext.CurrentCustomer.BillingAddress?.Country?.TwoLetterIsoCode; model.BillingState = _workContext.CurrentCustomer.BillingAddress?.StateProvince?.Name; model.BillingCity = _workContext.CurrentCustomer.BillingAddress?.City; model.BillingPostalCode = _workContext.CurrentCustomer.BillingAddress?.ZipPostalCode; } return(View("~/Plugins/Payments.Square/Views/PaymentInfo.cshtml", model)); }
/// <summary> /// Create request parameters to charge transaction /// </summary> /// <param name="paymentRequest">Payment request parameters</param> /// <param name="isRecurringPayment">Whether it is a recurring payment</param> /// <returns>Charge request parameters</returns> private ExtendedChargeRequest CreateChargeRequest(ProcessPaymentRequest paymentRequest, bool isRecurringPayment) { //get customer var customer = _customerService.GetCustomerById(paymentRequest.CustomerId); if (customer == null) { throw new NopException("Customer cannot be loaded"); } //get the primary store currency var currency = _currencyService.GetCurrencyById(_currencySettings.PrimaryStoreCurrencyId); if (currency == null) { throw new NopException("Primary store currency cannot be loaded"); } //whether the currency is supported by the Square if (!CheckSupportCurrency(currency)) { throw new NopException($"The {currency.CurrencyCode} currency is not supported by the Square"); } //check customer's billing address, shipping address and email, SquareModel.Address createAddress(Address address) => address == null ? null : new SquareModel.Address ( AddressLine1: address.Address1, AddressLine2: address.Address2, AdministrativeDistrictLevel1: address.StateProvince?.Abbreviation, AdministrativeDistrictLevel2: address.County, Country: string.Equals(address.Country?.TwoLetterIsoCode, new RegionInfo(address.Country?.TwoLetterIsoCode).TwoLetterISORegionName, StringComparison.InvariantCultureIgnoreCase) ? address.Country?.TwoLetterIsoCode : null, FirstName: address.FirstName, LastName: address.LastName, Locality: address.City, PostalCode: address.ZipPostalCode ); var billingAddress = createAddress(customer.BillingAddress); var shippingAddress = billingAddress == null?createAddress(customer.ShippingAddress) : null; var email = customer.BillingAddress != null ? customer.BillingAddress.Email : customer.ShippingAddress?.Email; //the transaction is ineligible for chargeback protection if they are not provided if ((billingAddress == null && shippingAddress == null) || string.IsNullOrEmpty(email)) { _logger.Warning("Square payment warning: Address or email is not provided, so the transaction is ineligible for chargeback protection", customer: customer); } //the amount of money, in the smallest denomination of the currency indicated by currency. For example, when currency is USD, amount is in cents; //most currencies consist of 100 units of smaller denomination, so we multiply the total by 100 var orderTotal = (int)(paymentRequest.OrderTotal * 100); var amountMoney = new SquareModel.Money(Amount: orderTotal, Currency: currency.CurrencyCode); //create common charge request parameters var chargeRequest = new ExtendedChargeRequest ( amountMoney: amountMoney, billingAddress: billingAddress, buyerEmailAddress: email, delayCapture: _squarePaymentSettings.TransactionMode == TransactionMode.Authorize, idempotencyKey: Guid.NewGuid().ToString(), integrationId: !string.IsNullOrEmpty(SquarePaymentDefaults.IntegrationId) ? SquarePaymentDefaults.IntegrationId : null, note: string.Format(SquarePaymentDefaults.PaymentNote, paymentRequest.OrderGuid), referenceId: paymentRequest.OrderGuid.ToString(), shippingAddress: shippingAddress ); //try to get previously stored card details var storedCardKey = _localizationService.GetResource("Plugins.Payments.Square.Fields.StoredCard.Key"); if (paymentRequest.CustomValues.TryGetValue(storedCardKey, out var storedCardId) && !storedCardId.ToString().Equals(Guid.Empty.ToString())) { //check whether customer exists var customerId = _genericAttributeService.GetAttribute <string>(customer, SquarePaymentDefaults.CustomerIdAttribute); var squareCustomer = _squarePaymentManager.GetCustomer(customerId); if (squareCustomer == null) { throw new NopException("Failed to retrieve customer"); } //set 'card on file' to charge chargeRequest.CustomerId = squareCustomer.Id; chargeRequest.CustomerCardId = storedCardId.ToString(); return(chargeRequest); } //or try to get the card nonce var cardNonceKey = _localizationService.GetResource("Plugins.Payments.Square.Fields.CardNonce.Key"); if (!paymentRequest.CustomValues.TryGetValue(cardNonceKey, out var cardNonce) || string.IsNullOrEmpty(cardNonce?.ToString())) { throw new NopException("Failed to get the card nonce"); } //remove the card nonce from payment custom values, since it is no longer needed paymentRequest.CustomValues.Remove(cardNonceKey); //whether to save card details for the future purchasing var saveCardKey = _localizationService.GetResource("Plugins.Payments.Square.Fields.SaveCard.Key"); if (paymentRequest.CustomValues.TryGetValue(saveCardKey, out var saveCardValue) && saveCardValue is bool saveCard && saveCard && !customer.IsGuest()) { //remove the value from payment custom values, since it is no longer needed paymentRequest.CustomValues.Remove(saveCardKey); try { //check whether customer exists var customerId = _genericAttributeService.GetAttribute <string>(customer, SquarePaymentDefaults.CustomerIdAttribute); var squareCustomer = _squarePaymentManager.GetCustomer(customerId); if (squareCustomer == null) { //try to create the new one, if not exists var customerRequest = new SquareModel.CreateCustomerRequest ( EmailAddress: customer.Email, Nickname: customer.Username, GivenName: _genericAttributeService.GetAttribute <string>(customer, NopCustomerDefaults.FirstNameAttribute), FamilyName: _genericAttributeService.GetAttribute <string>(customer, NopCustomerDefaults.LastNameAttribute), PhoneNumber: _genericAttributeService.GetAttribute <string>(customer, NopCustomerDefaults.PhoneAttribute), CompanyName: _genericAttributeService.GetAttribute <string>(customer, NopCustomerDefaults.CompanyAttribute), ReferenceId: customer.CustomerGuid.ToString() ); squareCustomer = _squarePaymentManager.CreateCustomer(customerRequest); if (squareCustomer == null) { throw new NopException("Failed to create customer. Error details in the log"); } //save customer identifier as generic attribute _genericAttributeService.SaveAttribute(customer, SquarePaymentDefaults.CustomerIdAttribute, squareCustomer.Id); } //create request parameters to create the new card var cardRequest = new SquareModel.CreateCustomerCardRequest ( BillingAddress: chargeRequest.BillingAddress ?? chargeRequest.ShippingAddress, CardNonce: cardNonce.ToString() ); //set postal code var postalCodeKey = _localizationService.GetResource("Plugins.Payments.Square.Fields.PostalCode.Key"); if (paymentRequest.CustomValues.TryGetValue(postalCodeKey, out var postalCode) && !string.IsNullOrEmpty(postalCode.ToString())) { //remove the value from payment custom values, since it is no longer needed paymentRequest.CustomValues.Remove(postalCodeKey); cardRequest.BillingAddress = cardRequest.BillingAddress ?? new SquareModel.Address(); cardRequest.BillingAddress.PostalCode = postalCode.ToString(); } //try to create card var card = _squarePaymentManager.CreateCustomerCard(squareCustomer.Id, cardRequest); if (card == null) { throw new NopException("Failed to create card. Error details in the log"); } //save card identifier to payment custom values for further purchasing if (isRecurringPayment) { paymentRequest.CustomValues.Add(storedCardKey, card.Id); } //set 'card on file' to charge chargeRequest.CustomerId = squareCustomer.Id; chargeRequest.CustomerCardId = card.Id; return(chargeRequest); } catch (Exception exception) { _logger.Warning(exception.Message, exception, customer); if (isRecurringPayment) { throw new NopException("For recurring payments you need to save the card details"); } } }