/// <summary> /// Starts a PayPal payment and returns a redirect result to PayPal (or payment info page if an error occurs) /// </summary> /// <param name="viewModel"></param> /// <returns></returns> protected ActionResult Payment_PayPalStartPayment(CheckoutPaymentInfoViewModel viewModel, WebFormResponse webFormResponse) { StoreFrontConfiguration storeFrontConfig = CurrentStoreFrontConfigOrThrow; Cart cart = storeFrontConfig.StoreFront.GetCart(Session.SessionID, CurrentUserProfileOrNull); Uri returnUri = new Uri(Url.Action("PayPalAccountConfirmed", null, null, Request.Url.Scheme)); Uri cancelUri = new Uri(Url.Action("PayPalCanceled", null, null, Request.Url.Scheme)); PayPalPaymentClient paypalClient = new PayPalPaymentClient(); PayPalPaymentData response; try { response = paypalClient.StartPayPalPayment(storeFrontConfig, cart, returnUri, cancelUri); } catch(PayPalExceptionOAuthFailed exOAuth) { string message = "Sorry, this store's configuration for PayPal OAuth is not operational. Please contact us for other payment options." + (exOAuth.IsSandbox ? "\nError in Sandbox Config." : "\nError in Live Config"); AddUserMessage("PayPal Error", message, UserMessageType.Danger); if (CurrentUserProfileOrNull != null && CurrentUserProfileOrThrow.AspNetIdentityUserIsInRoleSystemAdmin()) { string adminMessage = exOAuth.ToString() + "\n\nHTTP Response:\n" + exOAuth.ResponseString + "\n\nHTTP Headers:\n" + exOAuth.ResponseHeaders; AddUserMessage("PayPal Error (admin info)", "Error " + adminMessage, UserMessageType.Danger); } return RedirectToAction("PaymentInfo"); } catch(PayPalExceptionCreatePaymentFailed exPaymentFailed) { string message = "Sorry, there was an error sending your order to PayPal for payment. Please contact us for other payment options." + (exPaymentFailed.IsSandbox ? "\nError in Sandbox." : "\nError in Live Site."); AddUserMessage("PayPal Error", message, UserMessageType.Danger); if (CurrentUserProfileOrNull != null && CurrentUserProfileOrThrow.AspNetIdentityUserIsInRoleSystemAdmin()) { string adminMessage = exPaymentFailed.ToString() + "\n\nHTTP Response:\n" + exPaymentFailed.ResponseString + "\n\nHTTP Headers:\n" + exPaymentFailed.ResponseHeaders; AddUserMessage("PayPal Error (admin info)", "Error " + adminMessage, UserMessageType.Danger); } return RedirectToAction("PaymentInfo"); } catch (Exception ex) { string message = "Sorry, there was an error starting starting your order with PayPal. Please contact us for other payment options."; AddUserMessage("PayPal Error", message, UserMessageType.Danger); if (CurrentUserProfileOrNull != null && CurrentUserProfileOrThrow.AspNetIdentityUserIsInRoleSystemAdmin()) { string adminMessage = "Exception: " + ex.ToString(); AddUserMessage("PayPal Error (admin info)", "Error " + adminMessage, UserMessageType.Danger); } return RedirectToAction("PaymentInfo"); } CartPaymentInfo cartPaymentInfo = cart.CartPaymentInfo; if (cartPaymentInfo == null) { cartPaymentInfo = GStoreDb.CartPaymentInfos.Create(); cartPaymentInfo.SetFromPayPalResponse(cart, response); if (webFormResponse != null) { cartPaymentInfo.WebFormResponseId = webFormResponse.WebFormResponseId; } cartPaymentInfo = GStoreDb.CartPaymentInfos.Add(cartPaymentInfo); } else { cartPaymentInfo.SetFromPayPalResponse(cart, response); if (webFormResponse != null) { cartPaymentInfo.WebFormResponseId = webFormResponse.WebFormResponseId; } cartPaymentInfo = GStoreDb.CartPaymentInfos.Update(cartPaymentInfo); } GStoreDb.SaveChanges(); cart.CartPaymentInfoId = cartPaymentInfo.CartPaymentInfoId; cart.StatusPaymentInfoConfirmed = false; cart = GStoreDb.Carts.Update(cart); GStoreDb.SaveChanges(); PayPalLinkData confirmLink = response.links.Where(l => l.rel == "approval_url").SingleOrDefault(); if (string.IsNullOrEmpty(confirmLink.href)) { string message = "Sorry, there was an error getting your order info from PayPal. Please contact us for other payment options."; AddUserMessage("PayPal Error", message, UserMessageType.Danger); if (CurrentUserProfileOrNull != null && CurrentUserProfileOrThrow.AspNetIdentityUserIsInRoleSystemAdmin()) { string adminMessage = "PayPal Response parse error. Cannot find link with method: approval_url"; AddUserMessage("PayPal Error (admin info)", "Error " + adminMessage, UserMessageType.Danger); } return RedirectToAction("PaymentInfo"); } return Redirect(confirmLink.href); }
/// <summary> /// Processes paypal payment on an order if it has not been done already /// Saves Payment to cart, does not mark cart status /// Exceptions thrown if cart.StatusPlacedOrder = true or cart.OrderId.HasValue /// Otherwise, payment will be processed and if failed, a record with failure code will be returned /// </summary> /// <returns></returns> public static Payment ProcessPayPalPaymentForOrderAndSavePayment(this Cart cart, StoreFrontConfiguration storeFrontConfig, IGstoreDb db) { if (storeFrontConfig == null) { throw new ArgumentNullException("storeFrontConfig"); } if (cart == null) { throw new ArgumentNullException("cart"); } if (!cart.StatusPaymentInfoConfirmed) { throw new ApplicationException("cart.StatusPaymentInfoConfirmed = false. Be sure cart is updated with payment info status = true when payment is selected."); } if (cart.CartPaymentInfo == null) { throw new ArgumentNullException("cart.PaymentInfo"); } if (cart.OrderId.HasValue) { throw new ApplicationException("cart.OrderId.HasValue is set. This cart already has been processed and converted into an order. Order Id: " + cart.OrderId.Value); } if (cart.StatusPlacedOrder) { throw new ApplicationException("cart.StatusPlacedOrder = true. This cart already has been processed and converted into an order."); } if (cart.CartPaymentInfo.PayPalPaymentId.ToLower() != cart.CartPaymentInfo.PayPalReturnPaymentId.ToLower()) { throw new ApplicationException("PayPal Payment id mismatch. PaymentId: " + cart.CartPaymentInfo.PayPalPaymentId + " ReturnPaymentId: " + cart.CartPaymentInfo.PayPalReturnPaymentId); } if (cart.CartPaymentInfo.PaymentSource != Models.BaseClasses.GStorePaymentSourceEnum.PayPal) { throw new ApplicationException("Payment Source not supported: " + cart.CartPaymentInfo.PaymentSource.ToString()); } Payment payment = db.Payments.Create(); payment.SetDefaultsForNew(storeFrontConfig); payment.PaymentSource = cart.CartPaymentInfo.PaymentSource; payment.ProcessDateTimeUtc = DateTime.UtcNow; payment.CartId = cart.CartId; PayPalPaymentData response = new PayPal.Models.PayPalPaymentData(); PayPal.PayPalPaymentClient paypalClient = new PayPal.PayPalPaymentClient(); try { response = paypalClient.ExecutePayPalPayment(storeFrontConfig, cart); if (response.transactions == null || response.transactions.Count() == 0) { throw new ApplicationException("PayPal transactions missing from response. JSON: " + response.Json); } payment.SetFromPayPalPayment(response); payment.PaymentFailed = false; payment.FailureException = null; payment.IsProcessed = true; } catch (Exceptions.PayPalExceptionOAuthFailed exOAuth) { payment.PaymentFailed = true; payment.FailureException = exOAuth.ToString(); payment.Json = response.Json; payment.AmountPaid = 0M; payment.TransactionId = null; payment.IsProcessed = false; } catch (Exceptions.PayPalExceptionExecutePaymentFailed exPaymentFailed) { payment.PaymentFailed = true; payment.FailureException = exPaymentFailed.ToString(); payment.Json = response.Json; payment.AmountPaid = 0M; payment.TransactionId = null; payment.IsProcessed = false; } catch (Exception ex) { payment.PaymentFailed = true; payment.FailureException = ex.ToString(); payment.Json = response.Json; payment.AmountPaid = 0M; payment.TransactionId = null; payment.IsProcessed = false; } db.Payments.Add(payment); db.SaveChanges(); return payment; }
public static bool TestPayPal(this StoreFrontConfiguration config, BaseController controller) { if (config == null) { throw new ArgumentNullException("config"); } if (controller == null) { throw new ArgumentNullException("controller"); } if (!config.PaymentMethod_PayPal_Enabled) { controller.AddUserMessage("PayPal Test Failed!", "PayPal is not enabled in your store front configuration. Make sure to enable it on the Payments tab.", UserMessageType.Danger); return false; } else { bool useSandbox = !config.PaymentMethod_PayPal_UseLiveServer; PayPalPaymentClient client = new PayPalPaymentClient(); try { PayPalOAuthTokenData token = client.TestPayPalOAuthToken(config.PaymentMethod_PayPal_Client_Id, config.PaymentMethod_PayPal_Client_Secret, useSandbox); if (!string.IsNullOrWhiteSpace(token.access_token)) { //token appears good controller.AddUserMessage("PayPal Test Passed!", "PayPal tested successfully using the " + (useSandbox ? " TEST" : " LIVE") + " server", UserMessageType.Success); return true; } controller.AddUserMessage("PayPal Test Failed!", "PayPal test failed using the " + (useSandbox ? " TEST" : " LIVE") + " server", UserMessageType.Danger); return false; } catch (Exception ex) { controller.AddUserMessage("PayPal Test Failed!", "PayPal test failed. with error " + ex.GetType().FullName + " using the " + (useSandbox ? " TEST" : " LIVE") + " server.\nPlease verify your PayPal configuration in the store front edit page on the Payments Tab.\nError Message: " + ex.Message, UserMessageType.Danger); return false; } } }