Skip to content

Commit 83bdc27

Browse files
authored
Dev 1128 (#44)
* DEV-1128: Add models for Exchanges and Exchange-Partners * Add example tasks for exchanges
1 parent f15d0f6 commit 83bdc27

File tree

9 files changed

+198
-20
lines changed

9 files changed

+198
-20
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace Dwolla.Client.Models.Requests
5+
{
6+
public class CreateExchangeRequest
7+
{
8+
[JsonProperty(PropertyName = "_links")]
9+
public Dictionary<string, Link> Links { get; set; }
10+
public string Token { get; set; }
11+
public object Finicity { get; set; }
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Newtonsoft.Json;
4+
5+
namespace Dwolla.Client.Models.Responses
6+
{
7+
public class ExchangePartnerResponse : BaseResponse
8+
{
9+
[JsonProperty(PropertyName = "_links")]
10+
public Dictionary<string, Link> Links { get; set; }
11+
public string Id { get; set; }
12+
public string Name { get; set; }
13+
public string Status { get; set; }
14+
public DateTime Created { get; set; }
15+
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Newtonsoft.Json;
4+
5+
namespace Dwolla.Client.Models.Responses
6+
{
7+
public class ExchangeResponse : BaseResponse
8+
{
9+
[JsonProperty(PropertyName = "_links")]
10+
public Dictionary<string, Link> Links { get; set; }
11+
public string Id { get; set; }
12+
public DateTime Created { get; set; }
13+
public string Status { get; set; }
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace Dwolla.Client.Models.Responses
5+
{
6+
public class GetExchangePartnersResponse : BaseGetResponse<ExchangePartnerResponse>
7+
{
8+
[JsonProperty(PropertyName = "_links")]
9+
public Dictionary<string, Link> Links { get; set; }
10+
[JsonProperty(PropertyName = "_embedded")]
11+
public new ExchangePartnersEmbed Embedded { get; set; }
12+
}
13+
14+
public class ExchangePartnersEmbed : Embed<ExchangePartnerResponse>
15+
{
16+
[JsonProperty(PropertyName = "exchange-partners")]
17+
public List<ExchangePartnerResponse> ExchangePartners { get; set; }
18+
19+
public override List<ExchangePartnerResponse> Results() => ExchangePartners;
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace Dwolla.Client.Models.Responses
5+
{
6+
public class GetExchangesResponse : BaseGetResponse<ExchangeResponse>
7+
{
8+
[JsonProperty(PropertyName = "_links")]
9+
public Dictionary<string, Link> Links { get; set; }
10+
[JsonProperty(PropertyName = "_embedded")]
11+
public new ExchangesEmbed Embedded { get; set; }
12+
}
13+
14+
public class ExchangesEmbed : Embed<ExchangeResponse>
15+
{
16+
public List<ExchangeResponse> Exchanges { get; set; }
17+
18+
public override List<ExchangeResponse> Results() => Exchanges;
19+
}
20+
}

ExampleApp/DwollaBroker.cs

+46-20
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ internal class DwollaBroker
2020
internal async Task<TokenResponse> SetAuthorizationHeader(string key, string secret)
2121
{
2222
var response = await _client.PostAuthAsync<TokenResponse>(
23-
new Uri($"{_client.ApiBaseAddress}/token"), new AppTokenRequest {Key = key, Secret = secret});
23+
new Uri($"{_client.ApiBaseAddress}/token"), new AppTokenRequest { Key = key, Secret = secret });
2424

2525
// TODO: Securely store token in your database for reuse
2626
if (!_headers.ContainsKey("Authorization"))
@@ -53,7 +53,7 @@ internal async Task<BeneficialOwnershipResponse> GetBeneficialOwnershipAsync(Uri
5353
(await GetAsync<BeneficialOwnershipResponse>(uri)).Content;
5454

5555
internal async Task<Uri> CertifyBeneficialOwnershipAsync(Uri uri) =>
56-
(await PostAsync(uri, new CertifyBeneficialOwnershipRequest {Status = "certified"})).Response.Headers.Location;
56+
(await PostAsync(uri, new CertifyBeneficialOwnershipRequest { Status = "certified" })).Response.Headers.Location;
5757

5858
internal async Task<Uri> CreateCustomerAsync(Uri uri, string firstName, string lastName, string email) =>
5959
await CreateCustomerAsync(uri, new CreateCustomerRequest
@@ -83,14 +83,35 @@ internal async Task<GetCustomersResponse> GetCustomersAsync(Uri uri) =>
8383
internal async Task<GetDocumentsResponse> GetCustomerDocumentsAsync(Uri customerUri) =>
8484
(await GetAsync<GetDocumentsResponse>(new Uri(customerUri.AbsoluteUri + "/documents"))).Content;
8585

86-
internal async Task<Uri> CreateFundingSourceAsync(Uri uri, string routingNumber, string accountNumber, string bankAccountType, string name) =>
87-
await CreateFundingSourceAsync(uri, new CreateFundingSourceRequest
88-
{
89-
RoutingNumber = routingNumber,
90-
AccountNumber = accountNumber,
91-
BankAccountType = bankAccountType,
92-
Name = name,
93-
});
86+
internal async Task<GetExchangePartnersResponse> GetExchangePartnersAsync() => (await GetAsync<GetExchangePartnersResponse>(new Uri($"{_client.ApiBaseAddress}/exchange-partners"))).Content;
87+
88+
// Create an MX exchange for a customer
89+
// Exchange-Partner ID for MX = 'bca8d065-49a5-475b-a6b4-509bc8504d22'
90+
internal async Task<Uri> CreateExchangeAsync(Uri uri, string token)
91+
{
92+
var r = await PostAsync<CreateExchangeRequest, EmptyResponse>(uri, new CreateExchangeRequest
93+
{
94+
Token = token,
95+
Links = new Dictionary<string, Link>
96+
{
97+
{"exchange-partner", new Link {Href = new Uri($"{_client.ApiBaseAddress}/exchange-partners/bca8d065-49a5-475b-a6b4-509bc8504d22")}}
98+
},
99+
});
100+
return r.Response.Headers.Location;
101+
}
102+
103+
internal async Task<ExchangeResponse> GetExchangeAsync(Uri uri) => (await GetAsync<ExchangeResponse>(uri)).Content;
104+
105+
internal async Task<GetExchangesResponse> GetExchangesAsync(Uri uri) => (await GetAsync<GetExchangesResponse>(uri)).Content;
106+
107+
internal async Task<Uri> CreateFundingSourceAsync(Uri uri, string routingNumber, string accountNumber, string bankAccountType, string name) =>
108+
await CreateFundingSourceAsync(uri, new CreateFundingSourceRequest
109+
{
110+
RoutingNumber = routingNumber,
111+
AccountNumber = accountNumber,
112+
BankAccountType = bankAccountType,
113+
Name = name,
114+
});
94115
internal async Task<Uri> CreateFundingSourceAsync(Uri uri, CreateFundingSourceRequest request)
95116
{
96117
var response = await PostAsync<CreateFundingSourceRequest, EmptyResponse>(uri, request);
@@ -113,8 +134,8 @@ internal async Task<Uri> VerifyMicroDepositsAsync(string fundingSourceId, decima
113134
(await PostAsync(new Uri($"{_client.ApiBaseAddress}/funding-sources/{fundingSourceId}/micro-deposits"),
114135
new MicroDepositsRequest
115136
{
116-
Amount1 = new Money {Value = amount1, Currency = "USD"},
117-
Amount2 = new Money {Value = amount2, Currency = "USD"}
137+
Amount1 = new Money { Value = amount1, Currency = "USD" },
138+
Amount2 = new Money { Value = amount2, Currency = "USD" }
118139
})).Response.Headers.Location;
119140

120141

@@ -168,7 +189,7 @@ internal async Task<Uri> CreateTransferAsync(string sourceFundingSourceId, strin
168189
Values = new List<string> { destinationAddenda }
169190
}
170191
}
171-
}
192+
}
172193
});
173194
return response.Response.Headers.Location;
174195
}
@@ -212,7 +233,7 @@ internal async Task<MasspaymentResponse> GetMasspaymentAsync(string id) =>
212233
(await GetAsync<MasspaymentResponse>(new Uri($"{_client.ApiBaseAddress}/mass-payments/{id}"))).Content;
213234

214235
internal async Task<Uri> CreateWebhookSubscriptionAsync(Uri uri, string url, string secret) =>
215-
(await PostAsync(uri, new CreateWebhookSubscriptionRequest {Url = url, Secret = secret})).Response.Headers.Location;
236+
(await PostAsync(uri, new CreateWebhookSubscriptionRequest { Url = url, Secret = secret })).Response.Headers.Location;
216237

217238
internal async Task DeleteWebhookSubscriptionAsync(Uri uri) => await DeleteAsync<object>(uri, null);
218239

@@ -234,8 +255,8 @@ internal async Task<Uri> CreateLabelAsync(Uri uri, decimal amount) =>
234255
{
235256
Amount = new Money { Currency = "USD", Value = amount }
236257
});
237-
238-
258+
259+
239260
internal async Task<Uri> CreateLabelAsync(Uri uri, CreateLabelRequest request)
240261
{
241262
var response = await PostAsync(uri, request);
@@ -247,18 +268,18 @@ internal async Task<Label> GetLabelAsync(string id) =>
247268

248269
internal async Task<Label> GetLabelAsync(Uri uri) =>
249270
(await GetAsync<Label>(uri)).Content;
250-
271+
251272
internal async Task<GetLabelsResponse> GetLabelsAsync(string id) =>
252273
(await GetAsync<GetLabelsResponse>(new Uri($"{_client.ApiBaseAddress}/customers/{id}/labels"))).Content;
253274

254275
internal async Task<GetLabelsResponse> GetLabelsAsync(Uri uri) =>
255276
(await GetAsync<GetLabelsResponse>(uri)).Content;
256277

257-
internal async Task DeleteLabelAsync(string id) =>
278+
internal async Task DeleteLabelAsync(string id) =>
258279
await DeleteAsync<object>(new Uri($"{_client.ApiBaseAddress}/labels/{id}"), null);
259280

260281
internal async Task<Uri> CreateLabelLedgerEntryAsync(string id, decimal amount) =>
261-
await CreateLabelLedgerEntryAsync(new Uri($"{_client.ApiBaseAddress}/labels/{id}/ledger-entries"),
282+
await CreateLabelLedgerEntryAsync(new Uri($"{_client.ApiBaseAddress}/labels/{id}/ledger-entries"),
262283
new CreateLabelLedgerEntryRequest
263284
{
264285
Amount = new Money { Currency = "USD", Value = amount }
@@ -310,7 +331,7 @@ internal async Task<LabelReallocation> GetLabelReallocationAsync(string id) =>
310331

311332
internal async Task<LabelReallocation> GetLabelReallocationAsync(Uri uri) =>
312333
(await GetAsync<LabelReallocation>(uri)).Content;
313-
334+
314335
private async Task<RestResponse<TRes>> GetAsync<TRes>(Uri uri) where TRes : IDwollaResponse =>
315336
await ExecAsync(() => _client.GetAsync<TRes>(uri, _headers));
316337

@@ -343,5 +364,10 @@ private static async Task<RestResponse<TRes>> ExecAsync<TRes>(Func<Task<RestResp
343364

344365
return r;
345366
}
367+
368+
internal Task CreateBeneficialOwnerAsync(Uri uri, CreateExchangeRequest createExchangeRequest)
369+
{
370+
throw new NotImplementedException();
371+
}
346372
}
347373
}
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Threading.Tasks;
2+
using Newtonsoft.Json;
3+
4+
namespace ExampleApp.Tasks.ExchangePartners
5+
{
6+
[Task("lexp", "List Events")]
7+
internal class List : BaseTask
8+
{
9+
public override async Task Run()
10+
{
11+
var res = await Broker.GetExchangePartnersAsync();
12+
res.Embedded.ExchangePartners
13+
.ForEach(ep => WriteLine($" - ID: {ep.Id} Name: {ep.Name} Status: {ep.Status} Created: {ep.Created}"));
14+
}
15+
}
16+
}

ExampleApp/Tasks/Exchanges/Create.cs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
using Dwolla.Client;
5+
using Dwolla.Client.Models;
6+
using Dwolla.Client.Models.Requests;
7+
8+
namespace ExampleApp.Tasks.Exchanges
9+
{
10+
[Task("cex", "Create Exchange for a Customer")]
11+
internal class Create : BaseTask
12+
{
13+
public override async Task Run()
14+
{
15+
Write("Customer ID for whom to create an exchange: ");
16+
var input = ReadLine();
17+
Write("MX Token: ");
18+
var token = ReadLine();
19+
20+
var rootRes = await Broker.GetRootAsync();
21+
var uri = await Broker.CreateExchangeAsync(
22+
new Uri($"{rootRes.Links["customers"].Href}/{input}/exchanges"), token);
23+
24+
if (uri == null) return;
25+
26+
var exchange = await Broker.GetExchangeAsync(uri);
27+
WriteLine($"Created Exchange ID: {exchange.Id} Created: {exchange.Created}");
28+
}
29+
}
30+
}

ExampleApp/Tasks/Exchanges/List.cs

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace ExampleApp.Tasks.Exchanges
5+
{
6+
[Task("lex", "List Exchanges")]
7+
internal class List : BaseTask
8+
{
9+
public override async Task Run()
10+
{
11+
Write("Customer/Account ID for whom to list the exchanges: ");
12+
var input = ReadLine();
13+
14+
var rootRes = await Broker.GetRootAsync();
15+
var res = await Broker.GetExchangesAsync(new Uri($"{rootRes.Links["customers"].Href}/{input}/exchanges"));
16+
res.Embedded.Exchanges
17+
.ForEach(ex => WriteLine($" - ID: {ex.Id} Status: {ex.Status} Created: {ex.Created}"));
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)