public void MarkOrderAsPaid(int orderId) { Order order = Order.GetOrder(orderId); OrderController orderController = new OrderController(new StoreContext(HttpContext.Current.Request, order.StoreId.Value)); orderController.UpdateOrderStatus(order, order.OrderStatus, PaymentStatusName.Completed); //--- Delete the stored Credit Card number, even though it's encrypted we don't need the full # anymore order.CreditCardNumberEncrypted = string.Empty; order.CreditCardExpiration = string.Empty; order.CreditCardSecurityCode = string.Empty; order.Save(); PaymentTransaction newTransaction = new PaymentTransaction(); newTransaction.OrderId = order.Id; newTransaction.PaymentProviderId = this.ProviderId; newTransaction.GatewayUrl = ""; newTransaction.GatewayTransactionId = ""; newTransaction.GatewayResponse = "Marked as Paid"; newTransaction.GatewayDebugResponse = ""; newTransaction.Amount = order.Total; newTransaction.Save(); }
public override HttpWebResponse SubmitDirectPaymentRequest(Order order, CreditCardInfo creditCardInfo) { order.EncryptCreditCardNumber(creditCardInfo.CardNumber); order.CreditCardSecurityCode = creditCardInfo.SecurityCode; order.PaymentStatus = PaymentStatusName.Pending; order.Save(); PaymentTransaction newTransaction = new PaymentTransaction(); newTransaction.OrderId = order.Id; newTransaction.PaymentProviderId = this.ProviderId; newTransaction.GatewayUrl = ""; newTransaction.GatewayTransactionId = ""; newTransaction.GatewayResponse = "Payment Pending"; newTransaction.GatewayDebugResponse = ""; if (order.Total > 0) { // check for valid Credit Card CreditCardInfoValidator validator = new CreditCardInfoValidator(); ValidationResult results = validator.Validate(creditCardInfo); if (!results.IsValid && results.Errors.Count > 0) { newTransaction.GatewayResponse = "Credit Card Validation Error"; newTransaction.GatewayError = results.Errors.ToList().ConvertAll(e => e.ErrorMessage).ToDelimitedString(", "); } } newTransaction.Save(); return(null); }
public override HttpWebResponse SubmitDirectPaymentRequest(Order order, CreditCardInfo creditCardInfo) { order.PaymentStatus = PaymentStatusName.Pending; order.CustomerNotes += CustomerInstructions + " "; order.Save(); PaymentTransaction newTransaction = new PaymentTransaction(); newTransaction.OrderId = order.Id; newTransaction.PaymentProviderId = this.ProviderId; newTransaction.GatewayUrl = ""; newTransaction.GatewayTransactionId = ""; newTransaction.GatewayResponse = "Payment Pending"; newTransaction.GatewayDebugResponse = ""; newTransaction.Save(); return(null); }
public void MarkOrderAsPaid(int orderId) { Order order = Order.GetOrder(orderId); OrderController orderController = new OrderController(new StoreContext(HttpContext.Current.Request, order.StoreId.Value)); orderController.UpdateOrderStatus(order, order.OrderStatus, PaymentStatusName.Completed); PaymentTransaction newTransaction = new PaymentTransaction(); newTransaction.OrderId = order.Id; newTransaction.PaymentProviderId = this.ProviderId; newTransaction.GatewayUrl = ""; newTransaction.GatewayTransactionId = ""; newTransaction.GatewayResponse = "Marked as Paid"; newTransaction.GatewayDebugResponse = ""; newTransaction.Amount = order.Total; newTransaction.Save(); }
public override PaymentStatusName ProcessDirectPaymentResponse(Order order, HttpWebResponse response) { string responseString = HttpHelper.WebResponseToString(response); // Decode the response fields from PayPal API string[] encodedPairs = responseString.Split('&'); Dictionary <string, string> fields = new Dictionary <string, string>(encodedPairs.Length); foreach (string field in encodedPairs) { string[] pair = field.Split('='); string name = HttpUtility.UrlDecode(pair[0]); string value = HttpUtility.UrlDecode(pair[1]); fields[name] = value; } // parse response fields into variables string ack = fields["ACK"]; AckValues ackType = WA.Enum <AckValues> .TryParseOrDefault(ack, AckValues.Failure); int? orderId = WA.Parser.ToInt(fields.TryGetValueOrEmpty("CUSTOM")); string transactionId = fields.TryGetValueOrEmpty("TRANSACTIONID"); decimal?amount = WA.Parser.ToDecimal(fields.TryGetValueOrEmpty("AMT")); string error1Code = fields.TryGetValueOrEmpty("L_ERRORCODE0"); string error1ShortMsg = fields.TryGetValueOrEmpty("L_SHORTMESSAGE0"); string error1LongMsg = fields.TryGetValueOrEmpty("L_LONGMESSAGE0"); string error1Severity = fields.TryGetValueOrEmpty("L_SEVERITYCODE0"); PaymentTransaction newTransaction = new PaymentTransaction(); newTransaction.OrderId = order.Id; newTransaction.PaymentProviderId = this.ProviderId; newTransaction.GatewayUrl = ProviderUrl; newTransaction.GatewayTransactionId = transactionId; newTransaction.GatewayDebugResponse = HttpUtility.UrlDecode(responseString); newTransaction.Amount = amount; PaymentStatusName paymentStatus = order.PaymentStatus; if (ackType == AckValues.Success || ackType == AckValues.SuccessWithWarning) { bool paymentAmountMatches = (amount.GetValueOrDefault(-1) == order.Total.Value); if (paymentAmountMatches) { newTransaction.GatewayResponse = ackType.ToString(); paymentStatus = PaymentStatusName.Completed; } else { newTransaction.GatewayResponse = ackType.ToString() + " Amount from Payment Provider does not match the Order amount."; paymentStatus = PaymentStatusName.Pending; } if (ackType == AckValues.SuccessWithWarning) { newTransaction.GatewayError = ackType.ToString() + string.Format(@" ErrorCode: {0}, ShortMsg: {1}, LongMsg: {2}, SeverityCode: {3}", error1Code, error1ShortMsg, error1LongMsg, error1Severity); } } else if (ackType == AckValues.Failure || ackType == AckValues.FailureWithWarning || ackType == AckValues.Warning) { newTransaction.GatewayError = ackType.ToString() + string.Format(@" ErrorCode: {0}, ShortMsg: {1}, LongMsg: {2}, SeverityCode: {3}", error1Code, error1ShortMsg, error1LongMsg, error1Severity); paymentStatus = PaymentStatusName.ProviderError; } else { newTransaction.GatewayError = ack + " Invalid / Unknown Response from Payment Provider"; paymentStatus = PaymentStatusName.ProviderError; } newTransaction.Save(); return(paymentStatus); }
// Step 3. public PaymentStatusName DoExpressCheckoutPayment(Order order, Dictionary <string, string> payPalVariables) { string token = payPalVariables["token"]; string payerId = payPalVariables["PayerID"]; Dictionary <string, string> vars = new Dictionary <string, string>(); vars["METHOD"] = "DoExpressCheckoutPayment"; vars["VERSION"] = "60.0"; vars["USER"] = ApiUsername; vars["PWD"] = ApiPassword; vars["SIGNATURE"] = ApiSignature; vars["TOKEN"] = token; vars["PAYERID"] = payerId; IEnumerable <OrderItem> orderitems = order.OrderItemCollectionByOrderId; int itemNumber = 0; foreach (OrderItem orderItem in orderitems) { string orderItemAttributes = orderItem.GetProductFieldDataPlainTextDisplayString(); vars["L_NAME" + itemNumber] = orderItem.Name.Left(127); vars["L_DESC" + itemNumber] = (!string.IsNullOrEmpty(orderItemAttributes) ? " (" + orderItemAttributes + ")" : "").Left(127); vars["L_AMT" + itemNumber] = orderItem.PriceForSingleItem.ToString("N2"); vars["L_QTY" + itemNumber] = orderItem.Quantity.Value.ToString("N0"); vars["L_NUMBER" + itemNumber] = (!string.IsNullOrEmpty(orderItem.Sku) ? " (" + orderItem.Sku + ")" : ""); itemNumber++; } vars["PAYMENTACTION"] = "Sale"; vars["AMT"] = order.Total.Value.ToString("N2"); vars["CURRENCYCODE"] = order.UpToStoreByStoreId.Currency.Code; // Send Http POST to PayPal HttpWebResponse webResponse = HttpHelper.HttpPost(ProviderUrl, vars); string responseString = HttpHelper.WebResponseToString(webResponse); // Decode the response fields from PayPal API Dictionary <string, string> fields = HttpHelper.DecodeVarsFromHttpString(responseString); // parse response fields into variables string ack = fields["ACK"]; AckValues ackType = WA.Enum <AckValues> .TryParseOrDefault(ack, AckValues.Failure); string correlationId = fields.TryGetValueOrEmpty("CORRELATIONID"); string transactionId = fields.TryGetValueOrEmpty("TOKEN"); decimal?amount = WA.Parser.ToDecimal(fields.TryGetValueOrEmpty("AMT")); decimal?taxAmount = WA.Parser.ToDecimal(fields.TryGetValueOrEmpty("TAXAMT")); // TODO - do we need shipping amount too? PaymentTransaction newTransaction = new PaymentTransaction(); newTransaction.OrderId = order.Id; newTransaction.PaymentProviderId = this.ProviderId; newTransaction.GatewayUrl = ProviderUrl; newTransaction.GatewayTransactionId = transactionId; newTransaction.GatewayResponse = vars["METHOD"] + ": " + ack; newTransaction.GatewayDebugResponse = HttpUtility.UrlDecode(responseString); PaymentStatusName paymentStatus = order.PaymentStatus; if (ackType == AckValues.Success || ackType == AckValues.SuccessWithWarning) { bool paymentAmountMatches = (amount.GetValueOrDefault(-1) == order.Total.Value); if (paymentAmountMatches) { paymentStatus = PaymentStatusName.Completed; newTransaction.Amount = amount; } else { newTransaction.GatewayError = string.Format("Payment amount does not match Order Total. Order total {0:N2}. Payment amount {1:N2}", order.Total, amount); if (amount >= order.Total) { paymentStatus = PaymentStatusName.Completed; newTransaction.Amount = amount; } else { paymentStatus = PaymentStatusName.Pending; } } } else { newTransaction.GatewayError = ack + " Invalid / Unknown Response from Payment Provider"; paymentStatus = PaymentStatusName.ProviderError; } newTransaction.Save(); return(paymentStatus); }
// Step 2. private Dictionary <string, string> GetExpressCheckoutDetails(Order order, string payPalToken) { // TODO - implement this so we can get and update the Tax, Shipping, etc. amounts for the order Dictionary <string, string> vars = new Dictionary <string, string>(); vars["METHOD"] = "GetExpressCheckoutDetails"; vars["VERSION"] = "60.0"; vars["USER"] = ApiUsername; vars["PWD"] = ApiPassword; vars["SIGNATURE"] = ApiSignature; vars["TOKEN"] = payPalToken; IEnumerable <OrderItem> orderitems = order.OrderItemCollectionByOrderId; int itemNumber = 0; foreach (OrderItem orderItem in orderitems) { string orderItemAttributes = orderItem.GetProductFieldDataPlainTextDisplayString(); vars["L_NAME" + itemNumber] = orderItem.Name.Left(127); vars["L_DESC" + itemNumber] = (!string.IsNullOrEmpty(orderItemAttributes) ? " (" + orderItemAttributes + ")" : "").Left(127); vars["L_AMT" + itemNumber] = orderItem.PriceForSingleItem.ToString("N2"); vars["L_QTY" + itemNumber] = orderItem.Quantity.Value.ToString("N0"); vars["L_NUMBER" + itemNumber] = (!string.IsNullOrEmpty(orderItem.Sku) ? " (" + orderItem.Sku + ")" : ""); itemNumber++; } // Send Http POST to PayPal HttpWebResponse webResponse = HttpHelper.HttpPost(ProviderUrl, vars); string responseString = HttpHelper.WebResponseToString(webResponse); // Decode the response fields from PayPal API Dictionary <string, string> fields = HttpHelper.DecodeVarsFromHttpString(responseString); // parse response fields into variables string ack = fields.TryGetValueOrEmpty("ACK"); AckValues ackType = WA.Enum <AckValues> .TryParseOrDefault(ack, AckValues.Failure); PaymentTransaction newTransaction = new PaymentTransaction(); newTransaction.OrderId = order.Id; newTransaction.PaymentProviderId = this.ProviderId; newTransaction.GatewayUrl = ProviderUrl; newTransaction.GatewayTransactionId = payPalToken; newTransaction.GatewayResponse = vars["METHOD"] + ": " + ack; newTransaction.GatewayDebugResponse = HttpUtility.UrlDecode(responseString); //newTransaction.Amount = order.Total; if (ackType == AckValues.Success || ackType == AckValues.SuccessWithWarning) { // nothing } else { newTransaction.GatewayError = ack + " Invalid / Unknown Response from Payment Provider"; } newTransaction.Save(); return(fields); }
// Step 1. public string SetExpressCheckoutAndGetToken(Order order, string cancelUrl, string returnUrl) { Dictionary <string, string> vars = new Dictionary <string, string>(); vars["METHOD"] = "SetExpressCheckout"; vars["VERSION"] = "60.0"; vars["USER"] = ApiUsername; vars["PWD"] = ApiPassword; vars["SIGNATURE"] = ApiSignature; vars["RETURNURL"] = returnUrl; vars["CANCELURL"] = cancelUrl; //vars["CUSTOM"] = order.Id.HasValue ? order.Id.Value.ToString().Left(256) : ""; //vars["INVNUM"] = order.Id.HasValue ? order.Id.Value.ToString().Left(127) : ""; vars["CUSTOM"] = order.OrderNumber.Left(256); vars["INVNUM"] = order.OrderNumber.Left(127); vars["PAYMENTACTION"] = "Sale"; vars["AMT"] = order.Total.Value.ToString("N2"); vars["CURRENCYCODE"] = order.UpToStoreByStoreId.Currency.Code; if (order.HasNonEmptyShippingAddress()) { // Address Override (for when user choose PayPal on the Payment Screen, instead of the "check out with paypal" button) vars["ADDROVERRIDE"] = "1"; vars["SHIPTONAME"] = order.ShipRecipientName + (!string.IsNullOrEmpty(order.ShipRecipientBusinessName) ? " " + order.ShipRecipientBusinessName : ""); vars["SHIPTOSTREET"] = order.ShipAddress1; vars["SHIPTOSTREET2"] = order.ShipAddress2; vars["SHIPTOCITY"] = order.ShipCity; vars["SHIPTOSTATE"] = order.ShipRegion; vars["SHIPTOZIP"] = order.ShipPostalCode; vars["SHIPTOCOUNTRYCODE"] = order.ShipCountryCode; } IEnumerable <OrderItem> orderitems = order.OrderItemCollectionByOrderId; int itemNumber = 0; foreach (OrderItem orderItem in orderitems) { string orderItemAttributes = orderItem.GetProductFieldDataPlainTextDisplayString(); vars["L_NAME" + itemNumber] = orderItem.Name.Left(127); vars["L_DESC" + itemNumber] = (!string.IsNullOrEmpty(orderItemAttributes) ? " (" + orderItemAttributes + ")" : "").Left(127); vars["L_AMT" + itemNumber] = orderItem.PriceForSingleItem.ToString("N2"); vars["L_QTY" + itemNumber] = orderItem.Quantity.Value.ToString("N0"); vars["L_NUMBER" + itemNumber] = (!string.IsNullOrEmpty(orderItem.Sku) ? " (" + orderItem.Sku + ")" : ""); itemNumber++; } // Send Http POST to PayPal HttpWebResponse webResponse = HttpHelper.HttpPost(ProviderUrl, vars); string responseString = HttpHelper.WebResponseToString(webResponse); // Decode the response fields from PayPal API Dictionary <string, string> fields = HttpHelper.DecodeVarsFromHttpString(responseString); // parse response fields into variables string ack = fields["ACK"]; AckValues ackType = WA.Enum <AckValues> .TryParseOrDefault(ack, AckValues.Failure); string correlationId = fields.TryGetValueOrEmpty("CORRELATIONID"); string transactionId = fields.TryGetValueOrEmpty("TOKEN"); //string error1Code = fields.TryGetValueOrEmpty("L_ERRORCODE0"); //string error1ShortMsg = fields.TryGetValueOrEmpty("L_SHORTMESSAGE0"); //string error1LongMsg = fields.TryGetValueOrEmpty("L_LONGMESSAGE0"); //string error1Severity = fields.TryGetValueOrEmpty("L_SEVERITYCODE0"); PaymentTransaction newTransaction = new PaymentTransaction(); newTransaction.OrderId = order.Id; newTransaction.PaymentProviderId = this.ProviderId; newTransaction.GatewayUrl = ProviderUrl; newTransaction.GatewayTransactionId = transactionId; newTransaction.GatewayResponse = vars["METHOD"] + ": " + ack; newTransaction.GatewayDebugResponse = HttpUtility.UrlDecode(responseString); newTransaction.Amount = order.Total; string token = ""; if (ackType == AckValues.Success || ackType == AckValues.SuccessWithWarning) { token = transactionId; } else { token = ""; newTransaction.GatewayError = ack + " Invalid / Unknown Response from Payment Provider"; } newTransaction.Save(); return(token); }
public void ProcessRequest(HttpContext context) { try { CardNumber = ""; // Remove non-digits for (int i = 0; i < Provider.Request["CardNumber"].Length; i++) { if (char.IsDigit(Provider.Request["CardNumber"], i)) { CardNumber += Provider.Request["CardNumber"][i].ToString(); } } int year = 0; int.TryParse(Provider.Request["ExpiryYear"], out year); if (year < DateTime.Now.Year) { throw new Exception("Son kullanma tarihi yanlış"); } int month = 0; int.TryParse(Provider.Request["ExpiryMonth"], out month); if (!(month >= 1 && month <= 12)) { throw new Exception("Son kullanma tarihi yanlış"); } ExpiryDate = Provider.Request["ExpiryYear"] + Provider.Request["ExpiryMonth"]; CVV2 = Provider.Request["CVV2"]; if (CVV2.Length != 3 || !CVV2.CanConvertToInteger()) { throw new Exception("CCV2 kodu hatalı"); } CardType = (CardType)Enum.Parse(typeof(CardType), Provider.Request["CardType"]); string cardValid = Utility.ValidateCreditCardNumber(CardType, CardNumber); if (cardValid != "") { context.Response.Write("HATA: " + cardValid); return; } if (Transact()) { try { PaymentTransaction s = new PaymentTransaction(); s.Amount = AmountInCents; s.CheckoutType = CheckoutTypes.CreditCard; s.Result = Response; s.Save(); } catch (Exception ex) { string msg = (AmountInCents / 100d) + " TL tahsil edildi. Bu bilgi bir hata nedeniyle veritabanına kaydedilemedi. Lütfen bu bilgiyi manuel olarak kaydediniz."; Provider.SendMail("Tahsilat yapıldı ama sisteme kaydedilemedi!!!", msg); Provider.Log("Error", "Checkout", msg); } context.Response.Write("OK"); } else { context.Response.Write("HATA: Ödemenizin onaylanmasında bir hata oluştu."); Provider.Log("Error", "Checkout", (AmountInCents / 100d) + " TL tahsil edilmek istendi ama servisten " + ResponseErrorNo + " nolu hata döndü. (" + ResponseErrorMessage + ")"); } } catch (Exception ex) { context.Response.Write("HATA: " + ex.Message); Provider.Log("Error", "Checkout", ex.Message + (ex.InnerException != null ? "(" + ex.InnerException.Message + ")" : "")); } }
public override PaymentStatusName ProcessDirectPaymentResponse(Order order, HttpWebResponse response) { // returned values are returned as a stream, then read into a string string responseString = HttpHelper.WebResponseToString(response); // the response string is broken into an array // The split character specified here must match the delimiting character specified above string[] fields = responseString.Split(fieldDelimiterChar); ResponseCode responseCode = WA.Enum <ResponseCode> .TryParseOrDefault(fields[0], ResponseCode.Error); string responseSubcode = fields[1]; int? responseReasonCode = WA.Parser.ToInt(fields[2]); string responseReasonText = fields[3]; // could show this to the customer string authorizationCode = fields[4]; string avsResponse = fields[5]; string transactionId = fields[6]; int? orderId = WA.Parser.ToInt(fields[7]); // "Invoice Number" in Auth.Net docs string description = fields[8]; decimal?amount = WA.Parser.ToDecimal(fields[9]); string method = fields[10]; string transactionType = fields[11]; string customerId = fields[12]; //.... fields omitted here.... string md5Hash = fields[37]; string cardCodeResponse = fields[38]; // result of CCV verification string cavvResponse = fields[39]; // Cardholder Authentication Verification Response // Custom Merchant-Defined Fields (Pg. 36/37 of Auth.Net Docs) if (fields.Length >= 69) // custom fields start at position 69 { // grab any add'l merchant-defined fields here... } PaymentTransaction newTransaction = new PaymentTransaction(); newTransaction.OrderId = order.Id; newTransaction.PaymentProviderId = this.ProviderId; newTransaction.GatewayUrl = ProviderUrl; newTransaction.GatewayTransactionId = transactionId; newTransaction.GatewayDebugResponse = responseString; newTransaction.Amount = amount; PaymentStatusName paymentStatus = order.PaymentStatus; if (responseCode == ResponseCode.Approved) { bool paymentAmountMatches = (amount.GetValueOrDefault(-1) == order.Total.Value); if (paymentAmountMatches) { newTransaction.GatewayResponse = "Approved"; paymentStatus = PaymentStatusName.Completed; } else { newTransaction.GatewayResponse = "Payment amount does not match the order amount."; paymentStatus = PaymentStatusName.Pending; } } else if (responseCode == ResponseCode.Declined) { newTransaction.GatewayError = string.Format("Payment was declined. {1} (Response Reason Code: {0}).", responseReasonCode, responseReasonText); paymentStatus = PaymentStatusName.Denied; } else if (responseCode == ResponseCode.Error) { newTransaction.GatewayError = string.Format("{1} (Response Reason Code: {0}).", responseReasonCode, responseReasonText); paymentStatus = PaymentStatusName.ProviderError; } else if (responseCode == ResponseCode.HeldForReview) { newTransaction.GatewayError = string.Format("Payment has been held for review by Authorize.Net. {1} (Response Reason Code: {0}).", responseReasonCode, responseReasonText); paymentStatus = PaymentStatusName.Pending; } else { newTransaction.GatewayError = "Invalid / Unknown Response from Payment Provider"; paymentStatus = PaymentStatusName.ProviderError; } newTransaction.Save(); return(paymentStatus); }
public override Dictionary <string, string> CreateOffsitePaymentRequestVariables(Order order, StoreUrls storeUrls) { Dictionary <string, string> fields = new Dictionary <string, string>(); fields["cmd"] = "_cart"; fields["upload"] = "1"; fields["business"] = EmailAddress; fields["custom"] = order.Id.Value.ToString(); //fields["custom"] = order.OrderNumber; string siteWebRoot = storeUrls.PortalUrlRoot; string moduleRootWebPath = storeUrls.ModuleFolderUrlRoot; fields["shopping_url"] = storeUrls.CategoryHome(); fields["return"] = storeUrls.CheckoutCompleteForOrder(order.CreatedFromCartId.Value, string.Empty, new List <string>() { "ppstdreturn=true" }); // URL the user is returned to after PayPal Checkout is complete // BEFORE 7/1/2011 FIX //fields["notify_url"] = string.Format("{0}DesktopModules/DNNspot-Store/PayPal/PayPalIpnHandler.aspx", moduleRootWebPath); fields["notify_url"] = string.Format("{0}PayPal/PayPalIpnHandler.aspx", moduleRootWebPath); fields["currency_code"] = order.UpToStoreByStoreId.Currency.Code; // populate the Cart/Order Items IEnumerable <OrderItem> orderitems = order.OrderItemCollectionByOrderId; int itemNumber = 1; foreach (OrderItem orderItem in orderitems) { string orderItemAttributes = orderItem.GetProductFieldDataPlainTextDisplayString(); if (!orderItem.UpToProductByProductId.IsTaxable.GetValueOrDefault(true)) { fields["tax_rate_" + itemNumber] = "0.00"; } else { //fields["tax_rate_" + itemNumber] = TaxRegion.GetTaxRate(cart.StoreId.GetValueOrDefault(-1), taxCountry, taxRegion); } fields["item_name_" + itemNumber] = orderItem.Name + (!string.IsNullOrEmpty(orderItemAttributes) ? " (" + orderItemAttributes + ")" : ""); //fields["amount_" + itemNumber] = orderItem.PriceTotal.Value.ToString("N2"); // WRONG! "PriceTotal" includes the Qty. multiplier! fields["amount_" + itemNumber] = orderItem.PriceForSingleItem.ToString("N2"); fields["quantity_" + itemNumber] = orderItem.Quantity.Value.ToString("N0"); fields["item_number_" + itemNumber] = orderItem.Sku; itemNumber++; } if (order.DiscountAmount.GetValueOrDefault(0) > 0) { fields["discount_amount_cart"] = order.DiscountAmount.GetValueOrDefault(0).ToString("F2"); } if (order.ShippingAmount.HasValue && ShippingLogic == "Store") { //fields["shipping"] = order.ShippingAmount.Value.ToString("N2"); // doesn't seem to be honored by PayPal for cart uploads... fields["handling_cart"] = order.ShippingAmount.Value.ToString("N2"); } if (order.HasNonEmptyShippingAddress()) { fields["address1"] = order.ShipAddress1.ChopAt(100); fields["address2"] = order.ShipAddress2.ChopAt(100); fields["city"] = order.ShipCity.ChopAt(40); fields["state"] = order.ShipRegion; fields["zip"] = order.ShipPostalCode.ChopAt(32); fields["country"] = order.ShipCountryCode.ChopAt(2); } PaymentTransaction newTransaction = new PaymentTransaction(); newTransaction.OrderId = order.Id; newTransaction.PaymentProviderId = this.ProviderId; newTransaction.GatewayUrl = ProviderUrl; newTransaction.GatewayTransactionId = ""; newTransaction.GatewayResponse = "CreateOffsitePaymentRequest"; newTransaction.GatewayDebugResponse = fields.ImplodeToList("=").ToDelimitedString(", "); newTransaction.Save(); return(fields); }
public override PaymentStatusName ProcessOffsitePaymentResponse(Order order, HttpRequest request) { //---- Need to validate the incoming request with PayPal so we know it's authentic Dictionary <string, string> requestParams = HttpHelper.DecodeParamsFromHttpRequest(request); string requestDataString = HttpHelper.EncodeVarsForHttpPostString(requestParams); // send our modified request back to PayPal for validation string postData = requestDataString + "&cmd=_notify-validate"; HttpWebResponse payPalResponse = HttpHelper.HttpPost(ProviderUrl, postData); string payPalResponseString = HttpHelper.WebResponseToString(payPalResponse); // Parse response into some variables NameValueCollection fields = request.Params; string paymentStatus = fields["payment_status"]; string transactionId = fields["txn_id"]; string receiverEmail = fields["receiver_email"]; string businessEmail = fields["business"]; int? orderId = WA.Parser.ToInt(fields["custom"]); decimal?paymentAmount = WA.Parser.ToDecimal(fields["mc_gross"]); // amount before PayPal fee is subtracted decimal?payPalTransactionFee = WA.Parser.ToDecimal(fields["mc_fee"]); decimal shippingAmount = WA.Parser.ToDecimal(fields["mc_shipping"]).GetValueOrDefault(0); decimal handlingAmount = WA.Parser.ToDecimal(fields["mc_handling"]).GetValueOrDefault(0); decimal taxAmount = WA.Parser.ToDecimal(fields["tax"]).GetValueOrDefault(0); string firstName = fields["first_name"] ?? ""; string lastName = fields["last_name"] ?? ""; string email = fields["payer_email"] ?? ""; string phone = fields["contact_phone"] ?? ""; string shipName = fields["address_name"] ?? ""; string shipAddress1 = fields["address_street"] ?? ""; string shipCity = fields["address_city"] ?? ""; string shipRegion = fields["address_state"] ?? ""; string shipPostalCode = fields["address_zip"] ?? ""; string shipCountryCode = fields["address_country_code"] ?? ""; PaymentStatusName paymentStatusName = order.PaymentStatus; bool isValidReceiverEmail = (receiverEmail == EmailAddress) || (businessEmail == EmailAddress); PaymentTransaction newTransaction = new PaymentTransaction(); newTransaction.OrderId = orderId; newTransaction.PaymentProviderId = this.ProviderId; newTransaction.GatewayUrl = ProviderUrl; newTransaction.GatewayTransactionId = transactionId; newTransaction.GatewayResponse = paymentStatus; newTransaction.GatewayDebugResponse = requestDataString; newTransaction.Amount = paymentAmount; if (payPalResponseString != "VERIFIED") { newTransaction.GatewayError = "Invalid/Unknown response or response could not be validated as authentic"; newTransaction.Save(); return(PaymentStatusName.ProviderError); } if (!isValidReceiverEmail) { newTransaction.GatewayError = "Receiver Email does not match PayPal Account"; newTransaction.Save(); return(PaymentStatusName.ProviderError); } //Order pendingOrder = Order.GetOrder(orderId); if (payPalResponseString == "VERIFIED") { // check if we have already processed this transaction successfully // we might already have processed the IPN callback, and the user clicks "return to store" // which would trigger another transaction PaymentTransaction priorTransaction = PaymentTransaction.GetMostRecentByTransactionId(transactionId); if (priorTransaction != null && priorTransaction.OrderId == orderId) { // we have a duplicate transaction, we should NOT process this new one return(order.PaymentStatus); } //check the payment_status is Completed bool paymentStatusComplete = (paymentStatus.ToLower() == "completed"); if (paymentAmount.GetValueOrDefault(-1) < order.Total.Value) { newTransaction.GatewayError = string.Format("Payment amount does not match Order Total. Order total {0:N2}. Payment amount {1:N2}", order.Total, paymentAmount); newTransaction.Save(); return(PaymentStatusName.ProviderError); } //if (paymentStatusComplete && paymentAmountMatches && receiverEmailMatches) if (paymentStatusComplete) { newTransaction.GatewayResponse = "Verified Payment Completed"; if (request.RawUrl.Contains("PayPalIpnHandler.aspx")) { newTransaction.GatewayResponse += " via IPN"; } else if (request.RawUrl.Contains("Checkout-Complete.aspx")) { newTransaction.GatewayResponse += " via return button from PayPal"; } paymentStatusName = PaymentStatusName.Completed; //---- Update the Order order.CustomerFirstName = firstName; order.CustomerLastName = lastName; order.CustomerEmail = email; order.ShipRecipientName = shipName; order.ShipAddress1 = shipAddress1; //order.ShipAddress2 = shipAddress2; order.ShipCity = shipCity; order.ShipRegion = shipRegion; order.ShipPostalCode = shipPostalCode; order.ShipCountryCode = shipCountryCode; order.ShipTelephone = phone; order.BillAddress1 = shipAddress1; //order.BillAddress2 = shipAddress2; order.BillCity = shipCity; order.BillRegion = shipRegion; order.BillPostalCode = shipPostalCode; order.BillCountryCode = shipCountryCode; order.BillTelephone = phone; // PayPal 'paymentAmount' is the total amount paid by customer // so we need to do some basic math to get the other order amounts... order.ShippingAmount = shippingAmount + handlingAmount; order.TaxAmount = taxAmount; order.SubTotal = paymentAmount - (order.ShippingAmount + order.TaxAmount); order.Total = paymentAmount; order.Save(); } newTransaction.Save(); } return(paymentStatusName); }