Woodshop
Search…
Dwolla service
This service wraps the Dwolla SDK and provides the following implementation:
  • Pagination (on Customers & Transfers)
  • Fields to be displayed on the UI (select)
  • Search (on Customers & Transfers)
  • Filters (on Customers, cf isFilterable flag)
Prototype
Full implementation
1
"use strict";
2
3
const dwolla = require('dwolla-v2');
4
var _ = require('lodash');
5
6
class DwollaService {
7
// Allow to create a Dwolla Client based on the App Key a Secret
8
constructor(appKey, appSecret, environment);
9
10
// Get a List of Customers based on the query (page, filter, search, sort)
11
getCustomers (query);
12
13
// Get a Customer by Id
14
getCustomer (recordId);
15
16
// Get a Customer for a local database user (by email)
17
getCustomerSmartRelationship (user);
18
19
// Get a list of Funding Sources for a customer Id
20
getCustomerFundingSources (recordId, query);
21
22
// Get a Funding Source by Id
23
getFundingSource (recordId);
24
25
// Get a list of Transfers for a customer Id
26
getCustomerTransfers (recordId, query);
27
28
// Get a Transfer by Id
29
getTransfer (recordId);
30
31
32
}
33
34
module.exports = DwollaService;
35
Copied!
1
"use strict";
2
3
const dwolla = require('dwolla-v2');
4
var _ = require('lodash');
5
6
class DwollaService {
7
constructor(appKey, appSecret, environment) {
8
this.client = new dwolla.Client({
9
key: appKey,
10
secret: appSecret,
11
environment: environment // optional - defaults to production
12
});
13
}
14
15
getCustomers (query) {
16
const limit = parseInt(query.page.size) || 20;
17
const offset = (parseInt(query.page.number) - 1) * limit;
18
const sortBy = query.sort; // Sort Parameter
19
let fields = query.fields.dwollaCustomers.split(',');
20
if (fields && !fields.includes('id')) {
21
fields.push('id'); // id is required to get the ID
22
}
23
24
let opts = {
25
search: query.search, // Search parameter
26
limit,
27
offset,
28
};
29
30
// Build the Filter parameter
31
if (query.filters) {
32
const filters = JSON.parse(query.filters);
33
if (filters.aggregator) {
34
for (const filter of filters.conditions) {
35
opts[filter.field] = filter.value;
36
}
37
}
38
else {
39
opts[filters.field] = filters.value;
40
}
41
}
42
43
return this.client.auth.client()
44
.then(appToken => appToken.get('customers', opts))
45
.then(result => {
46
if (!result.body && !result.body._embedded) return null;
47
let dwollaCustomers = [];
48
// Only populate the fields required by the UI
49
for (const customer of result.body._embedded.customers) {
50
const clonePicked = _.pick(customer, fields);
51
dwollaCustomers.push(clonePicked);
52
}
53
const count = result.body.total;
54
return { list: dwollaCustomers, count }
55
});
56
57
};
58
59
async getCustomer (recordId) {
60
61
return this.client.auth.client()
62
.then(appToken => appToken.get(`customers/${recordId}`))
63
.then(result => {
64
if (!result.body) return null;
65
let dwollaCustomer = result.body;
66
return dwollaCustomer;
67
});
68
}
69
70
async getCustomerSmartRelationship (user) {
71
return this.client.auth.client()
72
.then(appToken => appToken.get('customers', { email: user.email })) // filter on email
73
.then(result => {
74
if (!result.body && !result.body._embedded && result.body._embedded.customers.length !== 1 ) return null;
75
let dwollaCustomer = result.body._embedded.customers[0];
76
// Only populate the fields required by the UI
77
const clonePicked = _.pick(dwollaCustomer, ['id', 'email', 'firstName', 'lastName' ]); // We ask only for the reference field + ID
78
return clonePicked;
79
});
80
}
81
82
getCustomerFundingSources (recordId, query) {
83
// No Pagingation available for this endpoint
84
// const limit = parseInt(query.page.size) || 20;
85
// const offset = (parseInt(query.page.number) - 1) * limit;
86
87
let fields = query.fields.dwollaFundingSources.split(',');
88
if (fields && !fields.includes('id')) {
89
fields.push('id'); // id is required to get the ID
90
}
91
if (fields && !fields.includes('balance') && fields.includes('balanceReadable')) {
92
fields.push('balance'); // balance is required for the amountReadable Smart Field
93
}
94
return this.client.auth.client()
95
.then(appToken => appToken.get(`customers/${recordId}/funding-sources`))
96
.then(result => {
97
if (!result.body && !result.body._embedded) return null;
98
let fundingSources = [];
99
// Only populate the fields required by the UI
100
for (const fundingSource of result.body._embedded['funding-sources']) {
101
const clonePicked = _.pick(fundingSource, fields);
102
fundingSources.push(clonePicked);
103
}
104
const count = fundingSources.length;
105
return { list: fundingSources, count }
106
});
107
108
};
109
110
getFundingSource (recordId) {
111
return this.client.auth.client()
112
.then(appToken => appToken.get(`funding-sources/${recordId}`))
113
.then(result => {
114
if (!result.body) return null;
115
let fundingSource = result.body;
116
return fundingSource;
117
});
118
};
119
120
getCustomerTransfers (recordId, query) {
121
const limit = parseInt(query.page.size) || 20;
122
const offset = (parseInt(query.page.number) - 1) * limit;
123
124
let fields = query.fields.dwollaTransfers.split(',');
125
if (fields && !fields.includes('id')) {
126
fields.push('id'); // id is required to get the ID
127
}
128
if (fields && !fields.includes('amount') && fields.includes('amountReadable')) {
129
fields.push('amount'); // amount is required for the amountReadable Smart Field
130
}
131
132
let opts = {
133
search: query.search, // Search parameter
134
limit,
135
offset,
136
};
137
138
return this.client.auth.client()
139
.then(appToken => appToken.get(`customers/${recordId}/transfers`, opts))
140
.then(result => {
141
if (!result.body && !result.body._embedded) return null;
142
let transfers = [];
143
// Only populate the fields required by the UI
144
for (const fundingSource of result.body._embedded['transfers']) {
145
const clonePicked = _.pick(fundingSource, fields);
146
transfers.push(clonePicked);
147
}
148
const count = transfers.length;
149
return { list: transfers, count }
150
});
151
152
};
153
154
getTransfer (recordId) {
155
return this.client.auth.client()
156
.then(appToken => appToken.get(`transfers/${recordId}`))
157
.then(result => {
158
if (!result.body) return null;
159
let fundingSource = result.body;
160
return fundingSource;
161
});
162
};
163
164
165
}
166
167
module.exports = DwollaService;
168
Copied!
Last modified 9mo ago
Copy link