sumsub-ruby-sdk 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 507bfecc21b02884373eeaaf2ef76729711b710b348a7d6de2b289349b5cb1ae
4
+ data.tar.gz: e943a0860aa49188e629a87a43a8b09ecac65079cacd76e7ffb601c1b4d4aec9
5
+ SHA512:
6
+ metadata.gz: 22eb29cf663da0995ae277ca39263b2c9e38a937c1b02a3ba7b750246b1292de7592ec336a772511555c34823e617506f8d4a9cc821560aed46dfc9be75695f7
7
+ data.tar.gz: 5a3c8f478845385fc6a6f326b9d13043d6dc20930a2353d555cd3853f9fa0f5118500e3b8bc43f42cb9d8aa9aaaabb358a65c91833590b12c0bca32e2e64d063
@@ -0,0 +1,13 @@
1
+ version: 2.1
2
+ jobs:
3
+ build:
4
+ docker:
5
+ - image: ruby:3.0.1
6
+ steps:
7
+ - checkout
8
+ - run:
9
+ name: Run the default task
10
+ command: |
11
+ gem install bundler -v 2.2.17
12
+ bundle install
13
+ bundle exec rake
data/.editorconfig ADDED
@@ -0,0 +1,20 @@
1
+ # top-most EditorConfig file
2
+ root = true
3
+
4
+ # Unix-style newlines with a newline ending every file
5
+ [*]
6
+ end_of_line = lf
7
+ insert_final_newline = true
8
+
9
+ # Set default charset
10
+ charset = utf-8
11
+
12
+ # General identation style
13
+ [*]
14
+ indent_style = space
15
+ indent_size = 2
16
+
17
+ # Makefile's only accept tab identations
18
+ [Makefile]
19
+ indent_style = tab
20
+ indent_size = 2
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ test_script
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in sumsub-ruby-sdk.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "rspec", "~> 3.0"
data/Gemfile.lock ADDED
@@ -0,0 +1,105 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sumsub-ruby-sdk (0.1.1)
5
+ dry-struct (~> 1.4.0)
6
+ http (~> 5.0.0)
7
+ mime-types (~> 3.3.1)
8
+ pry (~> 0.14.1)
9
+ rspec (~> 3.10.0)
10
+ timecop (~> 0.9.4)
11
+ webmock (~> 3.13.0)
12
+
13
+ GEM
14
+ remote: https://rubygems.org/
15
+ specs:
16
+ addressable (2.7.0)
17
+ public_suffix (>= 2.0.2, < 5.0)
18
+ coderay (1.1.3)
19
+ concurrent-ruby (1.1.8)
20
+ crack (0.4.5)
21
+ rexml
22
+ diff-lcs (1.4.4)
23
+ domain_name (0.5.20190701)
24
+ unf (>= 0.0.5, < 1.0.0)
25
+ dry-configurable (0.12.1)
26
+ concurrent-ruby (~> 1.0)
27
+ dry-core (~> 0.5, >= 0.5.0)
28
+ dry-container (0.7.2)
29
+ concurrent-ruby (~> 1.0)
30
+ dry-configurable (~> 0.1, >= 0.1.3)
31
+ dry-core (0.5.0)
32
+ concurrent-ruby (~> 1.0)
33
+ dry-inflector (0.2.0)
34
+ dry-logic (1.2.0)
35
+ concurrent-ruby (~> 1.0)
36
+ dry-core (~> 0.5, >= 0.5)
37
+ dry-struct (1.4.0)
38
+ dry-core (~> 0.5, >= 0.5)
39
+ dry-types (~> 1.5)
40
+ ice_nine (~> 0.11)
41
+ dry-types (1.5.1)
42
+ concurrent-ruby (~> 1.0)
43
+ dry-container (~> 0.3)
44
+ dry-core (~> 0.5, >= 0.5)
45
+ dry-inflector (~> 0.1, >= 0.1.2)
46
+ dry-logic (~> 1.0, >= 1.0.2)
47
+ ffi (1.15.0)
48
+ ffi-compiler (1.0.1)
49
+ ffi (>= 1.0.0)
50
+ rake
51
+ hashdiff (1.0.1)
52
+ http (5.0.0)
53
+ addressable (~> 2.3)
54
+ http-cookie (~> 1.0)
55
+ http-form_data (~> 2.2)
56
+ llhttp-ffi (~> 0.0.1)
57
+ http-cookie (1.0.3)
58
+ domain_name (~> 0.5)
59
+ http-form_data (2.3.0)
60
+ ice_nine (0.11.2)
61
+ llhttp-ffi (0.0.1)
62
+ ffi-compiler (~> 1.0)
63
+ rake (~> 13.0)
64
+ method_source (1.0.0)
65
+ mime-types (3.3.1)
66
+ mime-types-data (~> 3.2015)
67
+ mime-types-data (3.2021.0225)
68
+ pry (0.14.1)
69
+ coderay (~> 1.1)
70
+ method_source (~> 1.0)
71
+ public_suffix (4.0.6)
72
+ rake (13.0.3)
73
+ rexml (3.2.5)
74
+ rspec (3.10.0)
75
+ rspec-core (~> 3.10.0)
76
+ rspec-expectations (~> 3.10.0)
77
+ rspec-mocks (~> 3.10.0)
78
+ rspec-core (3.10.1)
79
+ rspec-support (~> 3.10.0)
80
+ rspec-expectations (3.10.1)
81
+ diff-lcs (>= 1.2.0, < 2.0)
82
+ rspec-support (~> 3.10.0)
83
+ rspec-mocks (3.10.2)
84
+ diff-lcs (>= 1.2.0, < 2.0)
85
+ rspec-support (~> 3.10.0)
86
+ rspec-support (3.10.2)
87
+ timecop (0.9.4)
88
+ unf (0.1.4)
89
+ unf_ext
90
+ unf_ext (0.0.7.7)
91
+ webmock (3.13.0)
92
+ addressable (>= 2.3.6)
93
+ crack (>= 0.3.2)
94
+ hashdiff (>= 0.4.0, < 2.0.0)
95
+
96
+ PLATFORMS
97
+ x86_64-linux
98
+
99
+ DEPENDENCIES
100
+ rake (~> 13.0)
101
+ rspec (~> 3.0)
102
+ sumsub-ruby-sdk!
103
+
104
+ BUNDLED WITH
105
+ 2.2.17
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Rodrigo W. Ehresmann
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # SumSub Ruby SDK
2
+
3
+ This gem is an unnoficial SDK for the [SumSub API](https://developers.sumsub.com/api-reference/).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'sumsub-ruby-sdk', '~> 0.1.1', require: 'sumsub'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ ## Configuration and Usage
18
+
19
+ You can configure your credentials using `Sumsub::Configure` block. There are three keys you can inform: *token*, *secret_key* and *production*. The token and secret key you need to generate from your SumSub account, and *production* is a boolean value where you specify if you wanna use SumSub production or test environtment. To use the test environment, just set production as `false`.
20
+
21
+ ```ruby
22
+ Sumsub.configure do |config|
23
+ config.token = your_token
24
+ config.secret_key = your_secret_key
25
+ config.production = false # is true by default
26
+ end
27
+ ```
28
+
29
+ Use the `Sumsub::Request` to call the methods that access SumSub API endpoints. Check it out the [implemented methods](https://github.com/rwehresmann/sumsub-ruby-sdk/blob/master/lib/sumsub/request.rb) to know what is already available to be used.
30
+
31
+ For requests where you need to inform full objects in the request's body, `Sumsub::Struct` have some models you can use to easily fill the necessary data for the request. Check it out the models available [here](https://github.com/rwehresmann/sumsub-ruby-sdk/tree/master/lib/sumsub/struct).
32
+
33
+ **Note:** To use `Sumsub::Struct` or not is up to you. A simple [ruby hash](https://ruby-doc.org/core-3.0.1/Hash.html) is a viable option too. Under the hood we call `to_json` to serialize it, so just ensure that this method is available and does what we expect of him: transform your object in a json string.
34
+
35
+ Usage example:
36
+
37
+ An applicant is an user that will go into the KYC process.
38
+
39
+ - Create the applicant;
40
+ - Add an ID document to it;
41
+ - Retrieve the current applicant's status.
42
+
43
+ ```ruby
44
+ request = Sumsub::Request.new
45
+
46
+ # If you didn't set your configurations on Sumsub.configure block,
47
+ # you have the option to inform it in the Request constructor, like this:
48
+ #
49
+ # request = Sumsub::Request.new(
50
+ # token: your_token,
51
+ # secret_key: your_secret_key,
52
+ # production: false
53
+ # )
54
+
55
+ applicant = Sumsub::Struct::Applicant.new(
56
+ externalUserId: 'appt20',
57
+ email: 'grivia@mail.com'
58
+ )
59
+
60
+ response = request.create_applicant('basic-kyc-level', applicant)
61
+
62
+ applicant_id = response['id']
63
+
64
+ metadata = Sumsub::Struct::DocumentMetadata.new(
65
+ idDocType: 'ID_CARD',
66
+ country: 'BRA'
67
+ )
68
+
69
+ request.add_id_doc(
70
+ applicant_id,
71
+ metadata,
72
+ file_path: 'home/myself/Pictures/id_card.png'
73
+ )
74
+
75
+ request.get_applicant_status(applicant_id)
76
+ ```
77
+
78
+ The return from `Sumsub::Request` method will always be a ruby hash (in case of success) or an instance of `Sumsub::Struct::ErrorResponse` (in case error).
79
+
80
+ ## Development
81
+
82
+ Run `bin/setup` to install dependencies. For an interactive prompt that will allow you to experiment, run `bin/console`.
83
+
84
+ Run `bundle exec rspec`, if none error appears you're ready to go.
85
+
86
+ ## License
87
+
88
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "sumsub"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/sumsub.rb ADDED
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'http'
4
+ require 'types'
5
+ require 'mime/types'
6
+
7
+ module Sumsub
8
+ require 'sumsub/message_signer'
9
+ require 'sumsub/configuration'
10
+ require 'sumsub/parser'
11
+ require 'sumsub/request'
12
+ require 'sumsub/struct/base_struct'
13
+ require 'sumsub/struct/error_response'
14
+ require 'sumsub/struct/address'
15
+ require 'sumsub/struct/info'
16
+ require 'sumsub/struct/applicant'
17
+ require 'sumsub/struct/applicant_update'
18
+ require 'sumsub/struct/document_metadata'
19
+ require 'sumsub/version'
20
+
21
+ class << self
22
+ attr_accessor :configuration
23
+ end
24
+
25
+ def self.configuration
26
+ @configuration ||= Configuration.new
27
+ end
28
+
29
+ def self.reset
30
+ @configuration = Configuration.new
31
+ end
32
+
33
+ def self.configure
34
+ yield(configuration)
35
+ end
36
+
37
+ def self.error_response?(response)
38
+ response.class == Sumsub::Struct::ErrorResponse
39
+ end
40
+ end
@@ -0,0 +1,11 @@
1
+ module Sumsub
2
+ class Configuration
3
+ attr_accessor :token, :secret_key, :production
4
+
5
+ def initialize
6
+ @token = nil
7
+ @secret_key = nil
8
+ @production = true
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Sumsub
2
+ # https://developers.sumsub.com/api-reference/#signing-a-request
3
+ class MessageSigner
4
+ def self.sign(
5
+ time:,
6
+ resource:,
7
+ method:,
8
+ body: nil,
9
+ secret_key: Sumsub.configuration.secret_key
10
+ )
11
+ data = time.to_s + method + '/resources/' + resource + body.to_s
12
+ digest = OpenSSL::Digest.new('sha256')
13
+
14
+ OpenSSL::HMAC.hexdigest(digest, secret_key, data)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module Sumsub
2
+ class Parser
3
+ def self.parse(json_payload)
4
+ payload = JSON.parse(json_payload)
5
+
6
+ # return unless is an error response
7
+ return payload unless (payload['code'] && payload['description'])
8
+
9
+ Sumsub::Struct::ErrorResponse.new(
10
+ description: payload['description'],
11
+ code: payload['code'],
12
+ correlation_id: payload['correlationId'],
13
+ error_code: payload['errorCode'],
14
+ error_name: payload['errorName']
15
+ )
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,204 @@
1
+ module Sumsub
2
+ class Request
3
+ PRODUCTION_URL = "https://api.sumsub.com/resources"
4
+ TEST_URL = "https://test-api.sumsub.com/resources"
5
+
6
+ attr_reader :url, :secret_key, :token
7
+
8
+ def initialize(
9
+ token: Sumsub.configuration.token,
10
+ secret_key: Sumsub.configuration.secret_key,
11
+ production: Sumsub.configuration.production
12
+ )
13
+ @token = token
14
+ @secret_key = secret_key
15
+ @url = production ? PRODUCTION_URL : TEST_URL
16
+ end
17
+
18
+ # API docs: https://developers.sumsub.com/api-reference/#creating-an-applicant
19
+ # Sumsub::Struct::Applicant can be used as applicant.
20
+ def create_applicant(lvl_name, applicant)
21
+ resource = "applicants?levelName=#{lvl_name}"
22
+ headers = build_header(resource, body: applicant.to_json)
23
+ response = HTTP.headers(headers)
24
+ .post("#{@url}/#{resource}", json: applicant)
25
+
26
+ parse_response(response)
27
+ end
28
+
29
+ # API docs: https://developers.sumsub.com/api-reference/#adding-an-id-document
30
+ # To understand how the body was build manually bellow: https://roytuts.com/boundary-in-multipart-form-data/
31
+ # Sumsub::Struct::DocumentMetadata can be used as metadata.
32
+ def add_id_doc(applicant_id, metadata, file_path: nil)
33
+ resource = "applicants/#{applicant_id}/info/idDoc"
34
+
35
+ boundary = '----XYZ'
36
+
37
+ body = + '--' + boundary + "\r\n"
38
+ body += 'Content-Disposition: form-data; name="metadata"'
39
+ body += "\r\nContent-type: application/json; charset=utf-8\r\n\r\n"
40
+ body += metadata.to_json
41
+ body += "\r\n"
42
+ body += '--' + boundary
43
+
44
+ if file_path
45
+ content = File.read(file_path)
46
+ file_name = File.basename(file_path)
47
+ content_type = MIME::Types.type_for(file_name).first.content_type
48
+
49
+ body += "\r\n"
50
+ body += 'Content-Disposition: form-data; name="content"; filename="' + file_name + '"'
51
+ body += "\r\nContent-type: #{content_type}; charset=utf-8\r\n\r\n"
52
+ body += content + "\r\n"
53
+ body += '--' + boundary + '--'
54
+ else
55
+ body += '--'
56
+ end
57
+
58
+ headers = build_header(
59
+ resource,
60
+ body: body,
61
+ content_type: 'multipart/form-data; boundary=' + boundary
62
+ ).merge({ "X-Return-Doc-Warnings": true })
63
+ response = HTTP.headers(headers)
64
+ .post("#{@url}/#{resource}", body: body)
65
+
66
+ parse_response(response)
67
+ end
68
+
69
+ # API docs: https://developers.sumsub.com/api-reference/#getting-applicant-status-api
70
+ def get_applicant_detailed_status(applicant_id)
71
+ resource = "applicants/#{applicant_id}/requiredIdDocsStatus"
72
+ headers = build_header(resource, method: 'GET')
73
+ response = HTTP.headers(headers)
74
+ .get("#{@url}/#{resource}")
75
+
76
+ parse_response(response)
77
+ end
78
+
79
+ # API docs: https://developers.sumsub.com/api-reference/#getting-applicant-data
80
+ def get_applicant_data(applicant_id, as_external_user_id: false)
81
+ resource = as_external_user_id ?
82
+ "applicants/-;externalUserId=#{applicant_id}/one" :
83
+ "applicants/#{applicant_id}/one"
84
+ headers = build_header(resource, method: 'GET')
85
+ response = HTTP.headers(headers)
86
+ .get("#{@url}/#{resource}")
87
+
88
+ parse_response(response)
89
+ end
90
+
91
+ # API docs: https://developers.sumsub.com/api-reference/#getting-applicant-status-sdk
92
+ def get_applicant_status(applicant_id)
93
+ resource = "applicants/#{applicant_id}/status"
94
+ headers = build_header(resource, method: 'GET')
95
+ response = HTTP.headers(headers)
96
+ .get("#{@url}/#{resource}")
97
+
98
+ parse_response(response)
99
+ end
100
+
101
+ # API docs: https://developers.sumsub.com/api-reference/#requesting-an-applicant-check
102
+ def request_applicant_check(applicant_id, reason: nil)
103
+ resource = "applicants/#{applicant_id}/status/pending?reason=#{reason}"
104
+ headers = build_header(resource)
105
+ response = HTTP.headers(headers)
106
+ .post("#{@url}/#{resource}")
107
+
108
+ parse_response(response)
109
+ end
110
+
111
+ # API docs: https://developers.sumsub.com/api-reference/#getting-document-images
112
+ def get_document_image(inspection_id, image_id)
113
+ resource = "inspections/#{inspection_id}/resources/#{image_id}"
114
+ headers = build_header(resource, method: 'GET')
115
+ response = HTTP.headers(headers)
116
+ .get("#{@url}/#{resource}")
117
+
118
+ parse_response(response)
119
+ end
120
+
121
+ # API docs: https://developers.sumsub.com/api-reference/#resetting-an-applicant
122
+ def reset_applicant(applicant_id)
123
+ resource = "applicants/#{applicant_id}/reset"
124
+ headers = build_header(resource)
125
+ response = HTTP.headers(headers)
126
+ .post("#{@url}/#{resource}")
127
+
128
+ parse_response(response)
129
+ end
130
+
131
+ # API docs: https://developers.sumsub.com/api-reference/#changing-top-level-info
132
+ # Sumsub::Struct::ApplicantUpdate can be used as applicant_new_values.
133
+ def change_applicant_top_level_info(applicant_new_values)
134
+ resource = "applicants/"
135
+ headers = build_header(resource, method: 'PATCH', body: applicant_new_values.to_json)
136
+ response = HTTP.headers(headers)
137
+ .patch("#{@url}/#{resource}", json: applicant_new_values)
138
+
139
+ parse_response(response)
140
+ end
141
+
142
+ # API docs: https://developers.sumsub.com/api-reference/#access-tokens-for-sdks
143
+ def get_access_token(user_id, ttl_in_seconds: nil, external_action_id: nil)
144
+ resource = "accessTokens?userId=#{user_id}&ttlInSecs=#{ttl_in_seconds}&external_action_id=#{external_action_id}"
145
+ headers = build_header(resource, method: 'POST')
146
+ response = HTTP.headers(headers)
147
+ .post("#{@url}/#{resource}")
148
+
149
+ parse_response(response)
150
+ end
151
+
152
+ # API docs: https://developers.sumsub.com/api-reference/#verifying-webhook-sender
153
+ # Your payload need to be informed as a string.
154
+ def verify_webhook_sender(webhook_secret_key, payload)
155
+ resource = "inspectionCallbacks/testDigest?secretKey=#{webhook_secret_key}"
156
+ headers = build_header(
157
+ resource,
158
+ method: 'POST',
159
+ content_type: 'text/plain',
160
+ accept: 'text/plain',
161
+ body: payload
162
+ )
163
+
164
+ response = HTTP.headers(headers)
165
+ .post("#{@url}/#{resource}", body: payload)
166
+
167
+ parse_response(response)
168
+ end
169
+
170
+ private
171
+
172
+ # More infos about the required header and the signing strategy:
173
+ # https://developers.sumsub.com/api-reference/#app-tokens
174
+ def build_header(
175
+ resource,
176
+ body: nil,
177
+ method: 'POST',
178
+ content_type: 'application/json',
179
+ accept: 'application/json'
180
+ )
181
+ epoch_time = Time.now.to_i
182
+ access_signature = Sumsub::MessageSigner.sign(
183
+ time: epoch_time,
184
+ resource: resource,
185
+ body: body,
186
+ method: method,
187
+ )
188
+
189
+ {
190
+ "X-App-Token": @token.encode("UTF-8"),
191
+ "X-App-Access-Sig": access_signature.encode("UTF-8"),
192
+ "X-App-Access-Ts": epoch_time.to_s.encode("UTF-8"),
193
+ "Accept": accept,
194
+ "Content-Type": content_type
195
+ }
196
+ end
197
+
198
+ def parse_response(response)
199
+ Sumsub::Parser.parse(response.to_s)
200
+ end
201
+ end
202
+ end
203
+
204
+
@@ -0,0 +1,20 @@
1
+ module Sumsub
2
+ module Struct
3
+ # https://developers.sumsub.com/api-reference/#addresses-elements-fields
4
+ class Address < BaseStruct
5
+ include Types
6
+
7
+ attribute? :country, Types::String
8
+ attribute? :postCode, Types::String
9
+ attribute? :town, Types::String
10
+ attribute? :street, Types::String
11
+ attribute? :subStreet, Types::String
12
+ attribute? :state, Types::String
13
+ attribute? :buildingName, Types::String
14
+ attribute? :flatNumber, Types::String
15
+ attribute? :buildingNumber, Types::String
16
+ attribute? :startDate, Types::String
17
+ attribute? :endDate, Types::String
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ module Sumsub
2
+ module Struct
3
+ # https://developers.sumsub.com/api-reference/#request-body
4
+ class Applicant < BaseStruct
5
+ include Types
6
+
7
+ attribute :externalUserId, Types::Coercible::String
8
+ attribute? :sourceKey, Types::String
9
+ attribute? :email, Types::String
10
+ attribute? :lang, Types::String
11
+ attribute? :metadata, Types::Array.of(Types::Hash)
12
+ attribute? :info, Types::Instance(Sumsub::Struct::Info)
13
+ attribute? :fixedInfo, Types::Instance(Sumsub::Struct::Info)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Sumsub
2
+ module Struct
3
+ # https://developers.sumsub.com/api-reference/#request-body-2
4
+ class ApplicantUpdate < BaseStruct
5
+ include Types
6
+
7
+ attribute :id, Types::String
8
+ attribute? :externalUserId, Types::String
9
+ attribute? :sourceKey, Types::String
10
+ attribute? :email, Types::String
11
+ attribute? :lang, Types::String
12
+ attribute? :metadata, Types::Array.of(Types::Hash)
13
+ attribute? :type, Types::String
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module Sumsub
2
+ module Struct
3
+ class BaseStruct < Dry::Struct
4
+ include Types
5
+
6
+ def to_json
7
+ attributes.to_json
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ module Sumsub
2
+ module Struct
3
+ # https://developers.sumsub.com/api-reference/#request-metadata-body-part-fields
4
+ class DocumentMetadata < BaseStruct
5
+ include Types
6
+
7
+ attribute :idDocType, Types::IdDocTypes
8
+ attribute? :idDocSubType, Types::IdDocSubType
9
+ attribute :country, Types::String # https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3
10
+ attribute? :firstName, Types::String
11
+ attribute? :middleName, Types::String
12
+ attribute? :lastName, Types::String
13
+ attribute? :issuedDate, Types::String
14
+ attribute? :validUntil, Types::String
15
+ attribute? :number, Types::String
16
+ attribute? :dob, Types::String
17
+ attribute? :placeOfBirth, Types::String
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ module Sumsub
2
+ module Struct
3
+ # https://developers.sumsub.com/api-reference/#response-body
4
+ class ErrorResponse < BaseStruct
5
+ include Types
6
+
7
+ attribute :description, Types::String.optional
8
+ attribute :code, Types::Coercible::String.optional
9
+ attribute :correlation_id, Types::Coercible::String.optional
10
+ attribute? :error_code, Types::Coercible::String.optional
11
+ attribute? :error_name, Types::String.optional
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ module Sumsub
2
+ module Struct
3
+ # https://developers.sumsub.com/api-reference/#fixedinfo-and-info-attributes
4
+ class Info < BaseStruct
5
+ include Types
6
+
7
+ attribute? :firstName, Types::String
8
+ attribute? :lastName, Types::String
9
+ attribute? :middleName, Types::String
10
+ attribute? :firstNameEn, Types::String
11
+ attribute? :lastNameEn, Types::String
12
+ attribute? :middleNameEn, Types::String
13
+ attribute? :legalName, Types::String
14
+ attribute? :gender, Types::String
15
+ attribute? :dob, Types::String
16
+ attribute? :placeOfBirth, Types::String
17
+ attribute? :countryOfBirth, Types::String
18
+ attribute? :stateOfBirth, Types::String
19
+ attribute? :country, Types::String
20
+ attribute? :nationality, Types::String
21
+ attribute? :phone, Types::String
22
+ attribute? :addresses, Types::Array.of(Sumsub::Struct::Address)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sumsub
4
+ VERSION = "0.1.1"
5
+ end
data/lib/types.rb ADDED
@@ -0,0 +1,39 @@
1
+ require 'dry-struct'
2
+
3
+ module Types
4
+ include Dry.Types()
5
+
6
+ # https://developers.sumsub.com/api-reference/#supported-document-types
7
+ IdDocTypes = Types::Strict::Symbol
8
+ .constructor(&:to_sym)
9
+ .enum(
10
+ :ID_CARD,
11
+ :PASSPORT,
12
+ :DRIVERS, # Driving license
13
+ :BANK_CARD,
14
+ :UTILITY_BILL,
15
+ :BANK_STATEMENT,
16
+ :SELFIE,
17
+ :VIDEO_SELFIE,
18
+ :PROFILE_IMAGE,
19
+ :ID_DOC_PHOTO,
20
+ :AGREEMENT,
21
+ :CONTRACT,
22
+ :RESIDENCE_PERMIT,
23
+ :EMPLOYMENT_CERTIFICATE,
24
+ :DRIVERS_TRANSLATION,
25
+ :INVESTOR_DOC,
26
+ :VEHICLE_REGISTRATION_CERTIFICATE,
27
+ :INCOME_SOURCE, # Proof of income
28
+ :PAYMENT_METHOD,
29
+ :OTHER,
30
+ nil,
31
+ )
32
+
33
+ IdDocSubType = Types::Strict::Symbol
34
+ .constructor(&:to_sym)
35
+ .enum(
36
+ :FRONT_SIDE,
37
+ :BACK_SIDE,
38
+ )
39
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/sumsub/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "sumsub-ruby-sdk"
7
+ spec.version = Sumsub::VERSION
8
+ spec.authors = ["Rodrigo W. Ehresmann"]
9
+ spec.email = ["igoehresmann@gmail.com"]
10
+
11
+ spec.summary = "SumSub Ruby SDK"
12
+ spec.description = "SDK written in Ruby to handle SumSub API."
13
+ spec.homepage = "https://github.com/rwehresmann/sumsub-ruby-sdk"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
16
+
17
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
18
+
19
+ spec.metadata["homepage_uri"] = spec.homepage
20
+ spec.metadata["source_code_uri"] = "https://github.com/rwehresmann/sumsub-ruby-sdk"
21
+ spec.metadata["changelog_uri"] = "https://github.com/rwehresmann/sumsub-ruby-sdk"
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
27
+ end
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ # Uncomment to register a new dependency of your gem
33
+ # spec.add_dependency "example-gem", "~> 1.0"
34
+
35
+ # For more information and examples about making a new gem, checkout our
36
+ # guide at: https://bundler.io/guides/creating_gem.html
37
+
38
+ spec.add_dependency "http", "~> 5.0.0"
39
+ spec.add_dependency "dry-struct", "~> 1.4.0"
40
+ spec.add_dependency "rspec", "~> 3.10.0"
41
+ spec.add_dependency "pry", "~> 0.14.1"
42
+ spec.add_dependency "webmock", "~> 3.13.0"
43
+ spec.add_dependency "timecop", "~> 0.9.4"
44
+ spec.add_dependency "mime-types", "~> 3.3.1"
45
+ end
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sumsub-ruby-sdk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Rodrigo W. Ehresmann
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-05-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: http
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: dry-struct
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.4.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.4.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.10.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.10.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.14.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.14.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 3.13.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 3.13.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: timecop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.9.4
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.9.4
97
+ - !ruby/object:Gem::Dependency
98
+ name: mime-types
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 3.3.1
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 3.3.1
111
+ description: SDK written in Ruby to handle SumSub API.
112
+ email:
113
+ - igoehresmann@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".circleci/config.yml"
119
+ - ".editorconfig"
120
+ - ".gitignore"
121
+ - ".rspec"
122
+ - Gemfile
123
+ - Gemfile.lock
124
+ - LICENSE.txt
125
+ - README.md
126
+ - Rakefile
127
+ - bin/console
128
+ - bin/setup
129
+ - lib/sumsub.rb
130
+ - lib/sumsub/configuration.rb
131
+ - lib/sumsub/message_signer.rb
132
+ - lib/sumsub/parser.rb
133
+ - lib/sumsub/request.rb
134
+ - lib/sumsub/struct/address.rb
135
+ - lib/sumsub/struct/applicant.rb
136
+ - lib/sumsub/struct/applicant_update.rb
137
+ - lib/sumsub/struct/base_struct.rb
138
+ - lib/sumsub/struct/document_metadata.rb
139
+ - lib/sumsub/struct/error_response.rb
140
+ - lib/sumsub/struct/info.rb
141
+ - lib/sumsub/version.rb
142
+ - lib/types.rb
143
+ - sumsub-ruby-sdk.gemspec
144
+ homepage: https://github.com/rwehresmann/sumsub-ruby-sdk
145
+ licenses:
146
+ - MIT
147
+ metadata:
148
+ allowed_push_host: https://rubygems.org
149
+ homepage_uri: https://github.com/rwehresmann/sumsub-ruby-sdk
150
+ source_code_uri: https://github.com/rwehresmann/sumsub-ruby-sdk
151
+ changelog_uri: https://github.com/rwehresmann/sumsub-ruby-sdk
152
+ post_install_message:
153
+ rdoc_options: []
154
+ require_paths:
155
+ - lib
156
+ required_ruby_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: 2.4.0
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ requirements: []
167
+ rubygems_version: 3.2.15
168
+ signing_key:
169
+ specification_version: 4
170
+ summary: SumSub Ruby SDK
171
+ test_files: []