protected PayPalPaymentData CreatePayPalPayment(PayPalOAuthTokenData token, decimal total, string description, PayPalItemData[] items, string return_url, string cancel_url, bool useSandbox) { if (string.IsNullOrEmpty(token.access_token)) { throw new ArgumentNullException("token.access_token"); } if (string.IsNullOrEmpty(return_url)) { throw new ArgumentNullException("return_url"); } if (string.IsNullOrEmpty(cancel_url)) { throw new ArgumentNullException("cancel_url"); } if (total < 0.01M) { throw new ArgumentOutOfRangeException("total", "total must be 1 cent or more; value invalid: " + total.ToString()); } PayPalPaymentData requestData = new PayPalPaymentData(); requestData.intent = "sale"; requestData.redirect_urls.return_url = return_url; requestData.redirect_urls.cancel_url = cancel_url; requestData.payer.payment_method = "paypal"; List<PayPalTransactionData> transactions = new List<PayPalTransactionData>(); transactions.Add(new PayPalTransactionData(total, description, items)); requestData.transactions = transactions.ToArray(); string requestJson = JsonConvert.SerializeObject(requestData, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); StringContent postContent = new StringContent(requestJson, Encoding.UTF8, "application/json"); HttpClient httpClient = new HttpClient(); httpClient.Timeout = new TimeSpan(0, 0, 30); Uri requestUri = null; if (useSandbox) { httpClient.BaseAddress = new Uri("https://api.sandbox.paypal.com/"); } else { httpClient.BaseAddress = new Uri("https://api.paypal.com/"); } requestUri = new Uri("v1/payments/payment", UriKind.Relative); HttpResponseMessage response; httpClient.DefaultRequestHeaders.Clear(); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml")); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.access_token); try { response = httpClient.PostAsync(requestUri, postContent).Result; } catch (Exception ex) { string message = "HTTP Client returned an error during PayPal Create Payment API post: " + ex.Message + ". See inner exception for details."; throw new Exceptions.PayPalExceptionCreatePaymentFailed(useSandbox, message, null, ex); } PayPalPaymentData paymentResponseData; if (response.IsSuccessStatusCode) { //get PayPal data string json = response.Content.ReadAsStringAsync().Result; try { paymentResponseData = JsonConvert.DeserializeObject<PayPalPaymentData>(json); } catch (Exception ex) { string message = "Error reading PayPal Create Payment API result! \nError code: " + response.StatusCode + " " + response.ReasonPhrase + "\n" + response.ToString() + " see inner exception for details.\nJSON Response Data: " + json; throw new Exceptions.PayPalExceptionCreatePaymentFailed(useSandbox, message, response, ex); } paymentResponseData.Json = json; } else { string message = "PayPal Create Payment API call failed! \nError code: " + response.StatusCode + " " + response.ReasonPhrase + "\n" + response.ToString(); throw new Exceptions.PayPalExceptionCreatePaymentFailed(useSandbox, message, response, null); } return paymentResponseData; }
public static void SetFromPayPalPayment(this Payment payment, PayPalPaymentData response) { if (response.transactions == null) { throw new ArgumentNullException("response.transactions"); } if (response.transactions.Count() != 1) { throw new ArgumentOutOfRangeException("response.transactions", "response.transactions count is invalid in the response. count must be 1. current count: " + response.transactions.Count()); } PayPalTransactionData transaction = response.transactions.SingleOrDefault(); PayPalPayerData payer = response.payer; if (!response.payer.payer_info.HasValue) { throw new ArgumentNullException("response.payer.payer_info"); } PayPalPayerInfoData payer_info = response.payer.payer_info.Value; if (payer.funding_instruments != null && payer.funding_instruments.Count() != 1 && payer.funding_instruments.Count() != 0) { //wrong number of funding instruments, only 1 is supported throw new ArgumentOutOfRangeException("response.payer.funding_instruments", "funding_instruments count is invalid in the response. count must be 1 or 0 (or null). current count: " + payer.funding_instruments.Count()); } PayPalCreditCardData? directCreditCard = null; if (payer.funding_instruments != null && payer.funding_instruments.Count() == 1) { directCreditCard = payer.funding_instruments[0].credit_card; } if (response.links == null || response.links.Count() == 0) { throw new ArgumentNullException("response.links"); } if (!response.links.Any(l => l.rel == "self")) { throw new ArgumentException("Response is invalid. response.links[rel = self] not found in response."); } PayPalLinkData linkToSelf = response.links.Single(l => l.rel == "self"); if (transaction.related_resources == null) { throw new ArgumentNullException("response.transactions[0].related_resources"); } if (transaction.related_resources.Count() != 1) { throw new ArgumentOutOfRangeException("response", "response.transactions[0].related_resources count is invalid in the response. count must be 1. current count: " + transaction.related_resources.Count()); } PayPalSaleData sale = transaction.related_resources[0].sale; if (!payer_info.shipping_address.HasValue) { throw new ArgumentNullException("response.payer.payer_info.shipping_address"); } PayPalShippingAddressData payerAddress = payer_info.shipping_address.Value; if (!transaction.item_list.HasValue) { throw new ArgumentNullException("response.transactions[0].item_list"); } if (!transaction.item_list.Value.shipping_address.HasValue) { throw new ArgumentNullException("response.transactions[0].item_list.shipping_address"); } PayPalShippingAddressData shippingAddress = transaction.item_list.Value.shipping_address.Value; if (sale.links == null) { throw new ArgumentNullException("response.transactions[0].related_resources[0].sale.links"); } if (!sale.links.Any(l => l.rel == "self")) { throw new ArgumentException("Response is invalid. response.transactions[0].related_resources[0].sale.links[rel = self] not found in response."); } PayPalLinkData linkToSale = sale.links.Single(l => l.rel == "self"); if (!sale.links.Any(l => l.rel == "refund")) { throw new ArgumentException("Response is invalid. response.transactions[0].related_resources[0].sale.links[rel = refund] not found in response."); } PayPalLinkData linkToRefund = sale.links.Single(l => l.rel == "refund"); if (!sale.links.Any(l => l.rel == "parent_payment")) { throw new ArgumentException("Response is invalid. response.transactions[0].related_resources[0].sale.links[rel = parent_payment] not found in response."); } PayPalLinkData linkToParentPayment = sale.links.Single(l => l.rel == "parent_payment"); //some doubt to the right id to put here payment.TransactionId = sale.id; payment.AmountPaid = transaction.amount.ToDecimal(); payment.Json = response.Json; //[Display(Name = "PayPal Payment Id", Description = "PayPal Payment Resource from PayPal payment (response.id)")] payment.PayPalPaymentResource = response.id; //[Display(Name = "PayPal Payment State", Description = "PayPal Payment State from PayPal payment (response.state")] payment.PayPalState = response.state; //[Display(Name = "PayPal Payment Intent", Description = "PayPal Payment Intent from PayPal payment (response.intent")] payment.PayPalIntent = response.intent; //[Display(Name = "PayPal Payment Create Time", Description = "Time payment was started from PayPal payment (response.create_time")] payment.PayPalCreateTime = response.create_time; //[Display(Name = "PayPal Payment Update Time", Description = "Time payment was completed from PayPal payment (response.update_time")] payment.PayPalUpdateTime = response.update_time; //[Display(Name = "PayPal Payment Method", Description = "Payment method from PayPal payment (response.payer.payment_method")] payment.PayPalPaymentMethod = payer.payment_method; if (!directCreditCard.HasValue) { //[Display(Name = "PayPal Payment Is a Direct Credit Card payment", Description = "Checked if this is a PayPal direct credit card payment from PayPal payment (response.payer.funding_instruments.Any()")] payment.PayPalIsDirectCreditCardPayment = false; } if (payer.funding_instruments != null && payer.funding_instruments.Count() == 1) { //[Display(Name = "PayPal Payment Is a Direct Credit Card payment", Description = "Checked if this is a PayPal direct credit card payment from PayPal payment (response.payer.funding_instruments.Any()")] payment.PayPalIsDirectCreditCardPayment = true; //[Display(Name = "PayPal Direct Credit Card Number", Description = "Credit card number for direct credit card payment from PayPal payment (response.payer.funding_instruments[0].credit_card.number")] payment.PayPalDirectCreditCardNumber = directCreditCard.Value.number; //[Display(Name = "PayPal Direct Credit Card Type", Description = "Credit card type for direct credit card payment from PayPal payment (response.payer.funding_instruments[0].credit_card.type")] payment.PayPalDirectCreditCardType = directCreditCard.Value.type; //[Display(Name = "PayPal Direct Credit Card Expire Month", Description = "Expiration month for direct credit card payment from PayPal payment (response.payer.funding_instruments[0].credit_card.expire_month")] payment.PayPalDirectCreditCardExpireMonth = directCreditCard.Value.expire_month; //[Display(Name = "PayPal Direct Credit Card Expire Year", Description = "Expiration year for direct credit card payment from PayPal payment (response.payer.funding_instruments[0].credit_card.expire_year")] payment.PayPalDirectCreditCardExpireYear = directCreditCard.Value.expire_year; //[Display(Name = "PayPal Direct Credit Card First Name", Description = "First Name for direct credit card payment from PayPal payment (response.payer.funding_instruments[0].credit_card.first_name")] payment.PayPalDirectCreditCardFirstName = directCreditCard.Value.first_name; //[Display(Name = "PayPal Direct Credit Card First Name", Description = "Last Name for direct credit card payment from PayPal payment (response.payer.funding_instruments[0].credit_card.last_name")] payment.PayPalDirectCreditCardLastName = directCreditCard.Value.last_name; } //[Display(Name = "PayPal Payer Email", Description = "Email address entered from PayPal payment (response.payer.payer_info.email")] payment.PayPalPayerEmail = payer_info.email; //[Display(Name = "PayPal Payer First Name", Description = "first name entered from PayPal payment (response.payer.payer_info.first_name")] payment.PayPalPayerFirstName = payer_info.first_name; //[Display(Name = "PayPal Payer Last Name", Description = "last name entered from PayPal payment (response.payer.payer_info.last_name")] payment.PayPalPayerLastName = payer_info.last_name; //[Display(Name = "PayPal Payer Id", Description = "Payer Id from PayPal payment (response.payer.payer_info.payer_id")] payment.PayPalPayerId = payer_info.payer_id; //[Display(Name = "PayPal Payment Resource API Link", Description = "Payment API Link from PayPal payment (response.links.[rel=self].href")] payment.PayPalPaymentResourceLink = linkToSelf.href; //[Display(Name = "PayPal Transaction Total", Description = "Transaction Total from PayPal payment (response.transactions.[0].amount.total")] payment.PayPalTransactionTotal = transaction.amount.total; //[Display(Name = "PayPal Transaction Currency", Description = "Transaction currency from PayPal payment (response.transactions.[0].amount.currency")] payment.PayPalTransactionCurrency = transaction.amount.currency; //[Display(Name = "PayPal Transaction Description", Description = "Transaction description from PayPal payment (response.transactions.[0].description")] payment.PayPalTransactionDescription = transaction.description; //[Display(Name = "PayPal Sale Transaction Id", Description = "PayPal Transaction Id from PayPal payment (response.transactions.[0].related_resources.[0].sale.id")] payment.PayPalSaleId = sale.id; //[Display(Name = "PayPal Sale Create Time", Description = "Time sale was started from PayPal payment (response.transactions.[0].related_resources.[0].sale.create_time")] payment.PayPalSaleCreateTime = sale.create_time; //[Display(Name = "PayPal Sale Update Time", Description = "Time sale was completed from PayPal payment (response.transactions.[0].related_resources.[0].sale.update_time")] payment.PayPalSaleUpdateTime = sale.update_time; //[Display(Name = "PayPal Sale Total", Description = "PayPal Sale Total from PayPal payment (response.transactions.[0].related_resources.[0].sale.amount.total")] payment.PayPalSaleAmountTotal = sale.amount.total; //[Display(Name = "PayPal Sale Currency", Description = "PayPal Sale Currency from PayPal payment (response.transactions.[0].related_resources.[0].sale.amount.currency")] payment.PayPalSaleAmountCurrency = sale.amount.currency; //[Display(Name = "PayPal Sale Payment Mode", Description = "PayPal Sale Payment Mode from PayPal payment (response.transactions.[0].related_resources.[0].sale.payment_mode")] payment.PayPalSalePaymentMode = sale.payment_mode; //[Display(Name = "PayPal Sale Status", Description = "PayPal Sale status from PayPal payment (response.transactions.[0].related_resources.[0].sale.state")] payment.PayPalSaleState = sale.state; //[Display(Name = "PayPal Sale Protection Eligibility", Description = "PayPal Sale protection eligibility from PayPal payment (response.transactions.[0].related_resources.[0].sale.protection_eligibility")] payment.PayPalSaleProtectionEligibility = sale.protection_eligibility; //[Display(Name = "PayPal Sale Protection Eligibility Type", Description = "PayPal Sale protection eligibility type from PayPal payment (response.transactions.[0].related_resources.[0].sale.protection_eligibility_type")] payment.PayPalSaleProtectionEligibilityType = sale.protection_eligibility_type; //[Display(Name = "PayPal Sale Transaction Fee", Description = "PayPal Sale transaction fee from PayPal payment (response.transactions.[0].related_resources.[0].sale.transaction_fee.value")] payment.PayPalSaleTransactionFeeValue = sale.transaction_fee.value ; //[Display(Name = "PayPal Sale Transaction Fee Currency", Description = "PayPal Sale transaction fee currency from PayPal payment (response.transactions.[0].related_resources.[0].sale.transaction_fee.currency")] payment.PayPalSaleTransactionFeeCurrency = sale.transaction_fee.currency; //[Display(Name = "PayPal Sale API Link to Sale", Description = "PayPal API Link to sale from PayPal payment (response.transactions.[0].related_resources.[0].sale.links.[rel=self]")] payment.PayPalSaleAPILinkToSelf = linkToSale.href; //[Display(Name = "PayPal Sale API Link to Refund", Description = "PayPal API Link to refund from PayPal payment (response.transactions.[0].related_resources.[0].sale.links.[rel=refund]")] payment.PayPalSaleAPILinkToRefund = linkToRefund.href; //[Display(Name = "PayPal Sale API Link to Refund", Description = "PayPal API Link to refund from PayPal payment (response.transactions.[0].related_resources.[0].sale.links.[rel=parent_payment]")] payment.PayPalSaleAPILinkToParentPayment = linkToParentPayment.href; //[Display(Name = "PayPal Shipping Address Recipient Name", Description = "Shipping recipient name from PayPal payment (response.transactions.[0].item_list.shipping_address.recipient_name")] payment.PayPalShippingAddressRecipientName = shippingAddress.recipient_name; //[Display(Name = "PayPal Shipping Address Line 1", Description = "Shipping address line 1 from PayPal payment (response.transactions.[0].item_list.shipping_address.line1")] payment.PayPalShippingAddressLine1 = shippingAddress.line1; //[Display(Name = "PayPal Shipping Address Line 2", Description = "Shipping address line 2 from PayPal payment (response.transactions.[0].item_list.shipping_address.line2")] payment.PayPalShippingAddressLine2 = shippingAddress.line2; //[Display(Name = "PayPal Shipping Address City", Description = "Shipping City from PayPal payment (response.transactions.[0].item_list.shipping_address.city")] payment.PayPalShippingAddressCity = shippingAddress.city; //[Display(Name = "PayPal Shipping Address State", Description = "Shipping State from PayPal payment (response.transactions.[0].item_list.shipping_address.state")] payment.PayPalShippingAddressState = shippingAddress.state; //[Display(Name = "PayPal Shipping Address Postal Code", Description = "Shipping (ZIP) Postal code from PayPal payment (response.transactions.[0].item_list.shipping_address.postal_code")] payment.PayPalShippingAddressPostalCode = shippingAddress.postal_code; //[Display(Name = "PayPal Shipping Country Code", Description = "Shipping Country Code from PayPal payment (response.transactions.[0].item_list.shipping_address.country_code")] payment.PayPalShippingAddressCountryCode = shippingAddress.country_code; //[Display(Name = "PayPal Shipping Address Recipient Name", Description = "Shipping recipient name from PayPal payment (response.payer.payer_info.shipping_address.recipient_name")] payment.PayPalPayerShippingAddressRecipientName = payerAddress.recipient_name; //[Display(Name = "PayPal Shipping Address Line 1", Description = "Shipping address line 1 from PayPal payment (response.payer.payer_info.shipping_address.line1")] payment.PayPalPayerShippingAddressLine1 = payerAddress.line1; //[Display(Name = "PayPal Shipping Address Line 2", Description = "Shipping address line 2 from PayPal payment (response.payer.payer_info.shipping_address.line2")] payment.PayPalPayerShippingAddressLine2 = payerAddress.line2; //[Display(Name = "PayPal Shipping Address City", Description = "Shipping City from PayPal payment (response.payer.payer_info.shipping_address.city")] payment.PayPalPayerShippingAddressCity = payerAddress.city; //[Display(Name = "PayPal Shipping Address State", Description = "Shipping State from PayPal payment (response.payer.payer_info.shipping_address.state")] payment.PayPalPayerShippingAddressState = payerAddress.state; //[Display(Name = "PayPal Shipping Address Postal Code", Description = "Shipping (ZIP) Postal code from PayPal payment (response.payer.payer_info.shipping_address.postal_code")] payment.PayPalPayerShippingAddressPostalCode = payerAddress.postal_code; //[Display(Name = "PayPal Shipping Country Code", Description = "Shipping Country Code from PayPal payment (response.payer.payer_info.shipping_address.country_code")] payment.PayPalPayerShippingAddressCountryCode = payerAddress.country_code; }
public PayPalPaymentData TestCreateOneItemPayment(PayPalOAuthTokenData token, decimal total, string description, string return_url, string cancel_url, bool useSandbox) { if (string.IsNullOrEmpty(token.access_token)) { throw new ArgumentNullException("token.access_token"); } if (string.IsNullOrEmpty(return_url)) { throw new ArgumentNullException("return_url"); } if (string.IsNullOrEmpty(cancel_url)) { throw new ArgumentNullException("cancel_url"); } if (total < 0.01M) { throw new ArgumentOutOfRangeException("total", "total must be 1 cent or more; value invalid: " + total.ToString()); } PayPalPaymentData requestData = new PayPalPaymentData(); requestData.intent = "sale"; requestData.redirect_urls.return_url = return_url; requestData.redirect_urls.cancel_url = cancel_url; requestData.payer.payment_method = "paypal"; List<PayPalItemData> transactionItems = new List<PayPalItemData>(); transactionItems.Add(new PayPalItemData("1", description, total.ToString("N2"), "X12345")); List<PayPalTransactionData> transactions = new List<PayPalTransactionData>(); transactions.Add(new PayPalTransactionData(total, description, transactionItems.ToArray())); requestData.transactions = transactions.ToArray(); string requestJson = JsonConvert.SerializeObject(requestData, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); StringContent postContent = new StringContent(requestJson, Encoding.UTF8, "application/json"); HttpClient httpClient = new HttpClient(); httpClient.Timeout = new TimeSpan(0, 0, 30); Uri requestUri = null; if (useSandbox) { httpClient.BaseAddress = new Uri("https://api.sandbox.paypal.com/"); } else { httpClient.BaseAddress = new Uri("https://api.paypal.com/"); } requestUri = new Uri("v1/payments/payment", UriKind.Relative); httpClient.DefaultRequestHeaders.Clear(); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml")); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.access_token); HttpResponseMessage response = httpClient.PostAsync(requestUri, postContent).Result; PayPalPaymentData paymentResponseData; if (response.IsSuccessStatusCode) { //get token data string json = response.Content.ReadAsStringAsync().Result; paymentResponseData = JsonConvert.DeserializeObject<PayPalPaymentData>(json); paymentResponseData.Json = json; } else { throw new ApplicationException("PayPal Create One Item Payment API call failed! \nError code: " + response.StatusCode + " " + response.ReasonPhrase + "\n" + response.ToString()); } return paymentResponseData; }
/// <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; }