dlocal_go 0.1.1 → 1.0
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 +4 -4
- data/.rubocop.yml +4 -1
- data/Gemfile.lock +32 -10
- data/README.md +66 -32
- data/lib/dlocal_go/client.rb +36 -56
- data/lib/dlocal_go/constants.rb +43 -0
- data/lib/dlocal_go/endpoint_generator.rb +93 -0
- data/lib/dlocal_go/errors.rb +9 -1
- data/lib/dlocal_go/responses/array.rb +20 -0
- data/lib/dlocal_go/responses/base.rb +11 -0
- data/lib/dlocal_go/responses/payment.rb +20 -11
- data/lib/dlocal_go/responses/recurring_payment.rb +17 -0
- data/lib/dlocal_go/responses/refund.rb +8 -10
- data/lib/dlocal_go/responses/response_parser.rb +84 -0
- data/lib/dlocal_go/responses/subscription.rb +33 -0
- data/lib/dlocal_go/responses/subscription_execution.rb +27 -0
- data/lib/dlocal_go/responses/subscription_plan.rb +31 -0
- data/lib/dlocal_go/utilities.rb +20 -0
- data/lib/dlocal_go/version.rb +1 -1
- data/lib/dlocal_go.rb +3 -0
- metadata +27 -7
- data/dlocal_go.gemspec +0 -36
- data/sig/dlocal_go/client.rbs +0 -26
- data/sig/dlocal_go/responses/payment.rbs +0 -7
- data/sig/dlocal_go/responses/refund.rbs +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 23d32c3c1f09afe545b9d6337792969bf19a3b07068a60e77e3d1f41a8837061
|
4
|
+
data.tar.gz: 04acfaa27fc1ac98fa0222d7c9d3d427d3ab075378cd01983cbbb7242993b5b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0be8022f5d868dbec5a81808e9e7a2c1f9d38b247e31cb94ab485359a1ec7564f24b3e96681aaa93237fe053f3bcce8d0b994befcb51d718829765c97ff734b3
|
7
|
+
data.tar.gz: 33c6ec1f139e3f07b4ae407c5475fb946d01c73c43632efd4f0d824d9d7eefafc964b4318d096179b8728c141daa906f0e6715ed369a702cefdb53527b5c9e74
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,43 +1,64 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dlocal_go (
|
4
|
+
dlocal_go (1.0)
|
5
|
+
activesupport
|
5
6
|
http
|
6
7
|
|
7
8
|
GEM
|
8
9
|
remote: https://rubygems.org/
|
9
10
|
specs:
|
11
|
+
activesupport (7.1.3)
|
12
|
+
base64
|
13
|
+
bigdecimal
|
14
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
15
|
+
connection_pool (>= 2.2.5)
|
16
|
+
drb
|
17
|
+
i18n (>= 1.6, < 2)
|
18
|
+
minitest (>= 5.1)
|
19
|
+
mutex_m
|
20
|
+
tzinfo (~> 2.0)
|
10
21
|
addressable (2.8.1)
|
11
22
|
public_suffix (>= 2.0.2, < 6.0)
|
12
23
|
ast (2.4.2)
|
24
|
+
base64 (0.2.0)
|
25
|
+
bigdecimal (3.1.6)
|
26
|
+
concurrent-ruby (1.2.3)
|
27
|
+
connection_pool (2.4.1)
|
13
28
|
crack (0.4.5)
|
14
29
|
rexml
|
15
30
|
debug (1.6.2)
|
16
31
|
irb (>= 1.3.6)
|
17
32
|
reline (>= 0.3.1)
|
18
33
|
diff-lcs (1.5.0)
|
19
|
-
domain_name (0.
|
20
|
-
|
21
|
-
|
34
|
+
domain_name (0.6.20240107)
|
35
|
+
drb (2.2.0)
|
36
|
+
ruby2_keywords
|
37
|
+
ffi (1.16.3)
|
22
38
|
ffi-compiler (1.0.1)
|
23
39
|
ffi (>= 1.0.0)
|
24
40
|
rake
|
25
41
|
hashdiff (1.0.1)
|
26
|
-
http (5.
|
42
|
+
http (5.2.0)
|
27
43
|
addressable (~> 2.8)
|
44
|
+
base64 (~> 0.1)
|
28
45
|
http-cookie (~> 1.0)
|
29
46
|
http-form_data (~> 2.2)
|
30
|
-
llhttp-ffi (~> 0.
|
47
|
+
llhttp-ffi (~> 0.5.0)
|
31
48
|
http-cookie (1.0.5)
|
32
49
|
domain_name (~> 0.5)
|
33
50
|
http-form_data (2.3.0)
|
51
|
+
i18n (1.14.1)
|
52
|
+
concurrent-ruby (~> 1.0)
|
34
53
|
io-console (0.5.11)
|
35
54
|
irb (1.4.1)
|
36
55
|
reline (>= 0.3.0)
|
37
56
|
json (2.6.2)
|
38
|
-
llhttp-ffi (0.
|
57
|
+
llhttp-ffi (0.5.0)
|
39
58
|
ffi-compiler (~> 1.0)
|
40
59
|
rake (~> 13.0)
|
60
|
+
minitest (5.22.2)
|
61
|
+
mutex_m (0.2.0)
|
41
62
|
parallel (1.22.1)
|
42
63
|
parser (3.1.2.1)
|
43
64
|
ast (~> 2.4.1)
|
@@ -74,9 +95,9 @@ GEM
|
|
74
95
|
rubocop-ast (1.21.0)
|
75
96
|
parser (>= 3.1.1.0)
|
76
97
|
ruby-progressbar (1.11.0)
|
77
|
-
|
78
|
-
|
79
|
-
|
98
|
+
ruby2_keywords (0.0.5)
|
99
|
+
tzinfo (2.0.6)
|
100
|
+
concurrent-ruby (~> 1.0)
|
80
101
|
unicode-display_width (2.2.0)
|
81
102
|
webmock (3.18.1)
|
82
103
|
addressable (>= 2.8.0)
|
@@ -85,6 +106,7 @@ GEM
|
|
85
106
|
|
86
107
|
PLATFORMS
|
87
108
|
arm64-darwin-21
|
109
|
+
arm64-darwin-23
|
88
110
|
x86_64-linux
|
89
111
|
|
90
112
|
DEPENDENCIES
|
data/README.md
CHANGED
@@ -13,14 +13,9 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
13
13
|
|
14
14
|
$ gem install dlocal_go
|
15
15
|
|
16
|
-
## Preview
|
17
|
-
|
18
|
-
https://user-images.githubusercontent.com/57004457/222937723-c95ca31c-2871-4f0f-a61e-fd4c9738e75f.mp4
|
19
|
-
|
20
|
-
|
21
16
|
## Usage
|
22
17
|
|
23
|
-
1. Configure DlocalGo
|
18
|
+
1. Configure DlocalGo inside an initializer
|
24
19
|
|
25
20
|
```ruby
|
26
21
|
DlocalGo.setup do |config|
|
@@ -31,46 +26,85 @@ https://user-images.githubusercontent.com/57004457/222937723-c95ca31c-2871-4f0f-
|
|
31
26
|
end
|
32
27
|
```
|
33
28
|
|
29
|
+
2. Use the client to interact with the API
|
34
30
|
|
35
|
-
|
31
|
+
- If you need to send body parameters just pass a hash:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
client = DlocalGo::Client.new
|
35
|
+
response = client.create_payment({country: "UY", currency: "UYU", amount: 500, notification_url: "https://notification.url"})
|
36
|
+
# or
|
37
|
+
# response = client.create_payment(country: "UY", currency: "UYU", amount: 500, notification_url: "https://notification.url")
|
38
|
+
```
|
36
39
|
|
37
|
-
-
|
40
|
+
- If you need to use path variables for specific endpoints you can also pass them as arguments
|
38
41
|
|
39
42
|
```ruby
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
success_url: "https://success.url", # Where the user will be redirected after the payment is approved
|
45
|
-
back_url: "https://back.url", # Where the user is redirected if they go back from the checkout page
|
46
|
-
notification_url: "https://notification.url" # Optional, where the notification will be sent when payment state changes, (It will send a POST request with a payment_id param in the body, which can be used to retrieve the payment)
|
47
|
-
}
|
48
|
-
response = DlocalGo::Client.create_payment(params)
|
49
|
-
# If request is not successful, it will raise a DlocalGo::Error, otherwise the response will be a DlocalGo::Response::Payment object
|
50
|
-
|
51
|
-
# You might want to save the payment from the response before redirecting, so you can update the state later via a webhook (notification_url)
|
52
|
-
redirect_to response.redirect_url, allow_other_host: true
|
43
|
+
client = DlocalGo::Client.new
|
44
|
+
|
45
|
+
# This will replace the payment_id path variable in the uri: /v1/payments/:payment_id
|
46
|
+
response = client.get_payment(payment_id: "payment_id")
|
53
47
|
```
|
54
48
|
|
55
|
-
-
|
49
|
+
- If you need to send query parameters just pass as a hash under a query_params key
|
56
50
|
|
57
51
|
```ruby
|
58
|
-
|
59
|
-
|
52
|
+
client = DlocalGo::Client.new
|
53
|
+
response = client.get_all_subscription_plans(query_params: {page: 2})
|
54
|
+
|
55
|
+
# You can also use it with endpoints that require path variables. Eg:
|
56
|
+
response = client.get_subscriptions_by_plan(plan_id: 1234, query_params: {page: 2})
|
60
57
|
```
|
61
58
|
|
62
|
-
|
59
|
+
3. Handle the response
|
60
|
+
|
61
|
+
- We return DlocalGo::Responses objects (eg: DlocalGo::Responses::Payment) which have the same schema as the documentation responses.
|
62
|
+
- All attributes inside responses use the snake_case syntax
|
63
|
+
|
64
|
+
- NOTE: If the request fails we raise a DlocalGo::Error with an error code and message, so you might want to rescue it. (We'll make it optional in the future, for now we always raise an error when the request fails)
|
63
65
|
|
64
66
|
```ruby
|
65
|
-
|
66
|
-
|
67
|
-
amount:
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
67
|
+
def create
|
68
|
+
# Example:
|
69
|
+
response = client.create_payment({country: "UY", currency: "UYU", amount: 500, notification_url: "https://notification.url"})
|
70
|
+
redirect_to response.redirect_url, allow_other_host: true
|
71
|
+
|
72
|
+
rescue DlocalGo::Error => e
|
73
|
+
# Do sth else
|
74
|
+
end
|
72
75
|
```
|
73
76
|
|
77
|
+
## Supported Endpoints
|
78
|
+
|
79
|
+
We support all endpoints from the [DlocalGo API](https://docs.dlocalgo.com/integration-api)
|
80
|
+
|
81
|
+
### Payments
|
82
|
+
- [x] Create Payment: `client.create_payment(params)`
|
83
|
+
- [x] Get Payment: `client.get_payment(payment_id: "the_id")`
|
84
|
+
- [x] Create Refund: `client.create_refund(params)`
|
85
|
+
- [x] Get Refund: `client.get_refund(refund_id: "the_id")`
|
86
|
+
|
87
|
+
## Recurring Payments
|
88
|
+
- [x] Create Recurring Payment: `client.create_recurring_payment(params)`
|
89
|
+
- [x] Get Recurring Payment: `client.get_recurring_payment(recurring_link_token: "the_token")`
|
90
|
+
- [x] Get All Recurring Payments: `client.get_all_recurring_payments`
|
91
|
+
|
92
|
+
## Subscriptions
|
93
|
+
- [x] Create Subscription Plan: `client.create_subscription_plan(params)`
|
94
|
+
- [x] Update Subscription Plan: `client.update_subscription_plan(plan_id: "the_id", params)`
|
95
|
+
- [x] Get All Subscription Plans: `client.get_all_subscription_plans`
|
96
|
+
- [x] Get Subscription Plan: `client.get_subscription_plan(plan_id: "the_id")`
|
97
|
+
- [x] Get Subscriptions by Plan: `client.get_subscriptions_by_plan(plan_id: "the_id")`
|
98
|
+
- [x] Get All Executions by Subscription: `client.get_all_executions_by_subscription(plan_id: "the_id", subscription_id: "the_id")`
|
99
|
+
- [x] Get Subscription Execution: `client.get_subscription_execution(subscription_id: "the_id", order_id: "the_id")`
|
100
|
+
- [x] Cancel Plan: `client.cancel_plan(plan_id: "the_id")`
|
101
|
+
- [x] Cancel Subscription: `client.cancel_subscription(plan_id: "the_id", subscription_id: "the_id")`
|
102
|
+
|
103
|
+
|
104
|
+
# Endpoints request and response schema details
|
105
|
+
|
106
|
+
- See the [DlocalGo API](https://docs.dlocalgo.com/integration-api) docs for more details on the request and response schema for each endpoint
|
107
|
+
|
74
108
|
## Contributing
|
75
109
|
|
76
110
|
Bug reports and pull requests are welcome on GitHub at https://github.com/MetaLabs-inc/dlocal_go.
|
data/lib/dlocal_go/client.rb
CHANGED
@@ -2,78 +2,58 @@
|
|
2
2
|
|
3
3
|
require_relative "responses/payment"
|
4
4
|
require_relative "responses/refund"
|
5
|
+
require_relative "responses/recurring_payment"
|
6
|
+
require_relative "responses/subscription_plan"
|
7
|
+
require_relative "responses/subscription"
|
8
|
+
require_relative "responses/subscription_execution"
|
9
|
+
require_relative "endpoint_generator"
|
5
10
|
|
6
11
|
module DlocalGo
|
7
12
|
# Client for Dlocal Go API
|
8
13
|
class Client
|
9
|
-
|
10
|
-
PRODUCTION_URL = "https://api.dlocalgo.com"
|
11
|
-
DEFAULT_SUPPORTED_COUNTRIES = %w[UY AR CL BO BR CO CR EC GT ID MX MY PE PY].freeze
|
12
|
-
CURRENCY_FOR_COUNTRY = { UY: "UYU", AR: "ARS", CL: "CLP", BO: "BOB", BR: "BRL",
|
13
|
-
CO: "COP", CR: "CRC", EC: "USD", GT: "GTQ", ID: "IDR", MX: "MXN",
|
14
|
-
MY: "MYR", PE: "PEN", PY: "PYG" }.freeze
|
14
|
+
include DlocalGo::EndpointGenerator
|
15
15
|
|
16
16
|
def initialize
|
17
|
-
|
18
|
-
|
19
|
-
@base_url = DlocalGo.environment == "production" ? PRODUCTION_URL : SANDBOX_URL
|
20
|
-
|
21
|
-
raise DlocalGo::Error, "Dlocal Go api key is not set" if @api_key.nil?
|
22
|
-
raise DlocalGo::Error, "Dlocal Go api secret is not set" if @api_secret.nil?
|
17
|
+
raise DlocalGo::Error, "Dlocal Go api key is not set" if api_key.nil?
|
18
|
+
raise DlocalGo::Error, "Dlocal Go api secret is not set" if api_secret.nil?
|
23
19
|
end
|
24
20
|
|
25
|
-
|
26
|
-
raise DlocalGo::Error, "Unsupported country" unless supported_countries.include?(params[:country_code])
|
27
|
-
|
28
|
-
uri = "/v1/payments"
|
29
|
-
body = { amount: params[:amount], country: params[:country_code], notification_url: params[:notification_url],
|
30
|
-
currency: params[:currency] || CURRENCY_FOR_COUNTRY[params[:country_code].to_sym],
|
31
|
-
success_url: params[:success_url], back_url: params[:back_url] }
|
32
|
-
|
33
|
-
response = HTTP.auth(auth_header).headers(json_content_type).post(endpoint_url(uri), json: body)
|
34
|
-
|
35
|
-
raise DlocalGo::Error, "Error creating checkout #{response.parse}" unless response.status.success?
|
21
|
+
# Request body requirements for each endpoint: https://docs.dlocalgo.com/integration-api/welcome-to-dlocal-go-api/
|
36
22
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
def get_payment(payment_id)
|
41
|
-
uri = "/v1/payments/#{payment_id}"
|
42
|
-
response = HTTP.auth(auth_header).get(endpoint_url(uri))
|
23
|
+
# ===== USAGE =====
|
24
|
+
#
|
43
25
|
|
44
|
-
|
26
|
+
# For get and delete requests, send the path variables as a hash, for example: client.get_payment(payment_id: "123") and it will get replaced automatically inside the uri
|
27
|
+
# Also for get and delete requests, query params are taken from the query_params hash key, for example: client.get_all_subscription_plans(query_params: { page: 2 })
|
28
|
+
# This is an example that uses query and path params: client.get_all_executions_by_subscription(subscription_id: "123", plan_id: "456", query_params: { page: 2 })
|
45
29
|
|
46
|
-
|
47
|
-
end
|
30
|
+
# For post and put/patch requests, the hash variables will be included in the body instead
|
48
31
|
|
49
|
-
|
50
|
-
|
51
|
-
body = { payment_id: params[:payment_id], currency: params[:currency], amount: params[:amount],
|
52
|
-
notification_url: params[:notification_url] }
|
32
|
+
#
|
33
|
+
# ===== USAGE =====
|
53
34
|
|
54
|
-
|
35
|
+
# PAYMENTS
|
36
|
+
endpoint :create_payment, uri: "/v1/payments", verb: :post, dto_class: DlocalGo::Responses::Payment
|
37
|
+
endpoint :get_payment, uri: "/v1/payments/:payment_id", verb: :get, dto_class: DlocalGo::Responses::Payment
|
38
|
+
endpoint :create_refund, uri: "/v1/refunds", verb: :post, dto_class: DlocalGo::Responses::Refund
|
39
|
+
endpoint :get_refund, uri: "/v1/refunds/:refund_id", verb: :get, dto_class: DlocalGo::Responses::Refund
|
55
40
|
|
56
|
-
|
41
|
+
# RECURRING PAYMENTS
|
42
|
+
endpoint :create_recurring_payment, uri: "/v1/recurring-payments", verb: :post, dto_class: DlocalGo::Responses::RecurringPayment
|
43
|
+
endpoint :get_recurring_payment, uri: "/v1/recurring-payments/:recurring_link_token", verb: :get, dto_class: DlocalGo::Responses::RecurringPayment
|
44
|
+
endpoint :get_all_recurring_payments, uri: "/v1/recurring-payments", verb: :get, dto_class: DlocalGo::Responses::RecurringPayment
|
57
45
|
|
58
|
-
|
59
|
-
|
46
|
+
# SUBSCRIPTIONS
|
47
|
+
endpoint :create_subscription_plan, uri: "/v1/subscription/plan", verb: :post, dto_class: DlocalGo::Responses::SubscriptionPlan
|
48
|
+
endpoint :update_subscription_plan, uri: "/v1/subscription/plan/:plan_id", verb: :patch, dto_class: DlocalGo::Responses::SubscriptionPlan
|
49
|
+
endpoint :get_all_subscription_plans, uri: "/v1/subscription/plan/all", verb: :get, dto_class: DlocalGo::Responses::SubscriptionPlan
|
50
|
+
endpoint :get_subscription_plan, uri: "/v1/subscription/plan/:plan_id", verb: :get, dto_class: DlocalGo::Responses::SubscriptionPlan
|
60
51
|
|
61
|
-
|
52
|
+
endpoint :get_subscriptions_by_plan, uri: "/v1/subscription/plan/:plan_id/subscription/all", verb: :get, dto_class: DlocalGo::Responses::Subscription
|
53
|
+
endpoint :get_all_executions_by_subscription, uri: "/v1/subscription/plan/:plan_id/subscription/:subscription_id/execution/all", verb: :get, dto_class: DlocalGo::Responses::SubscriptionExecution
|
54
|
+
endpoint :get_subscription_execution, uri: "/v1/subscription/:subscription_id/execution/:order_id", verb: :get, dto_class: DlocalGo::Responses::SubscriptionExecution
|
62
55
|
|
63
|
-
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
|
-
def json_content_type
|
68
|
-
{ 'content-type': "application/json" }
|
69
|
-
end
|
70
|
-
|
71
|
-
def endpoint_url(endpoint_url)
|
72
|
-
"#{@base_url}#{endpoint_url}"
|
73
|
-
end
|
74
|
-
|
75
|
-
def supported_countries
|
76
|
-
DlocalGo.supported_countries || DEFAULT_SUPPORTED_COUNTRIES
|
77
|
-
end
|
56
|
+
endpoint :cancel_plan, uri: "/v1/subscription/plan/:plan_id/deactivate", verb: :patch, dto_class: DlocalGo::Responses::SubscriptionPlan
|
57
|
+
endpoint :cancel_subscription, uri: "/v1/subscription/plan/:plan_id/subscription/:subscription_id/deactivate", verb: :patch, dto_class: DlocalGo::Responses::Subscription
|
78
58
|
end
|
79
59
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DlocalGo
|
4
|
+
# Constants we'll use throughout the gem
|
5
|
+
module Constants
|
6
|
+
SANDBOX_URL = "https://api-sbx.dlocalgo.com"
|
7
|
+
PRODUCTION_URL = "https://api.dlocalgo.com"
|
8
|
+
|
9
|
+
SUBSCRIPTION_BASE_SANDBOX_URL = "https://checkout-sbx.dlocalgo.com/validate/subscription"
|
10
|
+
SUBSCRIPTION_BASE_PRODUCTION_URL = "https://checkout.dlocalgo.com/validate/subscription"
|
11
|
+
|
12
|
+
DEFAULT_SUPPORTED_COUNTRIES = %w[UY AR CL BO BR CO CR EC GT ID MX MY PE PY].freeze
|
13
|
+
CURRENCY_FOR_COUNTRY = { UY: "UYU", AR: "ARS", CL: "CLP", BO: "BOB", BR: "BRL",
|
14
|
+
CO: "COP", CR: "CRC", EC: "USD", GT: "GTQ", ID: "IDR", MX: "MXN",
|
15
|
+
MY: "MYR", PE: "PEN", PY: "PYG" }.freeze
|
16
|
+
|
17
|
+
def currency_for_country(country)
|
18
|
+
CURRENCY_FOR_COUNTRY[country.to_sym]
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def api_key
|
24
|
+
@api_key ||= DlocalGo.api_key
|
25
|
+
end
|
26
|
+
|
27
|
+
def api_secret
|
28
|
+
@api_secret ||= DlocalGo.api_secret
|
29
|
+
end
|
30
|
+
|
31
|
+
def base_url
|
32
|
+
@base_url ||= DlocalGo.environment == "production" ? PRODUCTION_URL : SANDBOX_URL
|
33
|
+
end
|
34
|
+
|
35
|
+
def subscription_base_url
|
36
|
+
@subscription_base_url ||= DlocalGo.environment == "production" ? SUBSCRIPTION_BASE_PRODUCTION_URL : SUBSCRIPTION_BASE_SANDBOX_URL
|
37
|
+
end
|
38
|
+
|
39
|
+
def supported_countries
|
40
|
+
@supported_countries ||= DlocalGo.supported_countries || DEFAULT_SUPPORTED_COUNTRIES
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "http"
|
4
|
+
|
5
|
+
require_relative "constants"
|
6
|
+
require_relative "responses/array"
|
7
|
+
|
8
|
+
module DlocalGo
|
9
|
+
# Module that allows us to define endpoints in the DlocalGo::Client class just by calling the endpoint method
|
10
|
+
module EndpointGenerator
|
11
|
+
include Constants
|
12
|
+
|
13
|
+
def self.included(base)
|
14
|
+
base.extend(ClassMethods)
|
15
|
+
end
|
16
|
+
|
17
|
+
# "Define the DSL"
|
18
|
+
module ClassMethods
|
19
|
+
def endpoint(method, uri:, verb:, dto_class:)
|
20
|
+
define_method(method) do |params = {}|
|
21
|
+
if params[:country].present? && supported_countries.exclude?(params[:country])
|
22
|
+
raise DlocalGo::Error,
|
23
|
+
"Unsupported country"
|
24
|
+
end
|
25
|
+
|
26
|
+
response = call_api(verb, uri, params)
|
27
|
+
parse_response(response, dto_class)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def call_api(http_method, uri, params)
|
35
|
+
parsed_uri, keys_to_remove = parse_uri(uri, params)
|
36
|
+
url = endpoint_url(parsed_uri)
|
37
|
+
args = [http_method, url]
|
38
|
+
needs_body = %i[post put patch].include?(http_method)
|
39
|
+
|
40
|
+
request_body = params.except(*keys_to_remove)
|
41
|
+
args << { json: request_body } if needs_body
|
42
|
+
|
43
|
+
HTTP.auth(auth_header).headers(json_content_type).send(*args)
|
44
|
+
end
|
45
|
+
|
46
|
+
# We grab the query_params from the params hash
|
47
|
+
# We also grab the path variables from the params hash and replace them in the uri
|
48
|
+
# We return the uri and the keys from the params hash that we used so we can remove them later and not include them in the json body
|
49
|
+
def parse_uri(uri, params)
|
50
|
+
parsed_uri = uri
|
51
|
+
keys_to_remove = %i[query_params]
|
52
|
+
query_params = params[:query_params] || {}
|
53
|
+
|
54
|
+
params.each do |key, value|
|
55
|
+
next unless uri.include?(":#{key}")
|
56
|
+
|
57
|
+
parsed_uri = parsed_uri.gsub(":#{key}", value.to_s)
|
58
|
+
keys_to_remove << key
|
59
|
+
end
|
60
|
+
|
61
|
+
["#{parsed_uri}?#{query_params.to_query}", keys_to_remove]
|
62
|
+
end
|
63
|
+
|
64
|
+
def parse_response(response, dto_class)
|
65
|
+
response_body = response.parse
|
66
|
+
unless response.status.success?
|
67
|
+
raise DlocalGo::Error.new(response_body["message"],
|
68
|
+
error_code: response_body["code"])
|
69
|
+
end
|
70
|
+
|
71
|
+
parse_successful_response(response_body, dto_class)
|
72
|
+
end
|
73
|
+
|
74
|
+
def parse_successful_response(response_body, dto_class)
|
75
|
+
struct = OpenStruct.new(response_body)
|
76
|
+
array_response = response_body["data"].is_a?(Array)
|
77
|
+
|
78
|
+
array_response ? DlocalGo::Responses::Array.new(struct, { data_class: dto_class }) : dto_class.new(struct)
|
79
|
+
end
|
80
|
+
|
81
|
+
def auth_header
|
82
|
+
"Bearer #{api_key}:#{api_secret}"
|
83
|
+
end
|
84
|
+
|
85
|
+
def json_content_type
|
86
|
+
{ 'content-type': "application/json" }
|
87
|
+
end
|
88
|
+
|
89
|
+
def endpoint_url(endpoint_url)
|
90
|
+
"#{base_url}#{endpoint_url}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/lib/dlocal_go/errors.rb
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module DlocalGo
|
4
|
-
class
|
4
|
+
# Generic error class for all errors that occur in the gem
|
5
|
+
class Error < StandardError
|
6
|
+
attr_reader :error_code
|
7
|
+
|
8
|
+
def initialize(message, error_code: nil)
|
9
|
+
@error_code = error_code
|
10
|
+
super(message)
|
11
|
+
end
|
12
|
+
end
|
5
13
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module DlocalGo
|
6
|
+
module Responses
|
7
|
+
# Wrapper for Dlocal Go array responses
|
8
|
+
class Array < DlocalGo::Responses::Base
|
9
|
+
has_array_data_attribute :data
|
10
|
+
|
11
|
+
has_attributes %i[
|
12
|
+
total_elements
|
13
|
+
total_pages
|
14
|
+
page
|
15
|
+
number_of_elements
|
16
|
+
size
|
17
|
+
]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,19 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "base"
|
4
|
+
|
3
5
|
module DlocalGo
|
4
6
|
module Responses
|
5
7
|
# Class that represents Dlocal Go payment schema
|
6
|
-
class Payment
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
8
|
+
class Payment < DlocalGo::Responses::Base
|
9
|
+
has_attributes %i[
|
10
|
+
id
|
11
|
+
amount
|
12
|
+
currency
|
13
|
+
country
|
14
|
+
created_date
|
15
|
+
status
|
16
|
+
order_id
|
17
|
+
success_url
|
18
|
+
back_url
|
19
|
+
redirect_url
|
20
|
+
notification_url
|
21
|
+
merchant_checkout_token
|
22
|
+
approved_date
|
23
|
+
description
|
24
|
+
direct
|
25
|
+
]
|
17
26
|
end
|
18
27
|
end
|
19
28
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module DlocalGo
|
6
|
+
module Responses
|
7
|
+
# Class that represents Dlocal Go recurring payment schema
|
8
|
+
class RecurringPayment < DlocalGo::Responses::Base
|
9
|
+
has_attributes %i[
|
10
|
+
currency
|
11
|
+
amount
|
12
|
+
recurring_link_token
|
13
|
+
enabled
|
14
|
+
]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,18 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "base"
|
4
|
+
|
3
5
|
module DlocalGo
|
4
6
|
module Responses
|
5
7
|
# Class that represents Dlocal Go refund schema
|
6
|
-
class Refund
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
RESPONSE_ATTRIBUTES.each do |attribute|
|
13
|
-
instance_variable_set("@#{attribute}", response.send(attribute))
|
14
|
-
end
|
15
|
-
end
|
8
|
+
class Refund < DlocalGo::Responses::Base
|
9
|
+
has_attributes %i[
|
10
|
+
id
|
11
|
+
amount
|
12
|
+
status
|
13
|
+
]
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DlocalGo
|
4
|
+
module Responses
|
5
|
+
# Module that makes it easier for DTOs to define their schema
|
6
|
+
module ResponseParser
|
7
|
+
def self.included(base)
|
8
|
+
base.class_eval { class_attribute :response_attributes, :response_associations, :array_data_attribute }
|
9
|
+
|
10
|
+
base.extend(ClassMethods)
|
11
|
+
|
12
|
+
base.class_eval <<-CODE, __FILE__, __LINE__ + 1
|
13
|
+
def initialize(response, options = {})
|
14
|
+
extract_options(options)
|
15
|
+
|
16
|
+
assign_attributes(response)
|
17
|
+
assign_associations(response)
|
18
|
+
end
|
19
|
+
CODE
|
20
|
+
end
|
21
|
+
|
22
|
+
# "Define the DSL" for all the DTOs
|
23
|
+
module ClassMethods
|
24
|
+
# rubocop:disable Naming/PredicateName
|
25
|
+
def has_attributes(attributes)
|
26
|
+
self.response_attributes = attributes
|
27
|
+
|
28
|
+
class_eval { attr_reader(*attributes) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def has_association(attribute, klass)
|
32
|
+
self.response_associations ||= {}
|
33
|
+
self.response_associations[attribute] = klass
|
34
|
+
|
35
|
+
class_eval { attr_reader attribute }
|
36
|
+
end
|
37
|
+
|
38
|
+
def has_array_data_attribute(attribute)
|
39
|
+
self.array_data_attribute = attribute
|
40
|
+
end
|
41
|
+
# rubocop:enable Naming/PredicateName
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def extract_options(options)
|
47
|
+
return unless options[:data_class].present?
|
48
|
+
|
49
|
+
raise ArgumentError, "array_data_attribute is required" if array_data_attribute.blank?
|
50
|
+
|
51
|
+
class_eval { has_association(array_data_attribute, options[:data_class]) }
|
52
|
+
end
|
53
|
+
|
54
|
+
def assign_attributes(response)
|
55
|
+
return if response_attributes.nil?
|
56
|
+
|
57
|
+
response_attributes.each do |attribute|
|
58
|
+
instance_variable_set("@#{attribute}",
|
59
|
+
response.send(attribute) || response.send(attribute.to_s.camelize(:lower)))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def assign_associations(response)
|
64
|
+
return if self.response_associations.nil?
|
65
|
+
|
66
|
+
self.response_associations.each do |attribute, klass|
|
67
|
+
response_data = response.send(attribute) || response.send(attribute.to_s.camelize(:lower))
|
68
|
+
|
69
|
+
if response_data.instance_of?(::Array)
|
70
|
+
mapped_data = response_data.map do |data|
|
71
|
+
struct = OpenStruct.new(data)
|
72
|
+
klass.new(struct)
|
73
|
+
end
|
74
|
+
|
75
|
+
instance_variable_set("@#{attribute}", mapped_data)
|
76
|
+
else
|
77
|
+
struct = OpenStruct.new(response_data)
|
78
|
+
instance_variable_set("@#{attribute}", klass.new(struct))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
require_relative "subscription_plan"
|
6
|
+
|
7
|
+
module DlocalGo
|
8
|
+
module Responses
|
9
|
+
# Class that represents Dlocal Go subscription schema
|
10
|
+
class Subscription < DlocalGo::Responses::Base
|
11
|
+
has_attributes %i[
|
12
|
+
id
|
13
|
+
country
|
14
|
+
subscription_token
|
15
|
+
status
|
16
|
+
language
|
17
|
+
scheduled_date
|
18
|
+
active
|
19
|
+
client_id
|
20
|
+
client_first_name
|
21
|
+
client_last_name
|
22
|
+
client_document_type
|
23
|
+
client_document
|
24
|
+
client_email
|
25
|
+
card_token
|
26
|
+
created_at
|
27
|
+
updated_at
|
28
|
+
]
|
29
|
+
|
30
|
+
has_association :plan, DlocalGo::Responses::SubscriptionPlan
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
require_relative "subscription"
|
5
|
+
|
6
|
+
module DlocalGo
|
7
|
+
module Responses
|
8
|
+
# Class that represents Dlocal Go subscription plan execution schema
|
9
|
+
class SubscriptionExecution < DlocalGo::Responses::Base
|
10
|
+
has_attributes %i[
|
11
|
+
id
|
12
|
+
status
|
13
|
+
order_id
|
14
|
+
merchant_checkout_id
|
15
|
+
currency
|
16
|
+
amount_paid
|
17
|
+
amount_received
|
18
|
+
checkout_currency
|
19
|
+
balance_currency
|
20
|
+
created_at
|
21
|
+
updated_at
|
22
|
+
]
|
23
|
+
|
24
|
+
has_association :subscription, DlocalGo::Responses::Subscription
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module DlocalGo
|
6
|
+
module Responses
|
7
|
+
# Class that represents Dlocal Go subscription plan schema
|
8
|
+
class SubscriptionPlan < DlocalGo::Responses::Base
|
9
|
+
has_attributes %i[
|
10
|
+
id
|
11
|
+
merchant_id
|
12
|
+
name
|
13
|
+
description
|
14
|
+
country
|
15
|
+
currency
|
16
|
+
amount
|
17
|
+
frequency_type
|
18
|
+
frequency_value
|
19
|
+
active
|
20
|
+
free_trial_days
|
21
|
+
plan_token
|
22
|
+
back_url
|
23
|
+
notification_url
|
24
|
+
success_url
|
25
|
+
error_url
|
26
|
+
created_at
|
27
|
+
updated_at
|
28
|
+
]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "constants"
|
4
|
+
|
5
|
+
module DlocalGo
|
6
|
+
# Utilities for using the Dlocal Go API
|
7
|
+
class Utilities
|
8
|
+
include Constants
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def subscription_url(token:, email: nil)
|
12
|
+
new.subscription_url(token: token, email: email)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def subscription_url(token:, email: nil)
|
17
|
+
email.present? ? "#{subscription_base_url}/#{token}?email=#{email}" : "#{base_url}#{token}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/dlocal_go/version.rb
CHANGED
data/lib/dlocal_go.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/all"
|
4
|
+
|
3
5
|
require_relative "dlocal_go/version"
|
4
6
|
require_relative "dlocal_go/errors"
|
5
7
|
require_relative "dlocal_go/client"
|
8
|
+
require_relative "dlocal_go/utilities"
|
6
9
|
|
7
10
|
# Main module for Dlocal Go, it provides a way to configure the gem and imports the client
|
8
11
|
module DlocalGo
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dlocal_go
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: '1.0'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- matiassalles99
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: http
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,17 +53,23 @@ files:
|
|
39
53
|
- LICENSE.txt
|
40
54
|
- README.md
|
41
55
|
- Rakefile
|
42
|
-
- dlocal_go.gemspec
|
43
56
|
- lib/dlocal_go.rb
|
44
57
|
- lib/dlocal_go/client.rb
|
58
|
+
- lib/dlocal_go/constants.rb
|
59
|
+
- lib/dlocal_go/endpoint_generator.rb
|
45
60
|
- lib/dlocal_go/errors.rb
|
61
|
+
- lib/dlocal_go/responses/array.rb
|
62
|
+
- lib/dlocal_go/responses/base.rb
|
46
63
|
- lib/dlocal_go/responses/payment.rb
|
64
|
+
- lib/dlocal_go/responses/recurring_payment.rb
|
47
65
|
- lib/dlocal_go/responses/refund.rb
|
66
|
+
- lib/dlocal_go/responses/response_parser.rb
|
67
|
+
- lib/dlocal_go/responses/subscription.rb
|
68
|
+
- lib/dlocal_go/responses/subscription_execution.rb
|
69
|
+
- lib/dlocal_go/responses/subscription_plan.rb
|
70
|
+
- lib/dlocal_go/utilities.rb
|
48
71
|
- lib/dlocal_go/version.rb
|
49
72
|
- sig/dlocal_go.rbs
|
50
|
-
- sig/dlocal_go/client.rbs
|
51
|
-
- sig/dlocal_go/responses/payment.rbs
|
52
|
-
- sig/dlocal_go/responses/refund.rbs
|
53
73
|
homepage: https://github.com/MetaLabs-inc/dlocal_go
|
54
74
|
licenses:
|
55
75
|
- MIT
|
@@ -72,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
92
|
- !ruby/object:Gem::Version
|
73
93
|
version: '0'
|
74
94
|
requirements: []
|
75
|
-
rubygems_version: 3.
|
95
|
+
rubygems_version: 3.4.10
|
76
96
|
signing_key:
|
77
97
|
specification_version: 4
|
78
98
|
summary: Dlocal Go client for ruby
|
data/dlocal_go.gemspec
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "lib/dlocal_go/version"
|
4
|
-
|
5
|
-
Gem::Specification.new do |spec|
|
6
|
-
spec.name = "dlocal_go"
|
7
|
-
spec.version = DlocalGo::VERSION
|
8
|
-
spec.authors = ["matiassalles99"]
|
9
|
-
spec.email = ["matiassalles99@gmail.com"]
|
10
|
-
|
11
|
-
spec.summary = "Dlocal Go client for ruby"
|
12
|
-
spec.description = "Dlocal Go client written in ruby to interact with Dlocal Go's API"
|
13
|
-
spec.homepage = "https://github.com/MetaLabs-inc/dlocal_go"
|
14
|
-
spec.license = "MIT"
|
15
|
-
spec.required_ruby_version = ">= 2.6.0"
|
16
|
-
|
17
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
-
spec.metadata["source_code_uri"] = "https://github.com/MetaLabs-inc/dlocal_go"
|
19
|
-
spec.metadata["changelog_uri"] = "https://github.com/MetaLabs-inc/dlocal_go/blob/main/CHANGELOG.md"
|
20
|
-
|
21
|
-
# Specify which files should be added to the gem when it is released.
|
22
|
-
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
-
spec.files = Dir.chdir(__dir__) do
|
24
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
25
|
-
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
26
|
-
end
|
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
|
-
spec.add_dependency "http"
|
33
|
-
|
34
|
-
# For more information and examples about making a new gem, check out our
|
35
|
-
# guide at: https://bundler.io/guides/creating_gem.html
|
36
|
-
end
|
data/sig/dlocal_go/client.rbs
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
module DlocalGo
|
2
|
-
class Client
|
3
|
-
CURRENCY_FOR_COUNTRY: Hash[Symbol, String]
|
4
|
-
DEFAULT_SUPPORTED_COUNTRIES: Array[String]
|
5
|
-
SANDBOX_URL: String
|
6
|
-
PRODUCTION_URL: String
|
7
|
-
|
8
|
-
@api_key: String
|
9
|
-
@api_secret: String
|
10
|
-
@base_url: String
|
11
|
-
|
12
|
-
def create_payment: -> Responses::Payment
|
13
|
-
def get_payment: -> Responses::Payment
|
14
|
-
def create_refund: -> Responses::Refund
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def auth_header: -> untyped
|
19
|
-
|
20
|
-
def endpoint_url: -> untyped
|
21
|
-
|
22
|
-
def json_content_type: -> untyped
|
23
|
-
|
24
|
-
def supported_countries: -> untyped
|
25
|
-
end
|
26
|
-
end
|