metrifox-sdk 1.0.1 → 1.0.2
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/README.md +99 -26
- data/lib/metrifox-sdk.rb +3 -0
- data/lib/metrifox_sdk/checkout/api.rb +15 -0
- data/lib/metrifox_sdk/checkout/module.rb +59 -0
- data/lib/metrifox_sdk/client.rb +4 -0
- data/lib/metrifox_sdk/customers/api.rb +31 -0
- data/lib/metrifox_sdk/customers/module.rb +5 -0
- data/lib/metrifox_sdk/types.rb +6 -2
- data/lib/metrifox_sdk/usages/api.rb +10 -0
- data/lib/metrifox_sdk/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dd2f3f03c15f2b2706851f83e95ddab68004fb5bf722201eae1301e2e5eb0ce9
|
|
4
|
+
data.tar.gz: 4cc5c6d239788de18628f4a929a2d6a328816ad74372afdf703e0f5993c87f78
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d429ea4b6554d8da627f4b98687eadf40a02c6cc6a5b98cf8a528cb0f9eb171c16463a530dac6646d63927591080a77f40632ddf71c532cc664abcf5155694ea
|
|
7
|
+
data.tar.gz: 78b222b28144cfef43f03f26941764fd914bcbfa6d80f5423b6d107833700ab9d6dd55aecc2075e43d927261a5e470bab43bfb8d3c27a9290b1cc9e00b7aae06
|
data/README.md
CHANGED
|
@@ -7,7 +7,7 @@ A Ruby SDK for interacting with the Metrifox platform API.
|
|
|
7
7
|
Add this line to your application's Gemfile:
|
|
8
8
|
|
|
9
9
|
```ruby
|
|
10
|
-
gem '
|
|
10
|
+
gem 'metrifox-sdk'
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
And then execute:
|
|
@@ -19,7 +19,7 @@ $ bundle install
|
|
|
19
19
|
Or install it yourself as:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
$ gem install
|
|
22
|
+
$ gem install metrifox-sdk
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
## Usage
|
|
@@ -27,25 +27,21 @@ $ gem install metrifox_sdk
|
|
|
27
27
|
### Configuration
|
|
28
28
|
|
|
29
29
|
```ruby
|
|
30
|
-
require '
|
|
30
|
+
require 'metrifox-sdk'
|
|
31
31
|
|
|
32
32
|
# Initialize with configuration
|
|
33
|
-
MetrifoxSDK.init({
|
|
34
|
-
api_key: "your-api-key",
|
|
35
|
-
base_url: "https://metrifox-api.staging.useyala.com/api/v1/",
|
|
36
|
-
web_app_base_url: "https://frontend-v3.staging.useyala.com"
|
|
37
|
-
})
|
|
33
|
+
METRIFOX_SDK = MetrifoxSDK.init({ api_key: "your-api-key"})
|
|
38
34
|
|
|
39
35
|
# Or set environment variable
|
|
40
36
|
ENV["METRIFOX_API_KEY"] = "your-api-key"
|
|
41
|
-
MetrifoxSDK.init
|
|
37
|
+
METRIFOX_SDK = MetrifoxSDK.init
|
|
42
38
|
```
|
|
43
39
|
|
|
44
40
|
### Access Control
|
|
45
41
|
|
|
46
42
|
```ruby
|
|
47
43
|
# Check feature access
|
|
48
|
-
response =
|
|
44
|
+
response = METRIFOX_SDK.usages.check_access({
|
|
49
45
|
feature_key: "premium_feature",
|
|
50
46
|
customer_key: "customer_123"
|
|
51
47
|
})
|
|
@@ -56,12 +52,39 @@ puts response["can_access"] # true/false
|
|
|
56
52
|
### Usage Tracking
|
|
57
53
|
|
|
58
54
|
```ruby
|
|
59
|
-
#
|
|
60
|
-
response =
|
|
55
|
+
# Basic usage recording
|
|
56
|
+
response = METRIFOX_SDK.usages.record_usage({
|
|
61
57
|
customer_key: "customer_123",
|
|
62
58
|
event_name: "api_call",
|
|
63
59
|
amount: 1
|
|
64
60
|
})
|
|
61
|
+
|
|
62
|
+
# Advanced usage recording with additional fields
|
|
63
|
+
response = METRIFOX_SDK.usages.record_usage({
|
|
64
|
+
customer_key: "customer_123",
|
|
65
|
+
event_name: "api_call",
|
|
66
|
+
amount: 1,
|
|
67
|
+
credit_used: 5,
|
|
68
|
+
event_id: "event_uuid_123",
|
|
69
|
+
timestamp: 1640995200,
|
|
70
|
+
metadata: {
|
|
71
|
+
source: "web_app",
|
|
72
|
+
feature: "premium_search"
|
|
73
|
+
}
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
# Using structured request object
|
|
77
|
+
usage_request = MetrifoxSDK::Types::UsageEventRequest.new(
|
|
78
|
+
customer_key: "customer_123",
|
|
79
|
+
event_name: "api_call",
|
|
80
|
+
amount: 1,
|
|
81
|
+
credit_used: 5,
|
|
82
|
+
event_id: "event_uuid_123",
|
|
83
|
+
timestamp: Time.now.to_i,
|
|
84
|
+
metadata: { source: "mobile_app" }
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
response = METRIFOX_SDK.usages.record_usage(usage_request)
|
|
65
88
|
```
|
|
66
89
|
|
|
67
90
|
### Customer Management
|
|
@@ -76,7 +99,7 @@ customer_data = {
|
|
|
76
99
|
display_name: "ACME"
|
|
77
100
|
}
|
|
78
101
|
|
|
79
|
-
response =
|
|
102
|
+
response = METRIFOX_SDK.customers.create(customer_data)
|
|
80
103
|
|
|
81
104
|
# Update customer
|
|
82
105
|
update_data = {
|
|
@@ -84,36 +107,86 @@ update_data = {
|
|
|
84
107
|
website_url: "https://acme.com"
|
|
85
108
|
}
|
|
86
109
|
|
|
87
|
-
response =
|
|
110
|
+
response = METRIFOX_SDK.customers.update("customer_123", update_data)
|
|
88
111
|
|
|
89
112
|
# Get customer
|
|
90
|
-
response =
|
|
113
|
+
response = METRIFOX_SDK.customers.get_customer({ customer_key: "customer_123" })
|
|
91
114
|
|
|
92
115
|
# Get customer details
|
|
93
|
-
response =
|
|
116
|
+
response = METRIFOX_SDK.customers.get_details({ customer_key: "customer_123" })
|
|
117
|
+
|
|
118
|
+
# List customers
|
|
119
|
+
response = METRIFOX_SDK.customers.list
|
|
120
|
+
|
|
121
|
+
# List customers with pagination
|
|
122
|
+
response = METRIFOX_SDK.customers.list({ page: 2, per_page: 10 })
|
|
123
|
+
|
|
124
|
+
# List customers with filters
|
|
125
|
+
response = METRIFOX_SDK.customers.list({
|
|
126
|
+
search_term: "TechStart",
|
|
127
|
+
customer_type: "BUSINESS",
|
|
128
|
+
date_created: "2025-09-01"
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
# List customers with combined pagination and filters
|
|
132
|
+
response = METRIFOX_SDK.customers.list({
|
|
133
|
+
page: 1,
|
|
134
|
+
per_page: 5,
|
|
135
|
+
search_term: "John",
|
|
136
|
+
customer_type: "INDIVIDUAL"
|
|
137
|
+
})
|
|
94
138
|
|
|
95
139
|
# Delete customer
|
|
96
|
-
response =
|
|
140
|
+
response = METRIFOX_SDK.customers.delete_customer({ customer_key: "customer_123" })
|
|
141
|
+
|
|
97
142
|
```
|
|
98
143
|
|
|
99
144
|
### CSV Upload
|
|
100
145
|
|
|
101
146
|
```ruby
|
|
102
147
|
# Upload customers via CSV
|
|
103
|
-
response =
|
|
148
|
+
response = METRIFOX_SDK.customers.upload_csv("/path/to/customers.csv")
|
|
104
149
|
|
|
105
150
|
puts response["data"]["total_customers"]
|
|
106
151
|
puts response["data"]["successful_upload_count"]
|
|
107
152
|
```
|
|
108
153
|
|
|
109
|
-
###
|
|
154
|
+
### Checkout URL Generation
|
|
110
155
|
|
|
111
156
|
```ruby
|
|
112
|
-
|
|
113
|
-
|
|
157
|
+
# Basic checkout URL generation
|
|
158
|
+
checkout_url = METRIFOX_SDK.checkout.url({
|
|
159
|
+
offering_key: "your_offering_key"
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
# With optional billing interval
|
|
163
|
+
checkout_url = METRIFOX_SDK.checkout.url({
|
|
164
|
+
offering_key: "your_offering_key",
|
|
165
|
+
billing_interval: "monthly"
|
|
114
166
|
})
|
|
115
167
|
|
|
116
|
-
|
|
168
|
+
# With customer key for pre-filled checkout
|
|
169
|
+
checkout_url = METRIFOX_SDK.checkout.url({
|
|
170
|
+
offering_key: "your_offering_key",
|
|
171
|
+
billing_interval: "monthly",
|
|
172
|
+
customer_key: "customer_123"
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
# Using structured config object
|
|
176
|
+
checkout_config = MetrifoxSDK::Types::CheckoutConfig.new(
|
|
177
|
+
offering_key: "your_offering_key",
|
|
178
|
+
billing_interval: "monthly",
|
|
179
|
+
customer_key: "customer_123"
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
checkout_url = METRIFOX_SDK.checkout.url(checkout_config)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Using Client Instance
|
|
186
|
+
|
|
187
|
+
```ruby
|
|
188
|
+
|
|
189
|
+
response = METRIFOX_SDK.usages.check_access({
|
|
117
190
|
feature_key: "premium_feature",
|
|
118
191
|
customer_key: "customer_123"
|
|
119
192
|
})
|
|
@@ -130,7 +203,7 @@ access_request = MetrifoxSDK::Types::AccessCheckRequest.new(
|
|
|
130
203
|
customer_key: "customer_123"
|
|
131
204
|
)
|
|
132
205
|
|
|
133
|
-
response =
|
|
206
|
+
response = METRIFOX_SDK.usages.check_access(access_request)
|
|
134
207
|
|
|
135
208
|
# Customer creation with structured data
|
|
136
209
|
customer_request = MetrifoxSDK::Types::CustomerCreateRequest.new(
|
|
@@ -140,14 +213,14 @@ customer_request = MetrifoxSDK::Types::CustomerCreateRequest.new(
|
|
|
140
213
|
legal_name: "Acme Corp"
|
|
141
214
|
)
|
|
142
215
|
|
|
143
|
-
response =
|
|
216
|
+
response = METRIFOX_SDK.customers.create(customer_request)
|
|
144
217
|
```
|
|
145
218
|
|
|
146
219
|
## Error Handling
|
|
147
220
|
|
|
148
221
|
```ruby
|
|
149
222
|
begin
|
|
150
|
-
response =
|
|
223
|
+
response = METRIFOX_SDK.usages.check_access({
|
|
151
224
|
feature_key: "premium_feature",
|
|
152
225
|
customer_key: "customer_123"
|
|
153
226
|
})
|
|
@@ -168,4 +241,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/yourus
|
|
|
168
241
|
|
|
169
242
|
## License
|
|
170
243
|
|
|
171
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
244
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/lib/metrifox-sdk.rb
CHANGED
|
@@ -4,8 +4,11 @@ require_relative "metrifox_sdk/types"
|
|
|
4
4
|
require_relative "metrifox_sdk/util_methods"
|
|
5
5
|
require_relative "metrifox_sdk/base_api"
|
|
6
6
|
require_relative "metrifox_sdk/base_module"
|
|
7
|
+
require_relative "metrifox_sdk/customers/api"
|
|
7
8
|
require_relative "metrifox_sdk/customers/module"
|
|
8
9
|
require_relative "metrifox_sdk/usages/module"
|
|
10
|
+
require_relative "metrifox_sdk/checkout/api"
|
|
11
|
+
require_relative "metrifox_sdk/checkout/module"
|
|
9
12
|
|
|
10
13
|
module MetrifoxSDK
|
|
11
14
|
class << self
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require "net/http"
|
|
2
|
+
require "uri"
|
|
3
|
+
require "json"
|
|
4
|
+
require_relative "../base_api"
|
|
5
|
+
|
|
6
|
+
module MetrifoxSDK::Checkout
|
|
7
|
+
class API < MetrifoxSDK::BaseApi
|
|
8
|
+
def fetch_checkout_key(base_url, api_key)
|
|
9
|
+
uri = URI.join(base_url, "auth/checkout-username")
|
|
10
|
+
response = make_request(uri, "GET", api_key)
|
|
11
|
+
data = parse_response(response, "Failed to get tenant checkout settings")
|
|
12
|
+
data.dig("data", "checkout_username")
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require_relative "api"
|
|
2
|
+
require_relative "../base_module"
|
|
3
|
+
|
|
4
|
+
module MetrifoxSDK
|
|
5
|
+
module Checkout
|
|
6
|
+
class Module < BaseModule
|
|
7
|
+
def url(config)
|
|
8
|
+
validate_api_key!
|
|
9
|
+
|
|
10
|
+
# Handle both hash and struct access patterns
|
|
11
|
+
offering_key = get_value(config, :offering_key)
|
|
12
|
+
billing_interval = get_value(config, :billing_interval)
|
|
13
|
+
customer_key = get_value(config, :customer_key)
|
|
14
|
+
|
|
15
|
+
raise ArgumentError, "offering_key is required" if offering_key.nil? || offering_key.empty?
|
|
16
|
+
|
|
17
|
+
checkout_key = get_checkout_key
|
|
18
|
+
raise StandardError, "Checkout Key could not be retrieved. Ensure the API key is valid" if checkout_key.nil? || checkout_key.empty?
|
|
19
|
+
|
|
20
|
+
url_string = "#{web_app_base_url}/#{checkout_key}/checkout/#{offering_key}"
|
|
21
|
+
uri = URI(url_string)
|
|
22
|
+
|
|
23
|
+
# Add query parameters if provided
|
|
24
|
+
query_params = {}
|
|
25
|
+
query_params["billing_period"] = billing_interval if billing_interval && !billing_interval.empty?
|
|
26
|
+
query_params["customer"] = customer_key if customer_key && !customer_key.empty?
|
|
27
|
+
|
|
28
|
+
uri.query = URI.encode_www_form(query_params) unless query_params.empty?
|
|
29
|
+
|
|
30
|
+
uri.to_s
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def get_checkout_key
|
|
36
|
+
api.fetch_checkout_key(base_url, api_key)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def web_app_base_url
|
|
40
|
+
@client.web_app_base_url
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def api
|
|
44
|
+
@api ||= API.new
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Helper method to get value from either hash or struct
|
|
48
|
+
def get_value(object, key)
|
|
49
|
+
if object.respond_to?(key)
|
|
50
|
+
object.public_send(key)
|
|
51
|
+
elsif object.respond_to?(:[])
|
|
52
|
+
object[key] || object[key.to_s]
|
|
53
|
+
else
|
|
54
|
+
nil
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
data/lib/metrifox_sdk/client.rb
CHANGED
|
@@ -41,6 +41,19 @@ module MetrifoxSDK::Customers
|
|
|
41
41
|
parse_response(response, "Failed to Fetch Customer Details")
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
def customer_list_request(base_url, api_key, request_payload = {})
|
|
45
|
+
uri = URI.join(base_url, "customers")
|
|
46
|
+
|
|
47
|
+
# Build query parameters from the request payload
|
|
48
|
+
query_params = build_query_params(request_payload)
|
|
49
|
+
if query_params && !query_params.empty?
|
|
50
|
+
uri.query = URI.encode_www_form(query_params)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
response = make_request(uri, "GET", api_key)
|
|
54
|
+
parse_response(response, "Failed to Fetch Customers")
|
|
55
|
+
end
|
|
56
|
+
|
|
44
57
|
def upload_customers_csv(base_url, api_key, file_path)
|
|
45
58
|
uri = URI.join(base_url, "customers/csv-upload")
|
|
46
59
|
|
|
@@ -68,6 +81,24 @@ module MetrifoxSDK::Customers
|
|
|
68
81
|
end
|
|
69
82
|
end
|
|
70
83
|
|
|
84
|
+
# Helper method to build query parameters for list requests
|
|
85
|
+
def build_query_params(request_payload)
|
|
86
|
+
return {} unless request_payload
|
|
87
|
+
|
|
88
|
+
params = {}
|
|
89
|
+
|
|
90
|
+
# Handle pagination parameters
|
|
91
|
+
params[:page] = get_value(request_payload, :page) if get_value(request_payload, :page)
|
|
92
|
+
params[:per_page] = get_value(request_payload, :per_page) if get_value(request_payload, :per_page)
|
|
93
|
+
|
|
94
|
+
# Handle filter parameters
|
|
95
|
+
params[:search_term] = get_value(request_payload, :search_term) if get_value(request_payload, :search_term)
|
|
96
|
+
params[:customer_type] = get_value(request_payload, :customer_type) if get_value(request_payload, :customer_type)
|
|
97
|
+
params[:date_created] = get_value(request_payload, :date_created) if get_value(request_payload, :date_created)
|
|
98
|
+
|
|
99
|
+
params.compact
|
|
100
|
+
end
|
|
101
|
+
|
|
71
102
|
# Helper method to get value from either hash or struct
|
|
72
103
|
def get_value(object, key)
|
|
73
104
|
if object.respond_to?(key)
|
|
@@ -29,6 +29,11 @@ module MetrifoxSDK
|
|
|
29
29
|
api.customer_delete_request(base_url, api_key, request_payload)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
def list(request_payload = {})
|
|
33
|
+
validate_api_key!
|
|
34
|
+
api.customer_list_request(base_url, api_key, request_payload)
|
|
35
|
+
end
|
|
36
|
+
|
|
32
37
|
def upload_csv(file_path)
|
|
33
38
|
validate_api_key!
|
|
34
39
|
api.upload_customers_csv(base_url, api_key, file_path)
|
data/lib/metrifox_sdk/types.rb
CHANGED
|
@@ -44,8 +44,11 @@ module MetrifoxSDK
|
|
|
44
44
|
:carryover_quantity, :balance, keyword_init: true
|
|
45
45
|
)
|
|
46
46
|
|
|
47
|
-
UsageEventRequest = Struct.new(
|
|
48
|
-
|
|
47
|
+
UsageEventRequest = Struct.new(
|
|
48
|
+
:customer_key, :event_name, :amount, :credit_used, :event_id, :timestamp, :metadata,
|
|
49
|
+
keyword_init: true
|
|
50
|
+
) do
|
|
51
|
+
def initialize(customer_key:, event_name:, amount: 1, credit_used: nil, event_id: nil, timestamp: nil, metadata: {})
|
|
49
52
|
super
|
|
50
53
|
end
|
|
51
54
|
end
|
|
@@ -107,5 +110,6 @@ module MetrifoxSDK
|
|
|
107
110
|
APIResponse = Struct.new(:status_code, :message, :data, :errors, :meta, keyword_init: true)
|
|
108
111
|
|
|
109
112
|
EmbedConfig = Struct.new(:container, :product_key, keyword_init: true)
|
|
113
|
+
CheckoutConfig = Struct.new(:offering_key, :billing_interval, :customer_key, keyword_init: true)
|
|
110
114
|
end
|
|
111
115
|
end
|
|
@@ -29,6 +29,10 @@ module MetrifoxSDK::Usages
|
|
|
29
29
|
customer_key = get_value(request_payload, :customer_key)
|
|
30
30
|
event_name = get_value(request_payload, :event_name)
|
|
31
31
|
amount = get_value(request_payload, :amount) || 1
|
|
32
|
+
credit_used = get_value(request_payload, :credit_used)
|
|
33
|
+
event_id = get_value(request_payload, :event_id)
|
|
34
|
+
timestamp = get_value(request_payload, :timestamp)
|
|
35
|
+
metadata = get_value(request_payload, :metadata) || {}
|
|
32
36
|
|
|
33
37
|
body = {
|
|
34
38
|
customer_key: customer_key,
|
|
@@ -36,6 +40,12 @@ module MetrifoxSDK::Usages
|
|
|
36
40
|
amount: amount
|
|
37
41
|
}
|
|
38
42
|
|
|
43
|
+
# Add optional fields if present
|
|
44
|
+
body[:credit_used] = credit_used if credit_used
|
|
45
|
+
body[:event_id] = event_id if event_id && !event_id.empty?
|
|
46
|
+
body[:timestamp] = timestamp if timestamp
|
|
47
|
+
body[:metadata] = metadata if metadata
|
|
48
|
+
|
|
39
49
|
response = make_request(uri, "POST", api_key, body)
|
|
40
50
|
parse_response(response, "Failed to record usage")
|
|
41
51
|
end
|
data/lib/metrifox_sdk/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: metrifox-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Metrifox
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-10-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: json
|
|
@@ -121,6 +121,8 @@ files:
|
|
|
121
121
|
- lib/metrifox-sdk.rb
|
|
122
122
|
- lib/metrifox_sdk/base_api.rb
|
|
123
123
|
- lib/metrifox_sdk/base_module.rb
|
|
124
|
+
- lib/metrifox_sdk/checkout/api.rb
|
|
125
|
+
- lib/metrifox_sdk/checkout/module.rb
|
|
124
126
|
- lib/metrifox_sdk/client.rb
|
|
125
127
|
- lib/metrifox_sdk/customers/api.rb
|
|
126
128
|
- lib/metrifox_sdk/customers/module.rb
|