Skip to content

Commit 93e077f

Browse files
committed
fix conflict
2 parents 2ae5793 + 2967e0e commit 93e077f

8 files changed

Lines changed: 201 additions & 82 deletions

File tree

client.go

Lines changed: 19 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ type Client struct {
8080
Document DocumentService
8181
Event EventService
8282
FundingSource FundingSourceService
83+
KBA KBAService
8384
MassPayment MassPaymentService
8485
OnDemandAuthorization OnDemandAuthorizationService
8586
Transfer TransferService
@@ -124,6 +125,7 @@ func NewWithHTTPClient(key, secret string, environment Environment, httpClient H
124125
c.Document = &DocumentServiceOp{c}
125126
c.Event = &EventServiceOp{c}
126127
c.FundingSource = &FundingSourceServiceOp{c}
128+
c.KBA = &KBAServiceOp{c}
127129
c.MassPayment = &MassPaymentServiceOp{c}
128130
c.OnDemandAuthorization = &OnDemandAuthorizationServiceOp{c}
129131
c.Transfer = &TransferServiceOp{c}
@@ -200,7 +202,7 @@ func (c *Client) RequestToken(ctx context.Context) error {
200202

201203
buf := bytes.NewBuffer([]byte("grant_type=client_credentials"))
202204

203-
req, err := http.NewRequest("POST", c.BuildAPIURL("token"), buf)
205+
req, err := http.NewRequestWithContext(ctx, "POST", c.BuildAPIURL("token"), buf)
204206
if err != nil {
205207
return err
206208
}
@@ -210,24 +212,19 @@ func (c *Client) RequestToken(ctx context.Context) error {
210212

211213
req.SetBasicAuth(c.Key, c.Secret)
212214

213-
req = req.WithContext(ctx)
214-
215215
res, err := c.HTTPClient.Do(req)
216-
217216
if err != nil {
218217
return err
219218
}
220219

221220
defer res.Body.Close()
222221

223222
resBody, err := ioutil.ReadAll(res.Body)
224-
225223
if err != nil {
226224
return err
227225
}
228226

229227
err = json.Unmarshal(resBody, &token)
230-
231228
if err != nil {
232229
return err
233230
}
@@ -270,8 +267,7 @@ func (c *Client) Get(ctx context.Context, path string, params *url.Values, heade
270267
return err
271268
}
272269

273-
req, err := http.NewRequest("GET", c.BuildAPIURL(path), nil)
274-
270+
req, err := http.NewRequestWithContext(ctx, "GET", c.BuildAPIURL(path), nil)
275271
if err != nil {
276272
return err
277273
}
@@ -288,18 +284,14 @@ func (c *Client) Get(ctx context.Context, path string, params *url.Values, heade
288284
req.URL.RawQuery = params.Encode()
289285
}
290286

291-
req = req.WithContext(ctx)
292-
293287
res, err := c.HTTPClient.Do(req)
294-
295288
if err != nil {
296289
return err
297290
}
298291

299292
defer res.Body.Close()
300293

301294
resBody, err := ioutil.ReadAll(res.Body)
302-
303295
if err != nil {
304296
return err
305297
}
@@ -345,16 +337,14 @@ func (c *Client) Post(ctx context.Context, path string, body interface{}, header
345337

346338
if body != nil {
347339
bodyBytes, err := json.Marshal(body)
348-
349340
if err != nil {
350341
return err
351342
}
352343

353344
bodyReader = bytes.NewReader(bodyBytes)
354345
}
355346

356-
req, err := http.NewRequest("POST", c.BuildAPIURL(path), bodyReader)
357-
347+
req, err := http.NewRequestWithContext(ctx, "POST", c.BuildAPIURL(path), bodyReader)
358348
if err != nil {
359349
return err
360350
}
@@ -368,10 +358,7 @@ func (c *Client) Post(ctx context.Context, path string, body interface{}, header
368358
req.Header.Set("Content-Type", "application/vnd.dwolla.v1.hal+json")
369359
req.Header.Set("User-Agent", "dwolla-v2-go")
370360

371-
req = req.WithContext(ctx)
372-
373361
res, err := c.HTTPClient.Do(req)
374-
375362
if err != nil {
376363
return err
377364
}
@@ -385,7 +372,6 @@ func (c *Client) Post(ctx context.Context, path string, body interface{}, header
385372
}
386373

387374
resBody, err := ioutil.ReadAll(res.Body)
388-
389375
if err != nil {
390376
return err
391377
}
@@ -427,8 +413,9 @@ func (c *Client) Post(ctx context.Context, path string, body interface{}, header
427413
// Upload performs a multipart file upload to the Dwolla API
428414
func (c *Client) Upload(ctx context.Context, path string, documentType DocumentType, fileName string, file io.Reader, container interface{}) error {
429415
var (
430-
err error
431-
halError HALError
416+
err error
417+
halError HALError
418+
validationError ValidationError
432419
)
433420

434421
if err = c.EnsureToken(ctx); err != nil {
@@ -438,31 +425,26 @@ func (c *Client) Upload(ctx context.Context, path string, documentType DocumentT
438425
body := &bytes.Buffer{}
439426
writer := multipart.NewWriter(body)
440427
part, err := writer.CreateFormFile("file", fileName)
441-
442428
if err != nil {
443429
return err
444430
}
445431

446432
_, err = io.Copy(part, file)
447-
448433
if err != nil {
449434
return err
450435
}
451436

452437
err = writer.WriteField("documentType", string(documentType))
453-
454438
if err != nil {
455439
return err
456440
}
457441

458442
err = writer.Close()
459-
460443
if err != nil {
461444
return err
462445
}
463446

464-
req, err := http.NewRequest("POST", c.BuildAPIURL(path), body)
465-
447+
req, err := http.NewRequestWithContext(ctx, "POST", c.BuildAPIURL(path), body)
466448
if err != nil {
467449
return err
468450
}
@@ -473,10 +455,7 @@ func (c *Client) Upload(ctx context.Context, path string, documentType DocumentT
473455
req.Header.Set("Content-Type", writer.FormDataContentType())
474456
req.Header.Set("User-Agent", "dwolla-v2-go")
475457

476-
req = req.WithContext(ctx)
477-
478458
res, err := c.HTTPClient.Do(req)
479-
480459
if err != nil {
481460
return err
482461
}
@@ -490,7 +469,6 @@ func (c *Client) Upload(ctx context.Context, path string, documentType DocumentT
490469
}
491470

492471
resBody, err := ioutil.ReadAll(res.Body)
493-
494472
if err != nil {
495473
return err
496474
}
@@ -511,6 +489,14 @@ func (c *Client) Upload(ctx context.Context, path string, documentType DocumentT
511489
return c.Upload(ctx, path, documentType, fileName, file, container)
512490
}
513491

492+
if halError.Code == "ValidationError" {
493+
if err := json.Unmarshal(resBody, &validationError); err != nil {
494+
return err
495+
}
496+
497+
return validationError
498+
}
499+
514500
return halError
515501
}
516502

@@ -532,8 +518,7 @@ func (c *Client) Delete(ctx context.Context, path string, params *url.Values, he
532518
return err
533519
}
534520

535-
req, err := http.NewRequest("DELETE", c.BuildAPIURL(path), nil)
536-
521+
req, err := http.NewRequestWithContext(ctx, "DELETE", c.BuildAPIURL(path), nil)
537522
if err != nil {
538523
return err
539524
}
@@ -550,10 +535,7 @@ func (c *Client) Delete(ctx context.Context, path string, params *url.Values, he
550535
req.URL.RawQuery = params.Encode()
551536
}
552537

553-
req = req.WithContext(ctx)
554-
555538
res, err := c.HTTPClient.Do(req)
556-
557539
if err != nil {
558540
return err
559541
}
@@ -562,7 +544,6 @@ func (c *Client) Delete(ctx context.Context, path string, params *url.Values, he
562544

563545
if res.StatusCode > 299 {
564546
resBody, err := ioutil.ReadAll(res.Body)
565-
566547
if err != nil {
567548
return err
568549
}
@@ -627,7 +608,7 @@ func (c *Client) CreateClientToken(ctx context.Context, action string, customer
627608

628609
var token ClientToken
629610

630-
if err := c.Post(ctx, "client-tokens", body, nil, token); err != nil {
611+
if err := c.Post(ctx, "client-tokens", body, nil, &token); err != nil {
631612
return nil, err
632613
}
633614

customer.go

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const (
3737
CustomerTypeUnverified CustomerType = "unverified"
3838
)
3939

40-
// CustomerService is the customerservice interface
40+
// CustomerService is the customer service interface
4141
//
4242
// see: https://docsv2.dwolla.com/#customers
4343
type CustomerService interface {
@@ -281,6 +281,25 @@ func (c *Customer) CreateFundingSource(ctx context.Context, body *FundingSourceR
281281
return &source, nil
282282
}
283283

284+
// CreateFundingSourceToken creates a funding source dwolla.js token
285+
//
286+
// see: https://docs.dwolla.com/#create-a-funding-sources-token-for-dwolla-js
287+
func (c *Customer) CreateFundingSourceToken(ctx context.Context) (*FundingSourceToken, error) {
288+
var token FundingSourceToken
289+
290+
if _, ok := c.Links["self"]; !ok {
291+
return nil, errors.New("No funding sources resource link")
292+
}
293+
294+
if err := c.client.Post(ctx, fmt.Sprintf("%s/funding-source-token", c.Links["self"].Href), nil, nil, &token); err != nil {
295+
return nil, err
296+
}
297+
298+
token.client = c.client
299+
300+
return &token, nil
301+
}
302+
284303
// Deactivate deactivates a dwolla customer
285304
func (c *Customer) Deactivate(ctx context.Context) error {
286305
if _, ok := c.Links["deactivate"]; !ok {
@@ -292,6 +311,25 @@ func (c *Customer) Deactivate(ctx context.Context) error {
292311
return c.client.Post(ctx, c.Links["deactivate"].Href, request, nil, c)
293312
}
294313

314+
// InitiateKBA initiates a knowledge based authentication session
315+
//
316+
// see: https://docs.dwolla.com/#initiate-kba-session
317+
func (c *Customer) InitiateKBA(ctx context.Context) (*KBA, error) {
318+
var kba KBA
319+
320+
if _, ok := c.Links["self"]; !ok {
321+
return nil, errors.New("No self resource link")
322+
}
323+
324+
if err := c.client.Post(ctx, fmt.Sprintf("%s/kba", c.Links["self"].Href), nil, nil, &kba); err != nil {
325+
return nil, err
326+
}
327+
328+
kba.client = c.client
329+
330+
return &kba, nil
331+
}
332+
295333
// ListBeneficialOwners returns the customer's beneficial owners
296334
//
297335
// see: https://docsv2.dwolla.com/#list-beneficial-owners

funding_source.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ type FundingSourceBankAccountType string
7676
type FundingSourceBalance struct {
7777
Resource
7878
Balance Amount `json:"balance"`
79+
Total Amount `json:"total"`
7980
LastUpdated string `json:"lastUpdated"`
8081
}
8182

@@ -91,6 +92,12 @@ type FundingSourceRequest struct {
9192
PlaidToken string `json:"plaidToken,omitempty"`
9293
}
9394

95+
// FundingSourceToken is a funding source dwolla.js token
96+
type FundingSourceToken struct {
97+
Resource
98+
Token string `json:"token"`
99+
}
100+
94101
// Retrieve retrieves a funding source with the matching id
95102
//
96103
// see: https://docsv2.dwolla.com/#retrieve-a-funding-source

hal.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ type HALError struct {
1414

1515
// HALError implements the error interface
1616
func (e HALError) Error() string {
17+
if e.Path != "" {
18+
return fmt.Sprintf("[%s] %s (%s)", e.Code, e.Message, e.Path)
19+
}
20+
1721
return fmt.Sprintf("[%s] %s", e.Code, e.Message)
1822
}
1923

@@ -24,17 +28,16 @@ type HALErrors map[string][]HALError
2428
type ValidationError struct {
2529
Code string `json:"code"`
2630
Message string `json:"message"`
27-
Path string `json:"path"`
2831
Embedded HALErrors `json:"_embedded"`
2932
}
3033

3134
// Error implements the error interface
3235
func (v ValidationError) Error() string {
33-
errorMessage := fmt.Sprintf("[%s] %s", v.Code, v.Message)
34-
if len(v.Embedded) != 0 && len(v.Embedded["errors"]) != 0 {
35-
errorMessage = v.Embedded["errors"][0].Message
36+
if _, ok := v.Embedded["errors"]; ok {
37+
return fmt.Sprintf("[%s] %s (%v)", v.Code, v.Message, v.Embedded["errors"])
3638
}
37-
return errorMessage
39+
40+
return fmt.Sprintf("[%s] %s", v.Code, v.Message)
3841
}
3942

4043
// Link is a hal resource link

0 commit comments

Comments
 (0)