privacygate 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_REQUEST_TEMPLATE/issue_request_template.md +36 -0
  3. data/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +51 -0
  4. data/.gitignore +51 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +21 -0
  7. data/README.md +278 -0
  8. data/Rakefile +6 -0
  9. data/examples/charge.rb +38 -0
  10. data/examples/checkout.rb +61 -0
  11. data/examples/event.rb +26 -0
  12. data/examples/webhook.rb +35 -0
  13. data/lib/privacygate/api_errors.rb +157 -0
  14. data/lib/privacygate/api_resources/base/api_object.rb +206 -0
  15. data/lib/privacygate/api_resources/base/api_resource.rb +25 -0
  16. data/lib/privacygate/api_resources/base/create.rb +15 -0
  17. data/lib/privacygate/api_resources/base/delete.rb +16 -0
  18. data/lib/privacygate/api_resources/base/list.rb +25 -0
  19. data/lib/privacygate/api_resources/base/save.rb +18 -0
  20. data/lib/privacygate/api_resources/base/update.rb +15 -0
  21. data/lib/privacygate/api_resources/charge.rb +14 -0
  22. data/lib/privacygate/api_resources/checkout.rb +19 -0
  23. data/lib/privacygate/api_resources/event.rb +13 -0
  24. data/lib/privacygate/api_response.rb +48 -0
  25. data/lib/privacygate/client.rb +120 -0
  26. data/lib/privacygate/util.rb +59 -0
  27. data/lib/privacygate/version.rb +3 -0
  28. data/lib/privacygate/webhooks.rb +52 -0
  29. data/lib/privacygate.rb +42 -0
  30. data/privacygate.gemspec +28 -0
  31. data/spec/api_resources/base/api_object_spec.rb +156 -0
  32. data/spec/api_resources/base/api_resource_spec.rb +32 -0
  33. data/spec/api_resources/charge_spec.rb +19 -0
  34. data/spec/api_resources/checkout_spec.rb +31 -0
  35. data/spec/api_resources/event_spec.rb +12 -0
  36. data/spec/endpont_spec.rb +103 -0
  37. data/spec/error_spec.rb +58 -0
  38. data/spec/response_spec.rb +43 -0
  39. data/spec/spec_helper.rb +15 -0
  40. data/spec/webhook_spec.rb +36 -0
  41. metadata +161 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5f07cc6ae11d0fdfdd6972cda01666bbe4713ddbcd164e2fd79fe38fdc31b7cb
