I am developing an iOS app using Swift code and want to integrate the Plaid/Dwolla ACH processing. I have a common function that essentially creates the raw cURL commands for doing this. Of course for each endpoint the parameters of the cURL request change appropriately. This function works fine for all the Plaid endpoints (link tokens, access tokens, processor tokens, etc.). It also works with the Dwolla endpoints that I have tried with one big exception, Authorization.
If I click on the “Create Token” button when I log in to the dashboard, I get the temporary access token, which I can then use successfully for endpoints like “GET Root” (GET …api-sandbox.dwolla.com/), “POST Create Customer” (POST …api-sandbox.dwolla.com/ customers), and “GET Get Customers” (GET …api-sandbox.dwolla.com/ customers). These functions all worked fine using Authorization: Bearer access token.
However the Authorization function “POST https://api-sandbox.dwolla.com/token” did not work for me. I use the two parameters from my dashboard concatenated together for Authorization: Basic. The body was “grant_type=client_credentials”. All other API requests use a key:value pair for the body, so I’m not sure why you use a statement with an equal sign. So I also tried “grant_type”: “client_credentials” in the body. Both gave the same error:
[“code”: InvalidCredentials, “message”: Missing or invalid Authorization header.]
As I say above the Authorization: Bearer header works so I don’t know why the Authorization: Basic doesn’t work. I use the same two parameters as is used with the dashboard “Create Token” button.
Here is a printout of what I am sending (with secret edited). I had to remove https: from the links since it would not let me post with active links, but all the links are https://. The 33 bytes of the body translates to [“grant_type=client_credentials”].
▿://api-sandbox.dwolla.com/token
▿ url : Optional
▿ some ://api-sandbox.dwolla.com/token
- _url : ://api-sandbox.dwolla.com/token
- cachePolicy : 0
- timeoutInterval : 60.0
- mainDocumentURL : nil
- networkServiceType : __C.NSURLRequestNetworkServiceType
- allowsCellularAccess : true
▿ httpMethod : Optional- some : “POST”
▿ allHTTPHeaderFields : Optional<Dictionary<String, String>>
▿ some : 2 elements
▿ 0 : 2 elements- key : “Authorization”
- value : "Basic 37r8iVcRCxhOmo6YHRtfvPw5KD5hpXks5rRS5DZuEW2sx3QFDPnSbZKfmTzkAbjyTPP…”
▿ 1 : 2 elements - key : “Content-Type”
- value : “application/x-www-form-urlencoded”
▿ httpBody : Optional
▿ some : 33 bytes - count : 33
▿ pointer : 0x00007fc34a89aa00- pointerValue : 140476745886208
▿ bytes : 33 elements - 0 : 91
- 1 : 34
- 2 : 103
- 3 : 114
- 4 : 97
- 5 : 110
- 6 : 116
- 7 : 95
- 8 : 116
- 9 : 121
- 10 : 112
- 11 : 101
- 12 : 61
- 13 : 99
- 14 : 108
- 15 : 105
- 16 : 101
- 17 : 110
- 18 : 116
- 19 : 95
- 20 : 99
- 21 : 114
- 22 : 101
- 23 : 100
- 24 : 101
- 25 : 110
- 26 : 116
- 27 : 105
- 28 : 97
- 29 : 108
- 30 : 115
- 31 : 34
- 32 : 93
- pointerValue : 140476745886208
- some : “POST”
- httpBodyStream : nil
- httpShouldHandleCookies : true
- httpShouldUsePipelining : false
Here is the complete response from the endpoint:
▿ Optional
- some : <NSHTTPURLResponse: 0x6000000724e0> { URL://api-sandbox.dwolla.com/token } { Status Code: 401, Headers {
“Access-Control-Allow-Origin” = (
“*”
);
“Content-Length” = (
82
);
“Content-Type” = (
“application/vnd.dwolla.v1.hal+json; profile=”://nocarrier.co.uk/profiles/vnd.error/""
);
Date = (
“Sun, 27 Sep 2020 21:16:54 GMT”
);
Server = (
cloudflare
);
“Set-Cookie” = (
“__cf_bm=cce82e97ca661ec448cbebb3eed4ca4db9c5e875-1601241414-1800-Af5ZfJLsbPtR3Yfkw9IoG+6TWlaM5xs8u9rglrZ6X6FeQcN28YSGvLkbFtcJ9M7ZcDEKjxvhmWQ8CG7Tv8bKX6Y=; path=/; expires=Sun, 27-Sep-20 21:46:54 GMT; domain=.dwolla.com; HttpOnly; Secure; SameSite=None”
);
“cf-cache-status” = (
DYNAMIC
);
“cf-ray” = (
“5d983f981820f045-EWR”
);
“cf-request-id” = (
05730613110000f045dc90d200000001
);
“expect-ct” = (
“max-age=604800, report-uri=”://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct""
);
“x-request-id” = (
“46508a67-ee16-4e2a-bfce-3c27dee3515e”
);
} }