diff --git a/Libraries/Hotcakes.Commerce/Accounts/StoreSettingsPayPal.cs b/Libraries/Hotcakes.Commerce/Accounts/StoreSettingsPayPal.cs index 1a6411fb0..d3e54b9ee 100644 --- a/Libraries/Hotcakes.Commerce/Accounts/StoreSettingsPayPal.cs +++ b/Libraries/Hotcakes.Commerce/Accounts/StoreSettingsPayPal.cs @@ -49,6 +49,18 @@ public string Password set { parent.SetPropEncrypted("PaypalPassword", value); } } + public string ClienId + { + get { return parent.GetPropEncrypted("PaypalClientId"); } + set { parent.SetPropEncrypted("PaypalClientId", value); } + } + + public string Secret + { + get { return parent.GetPropEncrypted("PaypalSecret"); } + set { parent.SetPropEncrypted("PaypalSecret", value); } + } + public string Signature { get { return parent.GetPropEncrypted("PaypalSignature"); } diff --git a/Libraries/Hotcakes.Commerce/BusinessRules/OrderTasks/ReceivePaypalExpressPayments.cs b/Libraries/Hotcakes.Commerce/BusinessRules/OrderTasks/ReceivePaypalExpressPayments.cs index bfbff0b3a..56cecb4be 100644 --- a/Libraries/Hotcakes.Commerce/BusinessRules/OrderTasks/ReceivePaypalExpressPayments.cs +++ b/Libraries/Hotcakes.Commerce/BusinessRules/OrderTasks/ReceivePaypalExpressPayments.cs @@ -48,7 +48,7 @@ public override bool Execute(OrderTaskContext context) { //Use the last transaction entered by customer first - List transactions = context.HccApp.OrderServices.Transactions + List transactions = context.HccApp.OrderServices.Transactions .FindForOrder(context.Order.bvin) .OrderByDescending(x => x.TimeStampUtc) .ToList(); diff --git a/Libraries/Hotcakes.Commerce/BusinessRules/OrderTasks/StartPaypalExpressCheckout.cs b/Libraries/Hotcakes.Commerce/BusinessRules/OrderTasks/StartPaypalExpressCheckout.cs index 0219cbc56..ee09dcf5d 100644 --- a/Libraries/Hotcakes.Commerce/BusinessRules/OrderTasks/StartPaypalExpressCheckout.cs +++ b/Libraries/Hotcakes.Commerce/BusinessRules/OrderTasks/StartPaypalExpressCheckout.cs @@ -32,8 +32,14 @@ using System.Web; using Hotcakes.Web.Logging; using System.Globalization; +using System.Net; +using System.Threading.Tasks; +using Hotcakes.Commerce.Common; using Hotcakes.Commerce.Globalization; using Hotcakes.Commerce.Payment; +using PayPalCheckoutSdk.Core; +using PayPalCheckoutSdk.Orders; +using PayPalHttp; namespace Hotcakes.Commerce.BusinessRules.OrderTasks { @@ -54,7 +60,7 @@ public override bool ProcessCheckout(OrderTaskContext context) { try { - PayPalAPI ppAPI = Utilities.PaypalExpressUtilities.GetPaypalAPI(context.HccApp.CurrentStore); + RestPayPalApi replacePayPal = Utilities.PaypalExpressUtilities.GetRestPaypalAPI(context.HccApp.CurrentStore); string cartReturnUrl = HccUrlBuilder.RouteHccUrl(HccRoute.ThirdPartyPayment, null, Uri.UriSchemeHttps); string cartCancelUrl = HccUrlBuilder.RouteHccUrl(HccRoute.Checkout, null, Uri.UriSchemeHttps); @@ -62,16 +68,16 @@ public override bool ProcessCheckout(OrderTaskContext context) EventLog.LogEvent("PayPal Express Checkout", "CartCancelUrl=" + cartCancelUrl, EventLogSeverity.Information); EventLog.LogEvent("PayPal Express Checkout", "CartReturnUrl=" + cartReturnUrl, EventLogSeverity.Information); - PaymentActionCodeType mode = PaymentActionCodeType.Authorization; + string mode = PayPalConstants.PAYMENT_MODE_AUTHORIZE; if (!context.HccApp.CurrentStore.Settings.PayPal.ExpressAuthorizeOnly) { - mode = PaymentActionCodeType.Sale; + mode = PayPalConstants.PAYMENT_MODE_CAPTURE; } // Accelerated boarding if (string.IsNullOrWhiteSpace(context.HccApp.CurrentStore.Settings.PayPal.UserName)) { - mode = PaymentActionCodeType.Sale; + mode = PayPalConstants.PAYMENT_MODE_CAPTURE; } var solutionType = context.HccApp.CurrentStore.Settings.PayPal.RequirePayPalAccount ? SolutionTypeType.Mark : SolutionTypeType.Sole; @@ -87,7 +93,7 @@ public override bool ProcessCheckout(OrderTaskContext context) PaymentDetailsItemType[] itemsDetails = GetOrderItemsDetails(context); - SetExpressCheckoutResponseType expressResponse; + PayPalHttp.HttpResponse expressResponse; if (addressSupplied) { Contacts.Address address = context.Order.ShippingAddress; @@ -101,12 +107,14 @@ public override bool ProcessCheckout(OrderTaskContext context) if (address.CountryData != null) { - var itemsTotalWithoutTax = context.Order.TotalOrderAfterDiscounts; + var ISOCode = address.CountryData.IsoCode; + + var itemsTotalWithoutTax = context.Order.TotalOrderAfterDiscounts; if (context.HccApp.CurrentStore.Settings.ApplyVATRules) { itemsTotalWithoutTax -= context.Order.ItemsTax; } - string itemsTotal = itemsTotalWithoutTax.ToString("N", CultureInfo.InvariantCulture); + string itemsTotal = itemsTotalWithoutTax.ToString("N", CultureInfo.InvariantCulture); string taxTotal = context.Order.TotalTax.ToString("N", CultureInfo.InvariantCulture); var shippingTotalWithoutTax = context.Order.TotalShippingAfterDiscounts; if (context.HccApp.CurrentStore.Settings.ApplyVATRules) @@ -116,27 +124,27 @@ public override bool ProcessCheckout(OrderTaskContext context) string shippingTotal = shippingTotalWithoutTax.ToString("N", CultureInfo.InvariantCulture); string orderTotal = context.Order.TotalGrand.ToString("N", CultureInfo.InvariantCulture); - expressResponse = ppAPI.SetExpressCheckout( - itemsDetails, - itemsTotal, - taxTotal, - shippingTotal, - orderTotal, - cartReturnUrl, - cartCancelUrl, - mode, - PayPalAPI.GetCurrencyCodeType(context.HccApp.CurrentStore.Settings.PayPal.Currency), - solutionType, - address.FirstName + " " + address.LastName, - address.CountryData.IsoCode, - address.Line1, - address.Line2, - address.City, - address.RegionBvin, - address.PostalCode, - address.Phone, - context.Order.OrderNumber + Guid.NewGuid().ToString(), - isNonShipping); + expressResponse = System.Threading.Tasks.Task.Run(() => replacePayPal.createOrder( + itemsDetails, + itemsTotal, + taxTotal, + shippingTotal, + orderTotal, + cartReturnUrl, + cartCancelUrl, + mode, + context.HccApp.CurrentStore.Settings.PayPal.Currency, + solutionType, + ($"{address.FirstName} {address.LastName}"), + ISOCode, + address.Line1, + address.Line2, + address.City, + address.RegionBvin, + address.PostalCode, + address.Phone, + context.Order.OrderNumber + Guid.NewGuid().ToString(), + isNonShipping)).GetAwaiter().GetResult(); if (expressResponse == null) { EventLog.LogEvent("PayPal Express Checkout", "Express Response Was Null!", EventLogSeverity.Error); @@ -163,26 +171,27 @@ public override bool ProcessCheckout(OrderTaskContext context) } string itemsTotal = itemsTotalWithoutTax.ToString("N", CultureInfo.InvariantCulture); string orderTotal = context.Order.TotalOrderAfterDiscounts.ToString("N", CultureInfo.InvariantCulture); - expressResponse = ppAPI.SetExpressCheckout(itemsDetails, - itemsTotal, - taxTotal, - orderTotal, - cartReturnUrl, - cartCancelUrl, - mode, - PayPalAPI.GetCurrencyCodeType(context.HccApp.CurrentStore.Settings.PayPal.Currency), - solutionType, - context.Order.OrderNumber + Guid.NewGuid().ToString(), - isNonShipping); + expressResponse = System.Threading.Tasks.Task.Run(() => replacePayPal.createOrder(itemsDetails, + itemsTotal, + taxTotal, + orderTotal, + cartReturnUrl, + cartCancelUrl, + mode, + context.HccApp.CurrentStore.Settings.PayPal.Currency, + solutionType, + context.Order.OrderNumber + Guid.NewGuid().ToString(), + isNonShipping)).GetAwaiter().GetResult(); + if (expressResponse == null) { EventLog.LogEvent("PayPal Express Checkout", "Express Response2 Was Null!", EventLogSeverity.Error); } } - if (expressResponse.Ack == AckCodeType.Success || expressResponse.Ack == AckCodeType.SuccessWithWarning) + if (expressResponse.StatusCode == HttpStatusCode.Created /*|| expressResponse.Ack == AckCodeType.SuccessWithWarning*/) { - context.Order.ThirdPartyOrderId = expressResponse.Token; + context.Order.ThirdPartyOrderId = expressResponse.Result().Id; // Recording of this info is handled on the paypal express // checkout page instead of here. @@ -193,38 +202,26 @@ public override bool ProcessCheckout(OrderTaskContext context) Orders.OrderNote note = new Orders.OrderNote(); note.IsPublic = false; - note.Note = "Paypal Order Accepted With Paypal Order Number: " + expressResponse.Token; + note.Note = "Paypal Order Accepted With Paypal Order Number: " + expressResponse.Result().Id; context.Order.Notes.Add(note); if (context.HccApp.OrderServices.Orders.Update(context.Order)) { string urlTemplate; if (string.Compare(context.HccApp.CurrentStore.Settings.PayPal.Mode, "Live", true) == 0) { - urlTemplate = "https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token={0}"; + urlTemplate = PayPalConstants.LIVE_URL; } else { - urlTemplate = "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token={0}"; + urlTemplate = PayPalConstants.SANDBOX_URL; } HttpContextBase httpContext = new HccHttpContextWrapper(HttpContext.Current); - httpContext.Response.Redirect(string.Format(urlTemplate, expressResponse.Token), true); + httpContext.Response.Redirect(string.Format(urlTemplate, expressResponse.Result().Id), true); } return true; } else { - foreach (ErrorType ppError in expressResponse.Errors) - { - context.Errors.Add(new WorkflowMessage(ppError.ErrorCode, ppError.ShortMessage, true)); - - //create a note to save the paypal error info onto the order - Orders.OrderNote note = new Orders.OrderNote(); - note.IsPublic = false; - note.Note = "Paypal error number: " + ppError.ErrorCode + " Paypal Error: '" + ppError.ShortMessage + "' Message: '" + ppError.LongMessage; - context.Order.Notes.Add(note); - - EventLog.LogEvent("Paypal error number: " + ppError.ErrorCode, "Paypal Error: '" + ppError.ShortMessage + "' Message: '" + ppError.LongMessage + "' " + " Values passed to SetExpressCheckout: Total=" + string.Format("{0:c}", context.Order.TotalOrderBeforeDiscounts) + " Cart Return Url: " + cartReturnUrl + " Cart Cancel Url: " + cartCancelUrl, EventLogSeverity.Error); - } context.Errors.Add(new WorkflowMessage("Paypal checkout error", GlobalLocalization.GetString("PaypalCheckoutCustomerError"), true)); return false; } diff --git a/Libraries/Hotcakes.Commerce/Common/Constants.cs b/Libraries/Hotcakes.Commerce/Common/Constants.cs index 4e95b377f..35c778954 100644 --- a/Libraries/Hotcakes.Commerce/Common/Constants.cs +++ b/Libraries/Hotcakes.Commerce/Common/Constants.cs @@ -163,5 +163,6 @@ public class Constants public const string TAG_IOGPRICEAMOUNT = ""; public const string TAG_IOGPRICECURRENCY = ""; #endregion + } } diff --git a/Libraries/Hotcakes.Commerce/Common/PayPalConstants.cs b/Libraries/Hotcakes.Commerce/Common/PayPalConstants.cs new file mode 100644 index 000000000..41e282099 --- /dev/null +++ b/Libraries/Hotcakes.Commerce/Common/PayPalConstants.cs @@ -0,0 +1,42 @@ +using System; + + +namespace Hotcakes.Commerce.Common +{ + public class PayPalConstants + { + //Payments Status + public const string PAYMENT_STATUS_COMPLETED = "COMPLETED"; + public const string PAYMENT_STATUS_COMPLETED_DESCRIPTION = "PayPal Express Payment Captured Successfully"; + public const string PAYMENT_STATUS_Pending = "PENDING"; + public const string PAYMENT_STATUS_Pending_DESCRIPTION = "PayPal Express Payment PENDING"; + public const string PAYMENT_STATUS_DENIED = "DENIED"; + public const string PAYMENT_STATUS_DENIED_DESCRIPTION = "PayPal Express Payment DENIED"; + public const string PAYMENT_STATUS_ERROR_DESCRIPTION = + "An error occurred while trying to capture your PayPal payment."; + public const string PAYMENT_CHARGE_ERROR = "An error occurred while trying to charge your PayPal payment."; + public const string PAYMENT_ERROR = "Paypal Express Payment Charge Failed."; + + //Payment Authorize + public const string PAYMENT_AUTHORIZE_SUCCESS = "PayPal Express Payment Authorized Successfully."; + public const string PAYMENT_AUTHORIZE_FAILED = "PayPal Express Payment Authorization Failed."; + + + //Payment Refund + public const string PAYMENT_REFUND_SUCCESS = "PayPal Express Payment Refunded Successfully."; + public const string PAYMENT_REFUND_FAILED = "Paypal Express Payment Refund Failed."; + + //Payment Void + public const string PAYMENT_Void_SUCCESS = "PayPal Express Payment Voided Successfully."; + public const string PAYMENT_Void_FAILED = "Paypal Express Payment Void Failed."; + + + //Payment Mode + public const string PAYMENT_MODE_AUTHORIZE = "AUTHORIZE"; + public const string PAYMENT_MODE_CAPTURE = "CAPTURE"; + + //Template URL + public const string LIVE_URL = "https://www.paypal.com/checkoutnow?token={0}"; + public const string SANDBOX_URL = "https://www.sandbox.paypal.com/checkoutnow?token={0}"; + } +} diff --git a/Libraries/Hotcakes.Commerce/Hotcakes.Commerce.csproj b/Libraries/Hotcakes.Commerce/Hotcakes.Commerce.csproj index 61f94d348..5cf2a99b9 100644 --- a/Libraries/Hotcakes.Commerce/Hotcakes.Commerce.csproj +++ b/Libraries/Hotcakes.Commerce/Hotcakes.Commerce.csproj @@ -94,6 +94,12 @@ ..\..\References\Dnn\Newtonsoft.Json.dll + + ..\..\packages\PayPalCheckoutSdk.1.0.4\lib\netstandard2.0\PayPalCheckoutSdk.dll + + + ..\..\packages\PayPalHttp.1.0.1\lib\netstandard2.0\PayPalHttp-Dotnet.dll + ..\..\References\Misc\paypal_base.dll True @@ -212,6 +218,7 @@ + diff --git a/Libraries/Hotcakes.Commerce/Orders/OrderPaymentManager.cs b/Libraries/Hotcakes.Commerce/Orders/OrderPaymentManager.cs index f6224c60e..ccfe2ac86 100644 --- a/Libraries/Hotcakes.Commerce/Orders/OrderPaymentManager.cs +++ b/Libraries/Hotcakes.Commerce/Orders/OrderPaymentManager.cs @@ -1242,6 +1242,7 @@ public bool PayPalExpressCompleteAllPayments() var t = CreateEmptyTransaction(); t.Card = p.CreditCard; t.Amount = p.Amount; + t.PreviousTransactionNumber = p.RefNum1; var processor = new PaypalExpress(); diff --git a/Libraries/Hotcakes.Commerce/Payment/Methods/PaypalExpress.cs b/Libraries/Hotcakes.Commerce/Payment/Methods/PaypalExpress.cs index e396529bd..3a80b05d2 100644 --- a/Libraries/Hotcakes.Commerce/Payment/Methods/PaypalExpress.cs +++ b/Libraries/Hotcakes.Commerce/Payment/Methods/PaypalExpress.cs @@ -25,10 +25,15 @@ using System; using System.Globalization; +using System.Net; +using System.Threading.Tasks; using com.paypal.soap.api; +using Hotcakes.Commerce.Common; using Hotcakes.Commerce.Utilities; using Hotcakes.Payment; using Hotcakes.PaypalWebServices; +using PayPalCheckoutSdk.Orders; +using PayPalHttp; namespace Hotcakes.Commerce.Payment.Methods { @@ -64,7 +69,7 @@ public bool Authorize(Transaction t, HotcakesApplication app) { try { - var ppAPI = PaypalExpressUtilities.GetPaypalAPI(app.CurrentStore); + var ppAPI = PaypalExpressUtilities.GetRestPaypalAPI(app.CurrentStore); if (t.PreviousTransactionNumber != null) { @@ -76,31 +81,22 @@ public bool Authorize(Transaction t, HotcakesApplication app) mode = PaymentActionCodeType.Sale; } - var paymentResponse = ppAPI.DoExpressCheckoutPayment(t.PreviousTransactionNumber, - t.PreviousTransactionAuthCode, - t.Amount.ToString("N", CultureInfo.InvariantCulture), - mode, - PayPalAPI.GetCurrencyCodeType(app.CurrentStore.Settings.PayPal.Currency), - OrderNumber); + var paymentResponse = Task.Run(() => ppAPI.AuthorizeOrder(t.PreviousTransactionNumber)).GetAwaiter().GetResult(); + - if (paymentResponse.Ack == AckCodeType.Success || - paymentResponse.Ack == AckCodeType.SuccessWithWarning) + if (paymentResponse.StatusCode == HttpStatusCode.Created) { - var paymentInfo = paymentResponse.DoExpressCheckoutPaymentResponseDetails.PaymentInfo[0]; + var paymentInfo = paymentResponse.Result().PurchaseUnits[0].Payments.Authorizations[0]; t.Result.Succeeded = true; - t.Result.ReferenceNumber = paymentInfo.TransactionID; + t.Result.ReferenceNumber = paymentInfo.Id; t.Result.ResponseCode = "OK"; - t.Result.ResponseCodeDescription = "PayPal Express Payment Authorized Successfully."; + t.Result.ResponseCodeDescription = PayPalConstants.PAYMENT_AUTHORIZE_SUCCESS; return true; } t.Result.Succeeded = false; - t.Result.Messages.Add(new Message("PayPal Express Payment Authorization Failed.", string.Empty, + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_AUTHORIZE_FAILED, string.Empty, MessageType.Error)); - foreach (var ppError in paymentResponse.Errors) - { - t.Result.Messages.Add(new Message(ppError.LongMessage, ppError.ErrorCode, MessageType.Error)); - } return false; } } @@ -116,79 +112,53 @@ public bool Capture(Transaction t, HotcakesApplication app) { try { - var ppAPI = PaypalExpressUtilities.GetPaypalAPI(app.CurrentStore); + var ppAPI = PaypalExpressUtilities.GetRestPaypalAPI(app.CurrentStore); var OrderNumber = t.MerchantInvoiceNumber + Guid.NewGuid(); - var captureResponse = ppAPI.DoCapture(t.PreviousTransactionNumber, - "Thank you for your payment.", + var captureResponse = Task.Run(() => ppAPI.CaptureAuthorizedOrder(t.PreviousTransactionNumber, t.Amount.ToString("N", CultureInfo.InvariantCulture), - PayPalAPI.GetCurrencyCodeType(app.CurrentStore.Settings.PayPal.Currency), - OrderNumber); + app.CurrentStore.Settings.PayPal.Currency, + OrderNumber)).GetAwaiter().GetResult(); - if (captureResponse.Ack == AckCodeType.Success || captureResponse.Ack == AckCodeType.SuccessWithWarning) + if (captureResponse.StatusCode == HttpStatusCode.OK || captureResponse.StatusCode == HttpStatusCode.Created) { - t.Result.ReferenceNumber = captureResponse.DoCaptureResponseDetails.PaymentInfo.TransactionID; + var capturedInfo = captureResponse.Result(); + t.Result.ReferenceNumber = capturedInfo.Id; - if (captureResponse.DoCaptureResponseDetails.PaymentInfo.PaymentStatus == - PaymentStatusCodeType.Pending) - { - t.Result.Succeeded = true; - t.Result.ResponseCode = "PENDING"; - t.Result.ResponseCodeDescription = "PayPal Express Payment PENDING"; - t.Result.Messages.Add(new Message("Paypal Express Payment PENDING.", "OK", - MessageType.Information)); - return true; - } - if (captureResponse.DoCaptureResponseDetails.PaymentInfo.PaymentStatus == - PaymentStatusCodeType.InProgress) - { - t.Result.Succeeded = true; - t.Result.ResponseCode = "PENDING"; - t.Result.ResponseCodeDescription = "PayPal Express Payment IN PROGRESS"; - t.Result.Messages.Add(new Message("Paypal Express Payment PENDING. In Progress.", "OK", - MessageType.Information)); - return true; - } - if (captureResponse.DoCaptureResponseDetails.PaymentInfo.PaymentStatus == PaymentStatusCodeType.None) + if (capturedInfo.Status == PayPalConstants.PAYMENT_STATUS_Pending) { t.Result.Succeeded = true; - t.Result.ResponseCode = "PENDING"; - t.Result.ResponseCodeDescription = "PayPal Express Payment: No Status Yet"; - t.Result.Messages.Add(new Message("Paypal Express Payment PENDING. No Status Yet.", "OK", + t.Result.ResponseCode = PayPalConstants.PAYMENT_STATUS_Pending; + t.Result.ResponseCodeDescription = PayPalConstants.PAYMENT_STATUS_Pending_DESCRIPTION; + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_STATUS_Pending_DESCRIPTION, "OK", MessageType.Information)); return true; } - if (captureResponse.DoCaptureResponseDetails.PaymentInfo.PaymentStatus == - PaymentStatusCodeType.Processed) + if (capturedInfo.Status == PayPalConstants.PAYMENT_STATUS_DENIED) { t.Result.Succeeded = true; - t.Result.ResponseCode = "PENDING"; - t.Result.ResponseCodeDescription = "PayPal Express Payment PENDING"; - t.Result.Messages.Add(new Message("Paypal Express Payment PENDING.", "OK", + t.Result.ResponseCode = PayPalConstants.PAYMENT_STATUS_DENIED; + t.Result.ResponseCodeDescription = PayPalConstants.PAYMENT_STATUS_DENIED_DESCRIPTION; + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_STATUS_DENIED_DESCRIPTION, "OK", MessageType.Information)); return true; } - if (captureResponse.DoCaptureResponseDetails.PaymentInfo.PaymentStatus == - PaymentStatusCodeType.Completed) + if (capturedInfo.Status == PayPalConstants.PAYMENT_STATUS_COMPLETED) { t.Result.Succeeded = true; - t.Result.Messages.Add(new Message("PayPal Express Payment Captured Successfully.", "OK", + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_STATUS_COMPLETED_DESCRIPTION, "OK", MessageType.Information)); return true; } t.Result.Succeeded = false; - t.Result.Messages.Add(new Message("An error occurred while trying to capture your PayPal payment.", + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_STATUS_ERROR_DESCRIPTION, string.Empty, MessageType.Error)); return false; } t.Result.Succeeded = false; - t.Result.Messages.Add(new Message("Paypal Express Payment Charge Failed.", string.Empty, + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_ERROR, string.Empty, MessageType.Error)); - foreach (var ppError in captureResponse.Errors) - { - t.Result.Messages.Add(new Message(ppError.LongMessage, ppError.ErrorCode, MessageType.Error)); - } return false; } catch (Exception ex) @@ -202,53 +172,45 @@ public bool Charge(Transaction t, HotcakesApplication app) { try { - var ppAPI = PaypalExpressUtilities.GetPaypalAPI(app.CurrentStore); + var ppAPI = PaypalExpressUtilities.GetRestPaypalAPI(app.CurrentStore); - var OrderNumber = t.MerchantInvoiceNumber + Guid.NewGuid(); - DoExpressCheckoutPaymentResponseType paymentResponse; + HttpResponse paymentResponse; //there was no authorization so we just need to do a direct sale - paymentResponse = ppAPI.DoExpressCheckoutPayment(t.PreviousTransactionNumber, - t.PreviousTransactionAuthCode, - t.Amount.ToString("N", CultureInfo.InvariantCulture), - PaymentActionCodeType.Sale, - PayPalAPI.GetCurrencyCodeType(app.CurrentStore.Settings.PayPal.Currency), - OrderNumber); + + paymentResponse = Task.Run(() => ppAPI.CaptureOrder(t.PreviousTransactionNumber)).GetAwaiter().GetResult(); - if (paymentResponse.Ack == AckCodeType.Success || paymentResponse.Ack == AckCodeType.SuccessWithWarning) + if (paymentResponse.StatusCode == HttpStatusCode.Created || paymentResponse.StatusCode == HttpStatusCode.OK) { - var paymentInfo = paymentResponse.DoExpressCheckoutPaymentResponseDetails.PaymentInfo[0]; + var paymentInfo = paymentResponse.Result().PurchaseUnits[0].Payments.Captures[0]; - t.Result.ReferenceNumber = paymentInfo.TransactionID; + t.Result.ReferenceNumber = paymentInfo.Id; - if (paymentInfo.PaymentStatus == PaymentStatusCodeType.Completed) + if (paymentInfo.Status == PayPalConstants.PAYMENT_STATUS_COMPLETED) { t.Result.Succeeded = true; - t.Result.Messages.Add(new Message("PayPal Express Payment Charged Successfully.", "OK", + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_STATUS_COMPLETED_DESCRIPTION, "OK", MessageType.Information)); return true; } - if (paymentInfo.PaymentStatus == PaymentStatusCodeType.Pending) + if (paymentInfo.Status == PayPalConstants.PAYMENT_STATUS_Pending) { t.Result.Succeeded = true; - t.Result.ResponseCode = "PENDING"; - t.Result.ResponseCodeDescription = "PayPal Express Payment PENDING"; - t.Result.Messages.Add(new Message("Paypal Express Payment PENDING.", "OK", + t.Result.ResponseCode = PayPalConstants.PAYMENT_STATUS_Pending; + t.Result.ResponseCodeDescription = PayPalConstants.PAYMENT_STATUS_Pending_DESCRIPTION; + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_STATUS_Pending_DESCRIPTION, "OK", MessageType.Information)); return true; } t.Result.Succeeded = false; - t.Result.Messages.Add(new Message("An error occurred while trying to charge your PayPal payment.", + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_CHARGE_ERROR, string.Empty, MessageType.Error)); return false; } t.Result.Succeeded = false; - t.Result.Messages.Add(new Message("Paypal Express Payment Charge Failed.", string.Empty, + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_ERROR, string.Empty, MessageType.Error)); - foreach (var ppError in paymentResponse.Errors) - { - t.Result.Messages.Add(new Message(ppError.LongMessage, ppError.ErrorCode, MessageType.Error)); - } + return false; } catch (Exception ex) @@ -262,33 +224,27 @@ public bool Refund(Transaction t, HotcakesApplication app) { try { - var ppAPI = PaypalExpressUtilities.GetPaypalAPI(app.CurrentStore); + var ppAPI = PaypalExpressUtilities.GetRestPaypalAPI(app.CurrentStore); if (t.PreviousTransactionNumber != null) { var refundType = string.Empty; //per paypal's request, the refund type should always be set to partial - refundType = "Partial"; - var refundResponse = ppAPI.RefundTransaction( + + var refundResponse = Task.Run(() => ppAPI.CapturesRefund( t.PreviousTransactionNumber, - refundType, t.Amount.ToString("N", CultureInfo.InvariantCulture), - PayPalAPI.GetCurrencyCodeType(app.CurrentStore.Settings.PayPal.Currency)); - if (refundResponse.Ack == AckCodeType.Success || - refundResponse.Ack == AckCodeType.SuccessWithWarning) + app.CurrentStore.Settings.PayPal.Currency)).GetAwaiter().GetResult(); + if (refundResponse.StatusCode == HttpStatusCode.Created) { t.Result.Succeeded = true; - t.Result.Messages.Add(new Message("PayPal Express Payment Refunded Successfully.", "OK", + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_REFUND_SUCCESS, "OK", MessageType.Information)); return true; } t.Result.Succeeded = false; - t.Result.Messages.Add(new Message("Paypal Express Payment Refund Failed.", string.Empty, + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_REFUND_FAILED, string.Empty, MessageType.Error)); - foreach (var ppError in refundResponse.Errors) - { - t.Result.Messages.Add(new Message(ppError.LongMessage, ppError.ErrorCode, MessageType.Error)); - } return false; } } @@ -303,25 +259,21 @@ public bool Void(Transaction t, HotcakesApplication app) { try { - var ppAPI = PaypalExpressUtilities.GetPaypalAPI(app.CurrentStore); + var ppAPI = PaypalExpressUtilities.GetRestPaypalAPI(app.CurrentStore); if (t.PreviousTransactionNumber != null) { - var voidResponse = ppAPI.DoVoid(t.PreviousTransactionNumber, "Transaction Voided"); - if (voidResponse.Ack == AckCodeType.Success || voidResponse.Ack == AckCodeType.SuccessWithWarning) + var voidResponse = Task.Run(() => ppAPI.VoidAuthorizedPayment(t.PreviousTransactionNumber)).GetAwaiter().GetResult(); + if (voidResponse.StatusCode == HttpStatusCode.NoContent) { t.Result.Succeeded = true; - t.Result.Messages.Add(new Message("PayPal Express Payment Voided Successfully.", "OK", + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_Void_SUCCESS, "OK", MessageType.Information)); return true; } t.Result.Succeeded = false; - t.Result.Messages.Add(new Message("Paypal Express Payment Void Failed.", string.Empty, + t.Result.Messages.Add(new Message(PayPalConstants.PAYMENT_Void_FAILED, string.Empty, MessageType.Error)); - foreach (var ppError in voidResponse.Errors) - { - t.Result.Messages.Add(new Message(ppError.LongMessage, ppError.ErrorCode, MessageType.Error)); - } return false; } } diff --git a/Libraries/Hotcakes.Commerce/Utilities/PaypalExpressUtilities.cs b/Libraries/Hotcakes.Commerce/Utilities/PaypalExpressUtilities.cs index 0eabb49cb..948c4fda0 100644 --- a/Libraries/Hotcakes.Commerce/Utilities/PaypalExpressUtilities.cs +++ b/Libraries/Hotcakes.Commerce/Utilities/PaypalExpressUtilities.cs @@ -33,50 +33,12 @@ namespace Hotcakes.Commerce.Utilities { public class PaypalExpressUtilities { - public static PayPalAPI GetPaypalAPI(Store currentStore) + public static RestPayPalApi GetRestPaypalAPI(Store currentStore) { - var APIProfile - = CreateAPIProfile(currentStore.Settings.PayPal.UserName, - currentStore.Settings.PayPal.Password, - currentStore.Settings.PayPal.Signature, - currentStore.Settings.PayPal.FastSignupEmail, - currentStore.Settings.PayPal.Mode); - - return new PayPalAPI(APIProfile); - } - - private static IAPIProfile CreateAPIProfile(string PayPalUserName, string PayPalPassword, string PayPalSignature, - string subject, string mode) - { - try - { - var profile = ProfileFactory.createSignatureAPIProfile(); - - if (profile != null) - { - profile.Environment = mode; - - EventLog.LogEvent("PayPal Express Get Api", "Getting Environment " + mode, - EventLogSeverity.Information); - - profile.APIUsername = PayPalUserName; - profile.APIPassword = PayPalPassword; - profile.APISignature = PayPalSignature; - profile.Subject = subject; - } - else - { - EventLog.LogEvent("Paypal API", - "Paypal com.paypal.sdk.profiles.ProfileFactory.CreateAPIProfile has failed.", - EventLogSeverity.Error); - } - return profile; - } - catch (Exception ex) - { - EventLog.LogEvent("PayPal Utilities", ex.Message + " | " + ex.StackTrace, EventLogSeverity.Warning); - } - return null; + return new RestPayPalApi(currentStore.Settings.PayPal.ClienId, + currentStore.Settings.PayPal.Secret, currentStore.Settings.PayPal.Mode); } } + + } \ No newline at end of file diff --git a/Libraries/Hotcakes.Commerce/app.config b/Libraries/Hotcakes.Commerce/app.config index bf878282b..bf9b35c1f 100644 --- a/Libraries/Hotcakes.Commerce/app.config +++ b/Libraries/Hotcakes.Commerce/app.config @@ -1,28 +1,28 @@ - + -
+
- + - + - + - - + + - + diff --git a/Libraries/Hotcakes.Commerce/packages.config b/Libraries/Hotcakes.Commerce/packages.config index 756907dc3..ff7fbc845 100644 --- a/Libraries/Hotcakes.Commerce/packages.config +++ b/Libraries/Hotcakes.Commerce/packages.config @@ -4,4 +4,6 @@ + + \ No newline at end of file diff --git a/Libraries/Hotcakes.PaypalWebServices/Hotcakes.PaypalWebServices.csproj b/Libraries/Hotcakes.PaypalWebServices/Hotcakes.PaypalWebServices.csproj index 0ba44f583..956a133a1 100644 --- a/Libraries/Hotcakes.PaypalWebServices/Hotcakes.PaypalWebServices.csproj +++ b/Libraries/Hotcakes.PaypalWebServices/Hotcakes.PaypalWebServices.csproj @@ -64,21 +64,37 @@ false + + ..\..\packages\PayPalCheckoutSdk.1.0.4\lib\netstandard2.0\PayPalCheckoutSdk.dll + + + ..\..\packages\PayPalHttp.1.0.1\lib\netstandard2.0\PayPalHttp-Dotnet.dll + False ..\..\References\Misc\paypal_base.dll + 3.5 + + ..\..\packages\System.IO.4.3.0\lib\net462\System.IO.dll + True + + + ..\..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll + True + Properties\CommonAssemblyInfo.cs + @@ -104,6 +120,9 @@ true + + +