using System.Collections.Generic; using Microsoft.Extensions.Logging; using Yavsc.Models.Billing; using Microsoft.AspNet.Http; using System.Threading.Tasks; using Newtonsoft.Json; using PayPal.PayPalAPIInterfaceService.Model; using PayPal.PayPalAPIInterfaceService; using Yavsc.ViewModels.PayPal; using Yavsc.Models; using Microsoft.Data.Entity; using System.Linq; using Yavsc.Models.Payment; namespace Yavsc.Helpers { public static class PayPalHelpers { private static Dictionary payPalProperties = null; public static Dictionary GetPayPalProperties() { if (payPalProperties==null) { payPalProperties = new Dictionary(); // Don't do: // payPalProperties.Add("mode", Startup.PayPalSettings.Mode); // Instead, set the endpoint parameter. if (Startup.PayPalSettings.Mode == "production") { // use nvp end point: https://api-3t.paypal.com/nvp payPalProperties.Add("endpoint", "https://api-3t.paypal.com/nvp"); } else { payPalProperties.Add("endpoint", "https://api-3t.sandbox.paypal.com/nvp"); } payPalProperties.Add("clientId", Startup.PayPalSettings.ClientId); payPalProperties.Add("clientSecret", Startup.PayPalSettings.ClientSecret); int numClient = 0; if (Startup.PayPalSettings.Accounts!=null) foreach (var account in Startup.PayPalSettings.Accounts) { numClient++; payPalProperties.Add ($"account{numClient}.apiUsername",account.ApiUsername); payPalProperties.Add ($"account{numClient}.apiPassword",account.ApiPassword); payPalProperties.Add ($"account{numClient}.apiSignature",account.Signature); } } return payPalProperties; } private static PayPalAPIInterfaceServiceService payPalService = null; public static PayPalAPIInterfaceServiceService PayPalService { get { if (payPalService==null) payPalService = new PayPal.PayPalAPIInterfaceService.PayPalAPIInterfaceServiceService(GetPayPalProperties()); return payPalService; }} public class PaymentUrls { public string ReturnUrl { get; set; } public string CancelUrl { get; set; } public string CGVUrl { get; set; } } public static PaymentUrls GetPaymentUrls(this HttpRequest request, string controllerName, string id) { var result = new PaymentUrls { ReturnUrl = request.ToAbsolute($"{controllerName}/PaymentConfirmation/{id}"), CancelUrl = request.ToAbsolute($"{controllerName}/ClientCancel/{id}"), CGVUrl = request.ToAbsolute($"{controllerName}/CGV") }; return result; } public static SetExpressCheckoutResponseType CreatePayment(this HttpRequest request, string controllerName, NominativeServiceCommand query, string intent = "sale", ILogger logger = null) { var items = query.GetBillItems(); var total = items.Addition().ToString("F2"); var coreq = new SetExpressCheckoutReq {}; var urls = request.GetPaymentUrls(controllerName, query.Id.ToString()); var pitem = new PaymentDetailsItemType {}; coreq.SetExpressCheckoutRequest = new SetExpressCheckoutRequestType{ DetailLevel = new List { DetailLevelCodeType.RETURNALL }, SetExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType { PaymentDetails = new List( new [] { new PaymentDetailsType{ OrderDescription = query.GetDescription(), OrderTotal = new BasicAmountType { currencyID = CurrencyCodeType.EUR, value = total }, PaymentDetailsItem = new List ( items.Select(i => new PaymentDetailsItemType { Amount = new BasicAmountType { currencyID = CurrencyCodeType.EUR, value = i.UnitaryCost.ToString("F2") }, Name = i.Name, Quantity = i.Count, Description = i.Description }) ) }}), InvoiceID = query.GetInvoiceId(), // NOTE don't set OrderDescription : "You cannot pass both the new and deprecated order description.","ErrorCode":"11804 CancelURL = urls.CancelUrl, ReturnURL = urls.ReturnUrl } }; var d = new SetExpressCheckoutRequestDetailsType(); logger.LogInformation($"Creating express checkout for {Startup.PayPalSettings.MerchantAccountUserName} : "+JsonConvert.SerializeObject(coreq)); var response = PayPalService.SetExpressCheckout( coreq, Startup.PayPalSettings.MerchantAccountUserName ); return response; } public static async Task GetCheckoutInfo( this ApplicationDbContext context, string token) { return await CreatePaymentViewModel(context,token,GetExpressCheckoutDetails(token)); } private static GetExpressCheckoutDetailsResponseType GetExpressCheckoutDetails(string token) { GetExpressCheckoutDetailsReq req = new GetExpressCheckoutDetailsReq{ GetExpressCheckoutDetailsRequest = new GetExpressCheckoutDetailsRequestType { Token = token } }; return PayPalService.GetExpressCheckoutDetails(req,Startup.PayPalSettings.Accounts[0].ApiUsername); } public static async Task ConfirmPayment( this ApplicationDbContext context, string userId, string payerId, string token) { var details = GetExpressCheckoutDetails(token); var payment = await context.PayPalPayments.SingleOrDefaultAsync(p=>p.CreationToken == token); if (payment == null) { payment = new PayPalPayment{ ExecutorId = userId, PaypalPayerId = payerId, CreationToken = token, // NOTE: 1 order <=> 1 bill <=> 1 payment OrderReference = details.GetExpressCheckoutDetailsResponseDetails.InvoiceID, State = details.Ack.ToString() }; context.PayPalPayments.Add(payment); } else { payment.ExecutorId = userId; payment.PaypalPayerId = payerId; payment.State = details.Ack.ToString(); } await context.SaveChangesAsync(userId); // GetCheckoutInfo(,token); return new PaymentInfo { DbContent = payment, DetailsFromPayPal = details }; } public static async Task CreatePaymentViewModel ( this ApplicationDbContext context, string token, GetExpressCheckoutDetailsResponseType fromPayPal) { return new PaymentInfo { DbContent = await context.PayPalPayments .Include(p=>p.Executor) .SingleOrDefaultAsync( p=>p.CreationToken==token), DetailsFromPayPal = fromPayPal }; } } }