4
+ data.tar.gz: 10e8c687b0040ae96276663c29b22f425c51d4a8e13de0778cade52dfc935e40
5
+ SHA512:
6
+ metadata.gz: c410c66a8912aa4aa218102390988fc2b8f47d0d02c26061043d13801480bf2f300ed989929ece57f3142b06fef5d7d124033da6960cf1bbcbb4e5df0fc87878
7
+ data.tar.gz: 90a1737cede4bfeaaa133573e94238ff063bcbb81a38667cb96cf1d2acaf1a23a036acc056a02b1e50ce0658cf34e1064699eed04925711b142cad4c1d7de1af
@@ -0,0 +1,36 @@
1
+ <!---
2
+ ISSUE TITLE: Please make your title easy to understand short summary, usually 4-10 words. Examples:
3
+
4
+ > Cannot install dependencies due to version error.
5
+ > How do I set a callback redirect url?
6
+ > Curl with API Key not working.
7
+ --->
8
+
9
+ **Severity:** <severity>
10
+
11
+ <!---
12
+ Replace <severity> with a priority ranking P0-P3:
13
+
14
+ > P0: severe/ blocking - completely broken or unusable.
15
+ > P1: high priority - breaking but non-essential.
16
+ > P2: medium priority - non-breaking issue.
17
+ > P3: low priority - questions or nice-to-haves.
18
+ --->
19
+
20
+ **Description:**
21
+ <description>
22
+
23
+ <!---
24
+ Replace <description> with a detailed summary of the issue or question, including any relevant context to avoid follow-up questions.
25
+ --->
26
+
27
+ **Steps to Reproduce:**
28
+ <steps>
29
+
30
+ <!---
31
+ Replace <steps> with instructions so others can reproduce.
32
+ --->
33
+
34
+ **Configuration:**
35
+
36
+ <!--- List your relevant environment/ server/ dependency versions. Any 3rd party plugin use (ie WooCommerce, etc) and corresponding versions. --->
@@ -0,0 +1,51 @@
1
+ <!---
2
+ PR TITLE: Please name your pull request according to this format: [type] short summary. Examples:
3
+
4
+ > [bugfix] added callback function to charge example.
5
+ > [feature] enabled refunds event signature.
6
+ > [chore] updated docs with webhooks instructions.
7
+ --->
8
+
9
+ **Issue:** <link>
10
+
11
+ <!---
12
+ IMPORTANT: Please do not create a Pull Request without creating an issue first. Replace <link> with the url link to the issue.
13
+ --->
14
+
15
+ **Type:** <type>
16
+
17
+ <!---
18
+ Same as in title, replace <type> with one of the following options: bugfix | feature | chore
19
+
20
+ > bugfix: a change which fixes an issue.
21
+ > feature: a change which adds functionality.
22
+ > chore: doc updates, dependencies, refactor, etc.
23
+ --->
24
+
25
+ **Description:** <description>
26
+
27
+ <!---
28
+ Replace <description> with a detailed summary of the change, including any relevant context to avoid follow-up questions.
29
+ --->
30
+
31
+ **Testing:** <testing>
32
+
33
+ <!---
34
+ Replace <testing> with a description of how you've tested/ verified your changes.
35
+ --->
36
+
37
+ **Configuration:**
38
+
39
+ <!---
40
+ List your relevant environment/ server/ dependency versions. Any 3rd party plugin use (ie WooCommerce, etc) and corresponding versions.
41
+ --->
42
+
43
+ <!---
44
+ CHECKLIST: Please ensure you have done the following.
45
+ > 1. I have performed a self-review of my own code.
46
+ > 2. I have commented my code, particularly in hard-to-understand areas.
47
+ > 3. I have made relevant changes to the documentation.
48
+ > 4. My changes generate no new warnings.
49
+ > 5. I have added any tests that prove my fix is effective or that my feature works.
50
+ > 6. New and existing unit tests pass locally with my changes.
51
+ --->
data/.gitignore ADDED
@@ -0,0 +1,51 @@
1
+ *.gem
2
+ *.rbc
3
+ .idea/
4
+ /.config
5
+ /coverage/
6
+ /InstalledFiles
7
+ /pkg/
8
+ /spec/reports/
9
+ /spec/examples.txt
10
+ /test/tmp/
11
+ /test/version_tmp/
12
+ /tmp/
13
+
14
+ # Used by dotenv library to load environment variables.
15
+ # .env
16
+
17
+ ## Specific to RubyMotion:
18
+ .dat*
19
+ .repl_history
20
+ build/
21
+ *.bridgesupport
22
+ build-iPhoneOS/
23
+ build-iPhoneSimulator/
24
+
25
+ ## Specific to RubyMotion (use of CocoaPods):
26
+ #
27
+ # We recommend against adding the Pods directory to your .gitignore. However
28
+ # you should judge for yourself, the pros and cons are mentioned at:
29
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
30
+ #
31
+ # vendor/Pods/
32
+
33
+ ## Documentation cache and generated files:
34
+ /.yardoc/
35
+ /_yardoc/
36
+ /doc/
37
+ /rdoc/
38
+
39
+ ## Environment normalization:
40
+ /.bundle/
41
+ /vendor/bundle
42
+ /lib/bundler/man/
43
+
44
+ # for a library or gem, you might want to ignore these files since the code is
45
+ # intended to run in multiple environments; otherwise, check them in:
46
+ # Gemfile.lock
47
+ # .ruby-version
48
+ # .ruby-gemset
49
+
50
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
51
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,278 @@
1
+ # privacygate-ruby
2
+ PrivacyGate Ruby Gem
3
+
4
+ # Table of contents
5
+
6
+ <!--ts-->
7
+ * [Ruby Versions](#ruby-version)
8
+ * [Third Party Libraries and Dependencies](#third-party-libraries-and-dependencies)
9
+ * [Documentation](#documentation)
10
+ * [Installation](#installation)
11
+ * [Usage](#usage)
12
+ * [Checkouts](#checkouts)
13
+ * [Charges](#charges)
14
+ * [Events](#events)
15
+ * [Validating webhook signatures](#validating-webhook-signatures)
16
+ * [Testing and Contributing](#testing-and-contributing)
17
+ <!--te-->
18
+
19
+ ## Ruby Version
20
+ Ruby 2.3, 2.4, 2.5, 2.6RC are supported and tested.
21
+
22
+ ## Third Party Libraries and Dependencies
23
+
24
+ The following libraries will be installed when you install the client library:
25
+ * [faraday](https://github.com/lostisland/faraday)
26
+
27
+
28
+ ## Installation
29
+
30
+ Add this line to your application's Gemfile:
31
+
32
+ ```ruby
33
+ gem 'privacygate'
34
+ ```
35
+ Then execute:
36
+
37
+ ```sh
38
+ bundle install
39
+ ```
40
+
41
+ Or install it yourself as:
42
+
43
+ ```sh
44
+ gem install privacygate
45
+ ```
46
+
47
+ ## Documentation
48
+
49
+ For more details visit [PrivacyGate API docs](https://privacygate.io/docs/).
50
+
51
+ To start using library, you'll need to [create a PrivacyGate account](https://dash.privacygate.io).
52
+ Once you've created your PrivacyGate account, create an ``API_KEY`` in Settings.
53
+
54
+ Next create a ``Client`` object for interacting with the API:
55
+ ```ruby
56
+ require 'privacygate'
57
+
58
+ API_KEY = "API KEY"
59
+ client = PrivacyGate::Client.new(api_key: API_KEY)
60
+
61
+ ```
62
+
63
+ ``Client`` contains links to every Ruby Class representations of the API resources
64
+ ``Checkout, Charge, Event``
65
+
66
+ You can call ``list, auto_paging, create, retrieve, modify`` methods from API resource classes
67
+
68
+ ```ruby
69
+ client.charge.create
70
+ client.checkout.auto_paging
71
+ client.event.list
72
+ client.charge.retrieve
73
+ client.checkout.modify
74
+ ```
75
+ as well as ``save, delete, refresh`` methods from API resource class instances.
76
+ ```python
77
+ checkout = client.checkout.retrieve <id>
78
+ checkout.refresh
79
+ checkout.save
80
+ checkout.delete
81
+ ```
82
+
83
+ Each API method returns an ``APIObject`` representing the JSON response from the API, all of the models support hash and JSON representation.\
84
+ Also when the response data is parsed into Ruby objects, the appropriate ``APIObject`` subclasses will be used automatically.
85
+ All subclasses of ``APIResource`` class support ``refresh`` method. This will update their attributes and all nested data by making a fresh ``GET`` request to the relevant API endpoint.
86
+
87
+ The client supports handling of common API errors and warnings.
88
+ All errors occuring during the interaction with the API will be raised as exceptions.
89
+
90
+
91
+ | Error | Status Code |
92
+ |--------------------------|-------------|
93
+ | APIError | * |
94
+ | InvalidRequestError | 400 |
95
+ | ParamRequiredError | 400 |
96
+ | ValidationError | 400 |
97
+ | AuthenticationError | 401 |
98
+ | ResourceNotFoundError | 404 |
99
+ | RateLimitExceededError | 429 |
100
+ | InternalServerError | 500 |
101
+ | ServiceUnavailableError | 503 |
102
+
103
+ ## Installation
104
+
105
+ Add this line to your application's Gemfile:
106
+
107
+ ```ruby
108
+ gem 'privacygate'
109
+ ```
110
+ Then execute:
111
+
112
+ ```sh
113
+ bundle install
114
+ ```
115
+
116
+ Or install it yourself as:
117
+
118
+ ```sh
119
+ gem install privacygate
120
+ ```
121
+
122
+ ## Usage
123
+ ```ruby
124
+ require 'privacygate'
125
+
126
+ client = PrivacyGate::Client.new(api_key: 'your_api_key')
127
+ ```
128
+ ## Checkouts
129
+ [Checkouts API docs](https://privacygate.io/docs/#checkouts)
130
+ ### Retrieve
131
+ ```ruby
132
+ checkout = client.checkout.retrieve <checkout_id>
133
+ ```
134
+ ### Create
135
+ ```ruby
136
+ checkout_info = {
137
+ "name": "The Sovereign Individual",
138
+ "description": "Mastering the Transition to the Information Age",
139
+ "pricing_type": "fixed_price",
140
+ "local_price": {
141
+ "amount": "1.00",
142
+ "currency": "USD"
143
+ },
144
+ "requested_info": ["name", "email"]
145
+ }
146
+ checkout = client.checkout.create(checkout_info)
147
+
148
+ # or
149
+
150
+ checkout = client.checkout.create(:name=>'The Sovereign Individual',
151
+ :description=>'Mastering the Transition to the Information Age',
152
+ :pricing_type=>'fixed_price',
153
+ :local_price=>{
154
+ "amount": "100.00",
155
+ "currency": "USD"
156
+ },
157
+ :requested_info=>["name", "email"])
158
+ ```
159
+ ### Update
160
+ ```ruby
161
+ checkout = client.checkout.retrieve <checkout_id>
162
+ checkout.name = 'new name'
163
+ checkout.save
164
+
165
+ # or
166
+
167
+ client.checkout.modify(<checkout_id>, "local_price": {
168
+ "amount": "10000.00",
169
+ "currency": "USD"
170
+ })
171
+ ```
172
+ ### Delete
173
+ ```ruby
174
+ checkout.delete
175
+ ```
176
+ ### List
177
+ ```ruby
178
+ checkouts = client.checkout.list
179
+ ```
180
+ ### Paging list iterations
181
+ ```ruby
182
+ client.checkout.auto_paging do |ch|
183
+ puts ch.id
184
+ end
185
+ ```
186
+ ## Charges
187
+ [Charges API docs](https://privacygate.io/docs/#charges)
188
+ ### Retrieve
189
+ ```ruby
190
+ charge = client.charge.retrieve <charge_id>
191
+ ```
192
+ ### Create
193
+ ```ruby
194
+ charge_info = {
195
+ "name": "The Sovereign Individual",
196
+ "description": "Mastering the Transition to the Information Age",
197
+ "pricing_type": "fixed_price",
198
+ "local_price": {
199
+ "amount": "1.00",
200
+ "currency": "USD"
201
+ },
202
+ "requested_info": ["name", "email"]
203
+ }
204
+ charge = client.charge.create(charge_info)
205
+
206
+ # or
207
+
208
+ charge = client.charge.create(:name=>'The Sovereign Individual',
209
+ :description=>'Mastering the Transition to the Information Age',
210
+ :pricing_type=>'fixed_price',
211
+ :local_price=>{
212
+ "amount": "100.00",
213
+ "currency": "USD"
214
+ })
215
+ ```
216
+ ### List
217
+ ```ruby
218
+ charges_list = client.charge.list
219
+ ```
220
+ ### Paging list iterations
221
+ ```ruby
222
+ client.charge.auto_paging do |charge|
223
+ puts charge.id
224
+ end
225
+ ```
226
+ ## Events
227
+ [Events API Docs](https://privacygate.io/docs/#events)
228
+ ### Retrieve
229
+ ```ruby
230
+ event = client.event.retrieve <event_id>
231
+ ```
232
+ ### List
233
+ ```ruby
234
+ events = client.event.list
235
+ ```
236
+ ### Paging list iterations
237
+ ```ruby
238
+ client.event.auto_paging do |event|
239
+ puts event.id
240
+ end
241
+ ```
242
+
243
+ ## Validating webhook signatures
244
+ You should verify the webhook signatures using our library.
245
+ To perform the verification you'll need to provide the event data, a webhook signature from the request header, and the endpoint’s secret.
246
+ In case of an invalid request signature or request payload, you will receive an appropriate error message.
247
+ ```ruby
248
+ WEBHOOK_SECRET = 'your_webhook_secret'
249
+
250
+ # Using Sinatra
251
+ post '/webhooks' do
252
+ request_payload = request.body.read
253
+ sig_header = request.env['HTTP_X_CC_WEBHOOK_SIGNATURE']
254
+
255
+ begin
256
+ event = PrivacyGate::Webhook.construct_event(request_payload, sig_header, WEBHOOK_SECRET)
257
+ # event handle
258
+ puts "Received event id=#{event.id}, type=#{event.type}"
259
+ status 200
260
+ # errors handle
261
+ rescue JSON::ParserError => e
262
+ puts "json parse error"
263
+ status 400
264
+ return
265
+ rescue PrivacyGate::Errors::SignatureVerificationError => e
266
+ puts "signature verification error"
267
+ status 400
268
+ return
269
+ rescue PrivacyGate::Errors::WebhookInvalidPayload => e
270
+ puts "missing request or headers data"
271
+ status 400
272
+ return
273
+ end
274
+ end
275
+ ```
276
+
277
+ ### Testing and Contributing
278
+ Any and all contributions are welcome! The process is simple: fork this repo, make your changes, add tests, run the test suite, and submit a pull request. Tests are run via rspec. To run the tests, clone the repository and then:
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task default: :spec
@@ -0,0 +1,38 @@
1
+ require 'privacygate'
2
+
3
+ client = PrivacyGate::Client.new(api_key: 'your_api_key')
4
+
5
+ # create charge
6
+ data = {
7
+ "name": "The Sovereign Individual",
8
+ "description": "Mastering the Transition to the Information Age",
9
+ "local_price": {
10
+ "amount": "100.00",
11
+ "currency": "USD"
12
+ },
13
+ "pricing_type": "fixed_price"
14
+
15
+ }
16
+ charge = client.charge.create(data)
17
+
18
+ # or retrieve it if you know charge id
19
+ charge = client.charge.retrieve charge.id
20
+
21
+ # get charges list
22
+ charges_list = client.charge.list
23
+
24
+ # in case you need provide additional params
25
+ charges_list = client.charge.list(limit: 10)
26
+
27
+ # or get results from another page
28
+ charges_list = client.charge.list(starting_after: charge.id, limit: 3)
29
+
30
+ # charges list could be iterated like
31
+ charges_list.data.each do |charge|
32
+ puts charge.id
33
+ end
34
+
35
+ # iterate over all charges with per-page limitation
36
+ client.charge.auto_paging limit: 20 do |charge|
37
+ puts charge.id
38
+ end
@@ -0,0 +1,61 @@
1
+ require 'privacygate'
2
+
3
+ client = PrivacyGate::Client.new(api_key: 'your_api_key')
4
+
5
+ # create checkout
6
+ data = {
7
+ "name": "The Sovereign Individual",
8
+ "description": "Mastering the Transition to the Information Age",
9
+ "pricing_type": "fixed_price",
10
+ "local_price": {
11
+ "amount": "1.00",
12
+ "currency": "USD"
13
+ },
14
+ "requested_info": ["name", "email"]
15
+ }
16
+ checkout = client.checkout.create(data)
17
+
18
+ # or retrieve it if you know checkout id
19
+ checkout = client.checkout.retrieve checkout.id
20
+
21
+ # update checkout with modify method
22
+ upd_checkout = client.checkout.modify(checkout.id, "local_price": {
23
+ "amount": "10000.00",
24
+ "currency": "USD"
25
+ })
26
+
27
+ # or with save method if you already have checkout object
28
+ upd_checkout.name
29
+ upd_checkout.description = "foo"
30
+ upd_checkout.to_hash
31
+ upd_checkout.name = "bar"
32
+ amount = "1000.00"
33
+ upd_checkout.local_price.amount = amount
34
+ upd_checkout.save
35
+
36
+ # get checkouts list
37
+ checkouts_list = client.checkout.list
38
+
39
+ # in case you need provide additional params
40
+ checkouts_list = client.checkout.list(limit: 10)
41
+
42
+ # or get results from another page
43
+ checkouts_list = client.checkout.list(starting_after: checkout.id, limit: 3)
44
+
45
+ # checkout list could be iterated like
46
+ checkouts_list.data.each do |ch|
47
+ # work with each checkout
48
+ puts ch.id
49
+ end
50
+
51
+ # iterate over all checkouts and modify them with per-page limitation
52
+ client.checkout.auto_paging limit: 20 do |ch|
53
+ puts ch.id
54
+ ch.name = 'name updated'
55
+ ch.save
56
+ # also could be deleted by
57
+ # ch.delete
58
+ end
59
+
60
+ # delete checkout
61
+ upd_checkout.delete
data/examples/event.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'privacygate'
2
+
3
+ client = PrivacyGate::Client.new(api_key: 'your_api_key')
4
+
5
+ # get events list
6
+ events_list = client.event.list
7
+
8
+ # in case you need provide additional params
9
+ events_list = client.event.list(limit: 10)
10
+
11
+ # or get results from another page
12
+ event = events_list.data[0]
13
+ events_list = client.event.list(starting_after: event.id, limit: 3)
14
+
15
+ # event list could be iterated like
16
+ events_list.data.each do |event|
17
+ puts event.id
18
+ end
19
+
20
+ # retrieve single event
21
+ event = client.event.retrieve event.id
22
+
23
+ # iterate over all events with per-page limitation
24
+ client.event.auto_paging limit: 20 do |event|
25
+ puts event.id
26
+ end
@@ -0,0 +1,35 @@
1
+ # Sinatra server example to test webhooks
2
+ # You may need tunnels to localhost webhook development tool and debugging tool.
3
+ # f.e. you could try ngrok
4
+
5
+ require 'sinatra'
6
+ require 'privacygate'
7
+
8
+ set :port, 5000
9
+ WEBHOOK_SECRET = 'your_webhook_secret'
10
+
11
+ # Using Sinatra
12
+ post '/webhooks' do
13
+ payload = request.body.read
14
+ sig_header = request.env['HTTP_X_CC_WEBHOOK_SIGNATURE']
15
+
16
+ begin
17
+ event = PrivacyGate::Webhook.construct_event(payload, sig_header, WEBHOOK_SECRET)
18
+ # event handle
19
+ puts "Received event id=#{event.id}, type=#{event.type}"
20
+ status 200
21
+ # errors handle
22
+ rescue JSON::ParserError => e
23
+ puts "json parse error"
24
+ status 400
25
+ return
26
+ rescue PrivacyGate::Errors::SignatureVerificationError => e
27
+ puts "signature verification error"
28
+ status 400
29
+ return
30
+ rescue PrivacyGate::Errors::WebhookInvalidPayload => e
31
+ puts "missing request or headers data"
32
+ status 400
33
+ return
34
+ end
35
+ end