2026-02-13 21:20:05 -06:00
|
|
|
|
2026-02-15 07:00:46 -06:00
|
|
|
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
2026-02-12 20:48:49 -06:00
|
|
|
namespace FiscalOS.Infra.Accounts.Plaid;
|
|
|
|
|
|
|
|
|
|
public sealed class PlaidService
|
|
|
|
|
{
|
|
|
|
|
private readonly PlaidClient _client;
|
|
|
|
|
|
|
|
|
|
private PlaidService(PlaidClient client)
|
|
|
|
|
{
|
|
|
|
|
_client = client;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static PlaidService From(IServiceProvider sp)
|
|
|
|
|
{
|
|
|
|
|
var client = sp.GetRequiredService<PlaidClient>();
|
|
|
|
|
return new(client);
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-15 07:00:46 -06:00
|
|
|
public async Task<string> CreateLinkTokenAsync(string id)
|
|
|
|
|
{
|
|
|
|
|
var assemblyName = Assembly.GetExecutingAssembly().GetName().FullName;
|
|
|
|
|
var environmentName = System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
|
|
|
|
|
|
|
|
|
|
var ltr = await _client.LinkTokenCreateAsync(new()
|
|
|
|
|
{
|
|
|
|
|
ClientName = $"{assemblyName}_{environmentName}",
|
|
|
|
|
Products = [Products.Transactions],
|
|
|
|
|
CountryCodes = [CountryCode.Us],
|
|
|
|
|
Language = Language.English,
|
|
|
|
|
User = new()
|
|
|
|
|
{
|
|
|
|
|
ClientUserId = id,
|
|
|
|
|
},
|
|
|
|
|
}).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
if (ltr.IsSuccessStatusCode is false)
|
|
|
|
|
{
|
|
|
|
|
throw new PlaidException("Unable to create link token");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ltr.LinkToken;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-12 20:48:49 -06:00
|
|
|
public async Task<(string ItemId, string AccessToken)> ExchangeTokenAsync(string publicToken)
|
|
|
|
|
{
|
|
|
|
|
var ptr = await _client.ItemPublicTokenExchangeAsync(new()
|
|
|
|
|
{
|
|
|
|
|
PublicToken = publicToken,
|
|
|
|
|
}).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
if (ptr.IsSuccessStatusCode is false)
|
|
|
|
|
{
|
|
|
|
|
throw new PlaidException("Unable to exchange public token for access token");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (ptr.ItemId, ptr.AccessToken);
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-13 21:20:05 -06:00
|
|
|
public async Task<List<Going.Plaid.Entity.Account>> GetAccountsAsync(string accessToken)
|
|
|
|
|
{
|
|
|
|
|
var ar = await _client.AccountsGetAsync(new()
|
|
|
|
|
{
|
|
|
|
|
AccessToken = accessToken,
|
|
|
|
|
}).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
if (ar.IsSuccessStatusCode is false)
|
|
|
|
|
{
|
|
|
|
|
throw new PlaidException("Unable to retrieve accounts");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return [.. ar.Accounts];
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-12 20:48:49 -06:00
|
|
|
public async Task<ItemWithConsentFields> GetItemAsync(string accessToken)
|
|
|
|
|
{
|
|
|
|
|
var ar = await _client.ItemGetAsync(new()
|
|
|
|
|
{
|
|
|
|
|
AccessToken = accessToken,
|
|
|
|
|
}).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
if (ar.IsSuccessStatusCode is false)
|
|
|
|
|
{
|
|
|
|
|
throw new PlaidException("Unable to retrieve item");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ar.Item;
|
|
|
|
|
}
|
2026-02-13 21:20:05 -06:00
|
|
|
}
|