yavsc/Yavsc/Helpers/PayPalHelpers.cs

178 lines
8.0 KiB
C#

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<string,string> payPalProperties = null;
public static Dictionary<string,string> GetPayPalProperties() {
if (payPalProperties==null) {
payPalProperties = new Dictionary<string,string>();
// 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?> { DetailLevelCodeType.RETURNALL },
SetExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType
{
PaymentDetails = new List<PaymentDetailsType>( new [] { new PaymentDetailsType{
OrderDescription = query.GetDescription(),
OrderTotal = new BasicAmountType {
currencyID = CurrencyCodeType.EUR,
value = total
},
PaymentDetailsItem = new List <PaymentDetailsItemType> (
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<PaymentInfo> 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<PaymentInfo> 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<PaymentInfo> 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
};
}
public static bool IsSuccess(this PayPalPayment info) {
return info.State == PayPal.PayPalAPIInterfaceService.Model.PaymentStatusCodeType.COMPLETED.ToString();
}
}
}