예제 #1
0
        private static string GetPaymentMethodText(ProcessOrder order)
        {
            var result = order.PaymentMethod == PaymentMethod.CreditCard ? "Credit Card" : "PayPal";

            result += " ({0})".FormatInvariant(order.PaymentCurrency.ToStringInvariant().ToUpperInvariant());
            return(result);
        }
예제 #2
0
        /// <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));
            }
        }
예제 #3
0
        /// <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)));
        }
예제 #4
0
        /// <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);
            }
        }
예제 #5
0
        /// <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);
            }
        }
예제 #6
0
        /// <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);
예제 #7
0
        /// <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);
        }
예제 #8
0
 /// <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 },