1
0
mirror of https://github.com/bitwarden/server.git synced 2025-05-30 07:44:50 -05:00
bitwarden/src/Billing/Models/PayPalIPNTransactionModel.cs
Conner Turnbull 73e049f878
[AC-2378] Added ProviderId to PayPal transaction model (#3995)
* Added ProviderId to PayPal transaction model

* Fixed issue with parsing provider id
2024-04-16 17:50:12 +00:00

121 lines
3.8 KiB
C#

using System.Globalization;
using System.Runtime.InteropServices;
using System.Web;
namespace Bit.Billing.Models;
public class PayPalIPNTransactionModel
{
public string TransactionId { get; }
public string TransactionType { get; }
public string ParentTransactionId { get; }
public string PaymentStatus { get; }
public string PaymentType { get; }
public decimal MerchantGross { get; }
public string MerchantCurrency { get; }
public string ReceiverId { get; }
public DateTime PaymentDate { get; }
public Guid? UserId { get; }
public Guid? OrganizationId { get; }
public Guid? ProviderId { get; }
public bool IsAccountCredit { get; }
public PayPalIPNTransactionModel(string formData)
{
var queryString = HttpUtility.ParseQueryString(formData);
var data = queryString
.AllKeys
.Where(key => !string.IsNullOrWhiteSpace(key))
.ToDictionary(key =>
key.Trim('\r'),
key => queryString[key]?.Trim('\r'));
TransactionId = Extract(data, "txn_id");
TransactionType = Extract(data, "txn_type");
ParentTransactionId = Extract(data, "parent_txn_id");
PaymentStatus = Extract(data, "payment_status");
PaymentType = Extract(data, "payment_type");
var merchantGross = Extract(data, "mc_gross");
if (!string.IsNullOrEmpty(merchantGross))
{
MerchantGross = decimal.Parse(merchantGross);
}
MerchantCurrency = Extract(data, "mc_currency");
ReceiverId = Extract(data, "receiver_id");
var paymentDate = Extract(data, "payment_date");
PaymentDate = ToUTCDateTime(paymentDate);
var custom = Extract(data, "custom");
if (string.IsNullOrEmpty(custom))
{
return;
}
var metadata = custom.Split(',')
.Where(field => !string.IsNullOrEmpty(field) && field.Contains(':'))
.Select(field => field.Split(':'))
.ToDictionary(parts => parts[0], parts => parts[1]);
if (metadata.TryGetValue("user_id", out var userIdStr) &&
Guid.TryParse(userIdStr, out var userId))
{
UserId = userId;
}
if (metadata.TryGetValue("organization_id", out var organizationIdStr) &&
Guid.TryParse(organizationIdStr, out var organizationId))
{
OrganizationId = organizationId;
}
if (metadata.TryGetValue("provider_id", out var providerIdStr) &&
Guid.TryParse(providerIdStr, out var providerId))
{
ProviderId = providerId;
}
IsAccountCredit = custom.Contains("account_credit:1");
}
private static string Extract(IReadOnlyDictionary<string, string> data, string key)
{
var success = data.TryGetValue(key, out var value);
return success ? value : null;
}
private static DateTime ToUTCDateTime(string input)
{
if (string.IsNullOrEmpty(input))
{
return default;
}
var success = DateTime.TryParseExact(input,
new[]
{
"HH:mm:ss dd MMM yyyy PDT",
"HH:mm:ss dd MMM yyyy PST",
"HH:mm:ss dd MMM, yyyy PST",
"HH:mm:ss dd MMM, yyyy PDT",
"HH:mm:ss MMM dd, yyyy PST",
"HH:mm:ss MMM dd, yyyy PDT"
}, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTime);
if (!success)
{
return default;
}
var pacificTime = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time")
: TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
return TimeZoneInfo.ConvertTimeToUtc(dateTime, pacificTime);
}
}