├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── VERSION
├── pom.xml
└── src
├── main
└── java
│ └── com
│ └── ost
│ └── kyc
│ ├── OSTKYCSDK.java
│ ├── lib
│ └── OSTKYCRequestClient.java
│ └── services
│ ├── OSTKYCAPIService.java
│ ├── OSTKYCServiceManifest.java
│ └── v2
│ ├── Manifest.java
│ ├── User.java
│ ├── UsersKyc.java
│ ├── UsersKycDetail.java
│ └── Validators.java
└── test
└── java
└── com
└── ost
└── kyc
├── OSTKYCSDKTest.java
└── services
├── ServiceTestBase.java
└── v2
├── SignatureTest.java
├── UserTest.java
├── UsersKycDetailTest.java
├── UsersKycTest.java
└── ValidatorsTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 |
25 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
26 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
27 | .idea/*
28 |
29 | # User-specific stuff
30 | .idea/**/workspace.xml
31 | .idea/**/tasks.xml
32 | .idea/**/dictionaries
33 | .idea/**/shelf
34 |
35 | # Sensitive or high-churn files
36 | .idea/**/dataSources/
37 | .idea/**/dataSources.ids
38 | .idea/**/dataSources.local.xml
39 | .idea/**/sqlDataSources.xml
40 | .idea/**/dynamic.xml
41 | .idea/**/uiDesigner.xml
42 | .idea/**/dbnavigator.xml
43 |
44 | # Gradle
45 | .idea/**/gradle.xml
46 | .idea/**/libraries
47 |
48 | # CMake
49 | cmake-build-debug/
50 | cmake-build-release/
51 |
52 | # Mongo Explorer plugin
53 | .idea/**/mongoSettings.xml
54 |
55 | # File-based project format
56 | *.iws
57 |
58 | # IntelliJ
59 | out/
60 |
61 | # mpeltonen/sbt-idea plugin
62 | .idea_modules/
63 |
64 | # JIRA plugin
65 | atlassian-ide-plugin.xml
66 |
67 | # Cursive Clojure plugin
68 | .idea/replstate.xml
69 |
70 | # Crashlytics plugin (for Android Studio and IntelliJ)
71 | com_crashlytics_export_strings.xml
72 | crashlytics.properties
73 | crashlytics-build.properties
74 | fabric.properties
75 |
76 | # Editor-based Rest Client
77 | .DS_Store
78 | target
79 |
80 | release.properties
81 | ost-kyc-sdk-java.iml
82 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | # The cross product of the jdk and env settings form the matrix of builds Travis will run.
3 | jdk:
4 | - oraclejdk8
5 | - oraclejdk9
6 | - openjdk7
7 | - openjdk8
8 | notifications:
9 | email:
10 | recipients:
11 | - ci.report@ost.com
12 | on_success: always
13 | on_failure: always
14 | sudo: false
15 | branches:
16 | only:
17 | - master
18 | - develop
19 | script: mvn clean verify
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | [OST KYC JAVA SDK v2.0.4](https://github.com/ostdotcom/ost-kyc-sdk-java/tree/v2.0.4) March 04 2019
2 | ---
3 |
4 | * Fix for escaping special character from parameters and added test case for signature matching.
5 |
6 | [OST KYC JAVA SDK v2.0.3](https://github.com/ostdotcom/ost-kyc-sdk-java/tree/v2.0.3) February 28 2019
7 | ---
8 |
9 | * Repository moved from OpenStFoundation to ostdotcom and related Readme Updated.
10 |
11 | [OST KYC JAVA SDK v2.0.2](https://github.com/ostdotcom/ost-kyc-sdk-java/tree/v2.0.2) December 21 2018
12 | ---
13 |
14 | * Fix to allow number values for id and user_id in the parameters.
15 |
16 | [OST KYC JAVA SDK v2.0.1](https://github.com/ostdotcom/ost-kyc-sdk-java/tree/v2.0.1) December 17 2018
17 | ---
18 |
19 | * Implemented API's for kyc email send
20 |
21 | [OST KYC JAVA SDK v2.0.0](https://github.com/ostdotcom/ost-kyc-sdk-java/tree/v2.0.0) November 28 2018
22 | ---
23 |
24 | Initial release of the official OST KYC JAVA SDK
25 | This release has the OST KYC API V2 interaction layer implementation.
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018 OST.com Ltd.
2 |
3 | MIT License
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OST KYC JAVA SDK
2 | The official [OST KYC JAVA SDK](https://dev.ost.com/docs/kyc/index.html).
3 |
4 |
5 | [](https://travis-ci.org/ostdotcom/ost-kyc-sdk-java)
6 |
7 | ## Requirements
8 |
9 | To use this node module, developers will need to:
10 | 1. Login on [https://kyc.ost.com/admin/login](https://kyc.ost.com/admin/login).
11 | 2. Obtain an API Key and API Secret from [https://kyc.ost.com/admin/settings/developer-integrations](https://kyc.ost.com/admin/settings/developer-integrations).
12 |
13 | ## Documentation
14 |
15 | [https://dev.ost.com/docs/kyc/index.html](https://dev.ost.com/docs/kyc/index.html)
16 |
17 | ## Installation
18 |
19 | ### Maven users
20 | #### Add this dependency to your project's POM:
21 | ```xml
22 |
23 | com.ost
24 | ost-kyc-sdk-java
25 | 2.0.4
26 |
27 | ```
28 |
29 | ### Building from source using Maven
30 |
31 | Clone the repository
32 | ```bash
33 | git clone https://github.com/ostdotcom/ost-kyc-sdk-java.git
34 | cd ost-kyc-sdk-java
35 | ```
36 |
37 |
38 | Package using MVN (without dependencies)
39 | ```bash
40 | mvn clean pacakge -DskipTests
41 | ```
42 |
43 | With dependencies
44 | ```bash
45 | mvn clean compile assembly:single -DskipTests
46 | ```
47 |
48 | The jar file can be found in the target folder.
49 |
50 | ## Example Usage
51 |
52 |
53 | Initialize the SDK object:
54 |
55 | ```java
56 | // the latest valid API endpoint is "https://kyc.sandboxost.com", this may change in the future
57 | HashMap sdkConfig = new HashMap();
58 | sdkConfig.put("apiEndpoint","[API_ENDPOINT]");
59 | sdkConfig.put("apiKey","[YOUR_API_KEY]");
60 | sdkConfig.put("apiSecret","[YOUR_API_SECRET]");
61 |
62 |
63 | // The config field is optional for sdkConfig Object
64 | HashMap nestedparam = new HashMap();
65 | // This is the timeout in seconds for which the socket connection will remain open
66 | // The value of timeout will always be of type long
67 | nestedparam.put("timeout", (long) 15);
68 | sdkConfig.put("config", nestedparam);
69 |
70 |
71 | OSTKYCSDK ostObj = new OSTKYCSDK(sdkConfig);
72 | com.ost.kyc.services.v2.Manifest services = (com.ost.kyc.services.v2.Manifest) ostObj.services;
73 | ```
74 |
75 | ### Users Module
76 |
77 | ```java
78 | com.ost.kyc.services.v2.User userService = services.user;
79 | ```
80 |
81 | Create a new user:
82 |
83 | ```java
84 | HashMap params = new HashMap();
85 | params.put("email", "email@domain.com");
86 | JsonObject response = userService.create( params );
87 | System.out.println("response: " + response.toString() );
88 | ```
89 |
90 | Get an existing user:
91 |
92 | ```java
93 | HashMap params = new HashMap();
94 | params.put("id", "11007");
95 | JsonObject response = userService.get( params );
96 | System.out.println("response: " + response.toString() );
97 | ```
98 |
99 | Get a list of existing users and other data:
100 |
101 | ```java
102 | HashMap params = new HashMap();
103 | JsonObject response = userService.list( params );
104 | System.out.println("response: " + response.toString() );
105 | ```
106 |
107 | ### UsersKyc Module
108 |
109 | ```java
110 | com.ost.kyc.services.v2.UsersKyc usersKycService = services.usersKyc;
111 | ```
112 |
113 | Get an existing user kyc:
114 |
115 | ```java
116 | HashMap params = new HashMap();
117 | params.put("user_id", "11007");
118 | JsonObject response = usersKycService.get( params );
119 | System.out.println("response: " + response.toString() );
120 | ```
121 |
122 | Create/Update a new user kyc:
123 |
124 | ```java
125 | HashMap params = new HashMap();
126 | params.put("user_id", "11052");
127 | params.put("first_name", "YOGESH");
128 | params.put("last_name", "SAWANT");
129 | params.put("birthdate", "29/07/1992");
130 | params.put("country", "INDIA");
131 | params.put("document_id_number", "ABCD123");
132 | params.put("document_id_file_path", "2/i/016be96da275031de2787b57c99f1471");
133 | params.put("selfie_file_path", "2/i/9e8d3a5a7a58f0f1be50b7876521aebc");
134 | params.put("ethereum_address", "0x04d39e0b112c20917868ffd5c42372ecc5df577b");
135 | params.put("estimated_participation_amount", "1.2");
136 | params.put("residence_proof_file_path", "2/i/4ed790b2d525f4c7b30fbff5cb7bbbdb");
137 | params.put("city", "pune");
138 | params.put("nationality", "INDIAN");
139 | params.put("state", "maharashtra");
140 | params.put("postal_code", "411028");
141 | JsonObject response = usersKycService.submit_kyc( params );
142 | System.out.println("response: " + response.toString() );
143 | ```
144 |
145 | Send Approve Email to User:
146 |
147 | ```java
148 | HashMap params = new HashMap();
149 | params.put("user_id", "11550");
150 | JsonObject response = usersKycService.email_approve( params );
151 | System.out.println("response: " + response.toString() );
152 | ```
153 |
154 | Send Deny Email to User:
155 |
156 | ```java
157 | HashMap params = new HashMap();
158 | params.put("user_id", "11550");
159 | JsonObject response = usersKycService.email_deny( params );
160 | System.out.println("response: " + response.toString() );
161 | ```
162 |
163 | Send Report Issue Email to User:
164 |
165 | ```java
166 | HashMap params = new HashMap();
167 | params.put("user_id", "11550");
168 | JsonObject response = usersKycService.email_report_issue( params );
169 | System.out.println("response: " + response.toString() );
170 | ```
171 |
172 | Get a list of existing users kyc and other data:
173 |
174 | ```java
175 | HashMap params = new HashMap();
176 | JsonObject response = usersKycService.list( params );
177 | System.out.println("response: " + response.toString() );
178 | ```
179 |
180 | Get an existing Presigned URL via POST call:
181 |
182 | ```java
183 | HashMap params = new HashMap();
184 | HashMap nestedparams = new HashMap();
185 | nestedparams.put("selfie", "image/jpeg");
186 | params.put("files", nestedparams);
187 | JsonObject response = usersKycService.get_presigned_url_post( params );
188 | System.out.println("response: " + response.toString() );
189 | ```
190 |
191 | Get an existing Presigned URL via PUT call:
192 |
193 | ```java
194 | HashMap params = new HashMap();
195 | HashMap nestedparams = new HashMap();
196 | nestedparams.put("selfie", "image/jpeg");
197 | params.put("files", nestedparams);
198 | JsonObject response = usersKycService.get_presigned_url_put( params );
199 | System.out.println("response: " + response.toString() );
200 | ```
201 |
202 |
203 | ### UsersKycDetail Module
204 |
205 | ```java
206 | com.ost.kyc.services.v2.UsersKycDetail usersKycDetailService = services.usersKycDetail;
207 | ```
208 |
209 | Get an user kyc detail:
210 |
211 | ```java
212 | HashMap params = new HashMap();
213 | params.put("user_id", "11052");
214 | JsonObject response = usersKycDetailService.get( params );
215 | System.out.println("response: " + response.toString() );
216 | ```
217 |
218 | ### Validators Module
219 |
220 | ```java
221 | com.ost.kyc.services.v2.Validators validatorService = services.validators;
222 | ```
223 |
224 | Verify Ethereum Address:
225 |
226 | ```java
227 | HashMap params = new HashMap();
228 | params.put("ethereum_address", "0x7f2ED21D1702057C7d9f163cB7e5458FA2B6B7c4");
229 | JsonObject response = validatorService.verify_ethereum_address( params );
230 | System.out.println("response: " + response.toString() );
231 | ```
232 |
233 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 2.0.4
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | com.ost
5 | ost-kyc-sdk-java
6 | 2.0.4
7 | OST KYC SDK for Java
8 | The official OST KYC SDK for Java(https://dev.ost.com/docs/kyc/index.html).
9 | jar
10 | https://kyc.ost.com/
11 |
12 |
13 | MIT License
14 | http://www.opensource.org/licenses/mit-license.php
15 |
16 |
17 |
18 |
19 |
20 | maven-assembly-plugin
21 |
22 |
23 | jar-with-dependencies
24 |
25 |
26 |
27 |
28 | maven-deploy-plugin
29 | 2.8.2
30 |
31 |
32 | default-deploy
33 | deploy
34 |
35 | deploy
36 |
37 |
38 |
39 |
40 |
41 | org.apache.maven.plugins
42 | maven-release-plugin
43 | 2.5.3
44 |
45 | true
46 | false
47 | forked-path
48 | -DskipTests -Dgpg.passphrase=${gpg.passphrase}
49 |
50 |
51 |
52 | org.apache.maven.scm
53 | maven-scm-provider-gitexe
54 | 1.9.5
55 |
56 |
57 |
58 |
59 | org.sonatype.plugins
60 | nexus-staging-maven-plugin
61 | 1.6.8
62 | true
63 |
64 | ossrh
65 | https://oss.sonatype.org/
66 | true
67 |
68 |
69 |
70 | org.apache.maven.plugins
71 | maven-source-plugin
72 | 3.0.1
73 |
74 |
75 | attach-sources
76 |
77 | jar
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | com.google.code.gson
88 | gson
89 | 2.8.2
90 |
91 |
92 | com.google.guava
93 | guava
94 | 18.0
95 |
96 |
97 | org.apache.commons
98 | commons-lang3
99 | 3.7
100 |
101 |
102 | com.squareup.okhttp3
103 | okhttp
104 | 3.10.0
105 |
106 |
107 | org.slf4j
108 | slf4j-api
109 | 1.7.7
110 |
111 |
112 | junit
113 | junit
114 | 4.12
115 | test
116 |
117 |
118 |
119 | 1.6
120 | 1.6
121 | UTF-8
122 | UTF-8
123 |
124 |
125 |
126 | ostdev
127 | OST.COM
128 | https://kyc.ost.com/
129 |
130 | developer
131 |
132 |
133 |
134 |
135 | scm:git:https://github.com/ostdotcom/ost-kyc-sdk-java.git
136 | scm:git:git@github.com:ostdotcom/ost-kyc-sdk-java.git
137 | https://github.com/ostdotcom/ost-kyc-sdk-java
138 | HEAD
139 |
140 |
141 |
142 | ossrh
143 | https://oss.sonatype.org/content/repositories/snapshots
144 |
145 |
146 | ossrh
147 | https://oss.sonatype.org/service/local/staging/deploy/maven2/
148 |
149 |
150 |
151 |
152 |
153 |
154 | release-sign-artifacts
155 |
156 |
157 | performRelease
158 | true
159 |
160 |
161 |
162 |
163 |
164 | org.apache.maven.plugins
165 | maven-gpg-plugin
166 | 1.6
167 |
168 |
169 | sign-artifacts
170 | verify
171 |
172 | sign
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
--------------------------------------------------------------------------------
/src/main/java/com/ost/kyc/OSTKYCSDK.java:
--------------------------------------------------------------------------------
1 | package com.ost.kyc;
2 |
3 | import com.ost.kyc.services.OSTKYCServiceManifest;
4 | import com.ost.kyc.services.v2.Manifest;
5 |
6 | import java.util.Map;
7 |
8 | public class OSTKYCSDK {
9 | String apiEndpoint;
10 | String apiKey;
11 | String apiSecret;
12 | public OSTKYCServiceManifest services;
13 |
14 | public OSTKYCSDK(Map params) {
15 | if (params.containsKey("apiEndpoint") && params.get("apiEndpoint") instanceof String &&
16 | params.get("apiEndpoint") != "") {
17 | apiEndpoint = (String) params.get("apiEndpoint");
18 | } else {
19 | throw new IllegalArgumentException("Invalid apiEndpoint.");
20 | }
21 |
22 | if (params.containsKey("apiKey") && params.get("apiKey") instanceof String &&
23 | params.get("apiKey") != "") {
24 | apiKey = (String) params.get("apiKey");
25 | } else {
26 | throw new IllegalArgumentException("Invalid apiKey.");
27 | }
28 |
29 | if (params.containsKey("apiSecret") && params.get("apiSecret") instanceof String &&
30 | params.get("apiSecret") != "") {
31 | apiSecret = (String) params.get("apiSecret");
32 | } else {
33 | throw new IllegalArgumentException("Invalid apiSecret.");
34 | }
35 |
36 | services = new Manifest(params);
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/ost/kyc/lib/OSTKYCRequestClient.java:
--------------------------------------------------------------------------------
1 | package com.ost.kyc.lib;
2 |
3 | import java.io.IOException;
4 | import java.net.SocketTimeoutException;
5 | import java.util.*;
6 |
7 | import com.google.gson.Gson;
8 | import com.google.gson.JsonObject;
9 | import com.google.common.escape.Escaper;
10 | import com.google.common.net.UrlEscapers;
11 | import okhttp3.*;
12 | import okio.Buffer;
13 | import okio.ByteString;
14 |
15 | import java.nio.charset.Charset;
16 | import java.security.NoSuchAlgorithmException;
17 | import java.security.InvalidKeyException;
18 | import java.util.concurrent.TimeUnit;
19 | import javax.crypto.Mac;
20 | import javax.crypto.spec.SecretKeySpec;
21 |
22 | public class OSTKYCRequestClient {
23 | private String apiKey;
24 | private String apiSecret;
25 | private String apiEndpoint;
26 | private Long timeout;
27 | private static final Gson gson = new Gson();
28 | private OkHttpClient client;
29 | private static final Escaper FormParameterEscaper = UrlEscapers.urlFormParameterEscaper();
30 | private static final String HMAC_SHA256 = "HmacSHA256";
31 | private static final Charset UTF_8 = Charset.forName("UTF-8");
32 | private static Boolean DEBUG = ("true").equalsIgnoreCase( System.getenv("OST_KYC_SDK_DEBUG") );
33 | private static Boolean VERBOSE = false;
34 |
35 | public static class HttpParam {
36 | private String paramName;
37 | private String paramValue;
38 |
39 | public HttpParam() {
40 |
41 | }
42 |
43 | public HttpParam(String paramName, String paramValue) {
44 | this.paramName = paramName;
45 | this.paramValue = paramValue;
46 | }
47 |
48 | public String getParamValue() {
49 | return paramValue;
50 | }
51 |
52 | public void setParamValue(String paramValue) {
53 | this.paramValue = paramValue;
54 | }
55 |
56 | public String getParamName() {
57 | return paramName;
58 | }
59 |
60 | public void setParamName(String paramName) {
61 | this.paramName = paramName;
62 | }
63 |
64 | }
65 |
66 | public OSTKYCRequestClient(Map params) {
67 | Object apiKey = params.get("apiKey");
68 | Object apiSecret = params.get("apiSecret");
69 | Object apiEndpoint = params.get("apiEndpoint");
70 |
71 | //default timeout is 10 seconds for socket connection
72 | long timeout = (long) 10;
73 | if(params.containsKey("config"))
74 | {
75 | HashMap config = (HashMap) params.get("config");
76 |
77 | if(config.containsKey("timeout")){
78 | timeout = (Long) config.get("timeout");
79 | }
80 | }
81 |
82 | if (!(apiKey instanceof String)) {
83 | throw new IllegalArgumentException("Api key not present.");
84 | }
85 |
86 | if (!(apiSecret instanceof String)) {
87 | throw new IllegalArgumentException("Api secret not present.");
88 | }
89 |
90 | if (!(apiEndpoint instanceof String)) {
91 | throw new IllegalArgumentException("Api EndPoint not present.");
92 | }
93 |
94 | this.apiKey = (String) apiKey;
95 | this.apiSecret = (String) apiSecret;
96 | this.apiEndpoint = (String) apiEndpoint;
97 | this.timeout = timeout;
98 |
99 |
100 | //To-Do: Discuss Dispatcher config with Team.
101 | Dispatcher dispatcher = new Dispatcher();
102 | dispatcher.setMaxRequests(500);
103 | dispatcher.setMaxRequestsPerHost(150);
104 |
105 | client = new OkHttpClient.Builder()
106 | .connectionPool(new ConnectionPool(10, 2, TimeUnit.MINUTES))
107 | .connectTimeout(30, TimeUnit.SECONDS)
108 | .readTimeout(timeout, TimeUnit.SECONDS)
109 | .dispatcher(dispatcher)
110 | .retryOnConnectionFailure(false)
111 | .build();
112 |
113 | }
114 |
115 | private static String GET_REQUEST = "GET";
116 | private static String POST_REQUEST = "POST";
117 | private static String SocketTimeoutExceptionString = "{'success':'false','err':{'code':'GATEWAY_TIMEOUT','internal_id':'TIMEOUT_ERROR','msg':'','error_data':[]}}";
118 |
119 |
120 | public JsonObject get(String resource, Map queryParams) throws IOException {
121 | return send(GET_REQUEST, resource, queryParams);
122 | }
123 |
124 | public JsonObject post(String resource, Map queryParams) throws IOException {
125 | return send(POST_REQUEST, resource, queryParams);
126 | }
127 |
128 | private JsonObject send(String requestType, String resource, Map mapParams) throws IOException {
129 | // Basic Sanity.
130 | if (!requestType.equalsIgnoreCase(POST_REQUEST) && !requestType.equalsIgnoreCase(GET_REQUEST)) {
131 | throw new IOException("Invalid requestType");
132 | }
133 | if (null == mapParams) {
134 | mapParams = new HashMap();
135 | }
136 |
137 | // Start Building the request, url of request and request form body.
138 | Request.Builder requestBuilder = new Request.Builder();
139 | HttpUrl baseUrl = HttpUrl.parse(apiEndpoint + resource);
140 | HttpUrl.Builder urlBuilder = baseUrl.newBuilder(resource);
141 |
142 | FormBody.Builder formBodyBuilder = new FormBody.Builder();
143 | if (null == urlBuilder) {
144 | throw new IOException("Failed to instantiate HttpUrl.Builder. resource or Api Endpoint is incorrect.");
145 | }
146 |
147 | // Evaluate the url generated so far.
148 | HttpUrl url = urlBuilder.build();
149 |
150 | //Reset urlBuilder.
151 | urlBuilder = baseUrl.newBuilder();
152 |
153 |
154 | ArrayList params = new ArrayList();
155 |
156 | mapParams.put("api_key", apiKey);
157 | mapParams.put("request_timestamp", String.valueOf(System.currentTimeMillis() / 1000));
158 |
159 | params = getRequestParam(resource, mapParams);
160 |
161 | String paramKey;
162 | String paramVal;
163 |
164 | // Add params to url/form-body & hmacInputBuffer.
165 | Iterator it = params.iterator();
166 |
167 | while (it.hasNext()) {
168 | HttpParam pair = (HttpParam) it.next();
169 |
170 | paramKey = pair.getParamName();
171 | paramVal = pair.getParamValue();
172 |
173 | if (GET_REQUEST.equalsIgnoreCase(requestType)) {
174 | urlBuilder.addEncodedQueryParameter(paramKey, paramVal);
175 | } else {
176 | formBodyBuilder.addEncoded(paramKey, paramVal);
177 | }
178 | }
179 |
180 | // Build the url.
181 | url = urlBuilder.build();
182 | if (DEBUG) System.out.println("url = " + url.toString());
183 |
184 | // Set url in requestBuilder.
185 | requestBuilder.url(url);
186 |
187 | // Build the request Object.
188 | Request request;
189 | if (GET_REQUEST.equalsIgnoreCase(requestType)) {
190 | requestBuilder.get().addHeader("content-type", "x-www-form-urlencoded");
191 | } else {
192 | FormBody formBody = formBodyBuilder.build();
193 | if (DEBUG && VERBOSE) {
194 | for (int i = 0; i < formBody.size(); i++) {
195 | System.out.println(formBody.name(i) + "\t\t" + formBody.value(i));
196 | }
197 | }
198 |
199 | requestBuilder.post(formBody);
200 | }
201 | request = requestBuilder.build();
202 |
203 | // Make the call and execute.
204 | String responseBody;
205 | Call call = client.newCall(request);
206 | try {
207 | okhttp3.Response response = call.execute();
208 | responseBody = getResponseBodyAsString(response);
209 | }catch (SocketTimeoutException e)
210 | {
211 | responseBody = SocketTimeoutExceptionString;
212 | }
213 | return buildApiResponse(responseBody);
214 | }
215 |
216 | public ArrayList getRequestParam(String resource, Map paramValObj) {
217 |
218 | // Start Building HMAC Input Buffer by parsing the url.
219 | Buffer hmacInputBuffer = new Buffer();
220 |
221 | hmacInputBuffer.writeUtf8(resource);
222 | hmacInputBuffer.writeByte('?');
223 |
224 |
225 | ArrayList params = new ArrayList();
226 | ArrayList escapedParams = new ArrayList();
227 | String paramKey;
228 | String paramVal;
229 |
230 | params = buildNestedQuery(params, "", paramValObj);
231 |
232 | // Add params to url/form-body & hmacInputBuffer.
233 | Iterator it = params.iterator();
234 | boolean firstParam = true;
235 |
236 | while (it.hasNext()) {
237 | HttpParam pair = (HttpParam) it.next();
238 |
239 | paramKey = pair.getParamName();
240 | paramVal = pair.getParamValue();
241 |
242 | paramKey = specialCharacterEscape(paramKey);
243 | paramVal = specialCharacterEscape(paramVal);
244 |
245 | if (!firstParam) {
246 | hmacInputBuffer.writeByte('&');
247 | }
248 | firstParam = false;
249 |
250 | hmacInputBuffer.writeUtf8(paramKey);
251 | hmacInputBuffer.writeByte('=');
252 | hmacInputBuffer.writeUtf8(paramVal);
253 |
254 | escapedParams.add(new HttpParam(paramKey, paramVal));
255 | if (DEBUG) System.out.println("paramKey " + paramKey + " paramVal " + paramVal);
256 | }
257 |
258 | paramVal = signQueryParams(hmacInputBuffer);
259 | escapedParams.add(new HttpParam("signature", paramVal));
260 | return escapedParams;
261 | }
262 |
263 | private String signQueryParams(Buffer hmacInputBuffer) {
264 | // Generate Signature for Params.
265 | SecretKeySpec keySpec = new SecretKeySpec(apiSecret.getBytes(UTF_8), HMAC_SHA256);
266 | Mac mac;
267 | try {
268 | mac = Mac.getInstance(HMAC_SHA256);
269 | // Initializing a Cipher
270 | mac.init(keySpec);
271 | } catch (NoSuchAlgorithmException e) {
272 | throw new IllegalStateException(e);
273 | } catch (InvalidKeyException e) {
274 | throw new IllegalStateException(e);
275 | }
276 | byte[] bytes = hmacInputBuffer.readByteArray();
277 | if (DEBUG) System.out.println("bytes to sign: " + new String(bytes, UTF_8));
278 | // Encryption of bytes
279 | byte[] result = mac.doFinal(bytes);
280 |
281 | String signature = ByteString.of(result).hex();
282 | if (DEBUG) System.out.println("signature: " + signature);
283 | return signature;
284 | }
285 |
286 | private static String SOMETHING_WRONG_RESPONSE = "{'success': false, 'err': {'code': 'SOMETHING_WENT_WRONG', 'internal_id': 'SDK(SOMETHING_WENT_WRONG)', 'msg': '', 'error_data':[]}}";
287 |
288 | private static String getResponseBodyAsString(okhttp3.Response response) {
289 | // Process the response.
290 | String responseBody;
291 | if (response.body() != null) {
292 | try {
293 | responseBody = response.body().string();
294 | if (responseBody.length() > 0) {
295 | if (DEBUG) System.out.println("responseCode: "+response.code()+"\nresponseBody:\n" + responseBody + "\n");
296 | return responseBody;
297 | }
298 | } catch (IOException e) {
299 | // Silently handle the error.
300 | e.printStackTrace();
301 | }
302 | }
303 |
304 | // Response does not have a body. Lets create one.
305 | switch (response.code()) {
306 | case 502:
307 | responseBody = "{'success': false, 'err': {'code': 'BAD_GATEWAY', 'internal_id': 'SDK(BAD_GATEWAY)', 'msg': '', 'error_data':[]}}";
308 | break;
309 | case 503:
310 | responseBody = "{'success': false, 'err': {'code': 'SERVICE_UNAVAILABLE', 'internal_id': 'SDK(SERVICE_UNAVAILABLE)', 'msg': '', 'error_data':[]}}";
311 | break;
312 | case 504:
313 | responseBody = "{'success': false, 'err': {'code': 'GATEWAY_TIMEOUT', 'internal_id': 'SDK(GATEWAY_TIMEOUT)', 'msg': '', 'error_data':[]}}";
314 | break;
315 | default:
316 | responseBody = SOMETHING_WRONG_RESPONSE;
317 | }
318 |
319 | if (DEBUG) System.out.println("local responseBody:\n" + responseBody + "\n");
320 | return responseBody;
321 | }
322 |
323 | private static JsonObject buildApiResponse(String jsonString) {
324 | try {
325 | return gson.fromJson(jsonString, JsonObject.class);
326 | } catch (Exception e) {
327 | e.printStackTrace();
328 | }
329 | if (DEBUG)
330 | System.out.println("Failed to parse response. local responseBody:\n" + SOMETHING_WRONG_RESPONSE + "\n");
331 | return gson.fromJson(SOMETHING_WRONG_RESPONSE, JsonObject.class);
332 | }
333 |
334 | private static ArrayList buildNestedQuery(ArrayList params, String paramKeyPrefix, Object paramValObj) {
335 |
336 | if (paramValObj instanceof Map) {
337 |
338 | // sort map.
339 | Map sortedMap = new TreeMap((Map extends String, ?>) paramValObj);
340 | for (Object paramPair : sortedMap.entrySet()) {
341 | Map.Entry pair = (Map.Entry) paramPair;
342 | String key = (String) pair.getKey();
343 | Object value = pair.getValue();
344 | String prefix = "";
345 | if (paramKeyPrefix.isEmpty()){
346 | prefix = key;
347 | }else{
348 | prefix = paramKeyPrefix + "[" + key + "]";
349 | }
350 |
351 | params = buildNestedQuery(params, prefix, value);
352 | }
353 |
354 | } else if (paramValObj instanceof Collection) {
355 | Iterator