private static string GetPaymentMethodText(ProcessOrder order) { var result = order.PaymentMethod == PaymentMethod.CreditCard ? "Credit Card" : "PayPal"; result += " ({0})".FormatInvariant(order.PaymentCurrency.ToStringInvariant().ToUpperInvariant()); return(result); }
/// <summary> /// Processes an order via credit card. /// </summary> /// <param name="order">The order to process.</param> /// <returns>The payment processing status.</returns> public async Task <PaymentResult> SubmitAsync(ProcessOrder order) { order.CheckNotNull(nameof(order)); order.Products.CheckNotNullOrEmpty(nameof(order.Products)); order.TotalConverted.CheckRange("order.TotalConverted", 0, false); if (!order.CreditCardMasterId.HasValue) { order.CreditCard.CheckNotNull(nameof(order.CreditCard)); } //order.Address.CheckNotNull(nameof(order.Address)); //order.Address.FirstName.CheckNotNullOrEmpty(nameof(order.Address.FirstName)); //order.Address.LastName.CheckNotNullOrEmpty(nameof(order.Address.LastName)); //order.Address.Address.CheckNotNullOrEmpty(nameof(order.Address.Address)); _bluepay.SetCurrency(order.PaymentCurrency); if (order.CreditCard != null) { var card = order.CreditCard; _bluepay.SetCCInformation( card.CardNumber, card.ExpirationMonth !.Value, card.ExpirationYear !.Value, card.SecurityCode); } var addr = order.Address !; _bluepay.SetCustomerInformation( addr.FirstName, addr.LastName, addr.Address, addr.Address2, addr.City, addr.State, addr.PostalCode, addr.Country, addr.Phone, addr.Email); _bluepay.Sale(order.TotalConverted, order.CreditCardMasterId?.ToStringInvariant()); var response = await _bluepay.ProcessAsync().ConfigureAwait(false); if (response.Status == "APPROVED") { return(new PaymentResult() { Status = PaymentStatus.Approved, TransactionId = response.TransId }); } else { return(new PaymentResult(PaymentStatus.Declined, response.Message)); } }
/// <summary> /// Submits the sale via Ontraport form. /// </summary> public string Submit(ProcessOrder order) { order.CheckNotNull(nameof(order)); order.OntraportFormId.CheckNotNullOrEmpty(nameof(order.OntraportFormId)); order.Address.CheckNotNull(nameof(order.Address)); if (order.PaymentCurrency != Currency.Usd) { throw new ArgumentException(Res.PayPalFormInvalidCurrency); } return(_ontraForms.ClientPost(order.OntraportFormId, GetFormData(order))); }
/// <summary> /// Logs a transaction in Ontraport, and optionally sends an invoice. /// </summary> /// <param name="order">The order to send.</param> /// <param name="result">The transaction result.</param> /// <param name="sendInvoice">Whether to send an invoice.</param> private async Task LogTransactionAsync(ProcessOrder order, PaymentResult result, bool sendInvoice) { await _ontraProcessor !.LogTransactionAsync(order).ConfigureAwait(false); if (sendInvoice && _invoiceSender != null) { // Use last 6 digits of transaction ID as invoice number. var invoiceId = (result.TransactionId.Length >= 6) ? int.Parse(result.TransactionId.Substring(result.TransactionId.Length - 6), CultureInfo.InvariantCulture) : _random?.GetDigits(6) ?? 0; await _invoiceSender.SendInvoiceAsync(order, invoiceId).ConfigureAwait(false); } }
/// <summary> /// Processes an order. /// </summary> /// <param name="order">The order data.</param> /// <returns>The payment processing result.</returns> public async Task <PaymentResult> SubmitAsync(ProcessOrder order) { order.CheckNotNull(nameof(order)); order.ValidateAndThrow(); if (order.PaymentMethod == PaymentMethod.CreditCard && _creditCard != null) { order.Products.CheckNotNullOrEmpty(nameof(order.Products)); order.Products.ForEach(x => x.Price.CheckRange("order.Products.Price", 0)); order.Total = order.Products.CalculateTotal(); order.TotalConverted = await ConvertTotalAsync(order.Total, order.PaymentCurrency).ConfigureAwait(false); if (order.Total > 0) { var result = await _creditCard.SubmitAsync(order).ConfigureAwait(false); if (result.Status == PaymentStatus.Approved) { await LogTransactionAsync(order, result, true).ConfigureAwait(false); } else { // Send admin notification on error. var addr = order.Address !; var body = $"First Name: {addr.FirstName}<br>Last Name: {addr.LastName}<br>Email: {addr.Email}<br><br>Error: {result.Message}"; await _emailSender.Create("Shopping Cart Error", body).SendAsync().ConfigureAwait(false); } return(result); } else { await LogTransactionAsync(order, new PaymentResult(PaymentStatus.Approved), false).ConfigureAwait(false); return(new PaymentResult(PaymentStatus.Approved)); } } else if (order.PaymentMethod == PaymentMethod.PayPalForm && _paypalForm != null) { var result = _paypalForm !.Submit(order); return(new PaymentResult(PaymentStatus.Approved, result)); } else { throw new InvalidOperationException(Res.PaymentMethodNotHandled); } }
/// <summary> /// Logs a transaction into Ontraport. /// </summary> /// <param name="order">The transaction data.</param> /// <param name="orderTotal">The total of the transaction.</param> public async Task LogTransactionAsync(ProcessOrder order) { order.CheckNotNull(nameof(order)); order.Address.CheckNotNull(nameof(order.Address)); order.Products.CheckNotNullOrEmpty(nameof(order.Products)); var offerTask = CreateTransactionOfferAsync(order.Products); // Add/edit contact via API. var addr = order.Address; var contact = await _ontraContacts.CreateOrMergeAsync(new ApiCustomContact() { Email = addr !.Email, FirstName = addr.FirstName, LastName = addr.LastName, Address = addr.Address, Address2 = addr.Address2, City = addr.City, State = addr.State.HasValue() ? addr.State : "_NOTLISTED_", Zip = addr.PostalCode, Country = addr.Country, HomePhone = addr.Phone, HearAboutUs = addr.Referral }.GetChanges()).ConfigureAwait(false);
/// <summary> /// Sends the invoice for the purchase to the client and to the admin. /// </summary> /// <param name="order">The order for which to send an invoice.</param> /// <param name="invoiceId">The invoice number to display on the invoice.</param> public async Task SendInvoiceAsync(ProcessOrder order, int invoiceId) { order.CheckNotNull(nameof(order)); order.Address.CheckNotNull(nameof(order.Address)); order.Address?.Email.CheckNotNullOrEmpty(nameof(order.Address.Email)); var invoiceTitle = string.Format(CultureInfo.InvariantCulture, Res.InvoiceEmailTitle, invoiceId); // Load invoice template. var template = await LoadResourceTemplateAsync(ResourceInvoice).ConfigureAwait(false); var templateItem = await LoadResourceTemplateAsync(ResourceInvoiceItem).ConfigureAwait(false); var invoiceBody = new StringBuilder(template); var addr = order.Address; invoiceBody.Replace("[Invoice ID]", invoiceId.ToStringInvariant()) .Replace("[Invoice Date]", DateTime.Now.ToString("d", CultureInfo.CurrentCulture)) .Replace("[Payment Method]", GetPaymentMethodText(order)) .Replace("[Email]", addr !.Email) .Replace("[First Name]", addr.FirstName) .Replace("[Last Name]", addr.LastName) .Replace("[Address]", addr.Address) .Replace("[Address 2]", addr.Address2) .Replace("[City]", addr.City) .Replace("[State]", addr.State) .Replace("[Zip Code]", addr.PostalCode) .Replace("[Country]", addr.Country) .Replace("[Phone]", addr.Phone); //if (order.Discount == 0) //{ invoiceBody.Replace("[SubtotalText]", "Subtotal"); invoiceBody.Replace("[Subtotal]", order.Total.ToString("c", CultureInfo.CurrentCulture)); //} //else //{ // invoiceBody.Replace("[SubtotalText]", "Discount"); // invoiceBody.Replace("[Subtotal]", order.Discount.ToString("c", CultureInfo.CurrentCulture)); //} invoiceBody.Replace("[Total]", order.PaymentCurrency == Currency.Usd ? order.Total.ToString("c", CultureInfo.CurrentCulture) : string.Format(CultureInfo.CurrentCulture, "{0:c} USD ({1:c} CAD)", order.Total, order.TotalConverted)); var invoiceItems = new StringBuilder(); foreach (var item in order.Products) { invoiceItems.AppendFormat(CultureInfo.InvariantCulture, templateItem, item.Name, item.Quantity, item.Price.ToString("c", CultureInfo.CurrentCulture), (item.Quantity * item.Price).ToString("c", CultureInfo.CurrentCulture)); } invoiceBody.Replace("[Items]", invoiceItems.ToString()); // Send invoice email. var email = _emailSender.Create(invoiceTitle, invoiceBody.ToString()); email.Mail.IsBodyHtml = true; email.To(addr.Email, $"{addr.FirstName} {addr.LastName}"); // Send to admin. email.Mail.Bcc.Add(email.DefaultMailAddress); await email.SendAsync().ConfigureAwait(false); }
/// <summary> /// Returns the form data as a collection. /// </summary> /// <param name="includePayment">Whether or not to include payment fields.</param> /// <returns>A NameValueConnection containing the form data.</returns> private static IDictionary <string, object?> GetFormData(ProcessOrder order) { var addr = order.Address; var result = new Dictionary <string, object?>() { { "firstname", addr !.FirstName },