From bcf788bc352185c6b3f9f4fd23f18f327990119a Mon Sep 17 00:00:00 2001 From: Michael Kelly Date: Thu, 16 Feb 2017 11:16:39 -0800 Subject: [PATCH] Fork plaid-java@0.3.2; set up plaid-java-legacy --- LICENSE | 20 + README.md | 88 +++- pom.xml | 239 +++++++++ .../client/DefaultPlaidPublicClient.java | 119 +++++ .../plaid/client/DefaultPlaidUserClient.java | 483 ++++++++++++++++++ .../java/com/plaid/client/PlaidClients.java | 108 ++++ .../com/plaid/client/PlaidPublicClient.java | 27 + .../com/plaid/client/PlaidUserClient.java | 71 +++ .../exception/PlaidClientsideException.java | 17 + .../PlaidCommunicationsException.java | 17 + .../client/exception/PlaidMfaException.java | 22 + .../exception/PlaidServersideException.java | 24 + ...aidServersideUnknownResponseException.java | 21 + .../http/ApacheHttpClientHttpDelegate.java | 252 +++++++++ .../com/plaid/client/http/HttpDelegate.java | 14 + .../client/http/HttpResponseWrapper.java | 33 ++ .../plaid/client/http/PlaidHttpRequest.java | 43 ++ .../com/plaid/client/http/WireLogger.java | 13 + .../plaid/client/request/ConnectOptions.java | 62 +++ .../com/plaid/client/request/Credentials.java | 39 ++ .../com/plaid/client/request/GetOptions.java | 66 +++ .../com/plaid/client/request/InfoOptions.java | 14 + .../plaid/client/request/MappingOptions.java | 23 + .../com/plaid/client/response/Account.java | 156 ++++++ .../client/response/AccountsResponse.java | 20 + .../client/response/CategoriesResponse.java | 20 + .../com/plaid/client/response/Category.java | 56 ++ .../plaid/client/response/ErrorResponse.java | 30 ++ .../response/ExchangeTokenResponse.java | 30 ++ .../plaid/client/response/InfoResponse.java | 162 ++++++ .../plaid/client/response/Institution.java | 110 ++++ .../client/response/InstitutionsResponse.java | 17 + .../client/response/LongTailInstitution.java | 26 + .../LongTailInstitutionsResponse.java | 20 + .../client/response/MessageResponse.java | 17 + .../plaid/client/response/MfaResponse.java | 183 +++++++ .../client/response/PlaidUserResponse.java | 43 ++ .../plaid/client/response/Transaction.java | 278 ++++++++++ .../client/response/TransactionsResponse.java | 20 + .../client/response/UnknownResponse.java | 34 ++ .../plaid/client/PlaidPublicClientTest.java | 84 +++ .../com/plaid/client/PlaidUserClientTest.java | 195 +++++++ .../PlaidServersideExceptionTest.java | 31 ++ .../__files/body-category-6JpxC.json | 1 + .../resources/__files/body-connect-5Htb4.json | 1 + .../resources/__files/body-connect-KwC7m.json | 1 + .../resources/__files/body-connect-MpWQ7.json | 1 + .../__files/body-connect-get-mU7ak.json | 1 + .../resources/__files/body-connect-qZWyb.json | 1 + .../__files/body-connect-step-XBxNh.json | 1 + .../__files/body-institutions-TqpVf.json | 1 + src/test/resources/logback.xml | 30 ++ .../mappings/mapping-category-6JpxC.json | 17 + .../mappings/mapping-connect-5Htb4.json | 17 + .../mappings/mapping-connect-KwC7m.json | 27 + .../mappings/mapping-connect-MpWQ7.json | 27 + .../mappings/mapping-connect-get-mU7ak.json | 18 + .../mappings/mapping-connect-qZWyb.json | 25 + .../mappings/mapping-connect-step-XBxNh.json | 23 + .../mappings/mapping-institutions-TqpVf.json | 17 + 60 files changed, 3555 insertions(+), 1 deletion(-) create mode 100644 LICENSE create mode 100644 pom.xml create mode 100644 src/main/java/com/plaid/client/DefaultPlaidPublicClient.java create mode 100644 src/main/java/com/plaid/client/DefaultPlaidUserClient.java create mode 100644 src/main/java/com/plaid/client/PlaidClients.java create mode 100644 src/main/java/com/plaid/client/PlaidPublicClient.java create mode 100644 src/main/java/com/plaid/client/PlaidUserClient.java create mode 100644 src/main/java/com/plaid/client/exception/PlaidClientsideException.java create mode 100644 src/main/java/com/plaid/client/exception/PlaidCommunicationsException.java create mode 100644 src/main/java/com/plaid/client/exception/PlaidMfaException.java create mode 100644 src/main/java/com/plaid/client/exception/PlaidServersideException.java create mode 100644 src/main/java/com/plaid/client/exception/PlaidServersideUnknownResponseException.java create mode 100644 src/main/java/com/plaid/client/http/ApacheHttpClientHttpDelegate.java create mode 100644 src/main/java/com/plaid/client/http/HttpDelegate.java create mode 100644 src/main/java/com/plaid/client/http/HttpResponseWrapper.java create mode 100644 src/main/java/com/plaid/client/http/PlaidHttpRequest.java create mode 100644 src/main/java/com/plaid/client/http/WireLogger.java create mode 100644 src/main/java/com/plaid/client/request/ConnectOptions.java create mode 100644 src/main/java/com/plaid/client/request/Credentials.java create mode 100644 src/main/java/com/plaid/client/request/GetOptions.java create mode 100644 src/main/java/com/plaid/client/request/InfoOptions.java create mode 100644 src/main/java/com/plaid/client/request/MappingOptions.java create mode 100644 src/main/java/com/plaid/client/response/Account.java create mode 100644 src/main/java/com/plaid/client/response/AccountsResponse.java create mode 100644 src/main/java/com/plaid/client/response/CategoriesResponse.java create mode 100644 src/main/java/com/plaid/client/response/Category.java create mode 100644 src/main/java/com/plaid/client/response/ErrorResponse.java create mode 100644 src/main/java/com/plaid/client/response/ExchangeTokenResponse.java create mode 100644 src/main/java/com/plaid/client/response/InfoResponse.java create mode 100644 src/main/java/com/plaid/client/response/Institution.java create mode 100644 src/main/java/com/plaid/client/response/InstitutionsResponse.java create mode 100644 src/main/java/com/plaid/client/response/LongTailInstitution.java create mode 100644 src/main/java/com/plaid/client/response/LongTailInstitutionsResponse.java create mode 100644 src/main/java/com/plaid/client/response/MessageResponse.java create mode 100644 src/main/java/com/plaid/client/response/MfaResponse.java create mode 100644 src/main/java/com/plaid/client/response/PlaidUserResponse.java create mode 100644 src/main/java/com/plaid/client/response/Transaction.java create mode 100644 src/main/java/com/plaid/client/response/TransactionsResponse.java create mode 100644 src/main/java/com/plaid/client/response/UnknownResponse.java create mode 100644 src/test/java/com/plaid/client/PlaidPublicClientTest.java create mode 100644 src/test/java/com/plaid/client/PlaidUserClientTest.java create mode 100644 src/test/java/com/plaid/client/exception/PlaidServersideExceptionTest.java create mode 100644 src/test/resources/__files/body-category-6JpxC.json create mode 100644 src/test/resources/__files/body-connect-5Htb4.json create mode 100644 src/test/resources/__files/body-connect-KwC7m.json create mode 100644 src/test/resources/__files/body-connect-MpWQ7.json create mode 100644 src/test/resources/__files/body-connect-get-mU7ak.json create mode 100644 src/test/resources/__files/body-connect-qZWyb.json create mode 100644 src/test/resources/__files/body-connect-step-XBxNh.json create mode 100644 src/test/resources/__files/body-institutions-TqpVf.json create mode 100644 src/test/resources/logback.xml create mode 100644 src/test/resources/mappings/mapping-category-6JpxC.json create mode 100644 src/test/resources/mappings/mapping-connect-5Htb4.json create mode 100644 src/test/resources/mappings/mapping-connect-KwC7m.json create mode 100644 src/test/resources/mappings/mapping-connect-MpWQ7.json create mode 100644 src/test/resources/mappings/mapping-connect-get-mU7ak.json create mode 100644 src/test/resources/mappings/mapping-connect-qZWyb.json create mode 100644 src/test/resources/mappings/mapping-connect-step-XBxNh.json create mode 100644 src/test/resources/mappings/mapping-institutions-TqpVf.json diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..07f877c --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License + +Copyright (c) 2014-2016 Plaid Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 9fc45ce..9df6ec5 100644 --- a/README.md +++ b/README.md @@ -1 +1,87 @@ -# plaid-java-legacy \ No newline at end of file +plaid-java-legacy +================= + +Java Bindings for the Plaid API (https://www.plaid.com/docs) + +These bindings are under active development and currently support the main usecases of the Plaid API. There are some parts that are as yet unimplemented so pull requests are welcome! + +### Installation + +Plaid-java is available at [Maven Central](https://search.maven.org/#search%7Cga%7C1%7Cplaid-java) with the following coordinates (latest release 0.3.2): + +```xml + + + com.plaid + plaid-java-legacy + 0.3.2 + + +``` + +### Basic Usage + +```java + +// Add Amex user, get 30 days of transactions + +PlaidUserClient plaidUserClient = PlaidClients.testUserClient("test_id", "test_secret"); +Credentials testCredentials = new Credentials("plaid_test", "plaid_good"); +TransactionsResponse response = plaidUserClient.addUser(testCredentials, "amex", "test@test.com", null); + +List transactions = response.getTransactions(); + + +// Get all Categories + +PlaidPublicClient plaidPublicClient = PlaidClients.testPublicClient(); +CategoriesResponse categoriesResponse = plaidPublicClient.getAllCategories(); + +List categories = categoriesResponse.getCategories(); +``` + +Check the Junit test classes for examples of more use cases. + +### Exchange a Plaid Link public_token for an API access_token + +```java +// Initialize a Plaid client with your client_id and secret +PlaidUserClient plaidUserClient = PlaidClients.testUserClient("test_id", "test_secret"); + +// Exchange the Link public_token ("test,bofa,connected") for an API access_token +PlaidUserResponse response = plaidUserClient.exchangeToken("test,bofa,connected"); + +// Initialize the user with the access_token returned by the exchangeToken call +plaidUserClient.setAccessToken(response.getAccessToken()); + +// Pull accounts for the user +// Note: This assumes you are using Link with the "auth" product +AccountsResponse response = plaidUserClient.updateAuth(); +``` + +To use [Stripe ACH + Plaid Integration](https://plaid.com/docs/link/stripe/) exchange a `public_token` and `account_id` to retrive a Stripe bank account token + +```java +// Initialize a Plaid client with your client_id and secret +PlaidUserClient plaidUserClient = PlaidClients.testUserClient("test_id", "test_secret"); + +// Exchange the Link public_token ("test,bofa,connected") and account_id ("test_account_id") +PlaidUserResponse response = plaidUserClient.exchangeToken("test,bofa,connected", "test_account_id"); + +// Get the Stripe bank account token from response +String stripeToken = response.getStripeBankAccountToken(); +``` + +### Dependencies + +There are two main dependencies (of course automatically managed by Maven): + +1. [Apache HTTPComponents Client](http://hc.apache.org/httpcomponents-client-ga/index.html). One reason for this, besides it being a nice library, is that the native JDK HttpUrlConnection doesn't have support for the HTTP Patch method, that is required by the Plaid API. The bindings are, however, designed so that you can replace HTTPComponents client with the HTTP library of your choice, by creating a different implementation of the HttpDelegate interface. + +2. The [Jackson JSON Parser](http://jackson.codehaus.org/). + +The project also has a test scope dependency on [Wiremock](http://wiremock.org), which is really useful in order to avoid hitting the sandbox API all the time. + +### Contributors + +- [@erimag](https://github.com/erimag) (Qapital Insight AB) diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4782244 --- /dev/null +++ b/pom.xml @@ -0,0 +1,239 @@ + + 4.0.0 + com.plaid + plaid-java-legacy + 0.3.3-SNAPSHOT + jar + + + org.sonatype.oss + oss-parent + 9 + + ${project.groupId}:${project.artifactId} + Bindings for the Plaid (plaid.com) API. Original code contributed by Qapital Insight AB (qapital.com) + http://github.com/plaid/plaid-java-legacy + + scm:git:git://github.com/plaid/plaid-java-legacy.git + scm:git:git@github.com:plaid/plaid-java-legacy.git + http://github.com/plaid/plaid-java-legacy + HEAD + + + Plaid Technologies, Inc. + http://plaid.com + + 2014 + + + The MIT License (MIT) + http://www.opensource.org/licenses/mit-license.php + + + + + Rahul Ramakrishnan + rahul@plaid.com + raha936 + Plaid Technologies, Inc + http://plaid.com + + + Erik Akterin + erik.akterin@qapital.com + erimag + Qapital + https://www.qapital.com + + + Adam Langsner + adamlangsner@gmail.com + adamlangsner + Betterment + https://www.betterment.com + + + + + UTF-8 + 1.7 + + + + + + + org.apache.httpcomponents + httpclient + 4.3.3 + + + com.fasterxml.jackson.core + jackson-core + 2.2.3 + + + com.fasterxml.jackson.core + jackson-annotations + 2.2.3 + + + com.fasterxml.jackson.core + jackson-databind + 2.2.3 + + + com.fasterxml.jackson.datatype + jackson-datatype-joda + 2.2.3 + + + joda-time + joda-time + 2.3 + + + commons-lang + commons-lang + 2.6 + + + org.slf4j + slf4j-api + 1.7.2 + + + + + ch.qos.logback + logback-classic + 1.1.1 + runtime + + + org.slf4j + log4j-over-slf4j + 1.7.6 + runtime + + + + + junit + junit + 4.11 + test + + + com.github.tomakehurst + wiremock + 1.44 + test + + standalone + + + + + + + maven-compiler-plugin + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-release-plugin + 2.5 + + -Dgpg.passphrase=${gpg.passphrase} + true + false + release + deploy + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + true + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + + + + + + + ossrh + Sonatype Nexus snapshot repository + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + Sonatype Nexus release repository + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + ${gpg.passphrase} + + + + sign-artifacts + verify + + sign + + + + + + + + + diff --git a/src/main/java/com/plaid/client/DefaultPlaidPublicClient.java b/src/main/java/com/plaid/client/DefaultPlaidPublicClient.java new file mode 100644 index 0000000..4b14fe4 --- /dev/null +++ b/src/main/java/com/plaid/client/DefaultPlaidPublicClient.java @@ -0,0 +1,119 @@ +package com.plaid.client; + +import com.plaid.client.exception.PlaidClientsideException; +import com.plaid.client.http.HttpDelegate; +import com.plaid.client.http.HttpResponseWrapper; +import com.plaid.client.http.PlaidHttpRequest; +import com.plaid.client.request.MappingOptions; +import com.plaid.client.response.CategoriesResponse; +import com.plaid.client.response.Category; +import com.plaid.client.response.Institution; +import com.plaid.client.response.InstitutionsResponse; +import com.plaid.client.response.LongTailInstitutionsResponse; +import org.apache.commons.lang.StringUtils; + +public class DefaultPlaidPublicClient implements PlaidPublicClient { + + private HttpDelegate httpDelegate; + + private String clientId; + private String secret; + + @Override + public Object getEntity(String entityId) { + throw new UnsupportedOperationException("Not implemented yet"); + } + + @Override + public Institution getInstitution(String institutionId) { + PlaidHttpRequest request = new PlaidHttpRequest("/institutions/" + institutionId); + HttpResponseWrapper response = httpDelegate.doGet(request, Institution.class); + return response.getResponseBody(); + } + + @Override + public InstitutionsResponse getAllInstitutions() { + PlaidHttpRequest request = new PlaidHttpRequest("/institutions"); + HttpResponseWrapper response = httpDelegate.doGet(request, Institution[].class); + return new InstitutionsResponse(response.getResponseBody()); + } + + @Override + public LongTailInstitutionsResponse getAllLongTailInstitutions(Integer offset, Integer count) { + PlaidHttpRequest request = new PlaidHttpRequest("/institutions/longtail"); + + if(StringUtils.isEmpty(clientId) || StringUtils.isEmpty(secret)) { + throw new PlaidClientsideException("ClientId and Secret is required"); + } + + request.addParameter("client_id", clientId); + request.addParameter("secret", secret); + + if(count != null) { + request.addParameter("count", count.toString()); + } + + if(offset != null) { + request.addParameter("offset", offset.toString()); + } + + HttpResponseWrapper response = httpDelegate.doPost(request, LongTailInstitutionsResponse.class); + return response.getResponseBody(); + } + + @Override + public CategoriesResponse getAllCategories() { + PlaidHttpRequest request = new PlaidHttpRequest("/categories"); + HttpResponseWrapper response = httpDelegate.doGet(request, Category[].class); + return new CategoriesResponse(response.getResponseBody()); + } + + @Override + public Object getCategory(String categoryId) { + throw new UnsupportedOperationException("Not implemented yet"); + } + + @Override + public Object getCategoriesByMapping(String mapping, MappingOptions options) { + throw new UnsupportedOperationException("Not implemented yet"); + } + + @Override + public HttpDelegate getHttpDelegate() { + return httpDelegate; + } + + public static class Builder { + + private String clientId; + private String secret; + private HttpDelegate httpDelegate; + + public Builder withClientId(String clientId) { + this.clientId = clientId; + return this; + } + + public Builder withSecret(String secret) { + this.secret = secret; + return this; + } + + public Builder withHttpDelegate(HttpDelegate httpDelegate) { + this.httpDelegate = httpDelegate; + return this; + } + + public DefaultPlaidPublicClient build() { + + DefaultPlaidPublicClient client = new DefaultPlaidPublicClient(); + client.clientId = this.clientId; + client.secret = this.secret; + client.httpDelegate = this.httpDelegate; + + return client; + } + + } + +} diff --git a/src/main/java/com/plaid/client/DefaultPlaidUserClient.java b/src/main/java/com/plaid/client/DefaultPlaidUserClient.java new file mode 100644 index 0000000..cd13cdd --- /dev/null +++ b/src/main/java/com/plaid/client/DefaultPlaidUserClient.java @@ -0,0 +1,483 @@ +package com.plaid.client; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.plaid.client.exception.PlaidClientsideException; +import com.plaid.client.exception.PlaidMfaException; +import com.plaid.client.http.HttpDelegate; +import com.plaid.client.http.HttpResponseWrapper; +import com.plaid.client.http.PlaidHttpRequest; +import com.plaid.client.request.ConnectOptions; +import com.plaid.client.request.Credentials; +import com.plaid.client.request.GetOptions; +import com.plaid.client.request.InfoOptions; +import com.plaid.client.response.*; +import org.apache.commons.lang.StringUtils; + +import java.util.HashMap; +import java.util.Map; + + +public class DefaultPlaidUserClient implements PlaidUserClient { + + private String accessToken; + + private String clientId; + private String secret; + + private ObjectMapper jsonMapper; + private HttpDelegate httpDelegate; + private Integer timeout; + + private DefaultPlaidUserClient() { + ObjectMapper jsonMapper = new ObjectMapper(); + jsonMapper.setSerializationInclusion(Include.NON_NULL); + this.jsonMapper = jsonMapper; + } + + @Override + public void setAccessToken(String accessToken) { + + this.accessToken = accessToken; + } + + @Override + public String getAccessToken() { + + return this.accessToken; + } + + @Override + public PlaidUserResponse exchangeToken(String publicToken) { + Map requestParams = new HashMap(); + requestParams.put("public_token", publicToken); + + return handlePost("/exchange_token", requestParams, PlaidUserResponse.class); + } + + @Override + public PlaidUserResponse exchangeToken(String publicToken, String accountId) { + Map requestParams = new HashMap(); + requestParams.put("public_token", publicToken); + requestParams.put("account_id", accountId); + + return handlePost("/exchange_token", requestParams, PlaidUserResponse.class); + } + + @Override + public TransactionsResponse addUser(Credentials credentials, String type, String email, ConnectOptions connectOptions) throws PlaidMfaException { + + Map requestParams = new HashMap(); + requestParams.put("credentials", credentials); + requestParams.put("type", type); + requestParams.put("email", email); + requestParams.put("options", connectOptions); + + return handlePost("/connect", requestParams, TransactionsResponse.class); + } + + @Override + public AccountsResponse achAuth(Credentials credentials, String type, ConnectOptions connectOptions) throws PlaidMfaException { + + Map requestParams = new HashMap(); + requestParams.put("credentials", credentials); + requestParams.put("type", type); + requestParams.put("options", connectOptions); + + return handlePost("/auth", requestParams, AccountsResponse.class); + } + + @Override + public TransactionsResponse mfaConnectStep(String mfa, String type) throws PlaidMfaException { + + return handleMfa("/connect/step", mfa, type, TransactionsResponse.class); + } + + @Override + public TransactionsResponse mfaConnectStep(String[] mfa, String type) throws PlaidMfaException { + + return handleMfa("/connect/step", mfa, type, TransactionsResponse.class); + } + + @Override + public AccountsResponse mfaAuthStep(String mfa, String type) throws PlaidMfaException { + + return handleMfa("/auth/step", mfa, type, AccountsResponse.class); + } + + @Override + public AccountsResponse mfaAuthStep(String[] mfa, String type) throws PlaidMfaException { + + return handleMfa("/auth/step", mfa, type, AccountsResponse.class); + } + + @Override + public AccountsResponse mfaAuthByDeviceMask(String deviceMask) throws PlaidMfaException { + + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + + if (StringUtils.isEmpty(deviceMask)) { + throw new PlaidClientsideException("No deviceMask provided"); + } + + Map requestParams = sendMethodParams(deviceMask); + + return handlePost("/auth/step", requestParams, AccountsResponse.class); + } + + @Override + public AccountsResponse mfaConnectByDeviceMask(String deviceMask) throws PlaidMfaException { + + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + + if (StringUtils.isEmpty(deviceMask)) { + throw new PlaidClientsideException("No deviceMask provided"); + } + + Map requestParams = sendMethodParams(deviceMask); + + return handlePost("/connect/step", requestParams, AccountsResponse.class); + } + + @Override + public AccountsResponse mfaAuthDeviceSelectionByDeviceType(String deviceType, String type) throws PlaidMfaException { + + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + + if (StringUtils.isEmpty(deviceType)){ + throw new PlaidClientsideException("No device selected"); + } + + Map requestParams = new HashMap(); + requestParams.put("type", type); + + HashMap mask = new HashMap(); + mask.put("type", deviceType); + HashMap sendMethod = new HashMap(); + sendMethod.put("send_method", mask); + requestParams.put("options", sendMethod); + + return handlePost("/auth/step", requestParams, AccountsResponse.class); + } + + @Override + public AccountsResponse mfaAuthDeviceSelectionByDeviceMask(String deviceMask, String type) throws PlaidMfaException { + + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + + if (StringUtils.isEmpty(deviceMask)) { + throw new PlaidClientsideException("No device selected"); + } + + Map requestParams = new HashMap(); + requestParams.put("type", type); + + HashMap mask = new HashMap(); + mask.put("mask", deviceMask); + HashMap sendMethod = new HashMap(); + sendMethod.put("send_method", mask); + requestParams.put("options", sendMethod); + + return handlePost("/auth/step", requestParams, AccountsResponse.class); + } + + @Override + public TransactionsResponse updateTransactions() { + + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + + PlaidHttpRequest request = new PlaidHttpRequest("/connect", authenticationParams(), timeout); + + HttpResponseWrapper response = + httpDelegate.doGet(request, TransactionsResponse.class); + + TransactionsResponse body = response.getResponseBody(); + setAccessToken(body.getAccessToken()); + return body; + + } + + @Override + public TransactionsResponse updateTransactions(GetOptions options) { + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + + Map requestParams = new HashMap(); + if (options != null) { + requestParams.put("options", options); + } + + return handlePost("/connect/get", requestParams, TransactionsResponse.class); + } + + @Override + public AccountsResponse updateAuth() { + return updateAuth(new HashMap()); + } + + @Override + public AccountsResponse updateAuth(Map requestParams) { + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + return handlePost("/auth/get", requestParams, AccountsResponse.class); + } + + @Override + public AccountsResponse getAuth(String account) { + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + + PlaidHttpRequest request = new PlaidHttpRequest("/auth", authenticationParams(), timeout); + + if (null != account) { + ObjectNode optionsNode = jsonMapper.createObjectNode(); + optionsNode.put("account", account); + request.addParameter("options", optionsNode.toString()); + } + + HttpResponseWrapper response = + httpDelegate.doGet(request, AccountsResponse.class); + + AccountsResponse body = response.getResponseBody(); + setAccessToken(body.getAccessToken()); + return body; + } + + @Override + public TransactionsResponse updateCredentials(Credentials credentials, String type) { + + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + + PlaidHttpRequest request = new PlaidHttpRequest("/connect", authenticationParams(), timeout); + + request.addParameter("credentials", serialize(credentials)); + request.addParameter("type", type); + + HttpResponseWrapper response = + httpDelegate.doPatch(request, TransactionsResponse.class); + + TransactionsResponse body = response.getResponseBody(); + + setAccessToken(body.getAccessToken()); + + return body; + } + + @Override + public TransactionsResponse updateWebhook(String webhook) { + + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + + PlaidHttpRequest request = new PlaidHttpRequest("/connect", authenticationParams(), timeout); + + ConnectOptions connectOptions = new ConnectOptions(); + connectOptions.setWebhook(webhook); + + request.addParameter("options", serialize(connectOptions)); + + HttpResponseWrapper response = + httpDelegate.doPatch(request, TransactionsResponse.class); + + TransactionsResponse body = response.getResponseBody(); + + setAccessToken(body.getAccessToken()); + + return body; + } + + @Override + public MessageResponse deleteUser() { + + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + + PlaidHttpRequest request = new PlaidHttpRequest("/connect", authenticationParams(), timeout); + + HttpResponseWrapper response = + httpDelegate.doDelete(request, MessageResponse.class); + + return response.getResponseBody(); + } + + @Override + public AccountsResponse checkBalance() { + + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + + Map requestParams = new HashMap(); + + return handlePost("/balance", requestParams, AccountsResponse.class); + } + + @Override + public TransactionsResponse addProduct(String product, ConnectOptions options) { + + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + + Map requestParams = new HashMap(); + requestParams.put("upgrade_to", product); + + requestParams.put("login",true); + + if (options != null) { + requestParams.put("options", options); + } + + return handlePost("/upgrade", requestParams, TransactionsResponse.class); + } + + @Override + public InfoResponse info(Credentials credentials, String type, InfoOptions options) { + Map requestParams = new HashMap(); + requestParams.put("credentials", credentials); + requestParams.put("type", type); + requestParams.put("options", options); + + return handlePost("/info", requestParams, InfoResponse.class); + } + + private T handleMfa(String path, Object mfa, String type, Class returnTypeClass) throws PlaidMfaException { + + if (StringUtils.isEmpty(accessToken)) { + throw new PlaidClientsideException("No accessToken set"); + } + + Map requestParams = new HashMap(); + + requestParams.put("mfa", mfa); + + if (type != null) { + requestParams.put("type", type); + } + + return handlePost(path, requestParams, returnTypeClass); + } + + private T handlePost(String path, Map requestParams, Class returnTypeClass) throws PlaidMfaException { + + PlaidHttpRequest request = new PlaidHttpRequest(path, authenticationParams(), timeout); + + for (String param : requestParams.keySet()) { + Object value = requestParams.get(param); + + if (value == null) { + continue; + } + + request.addParameter(param, serialize(value)); + } + + try { + HttpResponseWrapper response = httpDelegate.doPost(request, returnTypeClass); + + T body = response.getResponseBody(); + setAccessToken(body.getAccessToken()); + return body; + + } + catch (PlaidMfaException e) { + setAccessToken(e.getMfaResponse().getAccessToken()); + throw e; + } + } + + private String serialize(Object value) { + if (value instanceof String) { + return (String) value; + } else { + try { + return jsonMapper.writeValueAsString(value); + } catch (JsonProcessingException e) { + throw new PlaidClientsideException(e); + } + } + } + + private Map sendMethodParams(String deviceMask) { + Map requestParams = new HashMap<>(); + HashMap mask = new HashMap<>(); + mask.put("mask", deviceMask); + HashMap sendMethod = new HashMap<>(); + sendMethod.put("send_method", mask); + requestParams.put("options", sendMethod); + return requestParams; + } + + private Map authenticationParams() { + + Map parameters = new HashMap(); + parameters.put("client_id", clientId); + parameters.put("secret", secret); + if (!StringUtils.isEmpty(accessToken)) { + parameters.put("access_token", accessToken); + } + return parameters; + } + + @Override + public HttpDelegate getHttpDelegate() { + return httpDelegate; + } + + public static class Builder { + private String clientId; + private String secret; + private Integer timeout; + private HttpDelegate httpDelegate; + + public Builder withClientId(String clientId) { + this.clientId = clientId; + return this; + } + + public Builder withSecret(String secret) { + this.secret = secret; + return this; + } + + public Builder withTimeout(Integer timeout) { + this.timeout = timeout; + return this; + } + + public Builder withHttpDelegate(HttpDelegate httpDelegate) { + this.httpDelegate = httpDelegate; + return this; + } + + public DefaultPlaidUserClient build() { + DefaultPlaidUserClient client = new DefaultPlaidUserClient(); + client.clientId = this.clientId; + client.secret = this.secret; + client.timeout = this.timeout; + client.httpDelegate = this.httpDelegate; + + return client; + } + + } +} diff --git a/src/main/java/com/plaid/client/PlaidClients.java b/src/main/java/com/plaid/client/PlaidClients.java new file mode 100644 index 0000000..072d767 --- /dev/null +++ b/src/main/java/com/plaid/client/PlaidClients.java @@ -0,0 +1,108 @@ +package com.plaid.client; + +import org.apache.http.impl.client.HttpClientBuilder; + +import com.plaid.client.http.ApacheHttpClientHttpDelegate; +import com.plaid.client.http.WireLogger; + +public class PlaidClients { + + public static final String BASE_URI_PRODUCTION = "https://api.plaid.com"; + public static final String BASE_URI_TEST = "https://tartan.plaid.com"; + + public static PlaidUserClient productionUserClient(String clientId, String secret, WireLogger wireLogger, Integer timeout) { + return new DefaultPlaidUserClient.Builder() + .withHttpDelegate(createHttpDelegate(BASE_URI_PRODUCTION, wireLogger)) + .withClientId(clientId) + .withSecret(secret) + .withTimeout(timeout) + .build(); + } + + public static PlaidUserClient testUserClient(String clientId, String secret, WireLogger wireLogger, Integer timeout) { + return new DefaultPlaidUserClient.Builder() + .withHttpDelegate(createHttpDelegate(BASE_URI_TEST, wireLogger, true)) + .withClientId(clientId) + .withSecret(secret) + .withTimeout(timeout) + .build(); + } + + public static PlaidPublicClient productionPublicClient(String clientId, String secret, WireLogger wireLogger) { + return new DefaultPlaidPublicClient.Builder() + .withHttpDelegate(createHttpDelegate(BASE_URI_PRODUCTION, wireLogger)) + .withClientId(clientId) + .withSecret(secret) + .build(); + } + + public static PlaidPublicClient productionPublicClient(WireLogger wireLogger) { + return new DefaultPlaidPublicClient.Builder() + .withHttpDelegate(createHttpDelegate(BASE_URI_PRODUCTION, wireLogger)) + .build(); + } + + public static PlaidPublicClient testPublicClient(WireLogger wireLogger) { + return new DefaultPlaidPublicClient.Builder() + .withHttpDelegate(createHttpDelegate(BASE_URI_TEST, wireLogger, true)) + .build(); + } + + public static PlaidPublicClient testPublicClient(String clientId, String secret, WireLogger wireLogger) { + return new DefaultPlaidPublicClient.Builder() + .withHttpDelegate(createHttpDelegate(BASE_URI_TEST, wireLogger, true)) + .withClientId(clientId) + .withSecret(secret) + .build(); + } + + public static PlaidUserClient productionUserClient(String clientId, String secret) { + + return productionUserClient(clientId, secret, null); + } + + public static PlaidUserClient productionUserClient(String clientId, String secret, Integer timeout) { + + return productionUserClient(clientId, secret, null, timeout); + } + + public static PlaidUserClient testUserClient(String clientId, String secret) { + + return testUserClient(clientId, secret, null); + } + + public static PlaidUserClient testUserClient(String clientId, String secret, Integer timeout) { + + return testUserClient(clientId, secret, null, timeout); + } + + public static PlaidPublicClient productionPublicClient() { + + return productionPublicClient(null); + } + + public static PlaidPublicClient testPublicClient() { + + return testPublicClient(null); + } + + private static ApacheHttpClientHttpDelegate createHttpDelegate(String uri, WireLogger wireLogger) { + + return createHttpDelegate(uri, wireLogger, false); + } + + private static ApacheHttpClientHttpDelegate createHttpDelegate(String uri, WireLogger wireLogger, boolean test) { + + ApacheHttpClientHttpDelegate httpDelegate; + if (test) { + httpDelegate = new ApacheHttpClientHttpDelegate(uri, HttpClientBuilder.create().disableContentCompression().useSystemProperties().build()); + } + else { + httpDelegate = ApacheHttpClientHttpDelegate.createDefault(uri); + } + if (wireLogger != null) { + httpDelegate.setWireLogger(wireLogger); + } + return httpDelegate; + } +} diff --git a/src/main/java/com/plaid/client/PlaidPublicClient.java b/src/main/java/com/plaid/client/PlaidPublicClient.java new file mode 100644 index 0000000..c8b4e6c --- /dev/null +++ b/src/main/java/com/plaid/client/PlaidPublicClient.java @@ -0,0 +1,27 @@ +package com.plaid.client; + +import com.plaid.client.http.HttpDelegate; +import com.plaid.client.request.MappingOptions; +import com.plaid.client.response.CategoriesResponse; +import com.plaid.client.response.Institution; +import com.plaid.client.response.InstitutionsResponse; +import com.plaid.client.response.LongTailInstitutionsResponse; + +public interface PlaidPublicClient { + + Object getEntity(String entityId); + + Institution getInstitution(String institutionId); + + InstitutionsResponse getAllInstitutions(); + + LongTailInstitutionsResponse getAllLongTailInstitutions(Integer offset, Integer count); + + CategoriesResponse getAllCategories(); + + Object getCategory(String categoryId); + + Object getCategoriesByMapping(String mapping, MappingOptions options); + + HttpDelegate getHttpDelegate(); +} diff --git a/src/main/java/com/plaid/client/PlaidUserClient.java b/src/main/java/com/plaid/client/PlaidUserClient.java new file mode 100644 index 0000000..0947f9e --- /dev/null +++ b/src/main/java/com/plaid/client/PlaidUserClient.java @@ -0,0 +1,71 @@ +package com.plaid.client; + +import com.plaid.client.exception.PlaidMfaException; +import com.plaid.client.http.HttpDelegate; +import com.plaid.client.request.ConnectOptions; +import com.plaid.client.request.Credentials; +import com.plaid.client.request.GetOptions; +import com.plaid.client.request.InfoOptions; +import com.plaid.client.response.AccountsResponse; +import com.plaid.client.response.InfoResponse; +import com.plaid.client.response.MessageResponse; +import com.plaid.client.response.MfaResponse; +import com.plaid.client.response.TransactionsResponse; +import com.plaid.client.response.PlaidUserResponse; + +import java.util.Map; + +public interface PlaidUserClient { + + void setAccessToken(String accesstoken); + + String getAccessToken(); + + PlaidUserResponse exchangeToken(String publicToken); + + PlaidUserResponse exchangeToken(String publicToken, String accountId); + + TransactionsResponse addUser(Credentials credentials, String type, String email, ConnectOptions connectOptions) throws PlaidMfaException; + + TransactionsResponse mfaConnectStep(String mfa, String type) throws PlaidMfaException; + + TransactionsResponse mfaConnectStep(String[] mfa, String type) throws PlaidMfaException; + + AccountsResponse achAuth(Credentials credentials, String type, ConnectOptions connectOptions) throws PlaidMfaException; + + AccountsResponse mfaAuthStep(String mfa, String type) throws PlaidMfaException; + + AccountsResponse mfaAuthStep(String[] mfa, String type) throws PlaidMfaException; + + AccountsResponse mfaAuthByDeviceMask(String deviceMask) throws PlaidMfaException; + + AccountsResponse mfaConnectByDeviceMask(String deviceMask) throws PlaidMfaException; + + AccountsResponse mfaAuthDeviceSelectionByDeviceType(String deviceType, String type) throws PlaidMfaException; + + AccountsResponse mfaAuthDeviceSelectionByDeviceMask(String deviceMask, String type) throws PlaidMfaException; + + TransactionsResponse updateTransactions(); + + TransactionsResponse updateTransactions(GetOptions options); + + TransactionsResponse updateCredentials(Credentials credentials, String type); + + TransactionsResponse updateWebhook(String webhook); + + AccountsResponse updateAuth(); + + AccountsResponse updateAuth(Map requestParams); + + AccountsResponse getAuth(String account); + + MessageResponse deleteUser(); + + AccountsResponse checkBalance(); + + InfoResponse info(Credentials credentials, String type, InfoOptions options); + + TransactionsResponse addProduct(String product, ConnectOptions options); + + HttpDelegate getHttpDelegate(); +} diff --git a/src/main/java/com/plaid/client/exception/PlaidClientsideException.java b/src/main/java/com/plaid/client/exception/PlaidClientsideException.java new file mode 100644 index 0000000..57ffa86 --- /dev/null +++ b/src/main/java/com/plaid/client/exception/PlaidClientsideException.java @@ -0,0 +1,17 @@ +package com.plaid.client.exception; + +public class PlaidClientsideException extends RuntimeException { + + public PlaidClientsideException(String message, Throwable cause) { + super(message, cause); + } + + public PlaidClientsideException(String message) { + super(message); + } + + public PlaidClientsideException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/com/plaid/client/exception/PlaidCommunicationsException.java b/src/main/java/com/plaid/client/exception/PlaidCommunicationsException.java new file mode 100644 index 0000000..cf8e9e2 --- /dev/null +++ b/src/main/java/com/plaid/client/exception/PlaidCommunicationsException.java @@ -0,0 +1,17 @@ +package com.plaid.client.exception; + +public class PlaidCommunicationsException extends RuntimeException { + + public PlaidCommunicationsException(String message, Throwable cause) { + super(message, cause); + } + + public PlaidCommunicationsException(String message) { + super(message); + } + + public PlaidCommunicationsException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/com/plaid/client/exception/PlaidMfaException.java b/src/main/java/com/plaid/client/exception/PlaidMfaException.java new file mode 100644 index 0000000..e658376 --- /dev/null +++ b/src/main/java/com/plaid/client/exception/PlaidMfaException.java @@ -0,0 +1,22 @@ +package com.plaid.client.exception; + +import com.plaid.client.response.MfaResponse; + +public class PlaidMfaException extends RuntimeException { + + private MfaResponse mfaResponse; + private int httpStatusCode; + + public PlaidMfaException(MfaResponse mfaResponse, int httpStatusCode) { + this.mfaResponse = mfaResponse; + this.httpStatusCode = httpStatusCode; + } + + public MfaResponse getMfaResponse() { + return mfaResponse; + } + + public int getHttpStatusCode() { + return httpStatusCode; + } +} diff --git a/src/main/java/com/plaid/client/exception/PlaidServersideException.java b/src/main/java/com/plaid/client/exception/PlaidServersideException.java new file mode 100644 index 0000000..aec77c7 --- /dev/null +++ b/src/main/java/com/plaid/client/exception/PlaidServersideException.java @@ -0,0 +1,24 @@ +package com.plaid.client.exception; + +import com.plaid.client.response.ErrorResponse; + +public class PlaidServersideException extends RuntimeException { + + private ErrorResponse errorResponse; + private int httpStatusCode; + + public PlaidServersideException(ErrorResponse errorResponse, int httpStatusCode) { + super(String.format("%s: %s", httpStatusCode, errorResponse != null ? errorResponse.getMessage() : null)); + this.errorResponse = errorResponse; + this.httpStatusCode = httpStatusCode; + } + + public ErrorResponse getErrorResponse() { + return errorResponse; + } + + public int getHttpStatusCode() { + return httpStatusCode; + } + +} \ No newline at end of file diff --git a/src/main/java/com/plaid/client/exception/PlaidServersideUnknownResponseException.java b/src/main/java/com/plaid/client/exception/PlaidServersideUnknownResponseException.java new file mode 100644 index 0000000..57ae5af --- /dev/null +++ b/src/main/java/com/plaid/client/exception/PlaidServersideUnknownResponseException.java @@ -0,0 +1,21 @@ +package com.plaid.client.exception; + +import com.plaid.client.response.UnknownResponse; + +public class PlaidServersideUnknownResponseException extends RuntimeException { + private UnknownResponse unknownResponse; + private int httpStatusCode; + + public PlaidServersideUnknownResponseException(UnknownResponse unknownResponse, int httpStatusCode) { + this.unknownResponse = unknownResponse; + this.httpStatusCode = httpStatusCode; + } + + public UnknownResponse getUnknownResponse() { + return unknownResponse; + } + + public int getHttpStatusCode() { + return httpStatusCode; + } +} diff --git a/src/main/java/com/plaid/client/http/ApacheHttpClientHttpDelegate.java b/src/main/java/com/plaid/client/http/ApacheHttpClientHttpDelegate.java new file mode 100644 index 0000000..c0e73a9 --- /dev/null +++ b/src/main/java/com/plaid/client/http/ApacheHttpClientHttpDelegate.java @@ -0,0 +1,252 @@ +package com.plaid.client.http; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpMessage; +import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPatch; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.plaid.client.exception.PlaidClientsideException; +import com.plaid.client.exception.PlaidCommunicationsException; +import com.plaid.client.exception.PlaidMfaException; +import com.plaid.client.exception.PlaidServersideException; +import com.plaid.client.exception.PlaidServersideUnknownResponseException; +import com.plaid.client.response.ErrorResponse; +import com.plaid.client.response.MfaResponse; +import com.plaid.client.response.UnknownResponse; + +public class ApacheHttpClientHttpDelegate implements HttpDelegate { + + private String baseUri; + private CloseableHttpClient httpClient; + private ObjectMapper jsonMapper; + private WireLogger wireLogger; + private static String LIBRARY_VERSION = ApacheHttpClientHttpDelegate.class.getPackage().getImplementationVersion(); + + public ApacheHttpClientHttpDelegate(String baseUri, CloseableHttpClient httpClient) { + this.baseUri = baseUri; + this.httpClient = httpClient; + this.jsonMapper = new ObjectMapper(); + if (LIBRARY_VERSION == null) { + LIBRARY_VERSION = "development version"; + } + } + + public static ApacheHttpClientHttpDelegate createDefault(String baseUri) { + CloseableHttpClient httpClient = System.getProperty("https.protocols") == null ? + HttpClients.createDefault() : HttpClients.createSystem(); + return new ApacheHttpClientHttpDelegate(baseUri, httpClient); + } + + public void setWireLogger(WireLogger wireLogger) { + this.wireLogger = wireLogger; + } + + public WireLogger getWireLogger() { + return wireLogger; + } + + @Override + public HttpResponseWrapper doPost(PlaidHttpRequest request, Class clazz) { + + List parameters = mapToNvps(request.getParameters()); + + try { + HttpPost post = new HttpPost(baseUri + request.getPath()); + + HttpEntity entity = new UrlEncodedFormEntity(parameters, "UTF-8"); + post.setEntity(entity); + + if (request.hasTimeout()) { + int timeout = request.getTimeout(); + + RequestConfig config = RequestConfig.custom() + .setConnectTimeout(timeout) + .setSocketTimeout(timeout) + .setConnectionRequestTimeout(timeout) + .build(); + post.setConfig(config); + } + + addUserAgent(post); + + CloseableHttpResponse response = httpClient.execute(post); + + return handleResponse(post, response, clazz); + + } catch (UnsupportedEncodingException e) { + throw new PlaidClientsideException(e); + } catch (IOException e) { + throw new PlaidCommunicationsException(e); + } + } + + @Override + public HttpResponseWrapper doGet(PlaidHttpRequest request, Class clazz) { + try { + + List parameters = mapToNvps(request.getParameters()); + + URI uri = new URIBuilder(baseUri) + .setPath(request.getPath()) + .addParameters(parameters) + .build(); + + HttpGet get = new HttpGet(uri); + + addUserAgent(get); + + CloseableHttpResponse response = httpClient.execute(get); + + return handleResponse(get, response, clazz); + + } catch (UnsupportedEncodingException e) { + throw new PlaidClientsideException(e); + } catch (IOException e) { + throw new PlaidCommunicationsException(e); + } catch (URISyntaxException e) { + throw new PlaidClientsideException(e); + } + } + + @Override + public HttpResponseWrapper doDelete(PlaidHttpRequest request, Class clazz) { + try { + + List parameters = mapToNvps(request.getParameters()); + + URI uri = new URIBuilder(baseUri) + .setPath(request.getPath()) + .addParameters(parameters) + .build(); + + HttpDelete delete = new HttpDelete(uri); + + addUserAgent(delete); + + CloseableHttpResponse response = httpClient.execute(delete); + + return handleResponse(delete, response, clazz); + + } catch (UnsupportedEncodingException e) { + throw new PlaidClientsideException(e); + } catch (IOException e) { + throw new PlaidCommunicationsException(e); + } catch (URISyntaxException e) { + throw new PlaidClientsideException(e); + } + } + + @Override + public HttpResponseWrapper doPatch(PlaidHttpRequest request, Class clazz) { + + List parameters = mapToNvps(request.getParameters()); + + try { + HttpEntity entity = new UrlEncodedFormEntity(parameters, "UTF-8"); + HttpPatch patch = new HttpPatch(baseUri + request.getPath()); + patch.setEntity(entity); + + addUserAgent(patch); + + CloseableHttpResponse response = httpClient.execute(patch); + + return handleResponse(patch, response, clazz); + + } catch (UnsupportedEncodingException e) { + throw new PlaidClientsideException(e); + } catch (IOException e) { + throw new PlaidCommunicationsException(e); + } + } + + private void wireLog(HttpRequestBase request, CloseableHttpResponse response, JsonNode responseBody) { + if (wireLogger != null) { + wireLogger.logRequestResponsePair(request, response, responseBody); + } + } + + private HttpResponseWrapper handleResponse(HttpRequestBase request, CloseableHttpResponse response, + Class clazz) { + + HttpEntity responseEntity = response.getEntity(); + + try { + + int statusCode = response.getStatusLine().getStatusCode(); + JsonNode jsonBody = jsonMapper.readTree(responseEntity.getContent()); + EntityUtils.consume(responseEntity); + + wireLog(request, response, jsonBody); + + if (HttpStatus.SC_OK == statusCode) { + + T responseBody = jsonMapper.convertValue(jsonBody, clazz); + return HttpResponseWrapper.create(statusCode, responseBody); + + } else if (HttpStatus.SC_CREATED == statusCode) { + + MfaResponse mfaResponse = jsonMapper.convertValue(jsonBody, MfaResponse.class); + throw new PlaidMfaException(mfaResponse, statusCode); + + } else if (statusCode >= HttpStatus.SC_BAD_REQUEST) { + + ErrorResponse errorResponse = jsonMapper.convertValue(jsonBody, ErrorResponse.class); + throw new PlaidServersideException(errorResponse, statusCode); + + } else { + UnknownResponse unknownResponse = jsonMapper.convertValue(jsonBody, UnknownResponse.class); + throw new PlaidServersideUnknownResponseException(unknownResponse, statusCode); + } + + } catch (IllegalStateException | IOException e) { + + throw new PlaidCommunicationsException("Unable to interpret Plaid response", e); + } finally { + + try { + response.close(); + } catch (IOException e) { + + } + + } + + } + + private static List mapToNvps(Map params) { + List nvps = new ArrayList(); + for (Entry entry : params.entrySet()) { + nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); + } + return nvps; + } + + private static void addUserAgent(HttpMessage httpMessage) { + httpMessage.addHeader("User-Agent", "plaid-java " + LIBRARY_VERSION); + } + +} diff --git a/src/main/java/com/plaid/client/http/HttpDelegate.java b/src/main/java/com/plaid/client/http/HttpDelegate.java new file mode 100644 index 0000000..2b8c3e7 --- /dev/null +++ b/src/main/java/com/plaid/client/http/HttpDelegate.java @@ -0,0 +1,14 @@ +package com.plaid.client.http; + + +public interface HttpDelegate { + + HttpResponseWrapper doPost(PlaidHttpRequest request, Class clazz); + + HttpResponseWrapper doGet(PlaidHttpRequest request, Class clazz); + + HttpResponseWrapper doPatch(PlaidHttpRequest request, Class clazz); + + HttpResponseWrapper doDelete(PlaidHttpRequest request, Class clazz); + +} diff --git a/src/main/java/com/plaid/client/http/HttpResponseWrapper.java b/src/main/java/com/plaid/client/http/HttpResponseWrapper.java new file mode 100644 index 0000000..7d21799 --- /dev/null +++ b/src/main/java/com/plaid/client/http/HttpResponseWrapper.java @@ -0,0 +1,33 @@ +package com.plaid.client.http; + + +public class HttpResponseWrapper { + + private int httpStatusCode; + private T responseBody; + + public static HttpResponseWrapper create(int httpStatusCode, T responseBody) { + HttpResponseWrapper wrapper = new HttpResponseWrapper(); + + wrapper.setHttpStatusCode(httpStatusCode); + wrapper.setResponseBody(responseBody); + + return wrapper; + } + + public int getHttpStatusCode() { + return httpStatusCode; + } + + public void setHttpStatusCode(int httpStatusCode) { + this.httpStatusCode = httpStatusCode; + } + + public void setResponseBody(T responseBody) { + this.responseBody = responseBody; + } + + public T getResponseBody() { + return responseBody; + } +} diff --git a/src/main/java/com/plaid/client/http/PlaidHttpRequest.java b/src/main/java/com/plaid/client/http/PlaidHttpRequest.java new file mode 100644 index 0000000..e82f527 --- /dev/null +++ b/src/main/java/com/plaid/client/http/PlaidHttpRequest.java @@ -0,0 +1,43 @@ +package com.plaid.client.http; + +import java.util.HashMap; +import java.util.Map; + +public class PlaidHttpRequest { + + private String path; + private Map parameters; + private Integer timeout; + + public PlaidHttpRequest(String path) { + this.path = path; + this.parameters = new HashMap(); + } + + public PlaidHttpRequest(String path, Map parameters, Integer timeout) { + this.path = path; + this.parameters = parameters; + this.timeout = timeout; + } + + public PlaidHttpRequest addParameter(String key, String value) { + this.parameters.put(key, value); + return this; + } + + public String getPath() { + return path; + } + + public Map getParameters() { + return parameters; + } + + public Integer getTimeout() { + return timeout; + } + + public boolean hasTimeout() { + return timeout != null; + } +} diff --git a/src/main/java/com/plaid/client/http/WireLogger.java b/src/main/java/com/plaid/client/http/WireLogger.java new file mode 100644 index 0000000..841997a --- /dev/null +++ b/src/main/java/com/plaid/client/http/WireLogger.java @@ -0,0 +1,13 @@ +package com.plaid.client.http; + +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpRequestBase; + +import com.fasterxml.jackson.databind.JsonNode; + +public interface WireLogger { + + void logRequestResponsePair(HttpRequestBase request, CloseableHttpResponse response); + + void logRequestResponsePair(HttpRequestBase request, CloseableHttpResponse response, JsonNode jsonResponseBody); +} diff --git a/src/main/java/com/plaid/client/request/ConnectOptions.java b/src/main/java/com/plaid/client/request/ConnectOptions.java new file mode 100644 index 0000000..c982b5d --- /dev/null +++ b/src/main/java/com/plaid/client/request/ConnectOptions.java @@ -0,0 +1,62 @@ +package com.plaid.client.request; + +import com.fasterxml.jackson.annotation.JsonProperty; + + +public class ConnectOptions { + + private Boolean pretty; + private Boolean login; + private Boolean list; + private Boolean pending; + + private String webhook; + private String startDate; + private String endDate; + + public Boolean isPretty() { + return pretty; + } + public void setPretty(Boolean pretty) { + this.pretty = pretty; + } + public Boolean isLogin() { + return login; + } + public void setLogin(Boolean login) { + this.login = login; + } + public Boolean isList() { + return list; + } + public void setList(Boolean list) { + this.list = list; + } + public String getWebhook() { + return webhook; + } + public void setWebhook(String webhook) { + this.webhook = webhook; + } + @JsonProperty("start_date") + public String getStartDate() { + return startDate; + } + public void setStartDate(String startDate) { + this.startDate = startDate; + } + @JsonProperty("end_date") + public String getEndDate() { + return endDate; + } + public void setEndDate(String endDate) { + this.endDate = endDate; + } + public void setPending(Boolean pending) { + this.pending = pending; + } + public Boolean isPending() { + return pending; + } + +} diff --git a/src/main/java/com/plaid/client/request/Credentials.java b/src/main/java/com/plaid/client/request/Credentials.java new file mode 100644 index 0000000..f88eed8 --- /dev/null +++ b/src/main/java/com/plaid/client/request/Credentials.java @@ -0,0 +1,39 @@ +package com.plaid.client.request; + +public class Credentials { + + private String username; + private String password; + private String pin; + + public Credentials(String username, String password) { + // the json serializer will not include the pin when it is null + this(username, password, null); + } + + public Credentials(String username, String password, String pin) { + this.username = username; + this.password = password; + this.pin = pin; + } + + public String getUsername() { + return username; + } + public void setUsername(String username) { + this.username = username; + } + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + public String getPin() { + return pin; + } + public void setPin(String pin) { + this.pin = pin; + } + +} diff --git a/src/main/java/com/plaid/client/request/GetOptions.java b/src/main/java/com/plaid/client/request/GetOptions.java new file mode 100644 index 0000000..b1751bd --- /dev/null +++ b/src/main/java/com/plaid/client/request/GetOptions.java @@ -0,0 +1,66 @@ +package com.plaid.client.request; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonInclude(Include.NON_NULL) +public class GetOptions { + + private Boolean pending; + private String account; + private String last; + private String gte; + private String lte; + private Boolean includeOriginalDescription; + + public Boolean isPending() { + return pending; + } + + public void setPending(Boolean pending) { + this.pending = pending; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getLast() { + return last; + } + + public void setLast(String last) { + this.last = last; + } + + public String getGte() { + return gte; + } + + public void setGte(String gte) { + this.gte = gte; + } + + public String getLte() { + return lte; + } + + public void setLte(String lte) { + this.lte = lte; + } + + @JsonProperty("include_original_description") + public Boolean isIncludeOriginalDescription() { + return includeOriginalDescription; + } + + public void setIncludeOriginalDescription(Boolean includeOriginalDescription) { + this.includeOriginalDescription = includeOriginalDescription; + } +} diff --git a/src/main/java/com/plaid/client/request/InfoOptions.java b/src/main/java/com/plaid/client/request/InfoOptions.java new file mode 100644 index 0000000..ca495a2 --- /dev/null +++ b/src/main/java/com/plaid/client/request/InfoOptions.java @@ -0,0 +1,14 @@ +package com.plaid.client.request; + +public class InfoOptions { + + private Boolean list; + + public Boolean isList() { + return list; + } + public void setList(Boolean list) { + this.list = list; + } + +} diff --git a/src/main/java/com/plaid/client/request/MappingOptions.java b/src/main/java/com/plaid/client/request/MappingOptions.java new file mode 100644 index 0000000..75a3524 --- /dev/null +++ b/src/main/java/com/plaid/client/request/MappingOptions.java @@ -0,0 +1,23 @@ +package com.plaid.client.request; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class MappingOptions { + + private Boolean pretty; + private Boolean fullMatch; + + public Boolean isPretty() { + return pretty; + } + public void setPretty(Boolean pretty) { + this.pretty = pretty; + } + @JsonProperty("full_match") + public Boolean isFullMatch() { + return fullMatch; + } + public void setFullMatch(Boolean fullMatch) { + this.fullMatch = fullMatch; + } +} diff --git a/src/main/java/com/plaid/client/response/Account.java b/src/main/java/com/plaid/client/response/Account.java new file mode 100644 index 0000000..b647760 --- /dev/null +++ b/src/main/java/com/plaid/client/response/Account.java @@ -0,0 +1,156 @@ +package com.plaid.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class Account { + + private String id; + private String item; + private String userId; + + private Balance balance; + private AccountMeta meta; + private AccountNumbers numbers; + + private String institutionType; + private String type; + private String subtype; + + @JsonProperty("_id") + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + @JsonProperty("_item") + public String getItem() { + return item; + } + public void setItem(String item) { + this.item = item; + } + @JsonProperty("_user") + public String getUserId() { + return userId; + } + public void setUserId(String userId) { + this.userId = userId; + } + public Balance getBalance() { + return balance; + } + public void setBalance(Balance balance) { + this.balance = balance; + } + public AccountMeta getMeta() { + return meta; + } + public void setMeta(AccountMeta meta) { + this.meta = meta; + } + public AccountNumbers getNumbers() { + return numbers; + } + public void setNumbers(AccountNumbers numbers) { + this.numbers = numbers; + } + @JsonProperty("institution_type") + public String getInstitutionType() { + return institutionType; + } + public void setInstitutionType(String institutionType) { + this.institutionType = institutionType; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public String getSubtype() { + return subtype; + } + public void setSubtype(String subtype) { + this.subtype = subtype; + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public final static class Balance { + private Double available; + private Double current; + + public Double getAvailable() { + return available; + } + public void setAvailable(Double available) { + this.available = available; + } + public Double getCurrent() { + return current; + } + public void setCurrent(Double current) { + this.current = current; + } + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public final static class AccountMeta { + private Double limit; + private String name; + private String number; + + public Double getLimit() { + return limit; + } + public void setLimit(Double limit) { + this.limit = limit; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getNumber() { + return number; + } + public void setNumber(String number) { + this.number = number; + } + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public final static class AccountNumbers { + private String routing; + private String account; + private String wireRouting; + + public String getRouting() { + return routing; + } + + public void setRouting(String routing) { + this.routing = routing; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getWireRouting() { + return wireRouting; + } + + public void setWireRouting(String wireRouting) { + this.wireRouting = wireRouting; + } + } + +} diff --git a/src/main/java/com/plaid/client/response/AccountsResponse.java b/src/main/java/com/plaid/client/response/AccountsResponse.java new file mode 100644 index 0000000..8d03622 --- /dev/null +++ b/src/main/java/com/plaid/client/response/AccountsResponse.java @@ -0,0 +1,20 @@ +package com.plaid.client.response; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class AccountsResponse extends PlaidUserResponse { + + protected List accounts; + + public List getAccounts() { + return accounts; + } + + public void setAccounts(List accounts) { + this.accounts = accounts; + } + +} diff --git a/src/main/java/com/plaid/client/response/CategoriesResponse.java b/src/main/java/com/plaid/client/response/CategoriesResponse.java new file mode 100644 index 0000000..97d8977 --- /dev/null +++ b/src/main/java/com/plaid/client/response/CategoriesResponse.java @@ -0,0 +1,20 @@ +package com.plaid.client.response; + +import java.util.Arrays; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class CategoriesResponse { + + private List categories; + + public CategoriesResponse(Category[] categories) { + this.categories = Arrays.asList(categories); + } + + public List getCategories() { + return categories; + } +} diff --git a/src/main/java/com/plaid/client/response/Category.java b/src/main/java/com/plaid/client/response/Category.java new file mode 100644 index 0000000..f209f27 --- /dev/null +++ b/src/main/java/com/plaid/client/response/Category.java @@ -0,0 +1,56 @@ +package com.plaid.client.response; + + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class Category { + + private String id; + private List hierarchy; + private List mappings; + + @JsonProperty("_id") + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public List getHierarchy() { + return hierarchy; + } + public void setHierarchy(List hierarchy) { + this.hierarchy = hierarchy; + } + public List getMappings() { + return mappings; + } + public void setMappings(List mappings) { + this.mappings = mappings; + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public final static class Mapping { + private String mapType; + private List hierarchy; + + @JsonProperty("map_type") + public String getMapType() { + return mapType; + } + public void setMapType(String mapType) { + this.mapType = mapType; + } + public List getHierarchy() { + return hierarchy; + } + public void setHierarchy(List hierarchy) { + this.hierarchy = hierarchy; + } + } + +} diff --git a/src/main/java/com/plaid/client/response/ErrorResponse.java b/src/main/java/com/plaid/client/response/ErrorResponse.java new file mode 100644 index 0000000..3188360 --- /dev/null +++ b/src/main/java/com/plaid/client/response/ErrorResponse.java @@ -0,0 +1,30 @@ +package com.plaid.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class ErrorResponse { + + private Integer code; + private String message; + private String resolve; + + public Integer getCode() { + return code; + } + public void setCode(Integer code) { + this.code = code; + } + public String getMessage() { + return message; + } + public void setMessage(String message) { + this.message = message; + } + public String getResolve() { + return resolve; + } + public void setResolve(String resolve) { + this.resolve = resolve; + } +} diff --git a/src/main/java/com/plaid/client/response/ExchangeTokenResponse.java b/src/main/java/com/plaid/client/response/ExchangeTokenResponse.java new file mode 100644 index 0000000..5cb9159 --- /dev/null +++ b/src/main/java/com/plaid/client/response/ExchangeTokenResponse.java @@ -0,0 +1,30 @@ +package com.plaid.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class ExchangeTokenResponse { + + protected String accessToken; + protected String stripeBankAccountToken; + + @JsonProperty("access_token") + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + @JsonProperty("stripe_bank_account_token") + public String getStripeBankAccountToken() { + return stripeBankAccountToken; + } + + public void setStripeBankAccountToken(String bankAccountToken) { + this.stripeBankAccountToken = bankAccountToken; + } + +} diff --git a/src/main/java/com/plaid/client/response/InfoResponse.java b/src/main/java/com/plaid/client/response/InfoResponse.java new file mode 100644 index 0000000..207b079 --- /dev/null +++ b/src/main/java/com/plaid/client/response/InfoResponse.java @@ -0,0 +1,162 @@ +package com.plaid.client.response; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class InfoResponse extends PlaidUserResponse { + + private List accounts; + private Info info; + + public List getAccounts() { + return accounts; + } + + public void setAccounts(List accounts) { + this.accounts = accounts; + } + + public Info getInfo() { + return info; + } + + public void setInfo(Info info) { + this.info = info; + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public static final class Info { + private List names; + private List emails; + private List phoneNumbers; + private List
addresses; + + public List getNames() { + return names; + } + public void setNames(List names) { + this.names = names; + } + public List getEmails() { + return emails; + } + public void setEmails(List emails) { + this.emails = emails; + } + @JsonProperty("phone_numbers") + public List getPhoneNumbers() { + return phoneNumbers; + } + public void setPhoneNumbers(List phoneNumbers) { + this.phoneNumbers = phoneNumbers; + } + public List
getAddresses() { + return addresses; + } + public void setAddresses(List
addresses) { + this.addresses = addresses; + } + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public static final class Email { + private String data; + private String type; + + public String getData() { + return data; + } + public void setData(String data) { + this.data = data; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public static final class PhoneNumber { + private String data; + private String type; + private Boolean primary; + + public String getData() { + return data; + } + public void setData(String data) { + this.data = data; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public Boolean isPrimary() { + return primary; + } + public void setPrimary(Boolean primary) { + this.primary = primary; + } + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public static final class Address { + private Boolean primary; + private AddressDetails addressDetails; + + public Boolean getPrimary() { + return primary; + } + public void setPrimary(Boolean primary) { + this.primary = primary; + } + @JsonProperty("address") + public AddressDetails getAddressDetails() { + return addressDetails; + } + public void setAddressDetails(AddressDetails addressDetails) { + this.addressDetails = addressDetails; + } + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public static final class AddressDetails { + private String street; + private String city; + private String state; + private String zip; + + public String getStreet() { + return street; + } + public void setStreet(String street) { + this.street = street; + } + public String getCity() { + return city; + } + public void setCity(String city) { + this.city = city; + } + public String getState() { + return state; + } + public void setState(String state) { + this.state = state; + } + public String getZip() { + return zip; + } + public void setZip(String zip) { + this.zip = zip; + } + } + +} diff --git a/src/main/java/com/plaid/client/response/Institution.java b/src/main/java/com/plaid/client/response/Institution.java new file mode 100644 index 0000000..8b2e0a6 --- /dev/null +++ b/src/main/java/com/plaid/client/response/Institution.java @@ -0,0 +1,110 @@ +package com.plaid.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class Institution { + + private CredentialNames credentialNames; + private Boolean hasMfa; + private String id; + private List mfaTypes; + private String name; + private List products; + private String type; + + @JsonProperty("credentials") + public CredentialNames getCredentialNames() { + return credentialNames; + } + + public void setCredentialNames(CredentialNames credentialNames) { + this.credentialNames = credentialNames; + } + + @JsonProperty("has_mfa") + public void setHasMfa(boolean hasMfa) { + this.hasMfa = hasMfa; + } + + public boolean isHasMfa() { + return hasMfa; + } + + @JsonProperty("mfa") + public List getMfaTypes() { + return mfaTypes; + } + + public void setMfaTypes(List mfaTypes) { + this.mfaTypes = mfaTypes; + } + + public List getProducts() { + return products; + } + + public void setProducts(List products) { + this.products = products; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public static final class CredentialNames { + + private String username; + private String password; + private String pin; + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPin() { + return pin; + } + + public void setPin(String pin) { + this.pin = pin; + } + } + +} diff --git a/src/main/java/com/plaid/client/response/InstitutionsResponse.java b/src/main/java/com/plaid/client/response/InstitutionsResponse.java new file mode 100644 index 0000000..227d074 --- /dev/null +++ b/src/main/java/com/plaid/client/response/InstitutionsResponse.java @@ -0,0 +1,17 @@ +package com.plaid.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class InstitutionsResponse { + + private Institution[] institutions; + + public InstitutionsResponse(Institution[] institutions) { + this.institutions = institutions; + } + + public Institution[] getInstitutions() { + return institutions; + } +} diff --git a/src/main/java/com/plaid/client/response/LongTailInstitution.java b/src/main/java/com/plaid/client/response/LongTailInstitution.java new file mode 100644 index 0000000..c13e688 --- /dev/null +++ b/src/main/java/com/plaid/client/response/LongTailInstitution.java @@ -0,0 +1,26 @@ +package com.plaid.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class LongTailInstitution extends Institution { + + private String currencyCode; + private String url; + + public String getCurrencyCode() { + return currencyCode; + } + + public void setCurrencyCode(String currencyCode) { + this.currencyCode = currencyCode; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/src/main/java/com/plaid/client/response/LongTailInstitutionsResponse.java b/src/main/java/com/plaid/client/response/LongTailInstitutionsResponse.java new file mode 100644 index 0000000..851618e --- /dev/null +++ b/src/main/java/com/plaid/client/response/LongTailInstitutionsResponse.java @@ -0,0 +1,20 @@ +package com.plaid.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class LongTailInstitutionsResponse { + + private Integer totalCount; + private LongTailInstitution[] results; + + @JsonProperty("total_count") + public Integer getTotalCount() { + return totalCount; + } + + public LongTailInstitution[] getResults() { + return results; + } +} diff --git a/src/main/java/com/plaid/client/response/MessageResponse.java b/src/main/java/com/plaid/client/response/MessageResponse.java new file mode 100644 index 0000000..02fbd26 --- /dev/null +++ b/src/main/java/com/plaid/client/response/MessageResponse.java @@ -0,0 +1,17 @@ +package com.plaid.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class MessageResponse { + + private String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/com/plaid/client/response/MfaResponse.java b/src/main/java/com/plaid/client/response/MfaResponse.java new file mode 100644 index 0000000..dea4248 --- /dev/null +++ b/src/main/java/com/plaid/client/response/MfaResponse.java @@ -0,0 +1,183 @@ +package com.plaid.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonSubTypes.Type; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.plaid.client.response.MfaResponse.DeviceChoiceMfaResponse; +import com.plaid.client.response.MfaResponse.DeviceListMfaResponse; +import com.plaid.client.response.MfaResponse.QuestionsMfaResponse; +import com.plaid.client.response.MfaResponse.SelectionsMfaResponse; + +@JsonIgnoreProperties(ignoreUnknown=true) +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "type") +@JsonSubTypes({ + @Type(value = DeviceChoiceMfaResponse.class, name = MfaResponse.DEVICE), + @Type(value = DeviceListMfaResponse.class, name = MfaResponse.LIST), + @Type(value = QuestionsMfaResponse.class, name = MfaResponse.QUESTIONS), + @Type(value = SelectionsMfaResponse.class, name = MfaResponse.SELECTIONS)}) +public abstract class MfaResponse extends PlaidUserResponse { + + public final static String DEVICE = "device"; + public final static String LIST = "list"; + public final static String QUESTIONS = "questions"; + public final static String SELECTIONS = "selections"; + + protected String type; + + public abstract String getType(); + + @JsonIgnoreProperties(ignoreUnknown=true) + public final static class DeviceChoiceMfaResponse extends MfaResponse { + + private Message deviceChoiceSentMessage; + + @JsonProperty("mfa") + public Message getDeviceChoiceSentMessage() { + return deviceChoiceSentMessage; + } + + public void setDeviceChoiceSentMessage(Message deviceChoiceSentMessage) { + this.deviceChoiceSentMessage = deviceChoiceSentMessage; + } + + @Override + public String getType() { + return DEVICE; + } + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public final static class QuestionsMfaResponse extends MfaResponse { + + private Question[] questions; + + @JsonProperty("mfa") + public Question[] getQuestions() { + return questions; + } + + public void setQuestions(Question[] questions) { + this.questions = questions; + } + + @Override + public String getType() { + return QUESTIONS; + } + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public final static class SelectionsMfaResponse extends MfaResponse { + + private Selection[] selections; + + @JsonProperty("mfa") + public Selection[] getSelections() { + return selections; + } + + public void setSelections(Selection[] selections) { + this.selections = selections; + } + + @Override + public String getType() { + return SELECTIONS; + } + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public final static class DeviceListMfaResponse extends MfaResponse { + + private DeviceType[] deviceTypes; + + @JsonProperty("mfa") + public DeviceType[] getDeviceTypes() { + return deviceTypes; + } + + public void setDeviceTypes(DeviceType[] deviceTypes) { + this.deviceTypes = deviceTypes; + } + + @Override + public String getType() { + return LIST; + } + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public final static class Message { + private String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public final static class Question { + private String question; + + public String getQuestion() { + return question; + } + + public void setQuestion(String question) { + this.question = question; + } + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public final static class Selection { + private String question; + private String[] answers; + + public String[] getAnswers() { + return answers; + } + + public String getQuestion() { + return question; + } + + public void setAnswers(String[] answers) { + this.answers = answers; + } + + public void setQuestion(String question) { + this.question = question; + } + } + + @JsonIgnoreProperties(ignoreUnknown=true) + public final static class DeviceType { + private String mask; + private String type; + + public String getMask() { + return mask; + } + + public void setMask(String mask) { + this.mask = mask; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + } +} diff --git a/src/main/java/com/plaid/client/response/PlaidUserResponse.java b/src/main/java/com/plaid/client/response/PlaidUserResponse.java new file mode 100644 index 0000000..117e4f7 --- /dev/null +++ b/src/main/java/com/plaid/client/response/PlaidUserResponse.java @@ -0,0 +1,43 @@ +package com.plaid.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class PlaidUserResponse { + + protected String accessToken; + protected String newAccessToken; + protected String stripeBankAccountToken; + + @JsonProperty("access_token") + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + @JsonProperty("stripe_bank_account_token") + public String getStripeBankAccountToken() { + return stripeBankAccountToken; + } + + public void setStripeBankAccountToken(String stripeBankAccountToken) { + this.stripeBankAccountToken = stripeBankAccountToken; + } + + /** + * Returns the user's new access token in the new format. Plaid announced this migration on 10/31/2014 through their developer newsletter. + * If this field is not blank, then you should update the records for this user with the new access token. + */ + @JsonProperty("new_access_token") + public String getNewAccessToken() { + return newAccessToken; + } + + public void setNewAccessToken(String newAccessToken) { + this.newAccessToken = newAccessToken; + } +} diff --git a/src/main/java/com/plaid/client/response/Transaction.java b/src/main/java/com/plaid/client/response/Transaction.java new file mode 100644 index 0000000..253d53a --- /dev/null +++ b/src/main/java/com/plaid/client/response/Transaction.java @@ -0,0 +1,278 @@ +package com.plaid.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.datatype.joda.deser.LocalDateDeserializer; +import org.joda.time.LocalDate; + +import java.util.List; +import java.util.Map; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Transaction { + + private String id; + private String accountId; + private String entityId; + private String categoryId; + private String pendingTransactionId; + + private String name; + private String originalDescription; + private List category; + private Double amount; + private LocalDate date; + private Map type; + + private Score score; + private TransactionMeta meta; + + private Boolean pending; + + @JsonProperty("_id") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @JsonProperty("_account") + public String getAccountId() { + return accountId; + } + + public void setAccountId(String accountId) { + this.accountId = accountId; + } + + @JsonProperty("_entity") + public String getEntityId() { + return entityId; + } + + public void setEntityId(String entityId) { + this.entityId = entityId; + } + + @JsonProperty("category_id") + public String getCategoryId() { + return categoryId; + } + + public void setCategoryId(String categoryId) { + this.categoryId = categoryId; + } + + @JsonProperty("_pendingTransaction") + public String getPendingTransactionId() { + return pendingTransactionId; + } + + public void setPendingTransactionId(String pendingTransactionId) { + this.pendingTransactionId = pendingTransactionId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @JsonProperty("original_description") + public String getOriginalDescription() { + return originalDescription; + } + + public void setOriginalDescription(String originalDescription) { + this.originalDescription = originalDescription; + } + + public List getCategory() { + return category; + } + + public void setCategory(List category) { + this.category = category; + } + + public Double getAmount() { + return amount; + } + + public void setAmount(Double amount) { + this.amount = amount; + } + + @JsonDeserialize(using = LocalDateDeserializer.class) + public LocalDate getDate() { + return date; + } + + public void setDate(LocalDate date) { + this.date = date; + } + + public Map getType() { + return type; + } + + public void setType(Map type) { + this.type = type; + } + + public Score getScore() { + return score; + } + + public void setScore(Score score) { + this.score = score; + } + + public TransactionMeta getMeta() { + return meta; + } + + public void setMeta(TransactionMeta meta) { + this.meta = meta; + } + + public Boolean isPending() { + return pending; + } + + public void setPending(Boolean pending) { + this.pending = pending; + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public final static class Score { + private Double master; + private Map detail; + + public Double getMaster() { + return master; + } + + public void setMaster(Double master) { + this.master = master; + } + + public Map getDetail() { + return detail; + } + + public void setDetail(Map detail) { + this.detail = detail; + } + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public final static class TransactionMeta { + private Location location; + private Map contact; + private Map ids; + + public Location getLocation() { + return location; + } + + public void setLocation(Location location) { + this.location = location; + } + + public Map getContact() { + return contact; + } + + public void setContact(Map contact) { + this.contact = contact; + } + + public Map getIds() { + return ids; + } + + public void setIds(Map ids) { + this.ids = ids; + } + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public final static class Location { + private Coordinates coordinates; + private String zip; + private String state; + private String city; + private String address; + + public Coordinates getCoordinates() { + return coordinates; + } + + public void setCoordinates(Coordinates coordinates) { + this.coordinates = coordinates; + } + + public String getZip() { + return zip; + } + + public void setZip(String zip) { + this.zip = zip; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public final static class Coordinates { + private Double longitude; + private Double latitude; + + @JsonProperty("lon") + public Double getLongitude() { + return longitude; + } + + public void setLongitude(Double longitude) { + this.longitude = longitude; + } + + @JsonProperty("lat") + public Double getLatitude() { + return latitude; + } + + public void setLatitude(Double latitude) { + this.latitude = latitude; + } + } + +} diff --git a/src/main/java/com/plaid/client/response/TransactionsResponse.java b/src/main/java/com/plaid/client/response/TransactionsResponse.java new file mode 100644 index 0000000..c05d1ee --- /dev/null +++ b/src/main/java/com/plaid/client/response/TransactionsResponse.java @@ -0,0 +1,20 @@ +package com.plaid.client.response; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown=true) +public class TransactionsResponse extends AccountsResponse { + + protected List transactions; + + public List getTransactions() { + return transactions; + } + + public void setTransactions(List transactions) { + this.transactions = transactions; + } + +} diff --git a/src/main/java/com/plaid/client/response/UnknownResponse.java b/src/main/java/com/plaid/client/response/UnknownResponse.java new file mode 100644 index 0000000..d10d55e --- /dev/null +++ b/src/main/java/com/plaid/client/response/UnknownResponse.java @@ -0,0 +1,34 @@ +package com.plaid.client.response; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class UnknownResponse { + private Integer code; + private String message; + private String resolve; + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getResolve() { + return resolve; + } + + public void setResolve(String resolve) { + this.resolve = resolve; + } +} diff --git a/src/test/java/com/plaid/client/PlaidPublicClientTest.java b/src/test/java/com/plaid/client/PlaidPublicClientTest.java new file mode 100644 index 0000000..0a2c287 --- /dev/null +++ b/src/test/java/com/plaid/client/PlaidPublicClientTest.java @@ -0,0 +1,84 @@ +package com.plaid.client; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; +import java.util.Map; + +import com.plaid.client.exception.PlaidClientsideException; +import com.plaid.client.response.LongTailInstitutionsResponse; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.junit.Before; +import org.junit.Test; + +import com.plaid.client.http.ApacheHttpClientHttpDelegate; +import com.plaid.client.http.HttpDelegate; +import com.plaid.client.response.CategoriesResponse; +import com.plaid.client.response.Institution; +import com.plaid.client.response.InstitutionsResponse; + +public class PlaidPublicClientTest { + + private CloseableHttpClient httpClient; + private HttpDelegate httpDelegate; + private PlaidPublicClient plaidPublicClientWithoutCredentials; + private PlaidPublicClient plaidPublicClientWithCredentials; + + //@Rule + //public WireMockRule wireMockRule = new WireMockRule(8089); + + @Before + public void setup() { + httpClient = HttpClients.custom().disableContentCompression().useSystemProperties().build(); + //httpDelegate = new ApacheHttpClientHttpDelegate("http://localhost:8089", httpClient); + HttpDelegate httpDelegate = new ApacheHttpClientHttpDelegate("https://tartan.plaid.com", httpClient); + plaidPublicClientWithoutCredentials = new DefaultPlaidPublicClient.Builder() + .withHttpDelegate(httpDelegate) + .build(); + + plaidPublicClientWithCredentials = new DefaultPlaidPublicClient.Builder() + .withHttpDelegate(httpDelegate) + .withClientId("test_id") + .withSecret("test_secret") + .build(); + } + + @Test + public void testGetAllCategories() { + CategoriesResponse categoriesResponse = plaidPublicClientWithoutCredentials.getAllCategories(); + assertTrue(categoriesResponse.getCategories().size() > 0); + } + + @Test + public void testGetInstitution() { + Institution institution = plaidPublicClientWithoutCredentials.getInstitution("bofa"); + assertEquals("Bank of America", institution.getName()); + } + + @Test + public void testGetAllInstitutions() { + InstitutionsResponse instResponse = plaidPublicClientWithoutCredentials.getAllInstitutions(); + assertNotNull(instResponse); + Institution[] institutions = instResponse.getInstitutions(); + Map map = new HashMap<>(); + for (Institution institution : institutions) { + map.put(institution.getName(), institution); + } + + assertNotNull(map.get("Bank of America")); + } + + @Test(expected = PlaidClientsideException.class) + public void testGetAllLongTailInstitutionsRequireCredentials() throws Exception { + plaidPublicClientWithoutCredentials.getAllLongTailInstitutions(0, 10); + } + + @Test + public void testGetAllLongTailInstitutions() throws Exception { + LongTailInstitutionsResponse response = plaidPublicClientWithCredentials.getAllLongTailInstitutions(0, 10); + assertEquals(10, response.getResults().length); + } +} diff --git a/src/test/java/com/plaid/client/PlaidUserClientTest.java b/src/test/java/com/plaid/client/PlaidUserClientTest.java new file mode 100644 index 0000000..2e78bc7 --- /dev/null +++ b/src/test/java/com/plaid/client/PlaidUserClientTest.java @@ -0,0 +1,195 @@ +package com.plaid.client; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.apache.http.HttpStatus; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.plaid.client.exception.PlaidMfaException; +import com.plaid.client.exception.PlaidServersideException; +import com.plaid.client.http.ApacheHttpClientHttpDelegate; +import com.plaid.client.http.HttpDelegate; +import com.plaid.client.request.ConnectOptions; +import com.plaid.client.request.Credentials; +import com.plaid.client.response.AccountsResponse; +import com.plaid.client.response.InfoResponse; +import com.plaid.client.response.MessageResponse; +import com.plaid.client.response.MfaResponse; +import com.plaid.client.response.MfaResponse.DeviceChoiceMfaResponse; +import com.plaid.client.response.MfaResponse.DeviceListMfaResponse; +import com.plaid.client.response.TransactionsResponse; +import com.plaid.client.response.PlaidUserResponse; + +public class PlaidUserClientTest { + + private CloseableHttpClient httpClient; + private HttpDelegate httpDelegate; + private PlaidUserClient plaidUserClient; + + // @Rule + // public WireMockRule wireMockRule = new WireMockRule(8089); + + @Before + public void setup() { + //httpClient = HttpClients.createDefault(); + httpClient = HttpClients.custom().disableContentCompression().useSystemProperties().build(); + //httpDelegate = new ApacheHttpClientHttpDelegate("http://localhost:8089", httpClient); + httpDelegate = new ApacheHttpClientHttpDelegate("https://tartan.plaid.com", httpClient); + plaidUserClient = new DefaultPlaidUserClient.Builder() + .withHttpDelegate(httpDelegate) + .withClientId("test_id") + .withSecret("test_secret") + .build(); + } + + @Test + public void testAddAmexUser() { + Credentials testCredentials = new Credentials("plaid_test", "plaid_good"); + TransactionsResponse response = plaidUserClient.addUser(testCredentials, "amex", "test@test.com", null); + + assertEquals("test_amex",response.getAccessToken()); + assertTrue(response.getAccounts().size() > 0); + assertTrue(response.getTransactions().size() > 0); + } + + @Test + public void testAddChaseUserListMfa() { + + try { + Credentials testCredentials = new Credentials("plaid_test", "plaid_good"); + ConnectOptions options = new ConnectOptions(); + options.setList(true); + TransactionsResponse response = plaidUserClient.addUser(testCredentials, "chase", "test@test.com", options); + } + catch (PlaidMfaException e) { + + MfaResponse mfaResponse = e.getMfaResponse(); + assertNotNull(mfaResponse); + assertEquals("list", mfaResponse.getType()); + assertEquals("test_chase", mfaResponse.getAccessToken()); + assertTrue(mfaResponse instanceof DeviceListMfaResponse); + } + } + + @Test + public void testAddChaseUserWithMfaStep() { + + try { + Credentials testCredentials = new Credentials("plaid_test", "plaid_good"); + ConnectOptions options = new ConnectOptions(); + options.setLogin(true); + plaidUserClient.addUser(testCredentials, "chase", "test@test.com", options); + } + catch (PlaidMfaException e) { + + MfaResponse mfaResponse = e.getMfaResponse(); + assertNotNull(mfaResponse); + assertEquals("test_chase", mfaResponse.getAccessToken()); + assertEquals("device", mfaResponse.getType()); + assertTrue(mfaResponse instanceof DeviceChoiceMfaResponse); + + TransactionsResponse response = plaidUserClient.mfaConnectStep("1234", "chase"); + assertEquals("test_chase",response.getAccessToken()); + assertTrue(response.getAccounts().size() > 0); + assertTrue(response.getTransactions().size() > 0); + } + } + + + @Test + public void testInfoWellsFargo() { + Credentials testCredentials = new Credentials("plaid_test", "plaid_good"); + InfoResponse response = plaidUserClient.info(testCredentials, "wells", null); + + assertEquals("test_wells",response.getAccessToken()); + assertNotNull(response.getInfo()); + } + + @Test + public void testUpdateTransactions() { + + plaidUserClient.setAccessToken("test_wells"); + TransactionsResponse response = plaidUserClient.updateTransactions(); + + assertEquals("test_wells",response.getAccessToken()); + assertTrue(response.getAccounts().size() > 0); + assertTrue(response.getTransactions().size() > 0); + } + + @Test + public void testUpdateAuth() { + + plaidUserClient.setAccessToken("test_wells"); + AccountsResponse response = plaidUserClient.updateAuth(); + + assertEquals("test_wells",response.getAccessToken()); + assertTrue(response.getAccounts().size() > 0); + assertNotNull(response.getAccounts().get(0).getNumbers()); + } + + @Test + public void testCheckBalance() { + + plaidUserClient.setAccessToken("test_wells"); + AccountsResponse response = plaidUserClient.checkBalance(); + assertEquals("test_wells",response.getAccessToken()); + assertTrue(response.getAccounts().size() > 0); + } + + @Test + public void testAddProduct() { + + plaidUserClient.setAccessToken("test_wells"); + AccountsResponse response = plaidUserClient.addProduct("auth", null); + assertEquals("test_wells",response.getAccessToken()); + assertTrue(response.getAccounts().size() > 0); + } + + @Test + // Not testable with WireMock since HTTP PATCH is unsupported + public void testUpdateCredentials() { + Credentials testCredentials = new Credentials("plaid_test", "plaid_good"); + plaidUserClient.setAccessToken("test_amex"); + TransactionsResponse response = plaidUserClient.updateCredentials(testCredentials, "amex"); + + assertEquals("test_amex",response.getAccessToken()); + assertTrue(response.getAccounts().size() > 0); +// assertTrue(response.getTransactions().size() > 0); + } + + @Test + public void testDeleteUser() { + plaidUserClient.setAccessToken("test_citi"); + MessageResponse response = plaidUserClient.deleteUser(); + + assertEquals("Successfully removed from your account", response.getMessage()); + } + + @Test + public void testExchangeTokenSuccess() { + PlaidUserResponse response = plaidUserClient.exchangeToken("test,chase,connected"); + + assertEquals("test_chase", response.getAccessToken()); + } + + //Result is "1109 unauthorized product" in Sandbox + @Ignore + @Test + public void testExchangeTokenFailure() { + try { + plaidUserClient.exchangeToken("invalid_public_token"); + } catch (PlaidServersideException e) { + assertEquals(HttpStatus.SC_UNAUTHORIZED, e.getHttpStatusCode()); + assertEquals(1106, e.getErrorResponse().getCode().intValue()); + assertEquals("bad public_token", e.getErrorResponse().getMessage()); + } + } + + +} diff --git a/src/test/java/com/plaid/client/exception/PlaidServersideExceptionTest.java b/src/test/java/com/plaid/client/exception/PlaidServersideExceptionTest.java new file mode 100644 index 0000000..9b7fb78 --- /dev/null +++ b/src/test/java/com/plaid/client/exception/PlaidServersideExceptionTest.java @@ -0,0 +1,31 @@ +package com.plaid.client.exception; + +import com.plaid.client.response.ErrorResponse; +import org.apache.http.HttpStatus; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class PlaidServersideExceptionTest { + + @Test + public void setsExceptionMessage() throws Exception { + + ErrorResponse errorResponse = new ErrorResponse(); + errorResponse.setMessage("Bad Request"); + + PlaidServersideException exception = new PlaidServersideException(errorResponse, HttpStatus.SC_BAD_REQUEST); + + assertEquals("400: Bad Request", exception.getMessage()); + + } + + @Test + public void setsExceptionMessageForNullErrorResponse() throws Exception { + + PlaidServersideException exception = new PlaidServersideException(null, HttpStatus.SC_BAD_REQUEST); + + assertEquals("400: null", exception.getMessage()); + + } +} \ No newline at end of file diff --git a/src/test/resources/__files/body-category-6JpxC.json b/src/test/resources/__files/body-category-6JpxC.json new file mode 100644 index 0000000..ca7a94d --- /dev/null +++ b/src/test/resources/__files/body-category-6JpxC.json @@ -0,0 +1 @@ +[{"_id":"52544965f71e87d007000002","hierarchy":["Arts & Entertainment"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","General Entertainment",""]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Public Art",""]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","",""]},{"map_type":"factual","hierarchy":["Social","Entertainment","Bingo",""]},{"map_type":"factual","hierarchy":["Social","","",""]}]},{"_id":"52544965f71e87d007000003","hierarchy":["Arts & Entertainment","Arcades and Amusement Parks"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Arcade",""]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Theme Park",""]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Water Park",""]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Theme Park","Theme Park Ride / Attraction"]},{"map_type":"factual","hierarchy":["Social","Entertainment","Arcades and Amusement Parks",""]}]},{"_id":"52544965f71e87d007000004","hierarchy":["Arts & Entertainment","Art Dealers and Galleries"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Art Gallery",""]},{"map_type":"factual","hierarchy":["Social","Arts","Art Dealers and Galleries",""]},{"map_type":"factual","hierarchy":["Social","Arts","",""]}]},{"_id":"52544965f71e87d007000005","hierarchy":["Arts & Entertainment","Billiard and Pool"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Pool Hall",""]},{"map_type":"factual","hierarchy":["Social","Entertainment","Billiard and Pool",""]}]},{"_id":"52544965f71e87d007000006","hierarchy":["Arts & Entertainment","Bowling"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Bowling Alley",""]},{"map_type":"factual","hierarchy":["Social","Entertainment","Bowling",""]}]},{"_id":"52544965f71e87d007000007","hierarchy":["Arts & Entertainment","Casinos and Gaming"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Casino",""]},{"map_type":"factual","hierarchy":["Social","Entertainment","Casinos and Gaming",""]}]},{"_id":"52544965f71e87d007000008","hierarchy":["Arts & Entertainment","Circuses and Carnivals"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Fair",""]},{"map_type":"factual","hierarchy":["Social","Entertainment","Circuses",""]},{"map_type":"factual","hierarchy":["Social","Entertainment","Carnivals",""]}]},{"_id":"52544965f71e87d007000009","hierarchy":["Arts & Entertainment","Dance Halls and Saloons"],"mappings":[{"map_type":"factual","hierarchy":["Social","Entertainment","Dance Halls and Saloons",""]}]},{"_id":"52544965f71e87d00700000a","hierarchy":["Arts & Entertainment","Entertainment"],"mappings":[{"map_type":"factual","hierarchy":["Social","Entertainment","",""]},{"map_type":"factual","hierarchy":["Social","Entertainment","Ticket Sales",""]}]},{"_id":"52544965f71e87d00700000b","hierarchy":["Arts & Entertainment","Fairgrounds and Rodeos"],"mappings":[{"map_type":"factual","hierarchy":["Social","Entertainment","Fairgrounds and Rodeos",""]}]},{"_id":"52544965f71e87d00700000c","hierarchy":["Arts & Entertainment","Go Carts"],"mappings":[{"map_type":"factual","hierarchy":["Social","Entertainment","Go Carts",""]}]},{"_id":"52544965f71e87d00700000d","hierarchy":["Arts & Entertainment","Hookah Lounges"],"mappings":[{"map_type":"factual","hierarchy":["Social","Entertainment","Hookah Lounges",""]}]},{"_id":"52544965f71e87d00700000e","hierarchy":["Arts & Entertainment","Miniature Golf"],"mappings":[{"map_type":"factual","hierarchy":["Social","Entertainment","Miniature Golf",""]}]},{"_id":"52544965f71e87d00700000f","hierarchy":["Arts & Entertainment","Movie Theatres"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Movie Theater","Indie Movie Theater"]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Movie Theater",""]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Movie Theater","Multiplex"]},{"map_type":"factual","hierarchy":["Social","Entertainment","Movie Theatres",""]}]},{"_id":"52544965f71e87d007000010","hierarchy":["Arts & Entertainment","Museums"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Museum",""]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Museum","Art Museum"]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Museum","Planetarium"]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Museum","History Museum"]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Museum","Science Museum"]},{"map_type":"factual","hierarchy":["Social","Arts","Museums",""]}]},{"_id":"52544965f71e87d007000011","hierarchy":["Arts & Entertainment","Music and Show Venues"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Music Venue",""]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Performing Arts Venue","Dance Studio"]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Performing Arts Venue","Indie Theater"]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Comedy Club",""]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Concert Hall",""]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Performing Arts Venue","Theater"]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Performing Arts Venue","Opera House"]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Performing Arts Venue",""]},{"map_type":"factual","hierarchy":["Social","Entertainment","Music and Show Venues",""]}]},{"_id":"52544965f71e87d007000012","hierarchy":["Arts & Entertainment","Party Centers"],"mappings":[{"map_type":"factual","hierarchy":["Social","Entertainment","Party Centers",""]}]},{"_id":"52544965f71e87d007000013","hierarchy":["Arts & Entertainment","Psychics and Astrologers"],"mappings":[{"map_type":"factual","hierarchy":["Social","Entertainment","Psychics and Astrologers",""]}]},{"_id":"52544965f71e87d007000014","hierarchy":["Arts & Entertainment","Social Clubs"],"mappings":[{"map_type":"factual","hierarchy":["Social","Social Clubs","",""]}]},{"_id":"52544965f71e87d007000015","hierarchy":["Arts & Entertainment","Sports Venues"],"mappings":[]},{"_id":"52544965f71e87d007000016","hierarchy":["Community","Animal Shelter"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Animal Shelter",""]},{"map_type":"factual","hierarchy":["Community and Government","Animal Shelters and Humane Societies","",""]}]},{"_id":"52544965f71e87d007000017","hierarchy":["Community","Assisted Living Services"],"mappings":[{"map_type":"foursquare","hierarchy":["Residences","Assisted Living",""]},{"map_type":"factual","hierarchy":["Healthcare","Assisted Living Services","",""]}]},{"_id":"52544965f71e87d007000018","hierarchy":["Community","Assisted Living Services","Caretakers"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Assisted Living Services","Caretakers",""]}]},{"_id":"52544965f71e87d007000019","hierarchy":["Community","Assisted Living Services","Facilities and Nursing Homes"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Assisted Living Services","Facilities and Nursing Homes",""]}]},{"_id":"52544965f71e87d00700001a","hierarchy":["Community","Cemetery"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Cemetery",""]},{"map_type":"factual","hierarchy":["Community and Government","Cemeteries","",""]}]},{"_id":"52544965f71e87d00700001b","hierarchy":["Community","Day Care and Preschools"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Day Care and Preschools","",""]}]},{"_id":"52544965f71e87d00700001c","hierarchy":["Community","Disabled Persons Services"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Disabled Persons Services","",""]}]},{"_id":"52544965f71e87d00700001d","hierarchy":["Community","Drug and Alcohol Services"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Drug and Alcohol Services","",""]}]},{"_id":"52544965f71e87d00700001e","hierarchy":["Community","Education"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","School",""]},{"map_type":"factual","hierarchy":["Community and Government","Education","",""]}]},{"_id":"52544965f71e87d00700001f","hierarchy":["Community","Education","Adult Education"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Education","Adult Education",""]}]},{"_id":"52544965f71e87d007000020","hierarchy":["Community","Education","Art School"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","School","Music School"]},{"map_type":"factual","hierarchy":["Community and Government","Education","Art Lessons and Schools",""]}]},{"_id":"52544965f71e87d007000021","hierarchy":["Community","Education","Colleges and Universities"],"mappings":[{"map_type":"foursquare","hierarchy":["Colleges & Universities","",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Academic Building",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Academic Building","College Communications Building"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Academic Building","College History Building"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Academic Building","College Arts Building"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Academic Building","College Math Building"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Academic Building","College Engineering Building"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Academic Building","College Technology Building"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Academic Building","College Science Building"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Administrative Building",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Cafeteria",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Classroom",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Gym",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Auditorium",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Bookstore",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Residence Hall",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Rec Center",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Quad",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Library",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Lab",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Stadium",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Theater",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","Law School",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","General College & University",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","Fraternity House",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","Medical School",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","Community College",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","Trade School",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","University",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","Student Center",""]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","Sorority House",""]},{"map_type":"factual","hierarchy":["Community and Government","Education","Colleges and Universities",""]}]},{"_id":"52544965f71e87d007000022","hierarchy":["Community","Education","Computer Training"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Education","Computer Training",""]}]},{"_id":"52544965f71e87d007000023","hierarchy":["Community","Education","Culinary Lessons and Schools"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Education","Culinary Lessons and Schools",""]}]},{"_id":"52544965f71e87d007000024","hierarchy":["Community","Education","Driving Schools"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Education","Driving Schools",""]}]},{"_id":"52544965f71e87d007000025","hierarchy":["Community","Education","Fraternities and Sororities"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Education","Fraternities and Sororities",""]}]},{"_id":"52544965f71e87d007000026","hierarchy":["Community","Education","Primary and Secondary Schools"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","School","Middle School"]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","School","High School"]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","School","Elementary School"]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","School","Nursery School"]},{"map_type":"foursquare","hierarchy":["Shops & Services","Daycare",""]},{"map_type":"factual","hierarchy":["Community and Government","Education","Primary and Secondary Schools",""]}]},{"_id":"52544965f71e87d007000027","hierarchy":["Community","Education","Tutoring and Educational Services"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Education","Tutoring and Educational Services",""]}]},{"_id":"52544965f71e87d007000028","hierarchy":["Community","Education","Vocational Schools"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Education","Vocational Schools",""]}]},{"_id":"52544965f71e87d007000029","hierarchy":["Community","Government Departments and Agencies"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Government Building",""]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Government Building","Capitol Building"]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Government Building","Courthouse"]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Government Building","City Hall"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Embassy / Consulate",""]},{"map_type":"factual","hierarchy":["Community and Government","Government Departments and Agencies","",""]}]},{"_id":"52544965f71e87d00700002a","hierarchy":["Community","Government Lobbyists"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Government Lobbyists","",""]}]},{"_id":"52544965f71e87d00700002b","hierarchy":["Community","Housing Assistance and Shelters"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Housing Assistance and Shelters","",""]}]},{"_id":"52544965f71e87d00700002c","hierarchy":["Community","Law Enforcement"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Law Enforcement and Public Safety","",""]},{"map_type":"factual","hierarchy":["Community and Government","Law Enforcement and Public Safety","Rescue Services",""]}]},{"_id":"52544965f71e87d00700002d","hierarchy":["Community","Law Enforcement","Fire Stations"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Government Building","Fire Station"]},{"map_type":"factual","hierarchy":["Community and Government","Law Enforcement and Public Safety","Fire Stations",""]}]},{"_id":"52544965f71e87d00700002e","hierarchy":["Community","Law Enforcement","Police Stations"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Government Building","Police Station"]},{"map_type":"factual","hierarchy":["Community and Government","Law Enforcement and Public Safety","Police Stations",""]}]},{"_id":"52544965f71e87d00700002f","hierarchy":["Community","Libraries"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Library",""]},{"map_type":"factual","hierarchy":["Community and Government","Libraries","",""]}]},{"_id":"52544965f71e87d007000030","hierarchy":["Community","Military"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Military Base",""]},{"map_type":"factual","hierarchy":["Community and Government","Military","",""]},{"map_type":"factual","hierarchy":["Community and Government","Military","Bases",""]}]},{"_id":"52544965f71e87d007000031","hierarchy":["Community","Organizations and Associations"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Organizations and Associations","",""]}]},{"_id":"52544965f71e87d007000032","hierarchy":["Community","Organizations and Associations","Charities and Non-Profits"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Non-Profit",""]},{"map_type":"factual","hierarchy":["Community and Government","Organizations and Associations","Charities and Non-Profits",""]}]},{"_id":"52544965f71e87d007000033","hierarchy":["Community","Organizations and Associations","Environmental"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Organizations and Associations","Environmental",""]}]},{"_id":"52544965f71e87d007000034","hierarchy":["Community","Organizations and Associations","Youth Organizations"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Organizations and Associations","Youth Organizations",""]}]},{"_id":"52544965f71e87d007000035","hierarchy":["Community","Post Offices"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Post Office",""]},{"map_type":"factual","hierarchy":["Community and Government","Post Offices","",""]}]},{"_id":"52544965f71e87d007000036","hierarchy":["Community","Public and Social Services"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Public and Social Services","",""]}]},{"_id":"52544965f71e87d007000037","hierarchy":["Community","Religious"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Spiritual Center","Shrine"]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Spiritual Center",""]},{"map_type":"factual","hierarchy":["Community and Government","Religious","",""]}]},{"_id":"52544965f71e87d007000038","hierarchy":["Community","Religious","Churches"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Spiritual Center","Church"]},{"map_type":"factual","hierarchy":["Community and Government","Religious","Churches",""]}]},{"_id":"52544965f71e87d007000039","hierarchy":["Community","Religious","Mosques"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Spiritual Center","Mosque"]},{"map_type":"factual","hierarchy":["Community and Government","Religious","Mosques",""]}]},{"_id":"52544965f71e87d00700003a","hierarchy":["Community","Religious","Synagogues"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Spiritual Center","Synagogue"]},{"map_type":"factual","hierarchy":["Community and Government","Religious","Synagogues",""]}]},{"_id":"52544965f71e87d00700003b","hierarchy":["Community","Religious","Temple"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Spiritual Center","Temple"]},{"map_type":"factual","hierarchy":["Community and Government","Religious","Hindu Temples",""]},{"map_type":"factual","hierarchy":["Community and Government","Religious","Buddhist Temples",""]}]},{"_id":"52544965f71e87d00700003c","hierarchy":["Community","Senior Citizen Services"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Senior Citizen Services","",""]}]},{"_id":"52544965f71e87d00700003d","hierarchy":["Community","Senior Citizen Services","Retirement"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Senior Citizen Services","Retirement",""]}]},{"_id":"52544965f71e87d00700003e","hierarchy":["Community","Utilities"],"mappings":[{"map_type":"factual","hierarchy":["Community and Government","Utility Companies","",""]}]},{"_id":"52544965f71e87d00700003f","hierarchy":["Community"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","City",""]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Event Space",""]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Convention Center","Meeting Room"]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Convention Center",""]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Auditorium",""]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Factory",""]},{"map_type":"foursquare","hierarchy":["Residences","",""]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Voting Booth",""]},{"map_type":"foursquare","hierarchy":["Residences","Residential Building (Apartment / Condo)",""]},{"map_type":"foursquare","hierarchy":["Residences","Housing Development",""]},{"map_type":"foursquare","hierarchy":["Residences","Home (private)",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","EV Charging Station",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","Recycling Facility",""]},{"map_type":"factual","hierarchy":["Community and Government","","",""]}]},{"_id":"52544965f71e87d007000040","hierarchy":["Fees & Payments"],"mappings":[]},{"_id":"52544965f71e87d007000041","hierarchy":["Food & Drink","Breweries"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Brewery",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Breweries",""]}]},{"_id":"52544965f71e87d007000042","hierarchy":["Food & Drink","Internet Cafes"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Gaming Cafe",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","Internet Cafe",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Internet Cafes",""]}]},{"_id":"52544965f71e87d007000043","hierarchy":["Food & Drink","Nightlife","Adult Entertainment"],"mappings":[{"map_type":"foursquare","hierarchy":["Nightlife Spots","Strip Club",""]},{"map_type":"factual","hierarchy":["Social","Entertainment","Adult",""]}]},{"_id":"52544965f71e87d007000044","hierarchy":["Food & Drink","Nightlife","Bar"],"mappings":[{"map_type":"foursquare","hierarchy":["Nightlife Spots","Gay Bar",""]},{"map_type":"foursquare","hierarchy":["Nightlife Spots","Dive Bar",""]},{"map_type":"foursquare","hierarchy":["Nightlife Spots","Lounge",""]},{"map_type":"foursquare","hierarchy":["Nightlife Spots","Cocktail Bar",""]},{"map_type":"foursquare","hierarchy":["Nightlife Spots","Speakeasy",""]},{"map_type":"foursquare","hierarchy":["Nightlife Spots","Beer Garden",""]},{"map_type":"foursquare","hierarchy":["Nightlife Spots","Sake Bar",""]},{"map_type":"foursquare","hierarchy":["Nightlife Spots","Hotel Bar",""]},{"map_type":"foursquare","hierarchy":["Nightlife Spots","Bar",""]},{"map_type":"foursquare","hierarchy":["Nightlife Spots","Pub",""]},{"map_type":"foursquare","hierarchy":["Nightlife Spots","Hookah Bar",""]},{"map_type":"foursquare","hierarchy":["Nightlife Spots","Whisky Bar",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Ski Area","Apres Ski Bar"]},{"map_type":"factual","hierarchy":["Social","Bars","",""]}]},{"_id":"52544965f71e87d007000045","hierarchy":["Food & Drink","Nightlife","Hotel Lounge"],"mappings":[{"map_type":"factual","hierarchy":["Social","Bars","Hotel Lounges",""]}]},{"_id":"52544965f71e87d007000046","hierarchy":["Food & Drink","Nightlife","Jazz and Blues Cafe"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Music Venue","Jazz Club"]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Music Venue","Piano Bar"]},{"map_type":"factual","hierarchy":["Social","Bars","Jazz and Blues Cafes",""]}]},{"_id":"52544965f71e87d007000047","hierarchy":["Food & Drink","Nightlife","Karaoke"],"mappings":[{"map_type":"foursquare","hierarchy":["Nightlife Spots","Karaoke Bar",""]},{"map_type":"factual","hierarchy":["Social","Entertainment","Karaoke",""]}]},{"_id":"52544965f71e87d007000048","hierarchy":["Food & Drink","Nightlife","Night Clubs"],"mappings":[{"map_type":"foursquare","hierarchy":["Nightlife Spots","Nightclub",""]},{"map_type":"factual","hierarchy":["Social","Entertainment","Night Clubs",""]}]},{"_id":"52544965f71e87d007000049","hierarchy":["Food & Drink","Nightlife","Sports Bar"],"mappings":[{"map_type":"foursquare","hierarchy":["Nightlife Spots","Sports Bar",""]},{"map_type":"factual","hierarchy":["Social","Bars","Sports Bars",""]}]},{"_id":"52544965f71e87d00700004a","hierarchy":["Food & Drink","Nightlife","Strip Club"],"mappings":[]},{"_id":"52544965f71e87d00700004b","hierarchy":["Food & Drink","Nightlife","Wine Bar"],"mappings":[{"map_type":"foursquare","hierarchy":["Nightlife Spots","Wine Bar",""]},{"map_type":"factual","hierarchy":["Social","Bars","Wine Bars",""]}]},{"_id":"52544965f71e87d00700004c","hierarchy":["Food & Drink","Restaurants"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","",""]},{"map_type":"foursquare","hierarchy":["Food","Arepa Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Argentinian Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Molecular Gastronomy Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Sandwich Place",""]},{"map_type":"foursquare","hierarchy":["Food","Salad Place",""]},{"map_type":"foursquare","hierarchy":["Food","Snack Place",""]},{"map_type":"foursquare","hierarchy":["Food","Soup Place",""]},{"map_type":"foursquare","hierarchy":["Food","Tea Room",""]},{"map_type":"foursquare","hierarchy":["Food","Vietnamese Restaurant",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","Food & Drink Shop","Food Court"]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Buffets"]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","",""]}]},{"_id":"52544965f71e87d00700004d","hierarchy":["Food & Drink","Restaurants","Afghan"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Afghan Restaurant",""]}]},{"_id":"52544965f71e87d00700004e","hierarchy":["Food & Drink","Restaurants","African"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","African Restaurant",""]}]},{"_id":"52544965f71e87d00700004f","hierarchy":["Food & Drink","Restaurants","American"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","American Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Fried Chicken Joint",""]},{"map_type":"foursquare","hierarchy":["Food","Hot Dog Joint",""]},{"map_type":"foursquare","hierarchy":["Food","Mac & Cheese Joint",""]},{"map_type":"foursquare","hierarchy":["Food","New American Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Southern / Soul Food Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Wings Joint",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","American"]}]},{"_id":"52544965f71e87d007000050","hierarchy":["Food & Drink","Restaurants","Asian"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Asian Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Dim Sum Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Dumpling Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Malaysian Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Mongolian Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Ramen / Noodle House",""]}]},{"_id":"52544965f71e87d007000051","hierarchy":["Food & Drink","Restaurants","Australian"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Australian Restaurant",""]}]},{"_id":"52544965f71e87d007000052","hierarchy":["Food & Drink","Restaurants","Bagel Shop"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Bagel Shop",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Bagels and Donuts",""]}]},{"_id":"52544965f71e87d007000053","hierarchy":["Food & Drink","Restaurants","Bakery"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Bakery",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Bakeries",""]}]},{"_id":"52544965f71e87d007000054","hierarchy":["Food & Drink","Restaurants","Barbecue"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","BBQ Joint",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Barbecue"]}]},{"_id":"52544965f71e87d007000055","hierarchy":["Food & Drink","Restaurants","Brazilian"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Brazilian Restaurant",""]}]},{"_id":"52544965f71e87d007000056","hierarchy":["Food & Drink","Restaurants","Breakfast Spot"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Breakfast Spot",""]}]},{"_id":"52544965f71e87d007000057","hierarchy":["Food & Drink","Restaurants","Burgers"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Burger Joint",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Burgers"]}]},{"_id":"52544965f71e87d007000058","hierarchy":["Food & Drink","Restaurants","Burrito"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Burrito Place",""]}]},{"_id":"52544965f71e87d007000059","hierarchy":["Food & Drink","Restaurants","Cafe"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Café",""]}]},{"_id":"52544965f71e87d00700005a","hierarchy":["Food & Drink","Restaurants","Cajun"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Cajun / Creole Restaurant",""]}]},{"_id":"52544965f71e87d00700005b","hierarchy":["Food & Drink","Restaurants","Caribbean"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Caribbean Restaurant",""]}]},{"_id":"52544965f71e87d00700005c","hierarchy":["Food & Drink","Restaurants","Chinese"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Chinese Restaurant",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Chinese"]}]},{"_id":"52544965f71e87d00700005d","hierarchy":["Food & Drink","Restaurants","Coffee Shop"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Coffee Shop",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Cafes, Coffee and Tea Houses",""]}]},{"_id":"52544965f71e87d00700005e","hierarchy":["Food & Drink","Restaurants","Cuban"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Cuban Restaurant",""]}]},{"_id":"52544965f71e87d00700005f","hierarchy":["Food & Drink","Restaurants","Cupcake Shop"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Cupcake Shop",""]}]},{"_id":"52544965f71e87d007000060","hierarchy":["Food & Drink","Restaurants","Delis"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Deli / Bodega",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Delis"]}]},{"_id":"52544965f71e87d007000061","hierarchy":["Food & Drink","Restaurants","Dessert"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Dessert Shop",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Dessert",""]}]},{"_id":"52544965f71e87d007000062","hierarchy":["Food & Drink","Restaurants","Diners"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Diner",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Diners"]}]},{"_id":"52544965f71e87d007000063","hierarchy":["Food & Drink","Restaurants","Distillery"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Distillery",""]}]},{"_id":"52544965f71e87d007000064","hierarchy":["Food & Drink","Restaurants","Donuts"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Donut Shop",""]}]},{"_id":"52544965f71e87d007000065","hierarchy":["Food & Drink","Restaurants","Eastern European"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Eastern European Restaurant",""]}]},{"_id":"52544965f71e87d007000066","hierarchy":["Food & Drink","Restaurants","Ethiopian"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Ethiopian Restaurant",""]}]},{"_id":"52544965f71e87d007000067","hierarchy":["Food & Drink","Restaurants","Falafel"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Falafel Restaurant",""]}]},{"_id":"52544965f71e87d007000068","hierarchy":["Food & Drink","Restaurants","Fast Food"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Fast Food Restaurant",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Fast Food"]}]},{"_id":"52544965f71e87d007000069","hierarchy":["Food & Drink","Restaurants","Filipino"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Filipino Restaurant",""]}]},{"_id":"52544965f71e87d00700006a","hierarchy":["Food & Drink","Restaurants","Fish & Chips"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Fish & Chips Shop",""]}]},{"_id":"52544965f71e87d00700006b","hierarchy":["Food & Drink","Restaurants","Food Truck"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Food Truck",""]}]},{"_id":"52544965f71e87d00700006c","hierarchy":["Food & Drink","Restaurants","French"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","French Restaurant",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","French"]}]},{"_id":"52544965f71e87d00700006d","hierarchy":["Food & Drink","Restaurants","Gastropub"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Gastropub",""]}]},{"_id":"52544965f71e87d00700006e","hierarchy":["Food & Drink","Restaurants","German"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","German Restaurant",""]}]},{"_id":"52544965f71e87d00700006f","hierarchy":["Food & Drink","Restaurants","Greek"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Greek Restaurant",""]}]},{"_id":"52544965f71e87d007000070","hierarchy":["Food & Drink","Restaurants","Ice Cream"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Ice Cream Shop",""]},{"map_type":"foursquare","hierarchy":["Food","Frozen Yogurt",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Ice Cream Parlors",""]}]},{"_id":"52544965f71e87d007000071","hierarchy":["Food & Drink","Restaurants","Indian"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Indian Restaurant",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Indian"]}]},{"_id":"52544965f71e87d007000072","hierarchy":["Food & Drink","Restaurants","Indonesian"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Indonesian Restaurant",""]}]},{"_id":"52544965f71e87d007000073","hierarchy":["Food & Drink","Restaurants","Italian"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Italian Restaurant",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Italian"]}]},{"_id":"52544965f71e87d007000074","hierarchy":["Food & Drink","Restaurants","Japanese"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Japanese Restaurant",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Japanese"]}]},{"_id":"52544965f71e87d007000075","hierarchy":["Food & Drink","Restaurants","Juice Bar"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Juice Bar",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Juice Bars and Smoothies",""]}]},{"_id":"52544965f71e87d007000076","hierarchy":["Food & Drink","Restaurants","Korean"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Korean Restaurant",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Korean"]}]},{"_id":"52544965f71e87d007000077","hierarchy":["Food & Drink","Restaurants","Latin American"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Latin American Restaurant",""]}]},{"_id":"52544965f71e87d007000078","hierarchy":["Food & Drink","Restaurants","Mediterranean"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Mediterranean Restaurant",""]}]},{"_id":"52544965f71e87d007000079","hierarchy":["Food & Drink","Restaurants","Mexican"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Mexican Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Taco Place",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Mexican"]}]},{"_id":"52544965f71e87d00700007a","hierarchy":["Food & Drink","Restaurants","Middle Eastern"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Middle Eastern Restaurant",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Middle Eastern"]}]},{"_id":"52544965f71e87d00700007b","hierarchy":["Food & Drink","Restaurants","Moroccan"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Moroccan Restaurant",""]}]},{"_id":"52544965f71e87d00700007c","hierarchy":["Food & Drink","Restaurants","Pizza"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Pizza Place",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Pizza"]}]},{"_id":"52544965f71e87d00700007d","hierarchy":["Food & Drink","Restaurants","Portuguese"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Portuguese Restaurant",""]}]},{"_id":"52544965f71e87d00700007e","hierarchy":["Food & Drink","Restaurants","Scandinavian"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Scandinavian Restaurant",""]}]},{"_id":"52544965f71e87d00700007f","hierarchy":["Food & Drink","Restaurants","Seafood"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Seafood Restaurant",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Seafood"]}]},{"_id":"52544965f71e87d007000080","hierarchy":["Food & Drink","Restaurants","Spanish"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Peruvian Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","South American Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Spanish Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Spanish Restaurant","Paella Restaurant"]},{"map_type":"foursquare","hierarchy":["Food","Tapas Restaurant",""]}]},{"_id":"52544965f71e87d007000081","hierarchy":["Food & Drink","Restaurants","Steakhouses"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Steakhouse",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Steakhouses"]}]},{"_id":"52544965f71e87d007000082","hierarchy":["Food & Drink","Restaurants","Sushi"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Sushi Restaurant",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Sushi"]}]},{"_id":"52544965f71e87d007000083","hierarchy":["Food & Drink","Restaurants","Swiss"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Swiss Restaurant",""]}]},{"_id":"52544965f71e87d007000084","hierarchy":["Food & Drink","Restaurants","Thai"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Thai Restaurant",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Thai"]}]},{"_id":"52544965f71e87d007000085","hierarchy":["Food & Drink","Restaurants","Turkish"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Turkish Restaurant",""]}]},{"_id":"52544965f71e87d007000086","hierarchy":["Food & Drink","Restaurants","Vegan and Vegetarian"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Gluten-free Restaurant",""]},{"map_type":"foursquare","hierarchy":["Food","Vegetarian / Vegan Restaurant",""]},{"map_type":"factual","hierarchy":["Social","Food and Dining","Restaurants","Vegan and Vegetarian"]}]},{"_id":"52544965f71e87d007000087","hierarchy":["Food & Drink","Restaurants","Winery"],"mappings":[{"map_type":"foursquare","hierarchy":["Food","Winery",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Vineyard",""]},{"map_type":"factual","hierarchy":["Social","Wineries and Vineyards","",""]}]},{"_id":"52544965f71e87d007000088","hierarchy":["Miscellaneous"],"mappings":[]},{"_id":"52544965f71e87d007000089","hierarchy":["Parks & Outdoors"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Stadium","Cricket Ground"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Stadium","College Cricket Pitch"]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Athletics & Sports",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Athletics & Sports","Volleyball Court"]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Neighborhood",""]},{"map_type":"factual","hierarchy":["Sports and Recreation","Baseball","Batting Ranges",""]},{"map_type":"factual","hierarchy":["Sports and Recreation","","",""]}]},{"_id":"52544965f71e87d00700008a","hierarchy":["Parks & Outdoors","Aquarium"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Aquarium",""]}]},{"_id":"52544965f71e87d00700008b","hierarchy":["Parks & Outdoors","Athletic Fields"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Athletic Fields","",""]}]},{"_id":"52544965f71e87d00700008c","hierarchy":["Parks & Outdoors","Baseball"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Stadium","Baseball Stadium"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Stadium","College Baseball Diamond"]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Athletics & Sports","Baseball Field"]},{"map_type":"factual","hierarchy":["Sports and Recreation","Baseball","",""]}]},{"_id":"52544965f71e87d00700008d","hierarchy":["Parks & Outdoors","Basketball"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Stadium","Basketball Stadium"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Stadium","College Basketball Court"]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Athletics & Sports","Basketball Court"]},{"map_type":"factual","hierarchy":["Sports and Recreation","Basketball","",""]}]},{"_id":"52544965f71e87d00700008e","hierarchy":["Parks & Outdoors","Batting Cages"],"mappings":[]},{"_id":"52544965f71e87d00700008f","hierarchy":["Parks & Outdoors","Boating"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Water Sports","Boating",""]}]},{"_id":"52544965f71e87d007000090","hierarchy":["Parks & Outdoors","Campgrounds and RV Parks"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Campground",""]},{"map_type":"factual","hierarchy":["Sports and Recreation","Outdoors","Campgrounds and RV Parks",""]}]},{"_id":"52544965f71e87d007000091","hierarchy":["Parks & Outdoors","Canoes and Kayaks"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Water Sports","Canoes and Kayaks",""]}]},{"_id":"52544965f71e87d007000092","hierarchy":["Parks & Outdoors","Combat Sports"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Combat Sports","",""]}]},{"_id":"52544965f71e87d007000093","hierarchy":["Parks & Outdoors","Cycling"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Cycling","",""]}]},{"_id":"52544965f71e87d007000094","hierarchy":["Parks & Outdoors","Dance"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Dance","",""]}]},{"_id":"52544965f71e87d007000095","hierarchy":["Parks & Outdoors","Equestrian"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Equestrian","",""]}]},{"_id":"52544965f71e87d007000096","hierarchy":["Parks & Outdoors","Football"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Stadium","Football Stadium"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Stadium","College Football Field"]},{"map_type":"factual","hierarchy":["Sports and Recreation","Football","",""]}]},{"_id":"52544965f71e87d007000097","hierarchy":["Parks & Outdoors","Golf"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Athletics & Sports","Golf Course"]},{"map_type":"factual","hierarchy":["Sports and Recreation","Golf","",""]}]},{"_id":"52544965f71e87d007000098","hierarchy":["Parks & Outdoors","Gun Ranges"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Gun Ranges","",""]}]},{"_id":"52544965f71e87d007000099","hierarchy":["Parks & Outdoors","Gymnastics"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Gymnastics","",""]}]},{"_id":"52544965f71e87d00700009a","hierarchy":["Parks & Outdoors","Gyms and Fitness Centers"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Gym / Fitness Center","Gym Pool"]},{"map_type":"foursquare","hierarchy":["Shops & Services","Gym / Fitness Center","Climbing Gym"]},{"map_type":"foursquare","hierarchy":["Shops & Services","Gym / Fitness Center",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","Gym / Fitness Center","Track"]},{"map_type":"foursquare","hierarchy":["Shops & Services","Gym / Fitness Center","Martial Arts Dojo"]},{"map_type":"foursquare","hierarchy":["Shops & Services","Gym / Fitness Center","Gym"]},{"map_type":"factual","hierarchy":["Sports and Recreation","Gyms and Fitness Centers","",""]}]},{"_id":"52544965f71e87d00700009b","hierarchy":["Parks & Outdoors","Hiking"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Hiking Trail",""]},{"map_type":"factual","hierarchy":["Sports and Recreation","Outdoors","Hiking",""]}]},{"_id":"52544965f71e87d00700009c","hierarchy":["Parks & Outdoors","Hockey"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Stadium","Hockey Arena"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Stadium","College Hockey Rink"]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Athletics & Sports","Hockey Field"]},{"map_type":"factual","hierarchy":["Sports and Recreation","Hockey","",""]}]},{"_id":"52544965f71e87d00700009d","hierarchy":["Parks & Outdoors","Hot Air Balloons"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Outdoors","Hot Air Balloons",""]}]},{"_id":"52544965f71e87d00700009e","hierarchy":["Parks & Outdoors","Hunting and Fishing"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Outdoors","Hunting and Fishing",""]}]},{"_id":"52544965f71e87d00700009f","hierarchy":["Parks & Outdoors","Landmarks"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Hot Spring",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Harbor / Marina",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Lighthouse",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Volcano",""]},{"map_type":"factual","hierarchy":["Landmarks","","",""]}]},{"_id":"52544965f71e87d0070000a0","hierarchy":["Parks & Outdoors","Landmarks","Buildings and Structures"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Castle",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Bridge",""]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Building",""]},{"map_type":"factual","hierarchy":["Landmarks","Buildings and Structures","",""]}]},{"_id":"52544965f71e87d0070000a1","hierarchy":["Parks & Outdoors","Landmarks","Gardens"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Garden",""]},{"map_type":"factual","hierarchy":["Landmarks","Gardens","",""]}]},{"_id":"52544965f71e87d0070000a2","hierarchy":["Parks & Outdoors","Landmarks","Historic Sites"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Historic Site",""]},{"map_type":"factual","hierarchy":["Landmarks","Historic and Protected Sites","",""]}]},{"_id":"52544965f71e87d0070000a3","hierarchy":["Parks & Outdoors","Landmarks","Monuments and Memorials"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Government Building","Monument / Landmark"]},{"map_type":"factual","hierarchy":["Landmarks","Monuments and Memorials","",""]}]},{"_id":"52544965f71e87d0070000a4","hierarchy":["Parks & Outdoors","Outdoors"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Field",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Farm",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Island",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Other Great Outdoors",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Dog Run",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Ski Area",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Stables",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Plaza",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Ski Area","Ski Trail"]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Sculpture Garden",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Ski Area","Ski Lodge"]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Well",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Scenic Lookout",""]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Ski Area","Ski Chalet"]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Ski Area","Ski Chairlift"]},{"map_type":"factual","hierarchy":["Landmarks","Natural","",""]},{"map_type":"factual","hierarchy":["Sports and Recreation","Outdoors","",""]}]},{"_id":"52544965f71e87d0070000a5","hierarchy":["Parks & Outdoors","Outdoors","Beaches"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Beach","Surf Spot"]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Beach",""]},{"map_type":"factual","hierarchy":["Landmarks","Natural","Beaches",""]}]},{"_id":"52544965f71e87d0070000a6","hierarchy":["Parks & Outdoors","Outdoors","Forests"],"mappings":[{"map_type":"factual","hierarchy":["Landmarks","Natural","Forests",""]}]},{"_id":"52544965f71e87d0070000a7","hierarchy":["Parks & Outdoors","Outdoors","Lakes"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Lake",""]},{"map_type":"factual","hierarchy":["Landmarks","Natural","Lakes",""]}]},{"_id":"52544965f71e87d0070000a8","hierarchy":["Parks & Outdoors","Outdoors","Mountains"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Mountain",""]},{"map_type":"factual","hierarchy":["Landmarks","Natural","Mountains",""]}]},{"_id":"52544965f71e87d0070000a9","hierarchy":["Parks & Outdoors","Outdoors","Rivers"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","River",""]},{"map_type":"factual","hierarchy":["Landmarks","Natural","Rivers",""]}]},{"_id":"52544965f71e87d0070000aa","hierarchy":["Parks & Outdoors","Paintball"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Athletics & Sports","Paintball Field"]},{"map_type":"factual","hierarchy":["Sports and Recreation","Paintball","",""]}]},{"_id":"52544965f71e87d0070000ab","hierarchy":["Parks & Outdoors","Parks"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Park",""]},{"map_type":"factual","hierarchy":["Landmarks","Parks","",""]},{"map_type":"factual","hierarchy":["Landmarks","Parks","Urban Parks",""]}]},{"_id":"52544965f71e87d0070000ac","hierarchy":["Parks & Outdoors","Parks","Natural Parks"],"mappings":[{"map_type":"factual","hierarchy":["Landmarks","Parks","Natural Parks",""]}]},{"_id":"52544965f71e87d0070000ad","hierarchy":["Parks & Outdoors","Parks","Picnic Areas"],"mappings":[{"map_type":"factual","hierarchy":["Landmarks","Parks","Picnic Areas",""]}]},{"_id":"52544965f71e87d0070000ae","hierarchy":["Parks & Outdoors","Parks","Playgrounds"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Playground",""]},{"map_type":"factual","hierarchy":["Landmarks","Parks","Playgrounds",""]}]},{"_id":"52544965f71e87d0070000af","hierarchy":["Parks & Outdoors","Personal Trainers"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Personal Trainers","",""]}]},{"_id":"52544965f71e87d0070000b0","hierarchy":["Parks & Outdoors","Race Tracks"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Racetrack",""]},{"map_type":"factual","hierarchy":["Sports and Recreation","Race Tracks","",""]}]},{"_id":"52544965f71e87d0070000b1","hierarchy":["Parks & Outdoors","Racquet Sports"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Racquet Sports","",""]}]},{"_id":"52544965f71e87d0070000b2","hierarchy":["Parks & Outdoors","Racquetball"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Racquet Sports","Racquetball",""]}]},{"_id":"52544965f71e87d0070000b3","hierarchy":["Parks & Outdoors","Rafting"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Water Sports","Rafting",""]}]},{"_id":"52544965f71e87d0070000b4","hierarchy":["Parks & Outdoors","Recreation Centers"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Recreation Centers","",""]}]},{"_id":"52544965f71e87d0070000b5","hierarchy":["Parks & Outdoors","Rock Climbing"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Rock Climbing Spot",""]},{"map_type":"factual","hierarchy":["Sports and Recreation","Outdoors","Rock Climbing",""]}]},{"_id":"52544965f71e87d0070000b6","hierarchy":["Parks & Outdoors","Running"],"mappings":[{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Stadium","College Track"]},{"map_type":"factual","hierarchy":["Sports and Recreation","Running","",""]}]},{"_id":"52544965f71e87d0070000b7","hierarchy":["Parks & Outdoors","Scuba Diving"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Water Sports","Scuba Diving",""]}]},{"_id":"52544965f71e87d0070000b8","hierarchy":["Parks & Outdoors","Skating"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Athletics & Sports","Skating Rink"]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Athletics & Sports","Skate Park"]},{"map_type":"factual","hierarchy":["Sports and Recreation","Skating","",""]}]},{"_id":"52544965f71e87d0070000b9","hierarchy":["Parks & Outdoors","Skydiving"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Outdoors","Skydiving",""]}]},{"_id":"52544965f71e87d0070000ba","hierarchy":["Parks & Outdoors","Snow Sports"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Snow Sports","",""]}]},{"_id":"52544965f71e87d0070000bb","hierarchy":["Parks & Outdoors","Soccer"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Stadium","Soccer Stadium"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Stadium","College Soccer Field"]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Athletics & Sports","Soccer Field"]},{"map_type":"factual","hierarchy":["Sports and Recreation","Soccer","",""]}]},{"_id":"52544965f71e87d0070000bc","hierarchy":["Parks & Outdoors","Sports Clubs"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Sports Clubs","",""]}]},{"_id":"52544965f71e87d0070000bd","hierarchy":["Parks & Outdoors","Stadiums and Arenas"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Stadium","Track Stadium"]},{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Stadium",""]},{"map_type":"factual","hierarchy":["Sports and Recreation","Stadiums and Arenas","",""]}]},{"_id":"52544965f71e87d0070000be","hierarchy":["Parks & Outdoors","Swimming"],"mappings":[{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Pool",""]},{"map_type":"factual","hierarchy":["Sports and Recreation","Water Sports","Swimming",""]},{"map_type":"factual","hierarchy":["Sports and Recreation","Swimming Pools","",""]}]},{"_id":"52544965f71e87d0070000bf","hierarchy":["Parks & Outdoors","Tennis"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Stadium","Tennis"]},{"map_type":"foursquare","hierarchy":["Colleges & Universities","College Stadium","College Tennis Court"]},{"map_type":"foursquare","hierarchy":["Outdoors & Recreation","Athletics & Sports","Tennis Court"]},{"map_type":"factual","hierarchy":["Sports and Recreation","Racquet Sports","Tennis",""]}]},{"_id":"52544965f71e87d0070000c0","hierarchy":["Parks & Outdoors","Water Sports"],"mappings":[{"map_type":"factual","hierarchy":["Sports and Recreation","Water Sports","",""]}]},{"_id":"52544965f71e87d0070000c1","hierarchy":["Parks & Outdoors","Yoga and Pilates"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Gym / Fitness Center","Yoga Studio"]},{"map_type":"factual","hierarchy":["Sports and Recreation","Yoga and Pilates","",""]}]},{"_id":"52544965f71e87d0070000c2","hierarchy":["Parks & Outdoors","Zoo"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Zoo",""]},{"map_type":"factual","hierarchy":["Social","Zoos, Aquariums and Wildlife Sanctuaries","",""]}]},{"_id":"52544965f71e87d0070000c3","hierarchy":["Professional"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","",""]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Office","Campaign Office"]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Office","Conference Room"]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Office","Cafeteria"]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Office",""]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Office","Tech Startup"]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Office","Coworking Space"]}]},{"_id":"52544965f71e87d0070000c4","hierarchy":["Professional","Advertising and Marketing"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Advertising and Marketing","",""]}]},{"_id":"52544965f71e87d0070000c5","hierarchy":["Professional","Advertising and Marketing","Advertising Agencies and Media Buyers"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Advertising and Marketing","Advertising Agencies and Media Buyers",""]}]},{"_id":"52544965f71e87d0070000c6","hierarchy":["Professional","Advertising and Marketing","Creative Services"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Advertising and Marketing","Creative Services",""]}]},{"_id":"52544965f71e87d0070000c7","hierarchy":["Professional","Advertising and Marketing","Direct Mail and Email Marketing Services"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Advertising and Marketing","Direct Mail and Email Marketing Services",""]}]},{"_id":"52544965f71e87d0070000c8","hierarchy":["Professional","Advertising and Marketing","Market Research and Consulting"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Advertising and Marketing","Market Research and Consulting",""]}]},{"_id":"52544965f71e87d0070000c9","hierarchy":["Professional","Advertising and Marketing","Online Advertising"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Advertising and Marketing","Online Advertising",""]}]},{"_id":"52544965f71e87d0070000ca","hierarchy":["Professional","Advertising and Marketing","Print, TV, Radio and Outdoor Advertising"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Radio Station",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Advertising and Marketing","Print, TV, Radio and Outdoor Advertising",""]}]},{"_id":"52544965f71e87d0070000cb","hierarchy":["Professional","Advertising and Marketing","Promotional Items"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Advertising and Marketing","Promotional Items",""]}]},{"_id":"52544965f71e87d0070000cc","hierarchy":["Professional","Advertising and Marketing","Public Relations"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Advertising and Marketing","Public Relations",""]}]},{"_id":"52544965f71e87d0070000cd","hierarchy":["Professional","Advertising and Marketing","Search Engine Marketing and Optimization"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Advertising and Marketing","Search Engine Marketing and Optimization",""]}]},{"_id":"52544965f71e87d0070000ce","hierarchy":["Professional","Advertising and Marketing","Writing, Copywriting and Technical Writing"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Advertising and Marketing","Writing, Copywriting and Technical Writing",""]}]},{"_id":"52544965f71e87d0070000cf","hierarchy":["Professional","Agriculture and Forestry"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Agriculture and Forestry","",""]}]},{"_id":"52544965f71e87d0070000d0","hierarchy":["Professional","Art Restoration"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Art Restoration","",""]}]},{"_id":"52544965f71e87d0070000d1","hierarchy":["Professional","Audiovisual"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Audiovisual","",""]}]},{"_id":"52544965f71e87d0070000d2","hierarchy":["Professional","Automation and Control Systems"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Automation and Control Systems","",""]}]},{"_id":"52544965f71e87d0070000d3","hierarchy":["Professional","Business and Strategy Consulting"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Business and Strategy Consulting","",""]}]},{"_id":"52544965f71e87d0070000d4","hierarchy":["Professional","Chemicals and Gasses"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Chemicals and Gasses","",""]}]},{"_id":"52544965f71e87d0070000d5","hierarchy":["Professional","Computers"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Computers","",""]}]},{"_id":"52544965f71e87d0070000d6","hierarchy":["Professional","Corporate HQ"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Corporate HQ","",""]}]},{"_id":"52544965f71e87d0070000d7","hierarchy":["Professional","Credit Counseling and Bankruptcy Services"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Legal","Credit Counseling and Bankruptcy Services",""]}]},{"_id":"52544965f71e87d0070000d8","hierarchy":["Professional","Employment Agencies"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Employment Agencies","",""]}]},{"_id":"52544965f71e87d0070000d9","hierarchy":["Professional","Engineering"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Engineering","",""]}]},{"_id":"52544965f71e87d0070000da","hierarchy":["Professional","Entertainment"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Entertainment","",""]}]},{"_id":"52544965f71e87d0070000db","hierarchy":["Professional","Entertainment","Media"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Entertainment","Media",""]}]},{"_id":"52544965f71e87d0070000dc","hierarchy":["Professional","Financial"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Financial","",""]}]},{"_id":"52544965f71e87d0070000dd","hierarchy":["Professional","Financial","Accounting and Bookkeeping"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Financial","Accounting and Bookkeeping",""]}]},{"_id":"52544965f71e87d0070000de","hierarchy":["Professional","Financial","ATMs"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Events and Event Planning","ATMs",""]}]},{"_id":"52544965f71e87d0070000df","hierarchy":["Professional","Financial","Banking and Finance"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Bank",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","Credit Union",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Financial","Banking and Finance",""]}]},{"_id":"52544965f71e87d0070000e0","hierarchy":["Professional","Financial","Business Brokers and Franchises"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Financial","Business Brokers and Franchises",""]}]},{"_id":"52544965f71e87d0070000e1","hierarchy":["Professional","Financial","Check Cashing"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Financial","Check Cashing",""]}]},{"_id":"52544965f71e87d0070000e2","hierarchy":["Professional","Financial","Collections"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Financial","Collections",""]}]},{"_id":"52544965f71e87d0070000e3","hierarchy":["Professional","Financial","Financial Planning and Investments"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Financial or Legal Service",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Financial","Financial Planning and Investments",""]}]},{"_id":"52544965f71e87d0070000e4","hierarchy":["Professional","Financial","Fund Raising"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Financial","Fund Raising",""]}]},{"_id":"52544965f71e87d0070000e5","hierarchy":["Professional","Financial","Loans and Mortgages"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Financial","Loans and Mortgages",""]}]},{"_id":"52544965f71e87d0070000e6","hierarchy":["Professional","Financial","Stock Brokers"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Financial","Stock Brokers",""]}]},{"_id":"52544965f71e87d0070000e7","hierarchy":["Professional","Financial","Student Aid and Grants"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Financial","Student Aid and Grants",""]}]},{"_id":"52544965f71e87d0070000e8","hierarchy":["Professional","Geological"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Geological","",""]}]},{"_id":"52544965f71e87d0070000e9","hierarchy":["Professional","Healthcare Services"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Medical Center","Doctor's Office"]},{"map_type":"factual","hierarchy":["Healthcare","","",""]},{"map_type":"factual","hierarchy":["Healthcare","AIDS Resources","",""]}]},{"_id":"52544965f71e87d0070000ea","hierarchy":["Professional","Healthcare Services","Acupuncture"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Holistic, Alternative and Naturopathic Medicine","Acupuncture",""]}]},{"_id":"52544965f71e87d0070000eb","hierarchy":["Professional","Healthcare Services","Alternative Medicine"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Holistic, Alternative and Naturopathic Medicine","",""]}]},{"_id":"52544965f71e87d0070000ec","hierarchy":["Professional","Healthcare Services","Blood Banks and Centers"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Blood Banks and Centers","",""]}]},{"_id":"52544965f71e87d0070000ed","hierarchy":["Professional","Healthcare Services","Chiropractors"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Chiropractors","",""]}]},{"_id":"52544965f71e87d0070000ee","hierarchy":["Professional","Healthcare Services","Counseling and Therapy"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Mental Health","Counseling and Therapy",""]}]},{"_id":"52544965f71e87d0070000ef","hierarchy":["Professional","Healthcare Services","Dentists"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Medical Center","Dentist's Office"]},{"map_type":"factual","hierarchy":["Healthcare","Dentists","",""]}]},{"_id":"52544965f71e87d0070000f0","hierarchy":["Professional","Healthcare Services","Emergency Services"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Medical Center","Emergency Room"]},{"map_type":"factual","hierarchy":["Healthcare","Emergency Services","Ambulance",""]},{"map_type":"factual","hierarchy":["Healthcare","Emergency Services","",""]}]},{"_id":"52544965f71e87d0070000f1","hierarchy":["Professional","Healthcare Services","Hospitals, Clinics and Medical Centers"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Medical Center",""]},{"map_type":"foursquare","hierarchy":["Professional & Other Places","Medical Center","Hospital"]},{"map_type":"factual","hierarchy":["Healthcare","Hospitals, Clinics and Medical Centers","",""]}]},{"_id":"52544965f71e87d0070000f2","hierarchy":["Professional","Healthcare Services","Medical Supplies and Labs"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Medical Center","Laboratory"]},{"map_type":"factual","hierarchy":["Healthcare","Medical Supplies and Labs","",""]}]},{"_id":"52544965f71e87d0070000f3","hierarchy":["Professional","Healthcare Services","Mental Health"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Mental Health","",""]}]},{"_id":"52544965f71e87d0070000f4","hierarchy":["Professional","Healthcare Services","Nurses"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Nurses","",""]}]},{"_id":"52544965f71e87d0070000f5","hierarchy":["Professional","Healthcare Services","Nutritionists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Weight Loss and Nutritionists","",""]}]},{"_id":"52544965f71e87d0070000f6","hierarchy":["Professional","Healthcare Services","Physical Therapy"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physical Therapy and Rehabilitation","",""]},{"map_type":"factual","hierarchy":["Healthcare","Physical Therapy and Rehabilitation","Sports Medicine",""]}]},{"_id":"52544965f71e87d0070000f7","hierarchy":["Professional","Healthcare Services","Podiatrists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Podiatrists","",""]}]},{"_id":"52544965f71e87d0070000f8","hierarchy":["Professional","Healthcare Services","Pregnancy and Sexual Health"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Pregnancy and Sexual Health","",""]}]},{"_id":"52544965f71e87d0070000f9","hierarchy":["Professional","Healthcare Services","Psychologists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Mental Health","Psychologists",""]}]},{"_id":"52544965f71e87d0070000fa","hierarchy":["Professional","Home Improvement"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","",""]}]},{"_id":"52544965f71e87d0070000fb","hierarchy":["Professional","Home Improvement","Architects"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Architects",""]}]},{"_id":"52544965f71e87d0070000fc","hierarchy":["Professional","Home Improvement","Carpenters"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Carpenters",""]}]},{"_id":"52544965f71e87d0070000fd","hierarchy":["Professional","Home Improvement","Carpet and Flooring"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Carpet and Flooring",""]}]},{"_id":"52544965f71e87d0070000fe","hierarchy":["Professional","Home Improvement","Contractors"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Contractors",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Contractors","Sewer"]},{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Contractors","Deck and Patio"]},{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Contractors","Bathrooms"]}]},{"_id":"52544965f71e87d0070000ff","hierarchy":["Professional","Home Improvement","Doors and Windows"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Doors and Windows",""]}]},{"_id":"52544965f71e87d007000100","hierarchy":["Professional","Home Improvement","Electricians"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Electricians",""]}]},{"_id":"52544965f71e87d007000101","hierarchy":["Professional","Home Improvement","Fences, Fireplaces and Garage Doors"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Fences, Fireplaces and Garage Doors",""]}]},{"_id":"52544965f71e87d007000102","hierarchy":["Professional","Home Improvement","Hardware and Services"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Hardware and Services",""]}]},{"_id":"52544965f71e87d007000103","hierarchy":["Professional","Home Improvement","Heating, Ventilating and Air Conditioning"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Heating, Ventilating and Air Conditioning",""]}]},{"_id":"52544965f71e87d007000104","hierarchy":["Professional","Home Improvement","Home Appliances"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Home Appliances",""]}]},{"_id":"52544965f71e87d007000105","hierarchy":["Professional","Home Improvement","Home Inspection Services"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Home Inspection Services",""]}]},{"_id":"52544965f71e87d007000106","hierarchy":["Professional","Home Improvement","Housewares"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Housewares",""]}]},{"_id":"52544965f71e87d007000107","hierarchy":["Professional","Home Improvement","Interior Design"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Interior Design",""]}]},{"_id":"52544965f71e87d007000108","hierarchy":["Professional","Home Improvement","Kitchens"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Kitchens",""]}]},{"_id":"52544965f71e87d007000109","hierarchy":["Professional","Home Improvement","Landscaping and Gardeners"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Landscaping and Gardeners",""]}]},{"_id":"52544965f71e87d00700010a","hierarchy":["Professional","Home Improvement","Lighting Fixtures"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Lighting Fixtures",""]}]},{"_id":"52544965f71e87d00700010b","hierarchy":["Professional","Home Improvement","Mobile Homes"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Mobile Homes",""]}]},{"_id":"52544965f71e87d00700010c","hierarchy":["Professional","Home Improvement","Movers"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Movers",""]}]},{"_id":"52544965f71e87d00700010d","hierarchy":["Professional","Home Improvement","Painting"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Painting",""]}]},{"_id":"52544965f71e87d00700010e","hierarchy":["Professional","Home Improvement","Pest Control"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Pest Control",""]}]},{"_id":"52544965f71e87d00700010f","hierarchy":["Professional","Home Improvement","Plumbing"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Plumbing",""]}]},{"_id":"52544965f71e87d007000110","hierarchy":["Professional","Home Improvement","Pools and Spas"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Pools and Spas",""]}]},{"_id":"52544965f71e87d007000111","hierarchy":["Professional","Home Improvement","Roofers"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Roofers",""]}]},{"_id":"52544965f71e87d007000112","hierarchy":["Professional","Home Improvement","Storage"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Storage Facility",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Storage",""]}]},{"_id":"52544965f71e87d007000113","hierarchy":["Professional","Home Improvement","Swimming Pool Maintenance and Services"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Swimming Pool Maintenance and Services",""]}]},{"_id":"52544965f71e87d007000114","hierarchy":["Professional","Home Improvement","Tree Service"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Tree Service",""]}]},{"_id":"52544965f71e87d007000115","hierarchy":["Professional","Home Improvement","Upholstery"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Home Improvement","Upholstery",""]}]},{"_id":"52544965f71e87d007000116","hierarchy":["Professional","Immigration"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Legal","Immigration",""]}]},{"_id":"52544965f71e87d007000117","hierarchy":["Professional","Import and Export"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Import and Export","",""]}]},{"_id":"52544965f71e87d007000118","hierarchy":["Professional","Insurance"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Legal","Insurance",""]}]},{"_id":"52544965f71e87d007000119","hierarchy":["Professional","Internet Services"],"mappings":[]},{"_id":"52544965f71e87d00700011a","hierarchy":["Professional","Legal"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Legal","",""]}]},{"_id":"52544965f71e87d00700011b","hierarchy":["Professional","Management"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Management","",""]}]},{"_id":"52544965f71e87d00700011c","hierarchy":["Professional","Physicians"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","",""]}]},{"_id":"52544965f71e87d00700011d","hierarchy":["Professional","Physicians","Anesthesiologists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Anesthesiologists",""]}]},{"_id":"52544965f71e87d00700011e","hierarchy":["Professional","Physicians","Cardiologists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Cardiologists",""]}]},{"_id":"52544965f71e87d00700011f","hierarchy":["Professional","Physicians","Dermatologists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Dermatologists",""]}]},{"_id":"52544965f71e87d007000120","hierarchy":["Professional","Physicians","Ear, Nose and Throat"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Ear, Nose and Throat",""]}]},{"_id":"52544965f71e87d007000121","hierarchy":["Professional","Physicians","Family Medicine"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Family Medicine",""]}]},{"_id":"52544965f71e87d007000122","hierarchy":["Professional","Physicians","Gastroenterologists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Gastroenterologists",""]}]},{"_id":"52544965f71e87d007000123","hierarchy":["Professional","Physicians","General Surgery"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","General Surgery",""]}]},{"_id":"52544965f71e87d007000124","hierarchy":["Professional","Physicians","Internal Medicine"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Internal Medicine",""]}]},{"_id":"52544965f71e87d007000125","hierarchy":["Professional","Physicians","Neurologists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Neurologists",""]}]},{"_id":"52544965f71e87d007000126","hierarchy":["Professional","Physicians","Obstetricians and Gynecologists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Obstetricians and Gynecologists",""]}]},{"_id":"52544965f71e87d007000127","hierarchy":["Professional","Physicians","Oncologists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Oncologists",""]}]},{"_id":"52544965f71e87d007000128","hierarchy":["Professional","Physicians","Ophthalmologists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Ophthalmologists",""]}]},{"_id":"52544965f71e87d007000129","hierarchy":["Professional","Physicians","Orthopedic Surgeons"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Orthopedic Surgeons",""]}]},{"_id":"52544965f71e87d00700012a","hierarchy":["Professional","Physicians","Pathologists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Pathologists",""]}]},{"_id":"52544965f71e87d00700012b","hierarchy":["Professional","Physicians","Pediatricians"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Pediatricians",""]}]},{"_id":"52544965f71e87d00700012c","hierarchy":["Professional","Physicians","Plastic Surgeons"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Plastic Surgeons",""]}]},{"_id":"52544965f71e87d00700012d","hierarchy":["Professional","Physicians","Psychiatrists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Psychiatrists",""]}]},{"_id":"52544965f71e87d00700012e","hierarchy":["Professional","Physicians","Radiologists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Radiologists",""]}]},{"_id":"52544965f71e87d00700012f","hierarchy":["Professional","Physicians","Respiratory"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Respiratory",""]}]},{"_id":"52544965f71e87d007000130","hierarchy":["Professional","Physicians","Urologists"],"mappings":[{"map_type":"factual","hierarchy":["Healthcare","Physicians","Urologists",""]}]},{"_id":"52544965f71e87d007000131","hierarchy":["Professional","Veterinarians"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Medical Center","Veterinarian"]},{"map_type":"factual","hierarchy":["Services and Supplies","Veterinarians","",""]}]},{"_id":"52544965f71e87d007000132","hierarchy":["Professional","Web Design and Development"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Design Studio",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Web Design and Development","",""]}]},{"_id":"52544965f71e87d007000133","hierarchy":["Service"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","",""]},{"map_type":"factual","hierarchy":["Services and Supplies","","",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Publishing","",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Professional Cleaning","",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Printing, Copying and Signage","",""]},{"map_type":"factual","hierarchy":["Automotive","","",""]}]},{"_id":"52544965f71e87d007000134","hierarchy":["Service","Automotive","Auto Oil and Lube"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","Maintenance and Repair","Oil and Lube",""]}]},{"_id":"52544965f71e87d007000135","hierarchy":["Service","Automotive","Auto Smog Check"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","Maintenance and Repair","Smog Check",""]}]},{"_id":"52544965f71e87d007000136","hierarchy":["Service","Automotive","Auto Tires"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","Maintenance and Repair","Tires",""]}]},{"_id":"52544965f71e87d007000137","hierarchy":["Service","Automotive","Auto Transmission"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","Maintenance and Repair","Transmissions",""]}]},{"_id":"52544965f71e87d007000138","hierarchy":["Service","Automotive","Car Appraisers"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","Car Appraisers","",""]}]},{"_id":"52544965f71e87d007000139","hierarchy":["Service","Automotive","Car Wash and Detail"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","Car Wash and Detail","",""]}]},{"_id":"52544965f71e87d00700013a","hierarchy":["Service","Automotive","Maintenance and Repair"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","Maintenance and Repair","",""]}]},{"_id":"52544965f71e87d00700013b","hierarchy":["Service","Automotive","Motorcycle, Moped and Scooter Repair"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","Motorcycles, Mopeds and Scooters","Repair",""]}]},{"_id":"52544965f71e87d00700013c","hierarchy":["Service","Automotive","Towing"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","Towing","",""]}]},{"_id":"52544965f71e87d00700013d","hierarchy":["Service","Events and Event Planning"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Events and Event Planning","",""]}]},{"_id":"52544965f71e87d00700013e","hierarchy":["Service","Food and Beverage"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Food and Beverage","",""]}]},{"_id":"52544965f71e87d00700013f","hierarchy":["Service","Food and Beverage","Catering"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Food and Beverage","Catering",""]}]},{"_id":"52544965f71e87d007000140","hierarchy":["Service","Food and Beverage","Distribution"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Food and Beverage","Distribution",""]}]},{"_id":"52544965f71e87d007000141","hierarchy":["Service","Funeral Services"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Funeral Home",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Funeral Services","",""]}]},{"_id":"52544965f71e87d007000142","hierarchy":["Service","Human Resources"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Human Resources","",""]}]},{"_id":"52544965f71e87d007000143","hierarchy":["Service","Industrial Machinery and Vehicles"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Industrial Machinery and Vehicles","",""]}]},{"_id":"52544965f71e87d007000144","hierarchy":["Service","Leather"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Leather","",""]}]},{"_id":"52544965f71e87d007000145","hierarchy":["Service","Logging and Sawmills"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Logging and Sawmills","",""]}]},{"_id":"52544965f71e87d007000146","hierarchy":["Service","Machine Shops"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Machine Shops","",""]}]},{"_id":"52544965f71e87d007000147","hierarchy":["Service","Manufacturing"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Manufacturing","",""]}]},{"_id":"52544965f71e87d007000148","hierarchy":["Service","Metals"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Metals","",""]}]},{"_id":"52544965f71e87d007000149","hierarchy":["Service","Packaging"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Packaging","",""]}]},{"_id":"52544965f71e87d00700014a","hierarchy":["Service","Paper"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Paper","",""]}]},{"_id":"52544965f71e87d00700014b","hierarchy":["Service","Personal Care"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Personal Care","",""]}]},{"_id":"52544965f71e87d00700014c","hierarchy":["Service","Personal Care","Dry Cleaning, Ironing and Laundry"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Laundry Service",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Personal Care","Dry Cleaning, Ironing and Laundry",""]}]},{"_id":"52544965f71e87d00700014d","hierarchy":["Service","Personal Care","Hair Removal"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Personal Care","Hair Removal",""]}]},{"_id":"52544965f71e87d00700014e","hierarchy":["Service","Personal Care","Hair Salons and Barbers"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Salon / Barbershop",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Personal Care","Hair Salons and Barbers",""]}]},{"_id":"52544965f71e87d00700014f","hierarchy":["Service","Personal Care","Manicures and Pedicures"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Nail Salon",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Personal Care","Manicures and Pedicures",""]}]},{"_id":"52544965f71e87d007000150","hierarchy":["Shops","Personal Care","Massage Clinics and Therapists"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Personal Care","Massage Clinics and Therapists",""]}]},{"_id":"52544965f71e87d007000151","hierarchy":["Service","Personal Care","Piercing"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Personal Care","Piercing",""]}]},{"_id":"52544965f71e87d007000152","hierarchy":["Service","Personal Care","Skin Care"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Personal Care","Skin Care",""]}]},{"_id":"52544965f71e87d007000153","hierarchy":["Service","Personal Care","Spas"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Spa / Massage",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Personal Care","Spas",""]}]},{"_id":"52544965f71e87d007000154","hierarchy":["Service","Personal Care","Tanning Salons"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Tanning Salon",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Personal Care","Tanning Salons",""]}]},{"_id":"52544965f71e87d007000155","hierarchy":["Service","Personal Care","Tattooing"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Tattoo Parlor",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Personal Care","Tattooing",""]}]},{"_id":"52544965f71e87d007000156","hierarchy":["Service","Petroleum"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Petroleum","",""]}]},{"_id":"52544965f71e87d007000157","hierarchy":["Service","Plastics"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Plastics","",""]}]},{"_id":"52544965f71e87d007000158","hierarchy":["Service","Real Estate"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Real Estate Office",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Real Estate","",""]}]},{"_id":"52544965f71e87d007000159","hierarchy":["Service","Real Estate","Apartments, Condos and Houses"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Real Estate","Apartments, Condos and Houses",""]}]},{"_id":"52544965f71e87d00700015a","hierarchy":["Service","Real Estate","Boarding Houses"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Real Estate","Boarding Houses",""]}]},{"_id":"52544965f71e87d00700015b","hierarchy":["Service","Real Estate","Building and Land Surveyors"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Real Estate","Building and Land Surveyors",""]}]},{"_id":"52544965f71e87d00700015c","hierarchy":["Service","Real Estate","Commercial Real Estate"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Real Estate","Commercial Real Estate",""]}]},{"_id":"52544965f71e87d00700015d","hierarchy":["Service","Real Estate","Corporate Housing"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Real Estate","Corporate Housing",""]}]},{"_id":"52544965f71e87d00700015e","hierarchy":["Service","Real Estate","Property Management"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Real Estate","Property Management",""]}]},{"_id":"52544965f71e87d00700015f","hierarchy":["Service","Real Estate","Real Estate Agents"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Real Estate","Real Estate Agents",""]}]},{"_id":"52544965f71e87d007000160","hierarchy":["Service","Real Estate","Real Estate Appraiser"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Real Estate","Real Estate Appraiser",""]}]},{"_id":"52544965f71e87d007000161","hierarchy":["Service","Real Estate","Real Estate Development and Title Companies"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Real Estate","Real Estate Development and Title Companies",""]}]},{"_id":"52544965f71e87d007000162","hierarchy":["Service","Refrigeration and Ice"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Refrigeration and Ice","",""]}]},{"_id":"52544965f71e87d007000163","hierarchy":["Service","Renewable Energy"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Renewable Energy","",""]}]},{"_id":"52544965f71e87d007000164","hierarchy":["Service","Repair Services"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Repair Services","",""]}]},{"_id":"52544965f71e87d007000165","hierarchy":["Service","Rubber"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Rubber","",""]}]},{"_id":"52544965f71e87d007000166","hierarchy":["Service","Scientific"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Scientific","",""]}]},{"_id":"52544965f71e87d007000167","hierarchy":["Service","Security and Safety"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Security and Safety","",""]}]},{"_id":"52544965f71e87d007000168","hierarchy":["Service","Shipping and Freight"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Shipping, Freight, and Material Transportation","",""]}]},{"_id":"52544965f71e87d007000169","hierarchy":["Service","Tailors"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Tailor Shop",""]},{"map_type":"factual","hierarchy":["Services and Supplies","Tailors","",""]}]},{"_id":"52544965f71e87d00700016a","hierarchy":["Service","Telecommunication Services"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Telecommunication Services","",""]}]},{"_id":"52544965f71e87d00700016b","hierarchy":["Service","Textiles"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Textiles","",""]}]},{"_id":"52544965f71e87d00700016c","hierarchy":["Service","Tourist Information and Services"],"mappings":[{"map_type":"factual","hierarchy":["Travel","Tourist Information and Services","",""]}]},{"_id":"52544965f71e87d00700016d","hierarchy":["Service","Travel Agents and Tour Operators"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Travel Agency",""]},{"map_type":"factual","hierarchy":["Travel","Travel Agents and Tour Operators","",""]}]},{"_id":"52544965f71e87d00700016e","hierarchy":["Service","Water and Waste Management"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Water and Waste Management","",""]}]},{"_id":"52544965f71e87d00700016f","hierarchy":["Service","Welding"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Welding","",""]}]},{"_id":"52544965f71e87d007000170","hierarchy":["Shops"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Miscellaneous Shop",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","Market",""]},{"map_type":"factual","hierarchy":["Retail","","",""]}]},{"_id":"52544965f71e87d007000171","hierarchy":["Shops","Adult"],"mappings":[{"map_type":"factual","hierarchy":["Retail","Adult","",""]}]},{"_id":"52544965f71e87d007000172","hierarchy":["Shops","Antiques"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Antique Shop",""]},{"map_type":"factual","hierarchy":["Retail","Antiques","",""]}]},{"_id":"52544965f71e87d007000173","hierarchy":["Shops","Arts and Crafts"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Arts & Crafts Store",""]},{"map_type":"factual","hierarchy":["Retail","Arts and Crafts","",""]}]},{"_id":"52544965f71e87d007000174","hierarchy":["Shops","Auctions"],"mappings":[{"map_type":"factual","hierarchy":["Retail","Auctions","",""]}]},{"_id":"52544965f71e87d007000175","hierarchy":["Shops","Automotive","Car Dealers and Leasing"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Car Dealership",""]},{"map_type":"factual","hierarchy":["Automotive","Car Dealers and Leasing","",""]}]},{"_id":"52544965f71e87d007000176","hierarchy":["Shops","Automotive","Car Parts and Accessories"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","Car Parts and Accessories","",""]}]},{"_id":"52544965f71e87d007000177","hierarchy":["Shops","Automotive","Classic and Antique Car"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","Classic and Antique Car","",""]}]},{"_id":"52544965f71e87d007000178","hierarchy":["Shops","Automotive","Motorcycles, Mopeds and Scooters"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Motorcycle Shop",""]},{"map_type":"factual","hierarchy":["Automotive","Motorcycles, Mopeds and Scooters","",""]},{"map_type":"factual","hierarchy":["Automotive","Motorcycles, Mopeds and Scooters","Sales",""]}]},{"_id":"52544965f71e87d007000179","hierarchy":["Shops","Automotive","RVs and Motor Homes"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","RVs and Motor Homes","",""]}]},{"_id":"52544965f71e87d00700017a","hierarchy":["Shops","Automotive","Salvage Yards"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","Salvage Yards","",""]}]},{"_id":"52544965f71e87d00700017b","hierarchy":["Shops","Automotive","Used Car Dealers"],"mappings":[{"map_type":"factual","hierarchy":["Automotive","Car Dealers and Leasing","Used Cars",""]}]},{"_id":"52544965f71e87d00700017c","hierarchy":["Shops","Beauty Products"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Cosmetics Shop",""]},{"map_type":"factual","hierarchy":["Retail","Beauty Products","",""]}]},{"_id":"52544965f71e87d00700017d","hierarchy":["Shops","Bicycles"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Bike Shop",""]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Bike Rental / Bike Share",""]},{"map_type":"factual","hierarchy":["Retail","Bicycles","",""]}]},{"_id":"52544965f71e87d00700017e","hierarchy":["Shops","Bookstores"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Bookstore",""]},{"map_type":"factual","hierarchy":["Retail","Bookstores","",""]}]},{"_id":"52544965f71e87d00700017f","hierarchy":["Shops","Cards and Stationery"],"mappings":[{"map_type":"factual","hierarchy":["Retail","Cards and Stationery","",""]}]},{"_id":"52544965f71e87d007000180","hierarchy":["Shops","Children"],"mappings":[{"map_type":"factual","hierarchy":["Retail","Children","",""]}]},{"_id":"52544965f71e87d007000181","hierarchy":["Shops","Clothing and Accessories"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Clothing Store",""]},{"map_type":"factual","hierarchy":["Retail","Fashion","Clothing and Accessories",""]},{"map_type":"factual","hierarchy":["Retail","Fashion","",""]}]},{"_id":"52544965f71e87d007000182","hierarchy":["Shops","Clothing and Accessories","Accessories Store"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Clothing Store","Accessories Store"]}]},{"_id":"52544965f71e87d007000183","hierarchy":["Shops","Clothing and Accessories","Boutique"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Clothing Store","Boutique"]}]},{"_id":"52544965f71e87d007000184","hierarchy":["Shops","Clothing and Accessories","Kids Store"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Clothing Store","Kids Store"]}]},{"_id":"52544965f71e87d007000185","hierarchy":["Shops","Clothing and Accessories","Lingerie Store"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Clothing Store","Lingerie Store"]}]},{"_id":"52544965f71e87d007000186","hierarchy":["Shops","Clothing and Accessories","Mens Store"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Clothing Store","Men's Store"]}]},{"_id":"52544965f71e87d007000187","hierarchy":["Shops","Clothing and Accessories","Shoe Store"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Clothing Store","Shoe Store"]},{"map_type":"factual","hierarchy":["Retail","Fashion","Shoes",""]}]},{"_id":"52544965f71e87d007000188","hierarchy":["Shops","Clothing and Accessories","Swimwear"],"mappings":[{"map_type":"factual","hierarchy":["Retail","Fashion","Swimwear",""]}]},{"_id":"52544965f71e87d007000189","hierarchy":["Shops","Clothing and Accessories","Women€™s Store"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Clothing Store","Women's Store"]}]},{"_id":"52544965f71e87d00700018a","hierarchy":["Shops","Computers and Electronics"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Electronics Store",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","Video Store",""]},{"map_type":"factual","hierarchy":["Retail","Computers and Electronics","",""]}]},{"_id":"52544965f71e87d00700018b","hierarchy":["Shops","Computers and Electronics","Cameras"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Camera Store",""]},{"map_type":"factual","hierarchy":["Retail","Computers and Electronics","Cameras",""]}]},{"_id":"52544965f71e87d00700018c","hierarchy":["Shops","Computers and Electronics","Mobile Phones"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Mobile Phone Shop",""]},{"map_type":"factual","hierarchy":["Retail","Computers and Electronics","Mobile Phones",""]}]},{"_id":"52544965f71e87d00700018d","hierarchy":["Shops","Computers and Electronics","Video Games"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Video Game Store",""]},{"map_type":"factual","hierarchy":["Retail","Computers and Electronics","Video Games",""]}]},{"_id":"52544965f71e87d00700018e","hierarchy":["Shops","Construction Supplies"],"mappings":[{"map_type":"factual","hierarchy":["Retail","Construction Supplies","",""]}]},{"_id":"52544965f71e87d00700018f","hierarchy":["Shops","Convenience Stores"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Convenience Store",""]},{"map_type":"factual","hierarchy":["Retail","Convenience Stores","",""]}]},{"_id":"52544965f71e87d007000190","hierarchy":["Shops","Costumes"],"mappings":[{"map_type":"factual","hierarchy":["Retail","Costumes","",""]}]},{"_id":"52544965f71e87d007000191","hierarchy":["Shops","Dance and Music"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Record Shop",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","Music Store",""]},{"map_type":"factual","hierarchy":["Retail","Dance and Music","",""]}]},{"_id":"52544965f71e87d007000192","hierarchy":["Shops","Department Stores"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Department Store",""]},{"map_type":"factual","hierarchy":["Retail","Department Stores, Discount Stores","",""]}]},{"_id":"52544965f71e87d007000193","hierarchy":["Shops","Digital Purchase"],"mappings":[]},{"_id":"52544965f71e87d007000194","hierarchy":["Shops","Discount Stores"],"mappings":[]},{"_id":"52544965f71e87d007000195","hierarchy":["Shops","Electrical Equipment"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Electrical Equipment","",""]}]},{"_id":"52544965f71e87d007000196","hierarchy":["Shops","Equipment Rental"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Equipment Rental","",""]}]},{"_id":"52544965f71e87d007000197","hierarchy":["Shops","Flea Markets"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Flea Market",""]},{"map_type":"factual","hierarchy":["Retail","Flea Markets","",""]}]},{"_id":"52544965f71e87d007000198","hierarchy":["Shops","Florists"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Flower Shop",""]},{"map_type":"factual","hierarchy":["Retail","Florists","",""]}]},{"_id":"52544965f71e87d007000199","hierarchy":["Shops","Food and Beverage Store"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Food & Drink Shop",""]},{"map_type":"factual","hierarchy":["Retail","Food and Beverage","",""]}]},{"_id":"52544965f71e87d00700019a","hierarchy":["Shops","Food and Beverage Store","Beer, Wine and Spirits"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Food & Drink Shop","Wine Shop"]},{"map_type":"foursquare","hierarchy":["Shops & Services","Food & Drink Shop","Liquor Store"]},{"map_type":"factual","hierarchy":["Retail","Food and Beverage","Beer, Wine and Spirits",""]}]},{"_id":"52544965f71e87d00700019b","hierarchy":["Shops","Food and Beverage Store","Farmers Markets"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Food & Drink Shop","Farmers Market"]},{"map_type":"factual","hierarchy":["Retail","Food and Beverage","Farmers' Markets",""]}]},{"_id":"52544965f71e87d00700019c","hierarchy":["Shops","Food and Beverage Store","Health Food"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Food & Drink Shop","Health Food Store"]},{"map_type":"factual","hierarchy":["Retail","Food and Beverage","Health and Diet Food",""]}]},{"_id":"52544965f71e87d00700019d","hierarchy":["Shops","Food and Beverage Store","Specialty"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Candy Store",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","Food & Drink Shop","Cheese Shop"]},{"map_type":"foursquare","hierarchy":["Shops & Services","Food & Drink Shop","Butcher"]},{"map_type":"foursquare","hierarchy":["Shops & Services","Food & Drink Shop","Gourmet Shop"]},{"map_type":"foursquare","hierarchy":["Shops & Services","Food & Drink Shop","Fish Market"]},{"map_type":"factual","hierarchy":["Retail","Food and Beverage","Cheese",""]},{"map_type":"factual","hierarchy":["Retail","Food and Beverage","Kosher",""]},{"map_type":"factual","hierarchy":["Retail","Food and Beverage","Candy Stores",""]},{"map_type":"factual","hierarchy":["Retail","Food and Beverage","Chocolate",""]}]},{"_id":"52544965f71e87d00700019e","hierarchy":["Shops","Furniture and Home Decor"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Furniture / Home Store",""]},{"map_type":"factual","hierarchy":["Retail","Furniture and Home Decor","",""]}]},{"_id":"52544965f71e87d00700019f","hierarchy":["Shops","Gift and Novelty"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Gift Shop",""]},{"map_type":"factual","hierarchy":["Retail","Gift and Novelty","",""]}]},{"_id":"52544965f71e87d0070001a0","hierarchy":["Shops","Glasses and Optometrist"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Medical Center","Optical Shop"]},{"map_type":"factual","hierarchy":["Retail","Glasses and Optometrist","",""]}]},{"_id":"52544965f71e87d0070001a1","hierarchy":["Shops","Hardware Store"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Hardware Store",""]}]},{"_id":"52544965f71e87d0070001a2","hierarchy":["Shops","Hobby and Collectibles"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Hobby Shop",""]},{"map_type":"factual","hierarchy":["Retail","Hobby and Collectibles","",""]}]},{"_id":"52544965f71e87d0070001a3","hierarchy":["Shops","Jewelry and Watches"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Jewelry Store",""]},{"map_type":"factual","hierarchy":["Retail","Fashion","Jewelry and Watches",""]}]},{"_id":"52544965f71e87d0070001a4","hierarchy":["Shops","Luggage"],"mappings":[{"map_type":"factual","hierarchy":["Retail","Luggage","",""]}]},{"_id":"52544965f71e87d0070001a5","hierarchy":["Shops","Music, Video and DVD"],"mappings":[{"map_type":"factual","hierarchy":["Retail","Music, Video and DVD","",""]}]},{"_id":"52544965f71e87d0070001a6","hierarchy":["Shops","Newsstands"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Newsstand",""]},{"map_type":"factual","hierarchy":["Retail","Newsstands","",""]}]},{"_id":"52544965f71e87d0070001a7","hierarchy":["Shops","Nurseries and Garden Centers"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Garden Center",""]},{"map_type":"factual","hierarchy":["Retail","Nurseries and Garden Centers","",""]}]},{"_id":"52544965f71e87d0070001a8","hierarchy":["Shops","Office Supplies"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Paper / Office Supplies Store",""]}]},{"_id":"52544965f71e87d0070001a9","hierarchy":["Shops","Outlet"],"mappings":[{"map_type":"factual","hierarchy":["Retail","Outlet","",""]}]},{"_id":"52544965f71e87d0070001aa","hierarchy":["Shops","Pawn Shops"],"mappings":[{"map_type":"factual","hierarchy":["Retail","Pawn Shops","",""]}]},{"_id":"52544965f71e87d0070001ab","hierarchy":["Shops","Pets"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Pet Service",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","Pet Store",""]},{"map_type":"factual","hierarchy":["Retail","Pets","",""]}]},{"_id":"52544965f71e87d0070001ac","hierarchy":["Shops","Pharmacies"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Drugstore / Pharmacy",""]},{"map_type":"factual","hierarchy":["Healthcare","Pharmacies","",""]}]},{"_id":"52544965f71e87d0070001ad","hierarchy":["Shops","Photos and Frames"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Photography Lab",""]},{"map_type":"factual","hierarchy":["Retail","Photos and Frames","",""]}]},{"_id":"52544965f71e87d0070001ae","hierarchy":["Shops","Shoes"],"mappings":[]},{"_id":"52544965f71e87d0070001af","hierarchy":["Shops","Shopping Centers and Malls"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Mall",""]},{"map_type":"factual","hierarchy":["Retail","Shopping Centers and Malls","",""]}]},{"_id":"52544965f71e87d0070001b0","hierarchy":["Shops","Sporting Goods"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Board Shop",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","Sporting Goods Shop",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","Hunting Supply",""]},{"map_type":"factual","hierarchy":["Retail","Sporting Goods","",""]}]},{"_id":"52544965f71e87d0070001b1","hierarchy":["Shops","Supermarkets and Groceries"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Food & Drink Shop","Grocery Store"]},{"map_type":"factual","hierarchy":["Retail","Supermarkets and Groceries","",""]}]},{"_id":"52544965f71e87d0070001b2","hierarchy":["Shops","Tobacco"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Smoke Shop",""]},{"map_type":"factual","hierarchy":["Retail","Tobacco","",""]}]},{"_id":"52544965f71e87d0070001b3","hierarchy":["Shops","Toys"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Toy / Game Store",""]},{"map_type":"factual","hierarchy":["Retail","Toys","",""]}]},{"_id":"52544965f71e87d0070001b4","hierarchy":["Shops","Vintage and Thrift"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Thrift / Vintage Store",""]},{"map_type":"factual","hierarchy":["Retail","Vintage and Thrift","",""]}]},{"_id":"52544965f71e87d0070001b5","hierarchy":["Shops","Warehouses and Wholesale Stores"],"mappings":[{"map_type":"factual","hierarchy":["Retail","Warehouses and Wholesale Stores","",""]}]},{"_id":"52544965f71e87d0070001b6","hierarchy":["Shops","Wedding and Bridal"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Bridal Shop",""]},{"map_type":"factual","hierarchy":["Retail","Wedding and Bridal","",""]}]},{"_id":"52544965f71e87d0070001b7","hierarchy":["Shops","Wholesale"],"mappings":[{"map_type":"factual","hierarchy":["Services and Supplies","Wholesale","",""]}]},{"_id":"52544965f71e87d0070001b8","hierarchy":["Travel"],"mappings":[{"map_type":"foursquare","hierarchy":["Travel & Transport","",""]},{"map_type":"foursquare","hierarchy":["Travel & Transport","General Travel",""]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Moving Target",""]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Road",""]},{"map_type":"factual","hierarchy":["Transportation","","",""]},{"map_type":"factual","hierarchy":["Travel","","",""]}]},{"_id":"52544965f71e87d0070001b9","hierarchy":["Travel","Airlines and Aviation Services"],"mappings":[{"map_type":"factual","hierarchy":["Transportation","Airlines and Aviation Services","",""]}]},{"_id":"52544965f71e87d0070001ba","hierarchy":["Travel","Airports"],"mappings":[{"map_type":"foursquare","hierarchy":["Travel & Transport","Airport","Airport Terminal"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Airport",""]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Airport","Airport Lounge"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Airport","Airport Tram"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Airport","Airport Gate"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Airport","Airport Food Court"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Airport","Plane"]},{"map_type":"factual","hierarchy":["Transportation","Transport Hubs","Airports",""]}]},{"_id":"52544965f71e87d0070001bb","hierarchy":["Travel","Boat"],"mappings":[{"map_type":"foursquare","hierarchy":["Travel & Transport","Ferry","Pier"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Ferry","Boat or Ferry"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Ferry",""]},{"map_type":"factual","hierarchy":["Transportation","Transport Hubs","Ports",""]}]},{"_id":"52544965f71e87d0070001bc","hierarchy":["Travel","Bus Stations"],"mappings":[{"map_type":"foursquare","hierarchy":["Travel & Transport","Bus Station","Bus Line"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Bus Station",""]},{"map_type":"factual","hierarchy":["Transportation","Transport Hubs","Bus Stations",""]}]},{"_id":"52544965f71e87d0070001bd","hierarchy":["Travel","Car and Truck Rentals"],"mappings":[{"map_type":"factual","hierarchy":["Transportation","Taxi and Car Services","Car and Truck Rentals",""]}]},{"_id":"52544965f71e87d0070001be","hierarchy":["Travel","Charter Buses"],"mappings":[{"map_type":"factual","hierarchy":["Transportation","Taxi and Car Services","Charter Buses",""]}]},{"_id":"52544965f71e87d0070001bf","hierarchy":["Travel","Cruises"],"mappings":[{"map_type":"factual","hierarchy":["Travel","Cruises","",""]}]},{"_id":"52544965f71e87d0070001c0","hierarchy":["Travel","Gas Stations"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Gas Station / Garage",""]},{"map_type":"factual","hierarchy":["Transportation","Gas Stations","",""]}]},{"_id":"52544965f71e87d0070001c1","hierarchy":["Travel","Heliports"],"mappings":[{"map_type":"factual","hierarchy":["Transportation","Transport Hubs","Heliports",""]}]},{"_id":"52544965f71e87d0070001c2","hierarchy":["Travel","Limos and Chauffeurs"],"mappings":[{"map_type":"factual","hierarchy":["Transportation","Taxi and Car Services","Limos and Chauffeurs",""]}]},{"_id":"52544965f71e87d0070001c3","hierarchy":["Travel","Lodging"],"mappings":[{"map_type":"factual","hierarchy":["Travel","Lodging","",""]}]},{"_id":"52544965f71e87d0070001c4","hierarchy":["Travel","Lodging","Bed and Breakfasts"],"mappings":[{"map_type":"foursquare","hierarchy":["Travel & Transport","Hotel","Bed & Breakfast"]},{"map_type":"factual","hierarchy":["Travel","Lodging","Bed and Breakfasts",""]}]},{"_id":"52544965f71e87d0070001c5","hierarchy":["Travel","Lodging","Cottages and Cabins"],"mappings":[{"map_type":"factual","hierarchy":["Travel","Lodging","Cottages and Cabins",""]}]},{"_id":"52544965f71e87d0070001c6","hierarchy":["Travel","Lodging","Hostels"],"mappings":[{"map_type":"foursquare","hierarchy":["Travel & Transport","Hotel","Hostel"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Hotel","Boarding House"]},{"map_type":"factual","hierarchy":["Travel","Lodging","Hostels",""]}]},{"_id":"52544965f71e87d0070001c7","hierarchy":["Travel","Lodging","Hotels and Motels"],"mappings":[{"map_type":"foursquare","hierarchy":["Travel & Transport","Hotel","Hotel Pool"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Hotel",""]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Hotel","Motel"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Hotel","Roof Deck"]},{"map_type":"factual","hierarchy":["Travel","Lodging","Hotels and Motels",""]}]},{"_id":"52544965f71e87d0070001c8","hierarchy":["Travel","Lodging","Lodges and Vacation Rentals"],"mappings":[{"map_type":"factual","hierarchy":["Travel","Lodging","Lodges and Vacation Rentals",""]}]},{"_id":"52544965f71e87d0070001c9","hierarchy":["Travel","Lodging","Resorts"],"mappings":[{"map_type":"foursquare","hierarchy":["Travel & Transport","Hotel","Resort"]},{"map_type":"factual","hierarchy":["Travel","Lodging","Resorts",""]}]},{"_id":"52544965f71e87d0070001ca","hierarchy":["Travel","Parking"],"mappings":[{"map_type":"foursquare","hierarchy":["Professional & Other Places","Parking",""]},{"map_type":"factual","hierarchy":["Transportation","Parking","",""]}]},{"_id":"52544965f71e87d0070001cb","hierarchy":["Travel","Public Transportation Services"],"mappings":[{"map_type":"foursquare","hierarchy":["Travel & Transport","Subway",""]},{"map_type":"factual","hierarchy":["Transportation","Public Transportation Services","",""]}]},{"_id":"52544965f71e87d0070001cc","hierarchy":["Travel","Rail"],"mappings":[{"map_type":"foursquare","hierarchy":["Travel & Transport","Light Rail",""]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Train Station","Train"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Train Station","Platform"]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Train Station",""]},{"map_type":"factual","hierarchy":["Transportation","Transport Hubs","Rail Stations",""]}]},{"_id":"52544965f71e87d0070001cd","hierarchy":["Travel","Taxi and Car Services"],"mappings":[{"map_type":"foursquare","hierarchy":["Travel & Transport","Taxi",""]},{"map_type":"factual","hierarchy":["Transportation","Taxi and Car Services","",""]}]},{"_id":"52544965f71e87d0070001ce","hierarchy":["Travel","Transportation Centers"],"mappings":[{"map_type":"foursquare","hierarchy":["Travel & Transport","Rental Car Location",""]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Tourist Information Center",""]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Travel Lounge",""]},{"map_type":"foursquare","hierarchy":["Travel & Transport","Rest Area",""]},{"map_type":"factual","hierarchy":["Transportation","Transport Hubs","",""]}]},{"_id":"52544965f71e87d0070001cf","hierarchy":["Travel","Travel Agencies"],"mappings":[]},{"_id":"52545fb002dc224334000000","hierarchy":["Food & Drink"],"mappings":[]},{"_id":"52545fb002dc224334000005","hierarchy":["Food & Drink","Nightlife"],"mappings":[{"map_type":"foursquare","hierarchy":["Arts & Entertainment","Music Venue","Rock Club"]},{"map_type":"foursquare","hierarchy":["Nightlife Spots","",""]},{"map_type":"foursquare","hierarchy":["Nightlife Spots","Other Nightlife",""]}]},{"_id":"52546a49e99997c901000017","hierarchy":["Shops","Automotive"],"mappings":[{"map_type":"foursquare","hierarchy":["Shops & Services","Automotive Shop",""]},{"map_type":"foursquare","hierarchy":["Shops & Services","Car Wash",""]}]},{"_id":"52681ab08965128406000492","hierarchy":["Service","Automotive"],"mappings":[]}] \ No newline at end of file diff --git a/src/test/resources/__files/body-connect-5Htb4.json b/src/test/resources/__files/body-connect-5Htb4.json new file mode 100644 index 0000000..729d920 --- /dev/null +++ b/src/test/resources/__files/body-connect-5Htb4.json @@ -0,0 +1 @@ +{"message":"Successfully removed from system"} \ No newline at end of file diff --git a/src/test/resources/__files/body-connect-KwC7m.json b/src/test/resources/__files/body-connect-KwC7m.json new file mode 100644 index 0000000..9a260f4 --- /dev/null +++ b/src/test/resources/__files/body-connect-KwC7m.json @@ -0,0 +1 @@ +{"type":"list","mfa":[{"mask":"xxx-xxx-5309","type":"phone"},{"mask":"t..t@plaid.com","type":"email"}],"access_token":"test"} \ No newline at end of file diff --git a/src/test/resources/__files/body-connect-MpWQ7.json b/src/test/resources/__files/body-connect-MpWQ7.json new file mode 100644 index 0000000..dfb4641 --- /dev/null +++ b/src/test/resources/__files/body-connect-MpWQ7.json @@ -0,0 +1 @@ +{"type":"device","mfa":{"message":"Code sent to t..t@plaid.com"},"access_token":"test"} \ No newline at end of file diff --git a/src/test/resources/__files/body-connect-get-mU7ak.json b/src/test/resources/__files/body-connect-get-mU7ak.json new file mode 100644 index 0000000..38e40f6 --- /dev/null +++ b/src/test/resources/__files/body-connect-get-mU7ak.json @@ -0,0 +1 @@ +{"accounts":[{"_id":"52db1be4be13cbc36e000004","_item":"52af631671c3bd1b25000064","_user":"52af630f71c3bd1b25000063","balance":{"available":null,"current":12230},"meta":{"limit":null,"name":"Plaid Savings","number":"31015"},"institution_type":"fake_institution","type":"depository"},{"_id":"52db1be4be13cbc36e000005","_item":"52af631671c3bd1b25000064","_user":"52af630f71c3bd1b25000063","balance":{"available":null,"current":1113.13},"meta":{"limit":null,"name":"Plaid Checking","number":"65008"},"institution_type":"fake_institution","type":"depository"},{"_id":"52db1be4be13cbc36e000006","_item":"52af631671c3bd1b25000064","_user":"52af630f71c3bd1b25000063","balance":{"available":3721,"current":8.98},"meta":{"limit":3500,"name":"Plaid Credit Card","number":"93004"},"institution_type":"fake_institution","type":"credit"}],"transactions":[{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":6.25,"date":"2014-01-16","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be6be13cbc36e00007b","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":56.26,"date":"2014-01-15","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000a4","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":10,"date":"2014-01-16","name":"GOOGLE CHECKOUT SELLER","meta":{"location":{},"contact":{"website":"google.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000b5","_entity":"52cca015ec558faf5f030294","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":19.56,"date":"2014-01-14","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000b7","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":25.49,"date":"2014-01-03","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000ae","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":125,"date":"2014-01-10","name":"Int*webpass Inc","meta":{"location":{"zip":"94103","state":"CA","city":"San Francisco","address":"262 7 Th Street"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000103","_entity":"5268478c5f23a60b0e00051b","category":["Professional"],"category_id":"52544965f71e87d0070000c3"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":525.25,"date":"2014-01-14","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e00010f","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":1,"date":"2014-01-09","name":"Online Payment Processed","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"# 100"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be9be13cbc36e0000d6","_entity":"52d46dcee8bb7c7c3b008269","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":142.52,"date":"2014-01-06","name":"Jaron Logo","meta":{"location":{"coordinates":{"lng":-122.399262,"lat":37.780718},"zip":"94107","state":"CA","city":"San Francisco","address":"425 4th St"},"contact":{"telephone":"(415) 597-7511"},"ids":{"factual":"a7b474ac-17ba-4fd5-8940-8f51eeedb915"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1beabe13cbc36e0000e2","_entity":"52cd5bf3ec558faf5f03557d","category":["Service","Textiles"],"category_id":"52544965f71e87d00700016b"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":6.44,"date":"2014-01-08","name":"Square Transaction","meta":{"location":{}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000c3","_entity":"51df2f3d364351e13d000009"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":516.53,"date":"2014-01-14","name":"Ikea Home Shopping","meta":{"location":{"zip":"21236","state":"NOTTINGHAM","city":"Md","address":"Baltimore"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be9be13cbc36e0000de","_entity":"52a127c10c16b9c47100035b","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":59.14,"date":"2014-01-14","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000116","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":0.8,"detail":{"name":1,"state":1,"city":1,"zip":1}},"type":{"primary":"unresolved"},"amount":29.95,"date":"2014-01-09","name":"Freshbooks","meta":{"location":{"zip":"M6R2J5","state":"TORONTO","city":"35 Golden Avenue Suite 105"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be9be13cbc36e0000d7","_entity":"52a4978ae411f6f2070204c4","category":["Professional","Financial","Banking and Finance"],"category_id":"52544965f71e87d0070000df"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital"},"amount":51.22,"date":"2014-01-07","name":"Seamless","meta":{"location":{},"contact":{"website":"seamless.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be6be13cbc36e00007e","_entity":"51df0152e52532e03b000002"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":24.04,"date":"2014-01-04","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000af","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":3.5,"date":"2014-01-08","name":"Capital One 360 Café","meta":{"location":{"coordinates":{"lng":-122.40372312029795,"lat":37.7888611347371},"zip":"94108","state":"CA","city":"San Francisco","address":"101 Post St"},"contact":{"telephone":"4152484920"},"ids":{"foursquare":"4d87c47c0c422d436a43ee30","factual":"2a04d84d-25ef-4bad-9603-9b333cc4e35b"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000100","_entity":"52a553acbdcc808903004b30","category":["Food & Drink","Restaurants","Cafe"],"category_id":"52544965f71e87d007000059"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":10.7,"date":"2014-01-12","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000d9","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":11.56,"date":"2014-01-15","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e1","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":29.85,"date":"2014-01-06","name":"Starbucks","meta":{"location":{"coordinates":{"lng":-122.40341336071333,"lat":37.7873326351124},"zip":"94103","state":"CA","city":"San Francisco","address":"7 3rd St"},"contact":{"telephone":"4159799530"},"ids":{"foursquare":"4a7324d9f964a520aadb1fe3","factual":"6ac4ea59-397d-498a-9d10-e4dc2cda6cac"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e0000fa","_entity":"526847885f23a60b0e00041c","category":["Food & Drink","Restaurants","Coffee Shop"],"category_id":"52544965f71e87d00700005d"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":600,"date":"2013-12-19","name":"Umami","meta":{"location":{"coordinates":{"lng":-122.43374347686768,"lat":37.79774659682308},"zip":"94123","state":"CA","city":"San Francisco","address":"2909 Webster St"},"contact":{"telephone":"4153463431"},"ids":{"foursquare":"4a0e428cf964a520da751fe3"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be9be13cbc36e0000df","_entity":"52684c615f23a60b0e002b15","category":["Food & Drink","Restaurants","Asian"],"category_id":"52544965f71e87d007000050"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":129.64,"date":"2014-01-15","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be8be13cbc36e0000d5","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":75.1,"date":"2014-01-09","name":"Online Payment Processed","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"# 100"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000107","_entity":"52d46dcee8bb7c7c3b008269","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":12.52,"date":"2014-01-14","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e3","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":-59.14,"date":"2014-01-14","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1beabe13cbc36e0000e5","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":25.49,"date":"2014-01-03","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000a5","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":346.26,"date":"2014-01-16","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000102","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":0.96667,"detail":{"zip":1,"name":0.3333333333333333,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":35.45,"date":"2014-01-12","name":"Mayes Oyster and Steak House","meta":{"location":{"coordinates":{"lng":-122.42027180518197,"lat":37.78830541267099},"zip":"94109","state":"CA","city":"San Francisco","address":"1233 Polk St"},"contact":{"telephone":"4154747674"},"ids":{"foursquare":"4afb7c6df964a5204d1e22e3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000db","_entity":"5272bee03429c3f11000bea5","category":["Food & Drink","Restaurants","American"],"category_id":"52544965f71e87d00700004f"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-2101.53,"date":"2014-01-15","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000b6","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":46.75,"date":"2014-01-13","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a2","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-800,"date":"2014-01-13","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e00009f","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":12.96,"date":"2014-01-16","name":"Galette 88","meta":{"location":{"coordinates":{"lng":-122.40363836288452,"lat":37.79031975640008},"zip":"94108","state":"CA","city":"San Francisco","address":"88 Hardie Pl"},"contact":{"telephone":"4159892222"},"ids":{"foursquare":"4edadafe6d869ce1d11cce2e"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e8","_entity":"52ae45270ae6dce65e009479","category":["Food & Drink","Restaurants","French"],"category_id":"52544965f71e87d00700006c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":175.49,"date":"2014-01-04","name":"Curtain Works","meta":{"location":{"zip":"28217","state":"NC","city":"Charlotte","address":"Ste 400"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e0000f5","_entity":"52c9ba92ec558faf5f01ab84","category":["Shops"],"category_id":"52544965f71e87d007000170"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":11.42,"date":"2014-01-14","name":"Sushirrito","meta":{"location":{"zip":"94108","state":"CA","city":"San Francisco","address":"226 Kearny St"},"ids":{"foursquare":"5169c1b4498eb65b81bd735a"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f2","_entity":"526847945f23a60b0e000707","category":["Food & Drink","Restaurants","Sushi"],"category_id":"52544965f71e87d007000082"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":22.74,"date":"2014-01-10","name":"Rouge Nightclub Inc","meta":{"location":{"zip":"94107","state":"CA","city":"San Francisco","address":"715 Harrison St"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000112","_entity":"526847955f23a60b0e000761","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":112.17,"date":"2014-01-14","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000cc","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":0.8,"date":"2014-01-04","name":"AMAZON WEB SERVICES","meta":{"location":{},"contact":{"website":"amazon.co"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000ce","_entity":"526847775f23a60b0e00017b","category":["Miscellaneous"],"category_id":"52544965f71e87d007000088"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":9.67,"date":"2014-01-06","name":"Bread and Cocoa","meta":{"location":{"coordinates":{"lng":-122.40359544754028,"lat":37.789709297957295},"zip":"94104","state":"CA","city":"San Francisco","address":"199 Sutter St"},"contact":{"telephone":"4159567200"},"ids":{"foursquare":"49e6c22df964a52069641fe3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000ef","_entity":"526847815f23a60b0e000313","category":["Food & Drink","Restaurants","Coffee Shop"],"category_id":"52544965f71e87d00700005d"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital"},"amount":2.99,"date":"2014-01-06","name":"Amazon Digital Downloads","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a6","_entity":"51df0af8e52532e03b000004"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":50,"date":"2014-01-09","name":"Lolinda","meta":{"location":{"coordinates":{"lng":-122.41880893707274,"lat":37.756804912698485},"zip":"94110","state":"CA","city":"San Francisco","address":"2518 Mission St"},"contact":{"telephone":"4155506970"},"ids":{"foursquare":"50243fd229a61e4b21a26e16"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be8be13cbc36e0000d3","_entity":"52a980d454dd694709000215","category":["Food & Drink","Restaurants","Steakhouses"],"category_id":"52544965f71e87d007000081"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":52.28,"date":"2014-01-03","name":"Blowfish","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"2170 Bryant St"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f4","_entity":"529048c708e4eabe44007b5d","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":12.33,"date":"2014-01-09","name":"Tropisueño","meta":{"location":{"coordinates":{"lng":-122.40393340587616,"lat":37.78534267732514},"zip":"94103","state":"CA","city":"San Francisco","address":"75 Yerba Buena Ln"},"contact":{"telephone":"4152430299"},"ids":{"foursquare":"4a5f8994f964a520d5bf1fe3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000ee","_entity":"526847945f23a60b0e000714","category":["Food & Drink","Restaurants","Mexican"],"category_id":"52544965f71e87d007000079"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":9.3,"date":"2014-01-07","name":"Chipotle Mexican Grill","meta":{"location":{"coordinates":{"lng":-122.40385587412636,"lat":37.7898142010025},"zip":"94108","state":"CA","city":"San Francisco","address":"211 Sutter St"},"contact":{"telephone":"4155904199"},"ids":{"foursquare":"50a40b4c498ef6257de3eb6a","factual":"93ecb774-185d-46a3-a17e-aaa1dfc421c4"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f8","_entity":"526847775f23a60b0e00014d","category":["Food & Drink","Restaurants","Mexican"],"category_id":"52544965f71e87d007000079"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":50.11,"date":"2014-01-03","name":"Safeway","meta":{"location":{"coordinates":{"lng":-122.43288516998291,"lat":37.8045623549303},"zip":"94123","state":"CA","city":"San Francisco","address":"15 Marina Blvd"},"contact":{"telephone":"4155634946"},"ids":{"foursquare":"4a5931a2f964a520f0b81fe3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be8be13cbc36e0000d4","_entity":"5272beb53429c3f11000b6a3","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":16,"date":"2013-12-29","name":"Vero Westside","meta":{"location":{"zip":"95448","state":"CA","city":"Healdsburg","address":"6050 Westside Rd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f0","_entity":"52c2cfc5590084f05f018796","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":10,"date":"2014-01-01","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000fc","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":11.25,"date":"2014-01-04","name":"Bovine Bakery Pt. Reyes","meta":{"location":{"zip":"94956","state":"POINT REYES STATION","city":"Ca","address":"Pt Reyes Station"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e9","_entity":"52a1042dc84b48ea010016db","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":33.3,"date":"2013-12-30","name":"Online Payment Processed","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"# 100"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e6","_entity":"52d46dcee8bb7c7c3b008269","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":0.58,"date":"2014-01-04","name":"AMAZON WEB SERVICES","meta":{"location":{},"contact":{"website":"amazon.co"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000b3","_entity":"526847775f23a60b0e00017b","category":["Miscellaneous"],"category_id":"52544965f71e87d007000088"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":72.11,"date":"2013-12-31","name":"Safeway 1206","meta":{"location":{"zip":"94133","state":"CA","city":"San Francisco","address":"Ste 6"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000fe","_entity":"52684e305f23a60b0e0077c3","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":15.02,"date":"2014-01-03","name":"Chevron Usa","meta":{"location":{"zip":"94520","state":"CA","city":"Concord","address":"2003 Diamond Blvd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000110","_entity":"5268478c5f23a60b0e000527","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":4.88,"date":"2013-12-30","name":"GOOGLE CHECKOUT SELLER","meta":{"location":{},"contact":{"website":"supermgoogle.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a3","_entity":"52a55227062d0fad200048ae","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":100.83,"date":"2014-01-03","name":"Hops & Hominy","meta":{"location":{"coordinates":{"lng":-122.40572547274216,"lat":37.78931076807203},"zip":"94108","state":"CA","city":"San Francisco","address":"1 Tillman Pl"},"contact":{"telephone":"4153736341"},"ids":{"foursquare":"4ed9a975be7be28336ddc111"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000dc","_entity":"526847885f23a60b0e000413","category":["Food & Drink","Restaurants","American"],"category_id":"52544965f71e87d00700004f"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":10,"date":"2013-12-29","name":"Porter Creek Winery","meta":{"location":{"coordinates":{"lng":-122.89016760129537,"lat":38.521034405303894},"zip":"95448","state":"CA","city":"Healdsburg","address":"8735 Westside Rd"},"contact":{"telephone":"7074336321"},"ids":{"foursquare":"4b661136f964a520cb112be3","factual":"4f0034b2-1bb6-4e91-93e8-519d6d570495"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000101","_entity":"52c2cfab590084f05f0185b6","category":["Food & Drink","Restaurants","Winery"],"category_id":"52544965f71e87d007000087"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-400,"date":"2014-01-02","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000b2","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":10.66,"date":"2013-12-26","name":"Wilco Food Mart 357","meta":{"location":{"zip":"28166","state":"NC","city":"Troutman","address":"1006 Charlotte Hwy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f7","_entity":"52bed9b710b439a912005644","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":52.76,"date":"2013-12-26","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e00009e","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":70.14,"date":"2014-01-03","name":"Sports Basement","meta":{"location":{"coordinates":{"lng":-122.41096,"lat":37.767054},"zip":"94103","state":"CA","city":"San Francisco","address":"1590 Bryant St"},"contact":{"telephone":"4155753000"},"ids":{"foursquare":"4a09ef9af964a52070741fe3","factual":"10930fc3-d54e-4dc0-84ed-f8ce95d2fefd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000115","_entity":"529048ce17c7425b3b00fb63","category":["Shops","Sporting Goods"],"category_id":"52544965f71e87d0070001b0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":47,"date":"2013-12-27","name":"Laurienzo Brick Oven","meta":{"location":{"zip":"21771","state":"MYERSVILLE","city":"Md","address":"Mount Airy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000ff","_entity":"52c07fe610b439a91200ae65","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":35.46,"date":"2013-12-29","name":"Cheese Plus","meta":{"location":{"coordinates":{"lng":-122.421783,"lat":37.795058},"zip":"94109","state":"CA","city":"San Francisco","address":"2001 Polk St"},"contact":{"telephone":"4159212001"},"ids":{"foursquare":"4a222e61f964a520677d1fe3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000eb","_entity":"52ae45246dd4e787270033b3","category":["Shops","Food and Beverage Store","Specialty"],"category_id":"52544965f71e87d00700019d"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":40.05,"date":"2013-12-27","name":"Mosaic","meta":{"location":{"coordinates":{"lng":-76.60696364892934,"lat":39.28950572222763},"zip":"21202","state":"MD","city":"Baltimore","address":"4 Market Pl"},"contact":{"telephone":"4102628713"},"ids":{"foursquare":"4b2315cef964a5201e5324e3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be8be13cbc36e0000d1","_entity":"52d2bce0e8bb7c7c3b000a96","category":["Food & Drink","Nightlife","Night Clubs"],"category_id":"52544965f71e87d007000048"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":17.42,"date":"2013-12-27","name":"Brewer's Alley","meta":{"location":{"coordinates":{"lng":-77.41064750324045,"lat":39.41609008056981},"zip":"21701","state":"MD","city":"Frederick","address":"124 N Market St"},"contact":{"telephone":"3016310089"},"ids":{"foursquare":"4ab3b494f964a520136e20e3","factual":"174c0d71-c905-4f7c-a07e-90718621006d"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000da","_entity":"52c08001590084f05f00ad1e","category":["Food & Drink","Breweries"],"category_id":"52544965f71e87d007000041"},{"score":{"master":1,"detail":{"zip":1,"name":0.94,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":4.55,"date":"2013-12-26","name":"Starbucks B #152","meta":{"location":{"zip":"28208","state":"NC","city":"Charlotte","address":"5501 Josh Birmingham Pkwy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000fd","_entity":"52684e025f23a60b0e0070f7","category":["Food & Drink","Nightlife","Bar"],"category_id":"52544965f71e87d007000044"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":12,"date":"2013-12-28","name":"Pickles Pub","meta":{"location":{"coordinates":{"lng":-76.62269711494446,"lat":39.285378238756444},"zip":"21230","state":"MD","city":"Baltimore","address":"520 Washington Blvd"},"contact":{"telephone":"4107521784"},"ids":{"foursquare":"4ab444edf964a520a97020e3","factual":"5e0aca04-6843-4639-ad82-54ffc0d36cb3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f6","_entity":"52c08009590084f05f00ae2c","category":["Food & Drink","Nightlife","Bar"],"category_id":"52544965f71e87d007000044"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":10,"date":"2013-12-26","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a8","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":54,"date":"2013-12-27","name":"The Corner Bistro & Winebar","meta":{"location":{"coordinates":{"lng":-76.62582365723517,"lat":39.285605663839426},"zip":"21230","state":"MD","city":"Baltimore","address":"213 Penn St"},"contact":{"telephone":"4107271155"},"ids":{"foursquare":"4e6fe217b9935ff0b50def7c","factual":"1bce75d1-b6bb-433b-94cc-2a2fae8ca084"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010d","_entity":"52db180352d559616e00012b","category":["Food & Drink","Restaurants","Winery"],"category_id":"52544965f71e87d007000087"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":4.35,"date":"2013-12-30","name":"GOOGLE CHECKOUT SELLER","meta":{"location":{},"contact":{"website":"cogoogle.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000cd","_entity":"526847825f23a60b0e000387","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":40,"date":"2013-12-29","name":"Online Payment Processed","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"# 100"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e4","_entity":"52d46dcee8bb7c7c3b008269","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":33.97,"date":"2013-12-27","name":"Sheetz","meta":{"location":{"coordinates":{"lng":-77.387792,"lat":39.407061},"zip":"21701","state":"MD","city":"Frederick","address":"1300 E Patrick St"},"contact":{"telephone":"3016315200"},"ids":{"foursquare":"4b40febff964a520f8be25e3","factual":"c26279c0-d71c-48d6-9994-56a0272b45c9"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010a","_entity":"52c07ff110b439a91200aef2","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":140,"date":"2013-12-25","name":"Olympic Meats","meta":{"location":{"zip":"97209","state":"OR","city":"Portland","address":"#132"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f9","_entity":"52bc3728d6da4e7c0b005a9d","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":37.43,"date":"2013-12-24","name":"Fresh Market The","meta":{"location":{"coordinates":{"lng":-80.31173,"lat":36.115811},"zip":"27106","state":"NC","city":"Winston Salem","address":"3285 Robinhood Rd"},"contact":{"telephone":"(336) 760-2519"},"ids":{"factual":"1a0e253e-d97c-4420-ab47-120b977876ce"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000104","_entity":"52bc3757d6da4e7c0b005c24","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":150,"date":"2013-12-24","name":"The Spa at Highland Oaks","meta":{"location":{"coordinates":{"lng":-80.30215623738016,"lat":36.05963070139284},"zip":"27103","state":"NC","city":"Winston Salem","address":"765 Highland Oaks Dr, Ste 150"},"ids":{"foursquare":"4ceab2bde888f04d7e974e6b","factual":"4db980c2-72f8-4f55-a82f-4b6bf1031a01"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be8be13cbc36e0000d2","_entity":"52bc3710fd90ebfd53005f01","category":["Service","Personal Care","Spas"],"category_id":"52544965f71e87d007000153"},{"score":{"master":0},"type":{"primary":"unresolved"},"amount":-0.01,"date":"2013-12-23","name":"","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000117","_entity":"52db1be7be13cbc36e0000c4","category":["Fees & Payments"],"category_id":"52544965f71e87d007000040"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital"},"amount":5.99,"date":"2013-12-23","name":"Amazon Digital Downloads","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000cf","_entity":"51df0af8e52532e03b000004"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":25,"date":"2013-12-25","name":"Us Airways Web Sales","meta":{"location":{"zip":"85034","state":"AZ","city":"Phoenix","address":"4000 E Sky Harbor Blvd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000dd","_entity":"52684be85f23a60b0e001722","category":["Travel","Airlines and Aviation Services"],"category_id":"52544965f71e87d0070001b9"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":21.48,"date":"2013-12-24","name":"Barnes & Noble 2761","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"1925 Hampton Inn Ct"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010c","_entity":"52bc3746fd90ebfd53005f69","category":["Shops","Bookstores"],"category_id":"52544965f71e87d00700017e"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":25,"date":"2013-12-22","name":"Schoolhouse Electric & Supply Co.","meta":{"location":{"coordinates":{"lng":-122.69696420281844,"lat":45.54129868720819},"zip":"97210","state":"OR","city":"Portland","address":"2181 NW Nicolai St, Portland, OR 97210"},"contact":{"telephone":"5032307082"},"ids":{"foursquare":"4ec84d6d9a52756c56b97c5f","factual":"d05199f8-a77c-44de-a9a3-d0c935c6c3fa"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e7","_entity":"52b5a4122c9e708730001d08","category":["Shops","Department Stores"],"category_id":"52544965f71e87d007000192"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital"},"amount":1.99,"date":"2013-12-23","name":"Amazon Digital Downloads","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a1","_entity":"51df0af8e52532e03b000004"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":20.25,"date":"2013-12-23","name":"Square Transaction","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000ad","_entity":"51df2f3d364351e13d000009"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":17.04,"date":"2013-12-22","name":"William Sonoma","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"3320 Silas Creek Pkwy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000ed","_entity":"52b993b9d6da4e7c0b00030a","category":["Shops","Furniture and Home Decor"],"category_id":"52544965f71e87d00700019e"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":21.02,"date":"2013-12-30","name":"GOOGLE CHECKOUT SELLER","meta":{"location":{},"contact":{"website":"google.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a0","_entity":"52cca015ec558faf5f030294","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":7.5,"date":"2013-12-22","name":"Delta Air Lines Inc.","meta":{"location":{"zip":"30320","state":"GA","city":"Atlanta","address":"Atlanta Airport"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000105","_entity":"52684d6f5f23a60b0e0057de","category":["Travel","Airlines and Aviation Services"],"category_id":"52544965f71e87d0070001b9"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":277.55,"date":"2013-12-22","name":"Great Outdoor Prvsn Co","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"402 S Stratford Rd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010e","_entity":"52684f455f23a60b0e009812","category":["Shops","Sporting Goods"],"category_id":"52544965f71e87d0070001b0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":96.1,"date":"2013-12-23","name":"Lsi Sonoma Rtl Wsj Wine","meta":{"location":{"zip":"06854","state":"CT","city":"Norwalk","address":"Ste 320"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000ea","_entity":"52a93c09d8511a177d007968","category":["Shops"],"category_id":"52544965f71e87d007000170"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":1.88,"date":"2013-12-22","name":"Kelly's Confections Inc","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"3320 Silas Creek Pkwy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000106","_entity":"52684e835f23a60b0e00855d","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":84,"date":"2013-12-23","name":"Zerve Tours Shows Events","meta":{"location":{"zip":"10013","state":"NY","city":"New York","address":"Rm 604"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f3","_entity":"52a24f89d627f2b54d00fb90","category":["Travel","Travel Agencies"],"category_id":"52544965f71e87d0070001cf"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":5.12,"date":"2013-12-19","name":"Chevron Usa","meta":{"location":{"zip":"94520","state":"CA","city":"Concord","address":"2003 Diamond Blvd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000109","_entity":"5268478c5f23a60b0e000527","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":20.57,"date":"2013-12-22","name":"Thelooppizzagrille","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"320 S Stratford Rd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010b","_entity":"52b993aafd90ebfd53000137","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":24.55,"date":"2013-12-22","name":"Van Davis Aveda","meta":{"location":{"coordinates":{"lng":-80.2816481,"lat":36.092929},"zip":"27103","state":"NC","city":"Winston Salem","address":"244 S Stratford Rd"},"contact":{"telephone":"3367211332"},"ids":{"foursquare":"4bc4d3974cdfc9b6ad389921"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000111","_entity":"52684e345f23a60b0e007824","category":["Service","Personal Care","Hair Salons and Barbers"],"category_id":"52544965f71e87d00700014e"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":50,"date":"2013-12-21","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f1","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":3.12,"date":"2013-12-21","name":"Starbucks Term C#153","meta":{"location":{"zip":"27623","state":"NC","city":"Raleigh","address":"1025 Airside Dr, Ste 2101"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000e0","_entity":"52684e205f23a60b0e00758b","category":["Food & Drink","Nightlife","Bar"],"category_id":"52544965f71e87d007000044"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":35.96,"date":"2013-12-22","name":"Wilco Fuel Plaza 1122","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"2026 S Hawthorne Rd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000113","_entity":"52b993acd6da4e7c0b0002e1","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":69,"date":"2013-12-21","name":"L L Bean","meta":{"location":{"coordinates":{"lng":-70.102862,"lat":43.857211},"zip":"04032","state":"ME","city":"Freeport","address":"95 Main St"},"contact":{"telephone":"(207) 865-6660"},"ids":{"factual":"22963af1-7bf9-492d-818b-4bb355d1fe62"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000108","_entity":"5278254010ce27ec03003e7a","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":8.98,"date":"2014-01-16","name":"Interest Charges on Purchases","meta":{"location":{}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be7be13cbc36e0000b4","_entity":"51df517968ab247d41000004"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":260.86,"date":"2014-01-16","name":"EVENTBRITE","meta":{"location":{},"contact":{"website":"*meatup.io"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be7be13cbc36e0000d0","_entity":"52a3f098524beee12801ddae","category":["Arts & Entertainment","Entertainment"],"category_id":"52544965f71e87d00700000a"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-1000,"date":"2014-01-02","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be6be13cbc36e000079","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":64.99,"date":"2014-01-04","name":"Crunch","meta":{"location":{"coordinates":{"lng":-73.9984,"lat":40.74205},"zip":"10011","state":"NY","city":"New York","address":"220 West 19th Street"},"contact":{"telephone":"2123700998"},"ids":{"foursquare":"5065e558011c9fb87575b212"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1bebbe13cbc36e0000fb","_entity":"52d08c2629b10e5f6a056eee","category":["Parks & Outdoors","Gyms and Fitness Centers"],"category_id":"52544965f71e87d00700009a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":9.8,"date":"2014-01-03","name":"Nyc Bike Share","meta":{"location":{"zip":"97214","state":"OR","city":"Portland","address":"711 Se Grand Avenue"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1bebbe13cbc36e0000ec","_entity":"52684c045f23a60b0e001b17","category":["Miscellaneous"],"category_id":"52544965f71e87d007000088"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-214.76,"date":"2014-01-15","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be6be13cbc36e00007c","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":28.85,"date":"2014-01-17","name":"La Folie","meta":{"location":{"coordinates":{"lng":-122.42219641613993,"lat":37.79805635393336},"zip":"94109","state":"CA","city":"San Francisco","address":"2316 Polk St"},"contact":{"telephone":"4157765577"},"ids":{"foursquare":"49e04b9af964a5204f611fe3","factual":"09740eae-2f29-4079-a828-fced3d4bd52b"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1bebbe13cbc36e000114","_entity":"527c3ec3a82308293a008586","category":["Food & Drink","Restaurants","French"],"category_id":"52544965f71e87d00700006c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":139.97,"date":"2014-01-01","name":"Crunch","meta":{"location":{"coordinates":{"lng":-122.42223,"lat":37.79827},"zip":"94109","state":"CA","city":"San Francisco","address":"2330 Polk Street"},"contact":{"telephone":"4152925444"},"ids":{"foursquare":"49d79743f964a520385d1fe3","factual":"ccd1c1d1-fd81-4535-98fe-64ac2364af15"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be9be13cbc36e0000d8","_entity":"52a6ff1c949382717e00e816","category":["Parks & Outdoors","Gyms and Fitness Centers"],"category_id":"52544965f71e87d00700009a"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-923.26,"date":"2013-12-24","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be6be13cbc36e00007d","_entity":"51df2f4f364351e13d00000a"}],"access_token":"test"} \ No newline at end of file diff --git a/src/test/resources/__files/body-connect-qZWyb.json b/src/test/resources/__files/body-connect-qZWyb.json new file mode 100644 index 0000000..38e40f6 --- /dev/null +++ b/src/test/resources/__files/body-connect-qZWyb.json @@ -0,0 +1 @@ +{"accounts":[{"_id":"52db1be4be13cbc36e000004","_item":"52af631671c3bd1b25000064","_user":"52af630f71c3bd1b25000063","balance":{"available":null,"current":12230},"meta":{"limit":null,"name":"Plaid Savings","number":"31015"},"institution_type":"fake_institution","type":"depository"},{"_id":"52db1be4be13cbc36e000005","_item":"52af631671c3bd1b25000064","_user":"52af630f71c3bd1b25000063","balance":{"available":null,"current":1113.13},"meta":{"limit":null,"name":"Plaid Checking","number":"65008"},"institution_type":"fake_institution","type":"depository"},{"_id":"52db1be4be13cbc36e000006","_item":"52af631671c3bd1b25000064","_user":"52af630f71c3bd1b25000063","balance":{"available":3721,"current":8.98},"meta":{"limit":3500,"name":"Plaid Credit Card","number":"93004"},"institution_type":"fake_institution","type":"credit"}],"transactions":[{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":6.25,"date":"2014-01-16","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be6be13cbc36e00007b","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":56.26,"date":"2014-01-15","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000a4","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":10,"date":"2014-01-16","name":"GOOGLE CHECKOUT SELLER","meta":{"location":{},"contact":{"website":"google.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000b5","_entity":"52cca015ec558faf5f030294","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":19.56,"date":"2014-01-14","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000b7","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":25.49,"date":"2014-01-03","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000ae","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":125,"date":"2014-01-10","name":"Int*webpass Inc","meta":{"location":{"zip":"94103","state":"CA","city":"San Francisco","address":"262 7 Th Street"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000103","_entity":"5268478c5f23a60b0e00051b","category":["Professional"],"category_id":"52544965f71e87d0070000c3"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":525.25,"date":"2014-01-14","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e00010f","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":1,"date":"2014-01-09","name":"Online Payment Processed","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"# 100"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be9be13cbc36e0000d6","_entity":"52d46dcee8bb7c7c3b008269","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":142.52,"date":"2014-01-06","name":"Jaron Logo","meta":{"location":{"coordinates":{"lng":-122.399262,"lat":37.780718},"zip":"94107","state":"CA","city":"San Francisco","address":"425 4th St"},"contact":{"telephone":"(415) 597-7511"},"ids":{"factual":"a7b474ac-17ba-4fd5-8940-8f51eeedb915"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1beabe13cbc36e0000e2","_entity":"52cd5bf3ec558faf5f03557d","category":["Service","Textiles"],"category_id":"52544965f71e87d00700016b"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":6.44,"date":"2014-01-08","name":"Square Transaction","meta":{"location":{}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000c3","_entity":"51df2f3d364351e13d000009"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":516.53,"date":"2014-01-14","name":"Ikea Home Shopping","meta":{"location":{"zip":"21236","state":"NOTTINGHAM","city":"Md","address":"Baltimore"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be9be13cbc36e0000de","_entity":"52a127c10c16b9c47100035b","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":59.14,"date":"2014-01-14","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000116","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":0.8,"detail":{"name":1,"state":1,"city":1,"zip":1}},"type":{"primary":"unresolved"},"amount":29.95,"date":"2014-01-09","name":"Freshbooks","meta":{"location":{"zip":"M6R2J5","state":"TORONTO","city":"35 Golden Avenue Suite 105"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be9be13cbc36e0000d7","_entity":"52a4978ae411f6f2070204c4","category":["Professional","Financial","Banking and Finance"],"category_id":"52544965f71e87d0070000df"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital"},"amount":51.22,"date":"2014-01-07","name":"Seamless","meta":{"location":{},"contact":{"website":"seamless.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be6be13cbc36e00007e","_entity":"51df0152e52532e03b000002"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":24.04,"date":"2014-01-04","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000af","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":3.5,"date":"2014-01-08","name":"Capital One 360 Café","meta":{"location":{"coordinates":{"lng":-122.40372312029795,"lat":37.7888611347371},"zip":"94108","state":"CA","city":"San Francisco","address":"101 Post St"},"contact":{"telephone":"4152484920"},"ids":{"foursquare":"4d87c47c0c422d436a43ee30","factual":"2a04d84d-25ef-4bad-9603-9b333cc4e35b"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000100","_entity":"52a553acbdcc808903004b30","category":["Food & Drink","Restaurants","Cafe"],"category_id":"52544965f71e87d007000059"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":10.7,"date":"2014-01-12","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000d9","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":11.56,"date":"2014-01-15","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e1","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":29.85,"date":"2014-01-06","name":"Starbucks","meta":{"location":{"coordinates":{"lng":-122.40341336071333,"lat":37.7873326351124},"zip":"94103","state":"CA","city":"San Francisco","address":"7 3rd St"},"contact":{"telephone":"4159799530"},"ids":{"foursquare":"4a7324d9f964a520aadb1fe3","factual":"6ac4ea59-397d-498a-9d10-e4dc2cda6cac"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e0000fa","_entity":"526847885f23a60b0e00041c","category":["Food & Drink","Restaurants","Coffee Shop"],"category_id":"52544965f71e87d00700005d"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":600,"date":"2013-12-19","name":"Umami","meta":{"location":{"coordinates":{"lng":-122.43374347686768,"lat":37.79774659682308},"zip":"94123","state":"CA","city":"San Francisco","address":"2909 Webster St"},"contact":{"telephone":"4153463431"},"ids":{"foursquare":"4a0e428cf964a520da751fe3"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be9be13cbc36e0000df","_entity":"52684c615f23a60b0e002b15","category":["Food & Drink","Restaurants","Asian"],"category_id":"52544965f71e87d007000050"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":129.64,"date":"2014-01-15","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be8be13cbc36e0000d5","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":75.1,"date":"2014-01-09","name":"Online Payment Processed","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"# 100"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000107","_entity":"52d46dcee8bb7c7c3b008269","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":12.52,"date":"2014-01-14","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e3","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":-59.14,"date":"2014-01-14","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1beabe13cbc36e0000e5","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":25.49,"date":"2014-01-03","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000a5","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":346.26,"date":"2014-01-16","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000102","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":0.96667,"detail":{"zip":1,"name":0.3333333333333333,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":35.45,"date":"2014-01-12","name":"Mayes Oyster and Steak House","meta":{"location":{"coordinates":{"lng":-122.42027180518197,"lat":37.78830541267099},"zip":"94109","state":"CA","city":"San Francisco","address":"1233 Polk St"},"contact":{"telephone":"4154747674"},"ids":{"foursquare":"4afb7c6df964a5204d1e22e3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000db","_entity":"5272bee03429c3f11000bea5","category":["Food & Drink","Restaurants","American"],"category_id":"52544965f71e87d00700004f"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-2101.53,"date":"2014-01-15","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000b6","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":46.75,"date":"2014-01-13","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a2","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-800,"date":"2014-01-13","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e00009f","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":12.96,"date":"2014-01-16","name":"Galette 88","meta":{"location":{"coordinates":{"lng":-122.40363836288452,"lat":37.79031975640008},"zip":"94108","state":"CA","city":"San Francisco","address":"88 Hardie Pl"},"contact":{"telephone":"4159892222"},"ids":{"foursquare":"4edadafe6d869ce1d11cce2e"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e8","_entity":"52ae45270ae6dce65e009479","category":["Food & Drink","Restaurants","French"],"category_id":"52544965f71e87d00700006c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":175.49,"date":"2014-01-04","name":"Curtain Works","meta":{"location":{"zip":"28217","state":"NC","city":"Charlotte","address":"Ste 400"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e0000f5","_entity":"52c9ba92ec558faf5f01ab84","category":["Shops"],"category_id":"52544965f71e87d007000170"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":11.42,"date":"2014-01-14","name":"Sushirrito","meta":{"location":{"zip":"94108","state":"CA","city":"San Francisco","address":"226 Kearny St"},"ids":{"foursquare":"5169c1b4498eb65b81bd735a"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f2","_entity":"526847945f23a60b0e000707","category":["Food & Drink","Restaurants","Sushi"],"category_id":"52544965f71e87d007000082"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":22.74,"date":"2014-01-10","name":"Rouge Nightclub Inc","meta":{"location":{"zip":"94107","state":"CA","city":"San Francisco","address":"715 Harrison St"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000112","_entity":"526847955f23a60b0e000761","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":112.17,"date":"2014-01-14","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000cc","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":0.8,"date":"2014-01-04","name":"AMAZON WEB SERVICES","meta":{"location":{},"contact":{"website":"amazon.co"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000ce","_entity":"526847775f23a60b0e00017b","category":["Miscellaneous"],"category_id":"52544965f71e87d007000088"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":9.67,"date":"2014-01-06","name":"Bread and Cocoa","meta":{"location":{"coordinates":{"lng":-122.40359544754028,"lat":37.789709297957295},"zip":"94104","state":"CA","city":"San Francisco","address":"199 Sutter St"},"contact":{"telephone":"4159567200"},"ids":{"foursquare":"49e6c22df964a52069641fe3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000ef","_entity":"526847815f23a60b0e000313","category":["Food & Drink","Restaurants","Coffee Shop"],"category_id":"52544965f71e87d00700005d"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital"},"amount":2.99,"date":"2014-01-06","name":"Amazon Digital Downloads","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a6","_entity":"51df0af8e52532e03b000004"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":50,"date":"2014-01-09","name":"Lolinda","meta":{"location":{"coordinates":{"lng":-122.41880893707274,"lat":37.756804912698485},"zip":"94110","state":"CA","city":"San Francisco","address":"2518 Mission St"},"contact":{"telephone":"4155506970"},"ids":{"foursquare":"50243fd229a61e4b21a26e16"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be8be13cbc36e0000d3","_entity":"52a980d454dd694709000215","category":["Food & Drink","Restaurants","Steakhouses"],"category_id":"52544965f71e87d007000081"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":52.28,"date":"2014-01-03","name":"Blowfish","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"2170 Bryant St"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f4","_entity":"529048c708e4eabe44007b5d","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":12.33,"date":"2014-01-09","name":"Tropisueño","meta":{"location":{"coordinates":{"lng":-122.40393340587616,"lat":37.78534267732514},"zip":"94103","state":"CA","city":"San Francisco","address":"75 Yerba Buena Ln"},"contact":{"telephone":"4152430299"},"ids":{"foursquare":"4a5f8994f964a520d5bf1fe3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000ee","_entity":"526847945f23a60b0e000714","category":["Food & Drink","Restaurants","Mexican"],"category_id":"52544965f71e87d007000079"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":9.3,"date":"2014-01-07","name":"Chipotle Mexican Grill","meta":{"location":{"coordinates":{"lng":-122.40385587412636,"lat":37.7898142010025},"zip":"94108","state":"CA","city":"San Francisco","address":"211 Sutter St"},"contact":{"telephone":"4155904199"},"ids":{"foursquare":"50a40b4c498ef6257de3eb6a","factual":"93ecb774-185d-46a3-a17e-aaa1dfc421c4"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f8","_entity":"526847775f23a60b0e00014d","category":["Food & Drink","Restaurants","Mexican"],"category_id":"52544965f71e87d007000079"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":50.11,"date":"2014-01-03","name":"Safeway","meta":{"location":{"coordinates":{"lng":-122.43288516998291,"lat":37.8045623549303},"zip":"94123","state":"CA","city":"San Francisco","address":"15 Marina Blvd"},"contact":{"telephone":"4155634946"},"ids":{"foursquare":"4a5931a2f964a520f0b81fe3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be8be13cbc36e0000d4","_entity":"5272beb53429c3f11000b6a3","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":16,"date":"2013-12-29","name":"Vero Westside","meta":{"location":{"zip":"95448","state":"CA","city":"Healdsburg","address":"6050 Westside Rd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f0","_entity":"52c2cfc5590084f05f018796","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":10,"date":"2014-01-01","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000fc","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":11.25,"date":"2014-01-04","name":"Bovine Bakery Pt. Reyes","meta":{"location":{"zip":"94956","state":"POINT REYES STATION","city":"Ca","address":"Pt Reyes Station"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e9","_entity":"52a1042dc84b48ea010016db","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":33.3,"date":"2013-12-30","name":"Online Payment Processed","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"# 100"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e6","_entity":"52d46dcee8bb7c7c3b008269","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":0.58,"date":"2014-01-04","name":"AMAZON WEB SERVICES","meta":{"location":{},"contact":{"website":"amazon.co"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000b3","_entity":"526847775f23a60b0e00017b","category":["Miscellaneous"],"category_id":"52544965f71e87d007000088"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":72.11,"date":"2013-12-31","name":"Safeway 1206","meta":{"location":{"zip":"94133","state":"CA","city":"San Francisco","address":"Ste 6"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000fe","_entity":"52684e305f23a60b0e0077c3","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":15.02,"date":"2014-01-03","name":"Chevron Usa","meta":{"location":{"zip":"94520","state":"CA","city":"Concord","address":"2003 Diamond Blvd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000110","_entity":"5268478c5f23a60b0e000527","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":4.88,"date":"2013-12-30","name":"GOOGLE CHECKOUT SELLER","meta":{"location":{},"contact":{"website":"supermgoogle.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a3","_entity":"52a55227062d0fad200048ae","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":100.83,"date":"2014-01-03","name":"Hops & Hominy","meta":{"location":{"coordinates":{"lng":-122.40572547274216,"lat":37.78931076807203},"zip":"94108","state":"CA","city":"San Francisco","address":"1 Tillman Pl"},"contact":{"telephone":"4153736341"},"ids":{"foursquare":"4ed9a975be7be28336ddc111"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000dc","_entity":"526847885f23a60b0e000413","category":["Food & Drink","Restaurants","American"],"category_id":"52544965f71e87d00700004f"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":10,"date":"2013-12-29","name":"Porter Creek Winery","meta":{"location":{"coordinates":{"lng":-122.89016760129537,"lat":38.521034405303894},"zip":"95448","state":"CA","city":"Healdsburg","address":"8735 Westside Rd"},"contact":{"telephone":"7074336321"},"ids":{"foursquare":"4b661136f964a520cb112be3","factual":"4f0034b2-1bb6-4e91-93e8-519d6d570495"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000101","_entity":"52c2cfab590084f05f0185b6","category":["Food & Drink","Restaurants","Winery"],"category_id":"52544965f71e87d007000087"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-400,"date":"2014-01-02","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000b2","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":10.66,"date":"2013-12-26","name":"Wilco Food Mart 357","meta":{"location":{"zip":"28166","state":"NC","city":"Troutman","address":"1006 Charlotte Hwy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f7","_entity":"52bed9b710b439a912005644","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":52.76,"date":"2013-12-26","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e00009e","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":70.14,"date":"2014-01-03","name":"Sports Basement","meta":{"location":{"coordinates":{"lng":-122.41096,"lat":37.767054},"zip":"94103","state":"CA","city":"San Francisco","address":"1590 Bryant St"},"contact":{"telephone":"4155753000"},"ids":{"foursquare":"4a09ef9af964a52070741fe3","factual":"10930fc3-d54e-4dc0-84ed-f8ce95d2fefd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000115","_entity":"529048ce17c7425b3b00fb63","category":["Shops","Sporting Goods"],"category_id":"52544965f71e87d0070001b0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":47,"date":"2013-12-27","name":"Laurienzo Brick Oven","meta":{"location":{"zip":"21771","state":"MYERSVILLE","city":"Md","address":"Mount Airy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000ff","_entity":"52c07fe610b439a91200ae65","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":35.46,"date":"2013-12-29","name":"Cheese Plus","meta":{"location":{"coordinates":{"lng":-122.421783,"lat":37.795058},"zip":"94109","state":"CA","city":"San Francisco","address":"2001 Polk St"},"contact":{"telephone":"4159212001"},"ids":{"foursquare":"4a222e61f964a520677d1fe3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000eb","_entity":"52ae45246dd4e787270033b3","category":["Shops","Food and Beverage Store","Specialty"],"category_id":"52544965f71e87d00700019d"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":40.05,"date":"2013-12-27","name":"Mosaic","meta":{"location":{"coordinates":{"lng":-76.60696364892934,"lat":39.28950572222763},"zip":"21202","state":"MD","city":"Baltimore","address":"4 Market Pl"},"contact":{"telephone":"4102628713"},"ids":{"foursquare":"4b2315cef964a5201e5324e3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be8be13cbc36e0000d1","_entity":"52d2bce0e8bb7c7c3b000a96","category":["Food & Drink","Nightlife","Night Clubs"],"category_id":"52544965f71e87d007000048"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":17.42,"date":"2013-12-27","name":"Brewer's Alley","meta":{"location":{"coordinates":{"lng":-77.41064750324045,"lat":39.41609008056981},"zip":"21701","state":"MD","city":"Frederick","address":"124 N Market St"},"contact":{"telephone":"3016310089"},"ids":{"foursquare":"4ab3b494f964a520136e20e3","factual":"174c0d71-c905-4f7c-a07e-90718621006d"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000da","_entity":"52c08001590084f05f00ad1e","category":["Food & Drink","Breweries"],"category_id":"52544965f71e87d007000041"},{"score":{"master":1,"detail":{"zip":1,"name":0.94,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":4.55,"date":"2013-12-26","name":"Starbucks B #152","meta":{"location":{"zip":"28208","state":"NC","city":"Charlotte","address":"5501 Josh Birmingham Pkwy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000fd","_entity":"52684e025f23a60b0e0070f7","category":["Food & Drink","Nightlife","Bar"],"category_id":"52544965f71e87d007000044"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":12,"date":"2013-12-28","name":"Pickles Pub","meta":{"location":{"coordinates":{"lng":-76.62269711494446,"lat":39.285378238756444},"zip":"21230","state":"MD","city":"Baltimore","address":"520 Washington Blvd"},"contact":{"telephone":"4107521784"},"ids":{"foursquare":"4ab444edf964a520a97020e3","factual":"5e0aca04-6843-4639-ad82-54ffc0d36cb3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f6","_entity":"52c08009590084f05f00ae2c","category":["Food & Drink","Nightlife","Bar"],"category_id":"52544965f71e87d007000044"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":10,"date":"2013-12-26","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a8","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":54,"date":"2013-12-27","name":"The Corner Bistro & Winebar","meta":{"location":{"coordinates":{"lng":-76.62582365723517,"lat":39.285605663839426},"zip":"21230","state":"MD","city":"Baltimore","address":"213 Penn St"},"contact":{"telephone":"4107271155"},"ids":{"foursquare":"4e6fe217b9935ff0b50def7c","factual":"1bce75d1-b6bb-433b-94cc-2a2fae8ca084"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010d","_entity":"52db180352d559616e00012b","category":["Food & Drink","Restaurants","Winery"],"category_id":"52544965f71e87d007000087"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":4.35,"date":"2013-12-30","name":"GOOGLE CHECKOUT SELLER","meta":{"location":{},"contact":{"website":"cogoogle.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000cd","_entity":"526847825f23a60b0e000387","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":40,"date":"2013-12-29","name":"Online Payment Processed","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"# 100"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e4","_entity":"52d46dcee8bb7c7c3b008269","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":33.97,"date":"2013-12-27","name":"Sheetz","meta":{"location":{"coordinates":{"lng":-77.387792,"lat":39.407061},"zip":"21701","state":"MD","city":"Frederick","address":"1300 E Patrick St"},"contact":{"telephone":"3016315200"},"ids":{"foursquare":"4b40febff964a520f8be25e3","factual":"c26279c0-d71c-48d6-9994-56a0272b45c9"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010a","_entity":"52c07ff110b439a91200aef2","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":140,"date":"2013-12-25","name":"Olympic Meats","meta":{"location":{"zip":"97209","state":"OR","city":"Portland","address":"#132"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f9","_entity":"52bc3728d6da4e7c0b005a9d","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":37.43,"date":"2013-12-24","name":"Fresh Market The","meta":{"location":{"coordinates":{"lng":-80.31173,"lat":36.115811},"zip":"27106","state":"NC","city":"Winston Salem","address":"3285 Robinhood Rd"},"contact":{"telephone":"(336) 760-2519"},"ids":{"factual":"1a0e253e-d97c-4420-ab47-120b977876ce"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000104","_entity":"52bc3757d6da4e7c0b005c24","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":150,"date":"2013-12-24","name":"The Spa at Highland Oaks","meta":{"location":{"coordinates":{"lng":-80.30215623738016,"lat":36.05963070139284},"zip":"27103","state":"NC","city":"Winston Salem","address":"765 Highland Oaks Dr, Ste 150"},"ids":{"foursquare":"4ceab2bde888f04d7e974e6b","factual":"4db980c2-72f8-4f55-a82f-4b6bf1031a01"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be8be13cbc36e0000d2","_entity":"52bc3710fd90ebfd53005f01","category":["Service","Personal Care","Spas"],"category_id":"52544965f71e87d007000153"},{"score":{"master":0},"type":{"primary":"unresolved"},"amount":-0.01,"date":"2013-12-23","name":"","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000117","_entity":"52db1be7be13cbc36e0000c4","category":["Fees & Payments"],"category_id":"52544965f71e87d007000040"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital"},"amount":5.99,"date":"2013-12-23","name":"Amazon Digital Downloads","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000cf","_entity":"51df0af8e52532e03b000004"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":25,"date":"2013-12-25","name":"Us Airways Web Sales","meta":{"location":{"zip":"85034","state":"AZ","city":"Phoenix","address":"4000 E Sky Harbor Blvd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000dd","_entity":"52684be85f23a60b0e001722","category":["Travel","Airlines and Aviation Services"],"category_id":"52544965f71e87d0070001b9"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":21.48,"date":"2013-12-24","name":"Barnes & Noble 2761","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"1925 Hampton Inn Ct"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010c","_entity":"52bc3746fd90ebfd53005f69","category":["Shops","Bookstores"],"category_id":"52544965f71e87d00700017e"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":25,"date":"2013-12-22","name":"Schoolhouse Electric & Supply Co.","meta":{"location":{"coordinates":{"lng":-122.69696420281844,"lat":45.54129868720819},"zip":"97210","state":"OR","city":"Portland","address":"2181 NW Nicolai St, Portland, OR 97210"},"contact":{"telephone":"5032307082"},"ids":{"foursquare":"4ec84d6d9a52756c56b97c5f","factual":"d05199f8-a77c-44de-a9a3-d0c935c6c3fa"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e7","_entity":"52b5a4122c9e708730001d08","category":["Shops","Department Stores"],"category_id":"52544965f71e87d007000192"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital"},"amount":1.99,"date":"2013-12-23","name":"Amazon Digital Downloads","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a1","_entity":"51df0af8e52532e03b000004"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":20.25,"date":"2013-12-23","name":"Square Transaction","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000ad","_entity":"51df2f3d364351e13d000009"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":17.04,"date":"2013-12-22","name":"William Sonoma","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"3320 Silas Creek Pkwy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000ed","_entity":"52b993b9d6da4e7c0b00030a","category":["Shops","Furniture and Home Decor"],"category_id":"52544965f71e87d00700019e"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":21.02,"date":"2013-12-30","name":"GOOGLE CHECKOUT SELLER","meta":{"location":{},"contact":{"website":"google.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a0","_entity":"52cca015ec558faf5f030294","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":7.5,"date":"2013-12-22","name":"Delta Air Lines Inc.","meta":{"location":{"zip":"30320","state":"GA","city":"Atlanta","address":"Atlanta Airport"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000105","_entity":"52684d6f5f23a60b0e0057de","category":["Travel","Airlines and Aviation Services"],"category_id":"52544965f71e87d0070001b9"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":277.55,"date":"2013-12-22","name":"Great Outdoor Prvsn Co","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"402 S Stratford Rd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010e","_entity":"52684f455f23a60b0e009812","category":["Shops","Sporting Goods"],"category_id":"52544965f71e87d0070001b0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":96.1,"date":"2013-12-23","name":"Lsi Sonoma Rtl Wsj Wine","meta":{"location":{"zip":"06854","state":"CT","city":"Norwalk","address":"Ste 320"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000ea","_entity":"52a93c09d8511a177d007968","category":["Shops"],"category_id":"52544965f71e87d007000170"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":1.88,"date":"2013-12-22","name":"Kelly's Confections Inc","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"3320 Silas Creek Pkwy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000106","_entity":"52684e835f23a60b0e00855d","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":84,"date":"2013-12-23","name":"Zerve Tours Shows Events","meta":{"location":{"zip":"10013","state":"NY","city":"New York","address":"Rm 604"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f3","_entity":"52a24f89d627f2b54d00fb90","category":["Travel","Travel Agencies"],"category_id":"52544965f71e87d0070001cf"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":5.12,"date":"2013-12-19","name":"Chevron Usa","meta":{"location":{"zip":"94520","state":"CA","city":"Concord","address":"2003 Diamond Blvd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000109","_entity":"5268478c5f23a60b0e000527","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":20.57,"date":"2013-12-22","name":"Thelooppizzagrille","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"320 S Stratford Rd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010b","_entity":"52b993aafd90ebfd53000137","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":24.55,"date":"2013-12-22","name":"Van Davis Aveda","meta":{"location":{"coordinates":{"lng":-80.2816481,"lat":36.092929},"zip":"27103","state":"NC","city":"Winston Salem","address":"244 S Stratford Rd"},"contact":{"telephone":"3367211332"},"ids":{"foursquare":"4bc4d3974cdfc9b6ad389921"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000111","_entity":"52684e345f23a60b0e007824","category":["Service","Personal Care","Hair Salons and Barbers"],"category_id":"52544965f71e87d00700014e"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":50,"date":"2013-12-21","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f1","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":3.12,"date":"2013-12-21","name":"Starbucks Term C#153","meta":{"location":{"zip":"27623","state":"NC","city":"Raleigh","address":"1025 Airside Dr, Ste 2101"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000e0","_entity":"52684e205f23a60b0e00758b","category":["Food & Drink","Nightlife","Bar"],"category_id":"52544965f71e87d007000044"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":35.96,"date":"2013-12-22","name":"Wilco Fuel Plaza 1122","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"2026 S Hawthorne Rd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000113","_entity":"52b993acd6da4e7c0b0002e1","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":69,"date":"2013-12-21","name":"L L Bean","meta":{"location":{"coordinates":{"lng":-70.102862,"lat":43.857211},"zip":"04032","state":"ME","city":"Freeport","address":"95 Main St"},"contact":{"telephone":"(207) 865-6660"},"ids":{"factual":"22963af1-7bf9-492d-818b-4bb355d1fe62"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000108","_entity":"5278254010ce27ec03003e7a","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":8.98,"date":"2014-01-16","name":"Interest Charges on Purchases","meta":{"location":{}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be7be13cbc36e0000b4","_entity":"51df517968ab247d41000004"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":260.86,"date":"2014-01-16","name":"EVENTBRITE","meta":{"location":{},"contact":{"website":"*meatup.io"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be7be13cbc36e0000d0","_entity":"52a3f098524beee12801ddae","category":["Arts & Entertainment","Entertainment"],"category_id":"52544965f71e87d00700000a"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-1000,"date":"2014-01-02","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be6be13cbc36e000079","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":64.99,"date":"2014-01-04","name":"Crunch","meta":{"location":{"coordinates":{"lng":-73.9984,"lat":40.74205},"zip":"10011","state":"NY","city":"New York","address":"220 West 19th Street"},"contact":{"telephone":"2123700998"},"ids":{"foursquare":"5065e558011c9fb87575b212"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1bebbe13cbc36e0000fb","_entity":"52d08c2629b10e5f6a056eee","category":["Parks & Outdoors","Gyms and Fitness Centers"],"category_id":"52544965f71e87d00700009a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":9.8,"date":"2014-01-03","name":"Nyc Bike Share","meta":{"location":{"zip":"97214","state":"OR","city":"Portland","address":"711 Se Grand Avenue"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1bebbe13cbc36e0000ec","_entity":"52684c045f23a60b0e001b17","category":["Miscellaneous"],"category_id":"52544965f71e87d007000088"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-214.76,"date":"2014-01-15","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be6be13cbc36e00007c","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":28.85,"date":"2014-01-17","name":"La Folie","meta":{"location":{"coordinates":{"lng":-122.42219641613993,"lat":37.79805635393336},"zip":"94109","state":"CA","city":"San Francisco","address":"2316 Polk St"},"contact":{"telephone":"4157765577"},"ids":{"foursquare":"49e04b9af964a5204f611fe3","factual":"09740eae-2f29-4079-a828-fced3d4bd52b"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1bebbe13cbc36e000114","_entity":"527c3ec3a82308293a008586","category":["Food & Drink","Restaurants","French"],"category_id":"52544965f71e87d00700006c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":139.97,"date":"2014-01-01","name":"Crunch","meta":{"location":{"coordinates":{"lng":-122.42223,"lat":37.79827},"zip":"94109","state":"CA","city":"San Francisco","address":"2330 Polk Street"},"contact":{"telephone":"4152925444"},"ids":{"foursquare":"49d79743f964a520385d1fe3","factual":"ccd1c1d1-fd81-4535-98fe-64ac2364af15"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be9be13cbc36e0000d8","_entity":"52a6ff1c949382717e00e816","category":["Parks & Outdoors","Gyms and Fitness Centers"],"category_id":"52544965f71e87d00700009a"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-923.26,"date":"2013-12-24","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be6be13cbc36e00007d","_entity":"51df2f4f364351e13d00000a"}],"access_token":"test"} \ No newline at end of file diff --git a/src/test/resources/__files/body-connect-step-XBxNh.json b/src/test/resources/__files/body-connect-step-XBxNh.json new file mode 100644 index 0000000..38e40f6 --- /dev/null +++ b/src/test/resources/__files/body-connect-step-XBxNh.json @@ -0,0 +1 @@ +{"accounts":[{"_id":"52db1be4be13cbc36e000004","_item":"52af631671c3bd1b25000064","_user":"52af630f71c3bd1b25000063","balance":{"available":null,"current":12230},"meta":{"limit":null,"name":"Plaid Savings","number":"31015"},"institution_type":"fake_institution","type":"depository"},{"_id":"52db1be4be13cbc36e000005","_item":"52af631671c3bd1b25000064","_user":"52af630f71c3bd1b25000063","balance":{"available":null,"current":1113.13},"meta":{"limit":null,"name":"Plaid Checking","number":"65008"},"institution_type":"fake_institution","type":"depository"},{"_id":"52db1be4be13cbc36e000006","_item":"52af631671c3bd1b25000064","_user":"52af630f71c3bd1b25000063","balance":{"available":3721,"current":8.98},"meta":{"limit":3500,"name":"Plaid Credit Card","number":"93004"},"institution_type":"fake_institution","type":"credit"}],"transactions":[{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":6.25,"date":"2014-01-16","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be6be13cbc36e00007b","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":56.26,"date":"2014-01-15","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000a4","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":10,"date":"2014-01-16","name":"GOOGLE CHECKOUT SELLER","meta":{"location":{},"contact":{"website":"google.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000b5","_entity":"52cca015ec558faf5f030294","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":19.56,"date":"2014-01-14","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000b7","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":25.49,"date":"2014-01-03","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000ae","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":125,"date":"2014-01-10","name":"Int*webpass Inc","meta":{"location":{"zip":"94103","state":"CA","city":"San Francisco","address":"262 7 Th Street"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000103","_entity":"5268478c5f23a60b0e00051b","category":["Professional"],"category_id":"52544965f71e87d0070000c3"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":525.25,"date":"2014-01-14","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e00010f","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":1,"date":"2014-01-09","name":"Online Payment Processed","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"# 100"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be9be13cbc36e0000d6","_entity":"52d46dcee8bb7c7c3b008269","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":142.52,"date":"2014-01-06","name":"Jaron Logo","meta":{"location":{"coordinates":{"lng":-122.399262,"lat":37.780718},"zip":"94107","state":"CA","city":"San Francisco","address":"425 4th St"},"contact":{"telephone":"(415) 597-7511"},"ids":{"factual":"a7b474ac-17ba-4fd5-8940-8f51eeedb915"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1beabe13cbc36e0000e2","_entity":"52cd5bf3ec558faf5f03557d","category":["Service","Textiles"],"category_id":"52544965f71e87d00700016b"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":6.44,"date":"2014-01-08","name":"Square Transaction","meta":{"location":{}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000c3","_entity":"51df2f3d364351e13d000009"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":516.53,"date":"2014-01-14","name":"Ikea Home Shopping","meta":{"location":{"zip":"21236","state":"NOTTINGHAM","city":"Md","address":"Baltimore"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be9be13cbc36e0000de","_entity":"52a127c10c16b9c47100035b","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":59.14,"date":"2014-01-14","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000116","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":0.8,"detail":{"name":1,"state":1,"city":1,"zip":1}},"type":{"primary":"unresolved"},"amount":29.95,"date":"2014-01-09","name":"Freshbooks","meta":{"location":{"zip":"M6R2J5","state":"TORONTO","city":"35 Golden Avenue Suite 105"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be9be13cbc36e0000d7","_entity":"52a4978ae411f6f2070204c4","category":["Professional","Financial","Banking and Finance"],"category_id":"52544965f71e87d0070000df"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital"},"amount":51.22,"date":"2014-01-07","name":"Seamless","meta":{"location":{},"contact":{"website":"seamless.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be6be13cbc36e00007e","_entity":"51df0152e52532e03b000002"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":24.04,"date":"2014-01-04","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000af","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":3.5,"date":"2014-01-08","name":"Capital One 360 Café","meta":{"location":{"coordinates":{"lng":-122.40372312029795,"lat":37.7888611347371},"zip":"94108","state":"CA","city":"San Francisco","address":"101 Post St"},"contact":{"telephone":"4152484920"},"ids":{"foursquare":"4d87c47c0c422d436a43ee30","factual":"2a04d84d-25ef-4bad-9603-9b333cc4e35b"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000100","_entity":"52a553acbdcc808903004b30","category":["Food & Drink","Restaurants","Cafe"],"category_id":"52544965f71e87d007000059"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":10.7,"date":"2014-01-12","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000d9","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":11.56,"date":"2014-01-15","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e1","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":29.85,"date":"2014-01-06","name":"Starbucks","meta":{"location":{"coordinates":{"lng":-122.40341336071333,"lat":37.7873326351124},"zip":"94103","state":"CA","city":"San Francisco","address":"7 3rd St"},"contact":{"telephone":"4159799530"},"ids":{"foursquare":"4a7324d9f964a520aadb1fe3","factual":"6ac4ea59-397d-498a-9d10-e4dc2cda6cac"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e0000fa","_entity":"526847885f23a60b0e00041c","category":["Food & Drink","Restaurants","Coffee Shop"],"category_id":"52544965f71e87d00700005d"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":600,"date":"2013-12-19","name":"Umami","meta":{"location":{"coordinates":{"lng":-122.43374347686768,"lat":37.79774659682308},"zip":"94123","state":"CA","city":"San Francisco","address":"2909 Webster St"},"contact":{"telephone":"4153463431"},"ids":{"foursquare":"4a0e428cf964a520da751fe3"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be9be13cbc36e0000df","_entity":"52684c615f23a60b0e002b15","category":["Food & Drink","Restaurants","Asian"],"category_id":"52544965f71e87d007000050"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":129.64,"date":"2014-01-15","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be8be13cbc36e0000d5","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":75.1,"date":"2014-01-09","name":"Online Payment Processed","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"# 100"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000107","_entity":"52d46dcee8bb7c7c3b008269","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":12.52,"date":"2014-01-14","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e3","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":-59.14,"date":"2014-01-14","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1beabe13cbc36e0000e5","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":25.49,"date":"2014-01-03","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1be7be13cbc36e0000a5","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":346.26,"date":"2014-01-16","name":"Urbanoutfitterscom Lp","meta":{"location":{"zip":"19112","state":"PA","city":"Philadelphia","address":"5000 S Broad St"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e000102","_entity":"526848e85f23a60b0e000cd5","category":["Shops","Digital Purchase"],"category_id":"52544965f71e87d007000193"},{"score":{"master":0.96667,"detail":{"zip":1,"name":0.3333333333333333,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":35.45,"date":"2014-01-12","name":"Mayes Oyster and Steak House","meta":{"location":{"coordinates":{"lng":-122.42027180518197,"lat":37.78830541267099},"zip":"94109","state":"CA","city":"San Francisco","address":"1233 Polk St"},"contact":{"telephone":"4154747674"},"ids":{"foursquare":"4afb7c6df964a5204d1e22e3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000db","_entity":"5272bee03429c3f11000bea5","category":["Food & Drink","Restaurants","American"],"category_id":"52544965f71e87d00700004f"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-2101.53,"date":"2014-01-15","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000b6","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":46.75,"date":"2014-01-13","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a2","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-800,"date":"2014-01-13","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e00009f","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":12.96,"date":"2014-01-16","name":"Galette 88","meta":{"location":{"coordinates":{"lng":-122.40363836288452,"lat":37.79031975640008},"zip":"94108","state":"CA","city":"San Francisco","address":"88 Hardie Pl"},"contact":{"telephone":"4159892222"},"ids":{"foursquare":"4edadafe6d869ce1d11cce2e"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e8","_entity":"52ae45270ae6dce65e009479","category":["Food & Drink","Restaurants","French"],"category_id":"52544965f71e87d00700006c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":175.49,"date":"2014-01-04","name":"Curtain Works","meta":{"location":{"zip":"28217","state":"NC","city":"Charlotte","address":"Ste 400"}},"_account":"52db1be4be13cbc36e000004","_id":"52db1bebbe13cbc36e0000f5","_entity":"52c9ba92ec558faf5f01ab84","category":["Shops"],"category_id":"52544965f71e87d007000170"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":11.42,"date":"2014-01-14","name":"Sushirrito","meta":{"location":{"zip":"94108","state":"CA","city":"San Francisco","address":"226 Kearny St"},"ids":{"foursquare":"5169c1b4498eb65b81bd735a"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f2","_entity":"526847945f23a60b0e000707","category":["Food & Drink","Restaurants","Sushi"],"category_id":"52544965f71e87d007000082"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":22.74,"date":"2014-01-10","name":"Rouge Nightclub Inc","meta":{"location":{"zip":"94107","state":"CA","city":"San Francisco","address":"715 Harrison St"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000112","_entity":"526847955f23a60b0e000761","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":112.17,"date":"2014-01-14","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000cc","_entity":"51df0130e52532e03b000001"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":0.8,"date":"2014-01-04","name":"AMAZON WEB SERVICES","meta":{"location":{},"contact":{"website":"amazon.co"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000ce","_entity":"526847775f23a60b0e00017b","category":["Miscellaneous"],"category_id":"52544965f71e87d007000088"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":9.67,"date":"2014-01-06","name":"Bread and Cocoa","meta":{"location":{"coordinates":{"lng":-122.40359544754028,"lat":37.789709297957295},"zip":"94104","state":"CA","city":"San Francisco","address":"199 Sutter St"},"contact":{"telephone":"4159567200"},"ids":{"foursquare":"49e6c22df964a52069641fe3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000ef","_entity":"526847815f23a60b0e000313","category":["Food & Drink","Restaurants","Coffee Shop"],"category_id":"52544965f71e87d00700005d"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital"},"amount":2.99,"date":"2014-01-06","name":"Amazon Digital Downloads","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a6","_entity":"51df0af8e52532e03b000004"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":50,"date":"2014-01-09","name":"Lolinda","meta":{"location":{"coordinates":{"lng":-122.41880893707274,"lat":37.756804912698485},"zip":"94110","state":"CA","city":"San Francisco","address":"2518 Mission St"},"contact":{"telephone":"4155506970"},"ids":{"foursquare":"50243fd229a61e4b21a26e16"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be8be13cbc36e0000d3","_entity":"52a980d454dd694709000215","category":["Food & Drink","Restaurants","Steakhouses"],"category_id":"52544965f71e87d007000081"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":52.28,"date":"2014-01-03","name":"Blowfish","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"2170 Bryant St"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f4","_entity":"529048c708e4eabe44007b5d","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":12.33,"date":"2014-01-09","name":"Tropisueño","meta":{"location":{"coordinates":{"lng":-122.40393340587616,"lat":37.78534267732514},"zip":"94103","state":"CA","city":"San Francisco","address":"75 Yerba Buena Ln"},"contact":{"telephone":"4152430299"},"ids":{"foursquare":"4a5f8994f964a520d5bf1fe3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000ee","_entity":"526847945f23a60b0e000714","category":["Food & Drink","Restaurants","Mexican"],"category_id":"52544965f71e87d007000079"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":9.3,"date":"2014-01-07","name":"Chipotle Mexican Grill","meta":{"location":{"coordinates":{"lng":-122.40385587412636,"lat":37.7898142010025},"zip":"94108","state":"CA","city":"San Francisco","address":"211 Sutter St"},"contact":{"telephone":"4155904199"},"ids":{"foursquare":"50a40b4c498ef6257de3eb6a","factual":"93ecb774-185d-46a3-a17e-aaa1dfc421c4"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f8","_entity":"526847775f23a60b0e00014d","category":["Food & Drink","Restaurants","Mexican"],"category_id":"52544965f71e87d007000079"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":50.11,"date":"2014-01-03","name":"Safeway","meta":{"location":{"coordinates":{"lng":-122.43288516998291,"lat":37.8045623549303},"zip":"94123","state":"CA","city":"San Francisco","address":"15 Marina Blvd"},"contact":{"telephone":"4155634946"},"ids":{"foursquare":"4a5931a2f964a520f0b81fe3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be8be13cbc36e0000d4","_entity":"5272beb53429c3f11000b6a3","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":16,"date":"2013-12-29","name":"Vero Westside","meta":{"location":{"zip":"95448","state":"CA","city":"Healdsburg","address":"6050 Westside Rd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f0","_entity":"52c2cfc5590084f05f018796","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":10,"date":"2014-01-01","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000fc","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":11.25,"date":"2014-01-04","name":"Bovine Bakery Pt. Reyes","meta":{"location":{"zip":"94956","state":"POINT REYES STATION","city":"Ca","address":"Pt Reyes Station"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e9","_entity":"52a1042dc84b48ea010016db","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":33.3,"date":"2013-12-30","name":"Online Payment Processed","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"# 100"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e6","_entity":"52d46dcee8bb7c7c3b008269","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":0.58,"date":"2014-01-04","name":"AMAZON WEB SERVICES","meta":{"location":{},"contact":{"website":"amazon.co"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000b3","_entity":"526847775f23a60b0e00017b","category":["Miscellaneous"],"category_id":"52544965f71e87d007000088"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":72.11,"date":"2013-12-31","name":"Safeway 1206","meta":{"location":{"zip":"94133","state":"CA","city":"San Francisco","address":"Ste 6"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000fe","_entity":"52684e305f23a60b0e0077c3","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":15.02,"date":"2014-01-03","name":"Chevron Usa","meta":{"location":{"zip":"94520","state":"CA","city":"Concord","address":"2003 Diamond Blvd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000110","_entity":"5268478c5f23a60b0e000527","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":4.88,"date":"2013-12-30","name":"GOOGLE CHECKOUT SELLER","meta":{"location":{},"contact":{"website":"supermgoogle.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a3","_entity":"52a55227062d0fad200048ae","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":100.83,"date":"2014-01-03","name":"Hops & Hominy","meta":{"location":{"coordinates":{"lng":-122.40572547274216,"lat":37.78931076807203},"zip":"94108","state":"CA","city":"San Francisco","address":"1 Tillman Pl"},"contact":{"telephone":"4153736341"},"ids":{"foursquare":"4ed9a975be7be28336ddc111"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000dc","_entity":"526847885f23a60b0e000413","category":["Food & Drink","Restaurants","American"],"category_id":"52544965f71e87d00700004f"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":10,"date":"2013-12-29","name":"Porter Creek Winery","meta":{"location":{"coordinates":{"lng":-122.89016760129537,"lat":38.521034405303894},"zip":"95448","state":"CA","city":"Healdsburg","address":"8735 Westside Rd"},"contact":{"telephone":"7074336321"},"ids":{"foursquare":"4b661136f964a520cb112be3","factual":"4f0034b2-1bb6-4e91-93e8-519d6d570495"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000101","_entity":"52c2cfab590084f05f0185b6","category":["Food & Drink","Restaurants","Winery"],"category_id":"52544965f71e87d007000087"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-400,"date":"2014-01-02","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000b2","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":10.66,"date":"2013-12-26","name":"Wilco Food Mart 357","meta":{"location":{"zip":"28166","state":"NC","city":"Troutman","address":"1006 Charlotte Hwy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f7","_entity":"52bed9b710b439a912005644","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":52.76,"date":"2013-12-26","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e00009e","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":70.14,"date":"2014-01-03","name":"Sports Basement","meta":{"location":{"coordinates":{"lng":-122.41096,"lat":37.767054},"zip":"94103","state":"CA","city":"San Francisco","address":"1590 Bryant St"},"contact":{"telephone":"4155753000"},"ids":{"foursquare":"4a09ef9af964a52070741fe3","factual":"10930fc3-d54e-4dc0-84ed-f8ce95d2fefd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000115","_entity":"529048ce17c7425b3b00fb63","category":["Shops","Sporting Goods"],"category_id":"52544965f71e87d0070001b0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":47,"date":"2013-12-27","name":"Laurienzo Brick Oven","meta":{"location":{"zip":"21771","state":"MYERSVILLE","city":"Md","address":"Mount Airy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000ff","_entity":"52c07fe610b439a91200ae65","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":35.46,"date":"2013-12-29","name":"Cheese Plus","meta":{"location":{"coordinates":{"lng":-122.421783,"lat":37.795058},"zip":"94109","state":"CA","city":"San Francisco","address":"2001 Polk St"},"contact":{"telephone":"4159212001"},"ids":{"foursquare":"4a222e61f964a520677d1fe3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000eb","_entity":"52ae45246dd4e787270033b3","category":["Shops","Food and Beverage Store","Specialty"],"category_id":"52544965f71e87d00700019d"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":40.05,"date":"2013-12-27","name":"Mosaic","meta":{"location":{"coordinates":{"lng":-76.60696364892934,"lat":39.28950572222763},"zip":"21202","state":"MD","city":"Baltimore","address":"4 Market Pl"},"contact":{"telephone":"4102628713"},"ids":{"foursquare":"4b2315cef964a5201e5324e3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be8be13cbc36e0000d1","_entity":"52d2bce0e8bb7c7c3b000a96","category":["Food & Drink","Nightlife","Night Clubs"],"category_id":"52544965f71e87d007000048"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":17.42,"date":"2013-12-27","name":"Brewer's Alley","meta":{"location":{"coordinates":{"lng":-77.41064750324045,"lat":39.41609008056981},"zip":"21701","state":"MD","city":"Frederick","address":"124 N Market St"},"contact":{"telephone":"3016310089"},"ids":{"foursquare":"4ab3b494f964a520136e20e3","factual":"174c0d71-c905-4f7c-a07e-90718621006d"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000da","_entity":"52c08001590084f05f00ad1e","category":["Food & Drink","Breweries"],"category_id":"52544965f71e87d007000041"},{"score":{"master":1,"detail":{"zip":1,"name":0.94,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":4.55,"date":"2013-12-26","name":"Starbucks B #152","meta":{"location":{"zip":"28208","state":"NC","city":"Charlotte","address":"5501 Josh Birmingham Pkwy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000fd","_entity":"52684e025f23a60b0e0070f7","category":["Food & Drink","Nightlife","Bar"],"category_id":"52544965f71e87d007000044"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":12,"date":"2013-12-28","name":"Pickles Pub","meta":{"location":{"coordinates":{"lng":-76.62269711494446,"lat":39.285378238756444},"zip":"21230","state":"MD","city":"Baltimore","address":"520 Washington Blvd"},"contact":{"telephone":"4107521784"},"ids":{"foursquare":"4ab444edf964a520a97020e3","factual":"5e0aca04-6843-4639-ad82-54ffc0d36cb3"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f6","_entity":"52c08009590084f05f00ae2c","category":["Food & Drink","Nightlife","Bar"],"category_id":"52544965f71e87d007000044"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital"},"amount":10,"date":"2013-12-26","name":"Amazon","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a8","_entity":"51df0130e52532e03b000001"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":54,"date":"2013-12-27","name":"The Corner Bistro & Winebar","meta":{"location":{"coordinates":{"lng":-76.62582365723517,"lat":39.285605663839426},"zip":"21230","state":"MD","city":"Baltimore","address":"213 Penn St"},"contact":{"telephone":"4107271155"},"ids":{"foursquare":"4e6fe217b9935ff0b50def7c","factual":"1bce75d1-b6bb-433b-94cc-2a2fae8ca084"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010d","_entity":"52db180352d559616e00012b","category":["Food & Drink","Restaurants","Winery"],"category_id":"52544965f71e87d007000087"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":4.35,"date":"2013-12-30","name":"GOOGLE CHECKOUT SELLER","meta":{"location":{},"contact":{"website":"cogoogle.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000cd","_entity":"526847825f23a60b0e000387","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":40,"date":"2013-12-29","name":"Online Payment Processed","meta":{"location":{"zip":"94110","state":"CA","city":"San Francisco","address":"# 100"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e4","_entity":"52d46dcee8bb7c7c3b008269","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":33.97,"date":"2013-12-27","name":"Sheetz","meta":{"location":{"coordinates":{"lng":-77.387792,"lat":39.407061},"zip":"21701","state":"MD","city":"Frederick","address":"1300 E Patrick St"},"contact":{"telephone":"3016315200"},"ids":{"foursquare":"4b40febff964a520f8be25e3","factual":"c26279c0-d71c-48d6-9994-56a0272b45c9"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010a","_entity":"52c07ff110b439a91200aef2","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":140,"date":"2013-12-25","name":"Olympic Meats","meta":{"location":{"zip":"97209","state":"OR","city":"Portland","address":"#132"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f9","_entity":"52bc3728d6da4e7c0b005a9d","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":37.43,"date":"2013-12-24","name":"Fresh Market The","meta":{"location":{"coordinates":{"lng":-80.31173,"lat":36.115811},"zip":"27106","state":"NC","city":"Winston Salem","address":"3285 Robinhood Rd"},"contact":{"telephone":"(336) 760-2519"},"ids":{"factual":"1a0e253e-d97c-4420-ab47-120b977876ce"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000104","_entity":"52bc3757d6da4e7c0b005c24","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":150,"date":"2013-12-24","name":"The Spa at Highland Oaks","meta":{"location":{"coordinates":{"lng":-80.30215623738016,"lat":36.05963070139284},"zip":"27103","state":"NC","city":"Winston Salem","address":"765 Highland Oaks Dr, Ste 150"},"ids":{"foursquare":"4ceab2bde888f04d7e974e6b","factual":"4db980c2-72f8-4f55-a82f-4b6bf1031a01"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be8be13cbc36e0000d2","_entity":"52bc3710fd90ebfd53005f01","category":["Service","Personal Care","Spas"],"category_id":"52544965f71e87d007000153"},{"score":{"master":0},"type":{"primary":"unresolved"},"amount":-0.01,"date":"2013-12-23","name":"","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000117","_entity":"52db1be7be13cbc36e0000c4","category":["Fees & Payments"],"category_id":"52544965f71e87d007000040"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital"},"amount":5.99,"date":"2013-12-23","name":"Amazon Digital Downloads","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000cf","_entity":"51df0af8e52532e03b000004"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":25,"date":"2013-12-25","name":"Us Airways Web Sales","meta":{"location":{"zip":"85034","state":"AZ","city":"Phoenix","address":"4000 E Sky Harbor Blvd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000dd","_entity":"52684be85f23a60b0e001722","category":["Travel","Airlines and Aviation Services"],"category_id":"52544965f71e87d0070001b9"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":21.48,"date":"2013-12-24","name":"Barnes & Noble 2761","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"1925 Hampton Inn Ct"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010c","_entity":"52bc3746fd90ebfd53005f69","category":["Shops","Bookstores"],"category_id":"52544965f71e87d00700017e"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":25,"date":"2013-12-22","name":"Schoolhouse Electric & Supply Co.","meta":{"location":{"coordinates":{"lng":-122.69696420281844,"lat":45.54129868720819},"zip":"97210","state":"OR","city":"Portland","address":"2181 NW Nicolai St, Portland, OR 97210"},"contact":{"telephone":"5032307082"},"ids":{"foursquare":"4ec84d6d9a52756c56b97c5f","factual":"d05199f8-a77c-44de-a9a3-d0c935c6c3fa"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000e7","_entity":"52b5a4122c9e708730001d08","category":["Shops","Department Stores"],"category_id":"52544965f71e87d007000192"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital"},"amount":1.99,"date":"2013-12-23","name":"Amazon Digital Downloads","meta":{"location":{},"contact":{"website":"amazon.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a1","_entity":"51df0af8e52532e03b000004"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":20.25,"date":"2013-12-23","name":"Square Transaction","meta":{"location":{}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000ad","_entity":"51df2f3d364351e13d000009"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":17.04,"date":"2013-12-22","name":"William Sonoma","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"3320 Silas Creek Pkwy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000ed","_entity":"52b993b9d6da4e7c0b00030a","category":["Shops","Furniture and Home Decor"],"category_id":"52544965f71e87d00700019e"},{"score":{"master":0.5,"detail":{"identifier":1,"website":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":21.02,"date":"2013-12-30","name":"GOOGLE CHECKOUT SELLER","meta":{"location":{},"contact":{"website":"google.com"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be7be13cbc36e0000a0","_entity":"52cca015ec558faf5f030294","category":["Professional","Internet Services"],"category_id":"52544965f71e87d007000119"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":7.5,"date":"2013-12-22","name":"Delta Air Lines Inc.","meta":{"location":{"zip":"30320","state":"GA","city":"Atlanta","address":"Atlanta Airport"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000105","_entity":"52684d6f5f23a60b0e0057de","category":["Travel","Airlines and Aviation Services"],"category_id":"52544965f71e87d0070001b9"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":277.55,"date":"2013-12-22","name":"Great Outdoor Prvsn Co","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"402 S Stratford Rd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010e","_entity":"52684f455f23a60b0e009812","category":["Shops","Sporting Goods"],"category_id":"52544965f71e87d0070001b0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":96.1,"date":"2013-12-23","name":"Lsi Sonoma Rtl Wsj Wine","meta":{"location":{"zip":"06854","state":"CT","city":"Norwalk","address":"Ste 320"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1beabe13cbc36e0000ea","_entity":"52a93c09d8511a177d007968","category":["Shops"],"category_id":"52544965f71e87d007000170"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":1.88,"date":"2013-12-22","name":"Kelly's Confections Inc","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"3320 Silas Creek Pkwy"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000106","_entity":"52684e835f23a60b0e00855d","category":["Shops","Supermarkets and Groceries"],"category_id":"52544965f71e87d0070001b1"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":84,"date":"2013-12-23","name":"Zerve Tours Shows Events","meta":{"location":{"zip":"10013","state":"NY","city":"New York","address":"Rm 604"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f3","_entity":"52a24f89d627f2b54d00fb90","category":["Travel","Travel Agencies"],"category_id":"52544965f71e87d0070001cf"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":5.12,"date":"2013-12-19","name":"Chevron Usa","meta":{"location":{"zip":"94520","state":"CA","city":"Concord","address":"2003 Diamond Blvd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000109","_entity":"5268478c5f23a60b0e000527","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":20.57,"date":"2013-12-22","name":"Thelooppizzagrille","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"320 S Stratford Rd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e00010b","_entity":"52b993aafd90ebfd53000137","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":24.55,"date":"2013-12-22","name":"Van Davis Aveda","meta":{"location":{"coordinates":{"lng":-80.2816481,"lat":36.092929},"zip":"27103","state":"NC","city":"Winston Salem","address":"244 S Stratford Rd"},"contact":{"telephone":"3367211332"},"ids":{"foursquare":"4bc4d3974cdfc9b6ad389921"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000111","_entity":"52684e345f23a60b0e007824","category":["Service","Personal Care","Hair Salons and Barbers"],"category_id":"52544965f71e87d00700014e"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":50,"date":"2013-12-21","name":"Uber","meta":{"location":{"zip":"94105","state":"CA","city":"San Francisco","address":"182 Howard Street"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e0000f1","_entity":"5294a976b71800e809000016","category":["Travel"],"category_id":"52544965f71e87d0070001b8"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":3.12,"date":"2013-12-21","name":"Starbucks Term C#153","meta":{"location":{"zip":"27623","state":"NC","city":"Raleigh","address":"1025 Airside Dr, Ste 2101"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1be9be13cbc36e0000e0","_entity":"52684e205f23a60b0e00758b","category":["Food & Drink","Nightlife","Bar"],"category_id":"52544965f71e87d007000044"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":35.96,"date":"2013-12-22","name":"Wilco Fuel Plaza 1122","meta":{"location":{"zip":"27103","state":"NC","city":"Winston Salem","address":"2026 S Hawthorne Rd"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000113","_entity":"52b993acd6da4e7c0b0002e1","category":["Travel","Gas Stations"],"category_id":"52544965f71e87d0070001c0"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":69,"date":"2013-12-21","name":"L L Bean","meta":{"location":{"coordinates":{"lng":-70.102862,"lat":43.857211},"zip":"04032","state":"ME","city":"Freeport","address":"95 Main St"},"contact":{"telephone":"(207) 865-6660"},"ids":{"factual":"22963af1-7bf9-492d-818b-4bb355d1fe62"}},"_account":"52db1be4be13cbc36e000005","_id":"52db1bebbe13cbc36e000108","_entity":"5278254010ce27ec03003e7a","category":["Food & Drink","Restaurants"],"category_id":"52544965f71e87d00700004c"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":8.98,"date":"2014-01-16","name":"Interest Charges on Purchases","meta":{"location":{}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be7be13cbc36e0000b4","_entity":"51df517968ab247d41000004"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"digital","secondary":"unresolved"},"amount":260.86,"date":"2014-01-16","name":"EVENTBRITE","meta":{"location":{},"contact":{"website":"*meatup.io"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be7be13cbc36e0000d0","_entity":"52a3f098524beee12801ddae","category":["Arts & Entertainment","Entertainment"],"category_id":"52544965f71e87d00700000a"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-1000,"date":"2014-01-02","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be6be13cbc36e000079","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":64.99,"date":"2014-01-04","name":"Crunch","meta":{"location":{"coordinates":{"lng":-73.9984,"lat":40.74205},"zip":"10011","state":"NY","city":"New York","address":"220 West 19th Street"},"contact":{"telephone":"2123700998"},"ids":{"foursquare":"5065e558011c9fb87575b212"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1bebbe13cbc36e0000fb","_entity":"52d08c2629b10e5f6a056eee","category":["Parks & Outdoors","Gyms and Fitness Centers"],"category_id":"52544965f71e87d00700009a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"unresolved"},"amount":9.8,"date":"2014-01-03","name":"Nyc Bike Share","meta":{"location":{"zip":"97214","state":"OR","city":"Portland","address":"711 Se Grand Avenue"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1bebbe13cbc36e0000ec","_entity":"52684c045f23a60b0e001b17","category":["Miscellaneous"],"category_id":"52544965f71e87d007000088"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-214.76,"date":"2014-01-15","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be6be13cbc36e00007c","_entity":"51df2f4f364351e13d00000a"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":28.85,"date":"2014-01-17","name":"La Folie","meta":{"location":{"coordinates":{"lng":-122.42219641613993,"lat":37.79805635393336},"zip":"94109","state":"CA","city":"San Francisco","address":"2316 Polk St"},"contact":{"telephone":"4157765577"},"ids":{"foursquare":"49e04b9af964a5204f611fe3","factual":"09740eae-2f29-4079-a828-fced3d4bd52b"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1bebbe13cbc36e000114","_entity":"527c3ec3a82308293a008586","category":["Food & Drink","Restaurants","French"],"category_id":"52544965f71e87d00700006c"},{"score":{"master":1,"detail":{"zip":1,"name":1,"state":1,"city":1,"address":1}},"type":{"primary":"place"},"amount":139.97,"date":"2014-01-01","name":"Crunch","meta":{"location":{"coordinates":{"lng":-122.42223,"lat":37.79827},"zip":"94109","state":"CA","city":"San Francisco","address":"2330 Polk Street"},"contact":{"telephone":"4152925444"},"ids":{"foursquare":"49d79743f964a520385d1fe3","factual":"ccd1c1d1-fd81-4535-98fe-64ac2364af15"}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be9be13cbc36e0000d8","_entity":"52a6ff1c949382717e00e816","category":["Parks & Outdoors","Gyms and Fitness Centers"],"category_id":"52544965f71e87d00700009a"},{"score":{"master":0.5,"detail":{"identifier":1}},"type":{"primary":"special"},"amount":-923.26,"date":"2013-12-24","name":"Online Credit Card Payment","meta":{"location":{}},"_account":"52db1be4be13cbc36e000006","_id":"52db1be6be13cbc36e00007d","_entity":"51df2f4f364351e13d00000a"}],"access_token":"test"} \ No newline at end of file diff --git a/src/test/resources/__files/body-institutions-TqpVf.json b/src/test/resources/__files/body-institutions-TqpVf.json new file mode 100644 index 0000000..de69b6c --- /dev/null +++ b/src/test/resources/__files/body-institutions-TqpVf.json @@ -0,0 +1 @@ +[{"id":"5301a93ac140de84910000e0","name":"Bank of America","type":"bofa","has_mfa":true,"mfa":["code","list","questions"]},{"id":"5301a99504977c52b60000d0","name":"Chase","type":"chase","has_mfa":true,"mfa":["code","list"]},{"id":"5301a9d704977c52b60000db","name":"American Express","type":"amex","has_mfa":false,"mfa":[]},{"id":"5301aa096b3f822b440001cb","name":"Wells Fargo","type":"wells","has_mfa":false,"mfa":[]},{"id":"5301aa306b3f82a00500018b","name":"Citi","type":"citi","has_mfa":false,"mfa":[]},{"id":"531ea6327de8211c80000440","name":"US Bank","type":"us","has_mfa":true,"mfa":["questions"]},{"id":"531ea6602ad939b68700047c","name":"USAA","type":"usaa","has_mfa":true,"mfa":["questions(x3)"]}] \ No newline at end of file diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml new file mode 100644 index 0000000..5d60089 --- /dev/null +++ b/src/test/resources/logback.xml @@ -0,0 +1,30 @@ + + + + + + %d{ISO8601} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-category-6JpxC.json b/src/test/resources/mappings/mapping-category-6JpxC.json new file mode 100644 index 0000000..2155043 --- /dev/null +++ b/src/test/resources/mappings/mapping-category-6JpxC.json @@ -0,0 +1,17 @@ +{ + "request" : { + "url" : "/category", + "method" : "GET" + }, + "response" : { + "status" : 200, + "bodyFileName" : "body-category-6JpxC.json", + "headers" : { + "Content-type" : "application/json", + "Date" : "Sun, 23 Mar 2014 07:41:49 GMT", + "X-Powered-By" : "Express", + "transfer-encoding" : "chunked", + "Connection" : "keep-alive" + } + } +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-connect-5Htb4.json b/src/test/resources/mappings/mapping-connect-5Htb4.json new file mode 100644 index 0000000..48cd924 --- /dev/null +++ b/src/test/resources/mappings/mapping-connect-5Htb4.json @@ -0,0 +1,17 @@ +{ + "request" : { + "urlPattern" : "/connect\\?secret=\\w+&client_id=\\w+&access_token\\=test", + "method" : "DELETE" + }, + "response" : { + "status" : 200, + "bodyFileName" : "body-connect-5Htb4.json", + "headers" : { + "Content-Type" : "application/json; charset=utf-8", + "Date" : "Wed, 26 Mar 2014 23:54:28 GMT", + "X-Powered-By" : "Express", + "Content-Length" : "46", + "Connection" : "keep-alive" + } + } +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-connect-KwC7m.json b/src/test/resources/mappings/mapping-connect-KwC7m.json new file mode 100644 index 0000000..21fa0b5 --- /dev/null +++ b/src/test/resources/mappings/mapping-connect-KwC7m.json @@ -0,0 +1,27 @@ +{ + "request" : { + "url" : "/connect", + "method" : "POST", + "bodyPatterns" : [ + { "contains" : "client_id" }, + { "contains" : "secret" }, + { "contains" : "type=chase" }, + { "contains" : "plaid_test" }, + { "contains" : "plaid_good" }, + { "contains" : "email" }, + { "contains" : "options" }, + { "contains" : "list" } + ] + }, + "response" : { + "status" : 201, + "bodyFileName" : "body-connect-KwC7m.json", + "headers" : { + "Content-Type" : "application/json; charset=utf-8", + "Date" : "Sun, 23 Mar 2014 07:27:05 GMT", + "X-Powered-By" : "Express", + "Content-Length" : "125", + "Connection" : "keep-alive" + } + } +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-connect-MpWQ7.json b/src/test/resources/mappings/mapping-connect-MpWQ7.json new file mode 100644 index 0000000..2b33f22 --- /dev/null +++ b/src/test/resources/mappings/mapping-connect-MpWQ7.json @@ -0,0 +1,27 @@ +{ + "request" : { + "url" : "/connect", + "method" : "POST", + "bodyPatterns" : [ + { "contains" : "client_id" }, + { "contains" : "secret" }, + { "contains" : "type=chase" }, + { "contains" : "plaid_test" }, + { "contains" : "plaid_good" }, + { "contains" : "email" }, + { "contains" : "options" }, + { "contains" : "login" } + ] + }, + "response" : { + "status" : 201, + "bodyFileName" : "body-connect-MpWQ7.json", + "headers" : { + "Content-Type" : "application/json; charset=utf-8", + "Date" : "Sun, 23 Mar 2014 07:27:32 GMT", + "X-Powered-By" : "Express", + "Content-Length" : "87", + "Connection" : "keep-alive" + } + } +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-connect-get-mU7ak.json b/src/test/resources/mappings/mapping-connect-get-mU7ak.json new file mode 100644 index 0000000..28e6180 --- /dev/null +++ b/src/test/resources/mappings/mapping-connect-get-mU7ak.json @@ -0,0 +1,18 @@ +{ + "request" : { + "method" : "GET", + "urlPattern" : "/connect\\?secret=\\w+&client_id=\\w+&access_token\\=test" + + }, + "response" : { + "status" : 200, + "bodyFileName" : "body-connect-get-mU7ak.json", + "headers" : { + "Content-Type" : "application/json; charset=utf-8", + "Date" : "Sun, 23 Mar 2014 07:29:32 GMT", + "X-Powered-By" : "Express", + "Content-Length" : "48187", + "Connection" : "keep-alive" + } + } +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-connect-qZWyb.json b/src/test/resources/mappings/mapping-connect-qZWyb.json new file mode 100644 index 0000000..90b0b26 --- /dev/null +++ b/src/test/resources/mappings/mapping-connect-qZWyb.json @@ -0,0 +1,25 @@ +{ + "request" : { + "url" : "/connect", + "method" : "POST", + "bodyPatterns" : [ + { "contains" : "client_id" }, + { "contains" : "secret" }, + { "contains" : "type=amex" }, + { "contains" : "plaid_test" }, + { "contains" : "plaid_good" }, + { "contains" : "email" } + ] + }, + "response" : { + "status" : 200, + "bodyFileName" : "body-connect-qZWyb.json", + "headers" : { + "Content-Type" : "application/json; charset=utf-8", + "Date" : "Sun, 23 Mar 2014 07:27:56 GMT", + "X-Powered-By" : "Express", + "Content-Length" : "48187", + "Connection" : "keep-alive" + } + } +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-connect-step-XBxNh.json b/src/test/resources/mappings/mapping-connect-step-XBxNh.json new file mode 100644 index 0000000..6e3a07f --- /dev/null +++ b/src/test/resources/mappings/mapping-connect-step-XBxNh.json @@ -0,0 +1,23 @@ +{ + "request" : { + "url" : "/connect/step", + "method" : "POST", + "bodyPatterns" : [ + { "contains" : "client_id" }, + { "contains" : "secret" }, + { "contains" : "mfa=1234" }, + { "contains" : "access_token=test" } + ] + }, + "response" : { + "status" : 200, + "bodyFileName" : "body-connect-step-XBxNh.json", + "headers" : { + "Content-Type" : "application/json; charset=utf-8", + "Date" : "Sun, 23 Mar 2014 07:31:55 GMT", + "X-Powered-By" : "Express", + "Content-Length" : "48187", + "Connection" : "keep-alive" + } + } +} \ No newline at end of file diff --git a/src/test/resources/mappings/mapping-institutions-TqpVf.json b/src/test/resources/mappings/mapping-institutions-TqpVf.json new file mode 100644 index 0000000..4db4bf1 --- /dev/null +++ b/src/test/resources/mappings/mapping-institutions-TqpVf.json @@ -0,0 +1,17 @@ +{ + "request" : { + "url" : "/institutions", + "method" : "GET" + }, + "response" : { + "status" : 200, + "bodyFileName" : "body-institutions-TqpVf.json", + "headers" : { + "Content-type" : "application/json", + "Date" : "Sun, 23 Mar 2014 07:37:36 GMT", + "X-Powered-By" : "Express", + "Content-Length" : "704", + "Connection" : "keep-alive" + } + } +} \ No newline at end of file