solidgate-ruby-sdk 0.1.8 → 0.1.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6805bc1e6550b6d5b4d2ead7727ec29e7d77e52f8310626675703f0011fc6e1b
4
- data.tar.gz: 52117f9e0258a8e1bdee027c83373f6022503cd18deab671605fb5169dab9013
3
+ metadata.gz: 3d961fde0b15268aa678aa14a4578f1de1ad1585d3729c4bdc75168760825bc1
4
+ data.tar.gz: bf319d42486fed3f868d17994da9041214c89daa63b02d24be45ea9afdd53ac7
5
5
  SHA512:
6
- metadata.gz: dc17597c86ca3a2c2b79032a0f637ee42661ddd6810421d24ec593b7f21c6e0fd679fb316ebac564d4559c461bf899ca86d27f1b6a8bed9e6c8dd0447ad648d2
7
- data.tar.gz: 3986537e710f2a3cbc0571cbc59f8bd74d4cfcaae5f135767ee40ce6775eb9e30abcbe07141a60e2175daef648be33ae75ac54219b6658e841e6eb19402f4fa2
6
+ metadata.gz: 02e23da68d02d2af05bc92880877f671c59c7eb55290e46bb5657207f3c8360fc19c1d31a4df8f0237e9f4fadf381270db3cec098b3ab0df80a1aa04ac21fb31
7
+ data.tar.gz: c2fa5f81f3d65fab20906c03f427fd15848962b3052801e6148871b02bfe4068547dcee3c45da97a428d905944094c208febcb9b8ffa2bb4b47e2c3aa4c0b298
data/CHANGELOG.md CHANGED
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.9] - 2026-02-03
11
+ - Added documentation for restore_subscription method
12
+ - Added restore_subscription to README.md usage examples
13
+ - Added tests for restore_subscription method
14
+
10
15
  ## [0.1.4] - 2026-01-14
11
16
  - Client Specs enhancements
12
17
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- solidgate-ruby-sdk (0.1.8)
4
+ solidgate-ruby-sdk (0.1.9)
5
5
  faraday
6
6
  faraday-multipart
7
7
 
data/README.md CHANGED
@@ -34,20 +34,35 @@ end
34
34
 
35
35
  ## Usage
36
36
 
37
- ### Creating a Payment
37
+ ### Creating a Client
38
+
39
+ ```ruby
40
+ # Using global configuration
41
+ client = Solidgate::Client.new
42
+
43
+ # Using custom configuration
44
+ client = Solidgate::Client.new(
45
+ public_key: 'your_public_key',
46
+ private_key: 'your_private_key'
47
+ )
48
+ ```
49
+
50
+ ### Payment Intent (Frontend Integration)
51
+
52
+ Generate an encrypted payment intent for use with Solidgate's JavaScript SDK:
38
53
 
39
54
  ```ruby
40
55
  SolidgateClient = Solidgate::Client.new
41
56
 
42
57
  payment_intent = {
43
- order_id: 'order_id_123', # Unique order identifier provided by the merchant
44
- product_id: 'product_id_456', # Product identifier generated in Solidgate Dashboard
45
- customer_account_id: 'customer_789', # Unique customer identifier provided by the merchant
58
+ order_id: 'order_id_123', # Unique order identifier provided by the merchant
59
+ product_id: 'product_id_456', # Product identifier generated in Solidgate Dashboard
60
+ customer_account_id: 'customer_789', # Unique customer identifier provided by the merchant
46
61
  order_description: 'Premium package',
47
- type: 'auth',
48
- settle_interval: 0, # delay in hours for automatic settlement, 0 means immediate settlement
62
+ type: 'auth', # 'auth' for authorization only, 'sale' for immediate charge
63
+ settle_interval: 0, # Delay in hours for automatic settlement, 0 means immediate
49
64
  retry_attempt: 3,
50
- language: I18n.locale # language to render the payment form
65
+ language: I18n.locale # Language to render the payment form
51
66
  }.to_json
52
67
 
53
68
  encrypted_payment_intent = client.generate_intent(payment_intent)
@@ -61,13 +76,153 @@ payment_data = {
61
76
  }
62
77
  ```
63
78
 
64
- ### Handling Webhooks
79
+ ### Payment Operations
80
+
81
+ ```ruby
82
+ client = Solidgate::Client.new
83
+
84
+ # Create a new payment
85
+ response = client.create_payment(
86
+ amount: 1000, # Amount in minor units (e.g., cents)
87
+ currency: 'USD',
88
+ order_id: 'order_123',
89
+ customer_email: 'customer@example.com'
90
+ )
91
+
92
+ # Get payment details
93
+ payment = client.get_payment('payment_id_123')
94
+
95
+ # Capture an authorized payment
96
+ client.capture_payment('payment_id_123')
97
+
98
+ # Capture with partial amount
99
+ client.capture_payment('payment_id_123', amount: 500)
100
+
101
+ # Void an authorized payment (before settlement)
102
+ client.void_payment('payment_id_123')
103
+
104
+ # Refund a captured payment
105
+ client.refund_payment('payment_id_123')
106
+
107
+ # Partial refund
108
+ client.refund_payment('payment_id_123', amount: 500, reason: 'Customer request')
109
+ ```
110
+
111
+ ### Subscription Management
112
+
113
+ ```ruby
114
+ client = Solidgate::Client.new
115
+
116
+ # Create a subscription
117
+ subscription = client.create_subscription(
118
+ product_id: 'prod_123',
119
+ customer_account_id: 'customer_456',
120
+ order_id: 'order_789'
121
+ )
122
+
123
+ # Get subscription status
124
+ status = client.subscription_status('subscription_id_123')
125
+
126
+ # Switch to a different product/plan
127
+ client.switch_subscription_product(
128
+ subscription_id: 'sub_123',
129
+ new_product_id: 'prod_premium_456'
130
+ )
131
+
132
+ # Cancel a subscription
133
+ client.cancel_subscription(
134
+ subscription_id: 'sub_123',
135
+ cancel_at_period_end: true,
136
+ reason: 'Customer requested cancellation'
137
+ )
138
+
139
+ # Restore a cancelled subscription
140
+ client.restore_subscription(
141
+ subscription_id: 'sub_123'
142
+ )
143
+ ```
144
+
145
+ ### Subscription Pause Scheduling
146
+
147
+ ```ruby
148
+ client = Solidgate::Client.new
149
+
150
+ # Create a pause schedule
151
+ client.create_subscription_pause('subscription_id_123',
152
+ pause_at: '2026-02-01T00:00:00Z',
153
+ resume_at: '2026-03-01T00:00:00Z'
154
+ )
155
+
156
+ # Update an existing pause schedule
157
+ client.update_subscription_pause('subscription_id_123',
158
+ resume_at: '2026-04-01T00:00:00Z'
159
+ )
160
+
161
+ # Delete/cancel a pending pause schedule
162
+ client.delete_subscription_pause('subscription_id_123')
163
+ ```
164
+
165
+ ### Product & Price Management
166
+
167
+ ```ruby
168
+ client = Solidgate::Client.new
169
+
170
+ # Create a product
171
+ product = client.create_product(
172
+ name: 'Premium Plan',
173
+ description: 'Access to all premium features',
174
+ type: 'subscription'
175
+ )
176
+
177
+ # Create a price for a product
178
+ price = client.create_price('product_id_123',
179
+ amount: 1999, # $19.99 in cents
180
+ currency: 'USD',
181
+ interval: 'month' # Billing interval for subscriptions
182
+ )
183
+
184
+ # List all products
185
+ all_products = client.products
186
+
187
+ # Get prices for a specific product
188
+ prices = client.product_prices('product_id_123')
189
+ ```
190
+
191
+ ### Signature Generation
192
+
193
+ Generate signatures for API authentication or custom integrations:
65
194
 
66
195
  ```ruby
67
- payload = request.body.read
68
- Solidgate::Webhook.new.validate_signature(payload, request.headers['Signature']) # returns true/false to verify the webhook
196
+ client = Solidgate::Client.new
197
+
198
+ # Generate signature with configured keys
199
+ signature = client.generate_signature(json_payload)
200
+
201
+ # Generate signature with custom keys
202
+ signature = client.generate_signature(
203
+ json_payload,
204
+ public_key: 'custom_public_key',
205
+ private_key: 'custom_private_key'
206
+ )
69
207
  ```
70
208
 
209
+ ### Handling Webhooks
210
+
211
+ ```ruby
212
+ # In your webhook controller
213
+ payload = request.body.read
214
+ signature = request.headers['Signature']
215
+
216
+ webhook = Solidgate::Webhook.new
217
+ if webhook.validate_signature(payload, signature)
218
+ # Process the webhook event
219
+ event = JSON.parse(payload)
220
+ # Handle event...
221
+ else
222
+ # Invalid signature, reject the webhook
223
+ head :unauthorized
224
+ end
225
+ ```
71
226
 
72
227
  ## Available Error Classes
73
228
 
@@ -9,130 +9,297 @@ require "openssl"
9
9
  require 'pry'
10
10
 
11
11
  module Solidgate
12
- # HTTP client for interacting with the Solidgate API
12
+ # HTTP client for interacting with the Solidgate API.
13
+ # Provides methods for payment processing, subscription management,
14
+ # product management, and payment intent generation.
15
+ #
16
+ # @example Basic usage
17
+ # client = Solidgate::Client.new
18
+ # client.create_payment(amount: 1000, currency: 'USD')
19
+ #
20
+ # @example With custom configuration
21
+ # client = Solidgate::Client.new(public_key: 'pk_xxx', private_key: 'sk_xxx')
22
+ #
13
23
  class Client
14
24
  attr_reader :config
15
25
 
26
+ # Length of initialization vector for AES encryption (in bytes)
16
27
  IV_LENGTH = 16
28
+
29
+ # Length of encryption key for AES-256 encryption (in bytes)
17
30
  KEY_LENGTH = 32
18
31
 
32
+ # Initializes a new Solidgate API client.
33
+ #
34
+ # @param options [Configuration, Hash] configuration options or a Configuration object.
35
+ # When a Hash is provided, it will be converted to a Configuration object.
36
+ # Defaults to global Solidgate.configuration.
37
+ # @raise [ConfigurationError] if required configuration is missing or invalid
38
+ #
39
+ # @example Using global configuration
40
+ # client = Solidgate::Client.new
41
+ #
42
+ # @example Using custom options
43
+ # client = Solidgate::Client.new(public_key: 'pk_xxx', private_key: 'sk_xxx')
44
+ #
19
45
  def initialize(options = Solidgate.configuration)
20
46
  @config = build_config(options)
21
47
  @config.validate!
22
48
  end
23
49
 
24
- # Create a new payment
50
+ # Creates a new payment charge.
51
+ #
52
+ # @param params [Hash] payment parameters including:
53
+ # - :amount [Integer] payment amount in minor units (e.g., cents)
54
+ # - :currency [String] three-letter ISO currency code (e.g., 'USD')
55
+ # - :order_id [String] unique order identifier
56
+ # - :customer_email [String] customer's email address
57
+ # - :card_number [String] credit card number (if applicable)
58
+ # @return [Hash] payment response containing payment ID, status, and transaction details
59
+ # @raise [InvalidRequestError] if payment parameters are invalid
60
+ # @raise [AuthenticationError] if API credentials are invalid
25
61
  #
26
- # @param params [Hash] payment parameters
27
- # @return [Hash] payment response
28
62
  def create_payment(params)
29
63
  post("/v1/charge", params)
30
64
  end
31
65
 
32
- # Get payment status
66
+ # Retrieves payment details and current status.
67
+ #
68
+ # @param payment_id [String] the unique payment identifier returned from create_payment
69
+ # @return [Hash] payment details including:
70
+ # - :id [String] payment identifier
71
+ # - :status [String] current payment status
72
+ # - :amount [Integer] payment amount
73
+ # - :currency [String] payment currency
74
+ # - :created_at [String] timestamp of payment creation
75
+ # @raise [InvalidRequestError] if payment_id is not found
33
76
  #
34
- # @param payment_id [String] payment ID
35
- # @return [Hash] payment details
36
77
  def get_payment(payment_id)
37
78
  get("/v1/charge/#{payment_id}")
38
79
  end
39
80
 
40
- # Capture a payment
81
+ # Captures a previously authorized payment.
82
+ # Use this to finalize a payment that was created with type 'auth'.
83
+ #
84
+ # @param payment_id [String] the unique payment identifier of an authorized payment
85
+ # @param params [Hash] optional capture parameters:
86
+ # - :amount [Integer] amount to capture (for partial captures), defaults to full amount
87
+ # @return [Hash] capture response with updated payment status
88
+ # @raise [InvalidRequestError] if payment cannot be captured (wrong status, already captured, etc.)
41
89
  #
42
- # @param payment_id [String] payment ID
43
- # @param params [Hash] capture parameters (optional)
44
- # @return [Hash] capture response
45
90
  def capture_payment(payment_id, params = {})
46
91
  post("/v1/charge/#{payment_id}/capture", params)
47
92
  end
48
93
 
49
- # Void a payment
94
+ # Voids a payment that has not yet been settled.
95
+ # Voiding cancels the authorization and releases the hold on customer funds.
96
+ #
97
+ # @param payment_id [String] the unique payment identifier of an authorized (unsettled) payment
98
+ # @return [Hash] void response with updated payment status
99
+ # @raise [InvalidRequestError] if payment cannot be voided (already settled, already voided, etc.)
50
100
  #
51
- # @param payment_id [String] payment ID
52
- # @return [Hash] void response
53
101
  def void_payment(payment_id)
54
102
  post("/v1/charge/#{payment_id}/void")
55
103
  end
56
104
 
57
- # Refund a payment
105
+ # Refunds a captured/settled payment.
106
+ # Supports both full and partial refunds.
107
+ #
108
+ # @param payment_id [String] the unique payment identifier of a captured payment
109
+ # @param params [Hash] optional refund parameters:
110
+ # - :amount [Integer] refund amount in minor units (for partial refunds)
111
+ # - :reason [String] reason for the refund
112
+ # @return [Hash] refund response including refund ID and status
113
+ # @raise [InvalidRequestError] if payment cannot be refunded
58
114
  #
59
- # @param payment_id [String] payment ID
60
- # @param params [Hash] refund parameters
61
- # @return [Hash] refund response
62
115
  def refund_payment(payment_id, params = {})
63
116
  post("/v1/charge/#{payment_id}/refund", params)
64
117
  end
65
118
 
66
- # Settle a payment
119
+ # Settles a payment for final processing.
120
+ # Note: This method appears to have a bug and returns config.api_url instead of making an API call.
67
121
  #
68
122
  # @param params [Hash] settlement parameters
69
- # @return [Hash] settlement response
123
+ # @return [String] currently returns the API URL (likely unintended behavior)
124
+ # @todo Fix this method to properly call the settlement endpoint
125
+ #
70
126
  def settle_payment(params = {})
71
127
  conifg.api_url
72
128
  end
73
129
 
74
- # Create a subscription
130
+ # Creates a new recurring subscription.
131
+ #
132
+ # @param params [Hash] subscription parameters including:
133
+ # - :product_id [String] Solidgate product identifier
134
+ # - :customer_account_id [String] unique customer identifier
135
+ # - :order_id [String] unique order identifier
136
+ # - :payment_method [Hash] payment method details
137
+ # @return [Hash] subscription response including subscription ID and status
138
+ # @raise [InvalidRequestError] if subscription parameters are invalid
75
139
  #
76
- # @param params [Hash] subscription parameters
77
- # @return [Hash] subscription response
78
140
  def create_subscription(params)
79
141
  post("/v1/subscription", params)
80
142
  end
81
143
 
82
- # Get subscription details
144
+ # Retrieves the current status and details of a subscription.
145
+ #
146
+ # @param subscription_id [String] the unique subscription identifier
147
+ # @return [Hash] subscription details including:
148
+ # - :id [String] subscription identifier
149
+ # - :status [String] current subscription status (active, paused, cancelled, etc.)
150
+ # - :current_period_start [String] start of current billing period
151
+ # - :current_period_end [String] end of current billing period
152
+ # @raise [InvalidRequestError] if subscription_id is not found
83
153
  #
84
- # @param subscription_id [String] subscription ID
85
- # @return [Hash] subscription details
86
154
  def subscription_status(subscription_id)
87
155
  post("/api/v1/subscription/status", { subscription_id: subscription_id })
88
156
  end
89
157
 
90
- # Update subscription product
158
+ # Switches a subscription to a different product/plan.
159
+ # Use this for upgrades, downgrades, or plan changes.
160
+ #
161
+ # @param params [Hash] subscription update parameters:
162
+ # - :subscription_id [String] the subscription to update
163
+ # - :new_product_id [String] Solidgate product ID to switch to
164
+ # @return [Hash] update response with new subscription details
165
+ # @raise [InvalidRequestError] if subscription or product is invalid
166
+ #
167
+ # @example Upgrade a subscription
168
+ # client.switch_subscription_product(
169
+ # subscription_id: 'sub_12345',
170
+ # new_product_id: 'prod_premium_67890'
171
+ # )
91
172
  #
92
- # @param params [Hash] subscription update parameters
93
- # @return [Hash] update response
94
- # params = { subscription_id: "sub_12345", new_product_id: "prod_67890" }
95
- # new product_id is the Solidgate ID of the product to switch to
96
173
  def switch_subscription_product(params)
97
174
  post("/api/v1/subscription/switch-subscription-product", params)
98
175
  end
99
176
 
177
+ # Updates an existing pause schedule for a subscription.
178
+ #
179
+ # @param subscription_id [String] the unique subscription identifier
180
+ # @param params [Hash] pause schedule update parameters:
181
+ # - :pause_at [String] new date/time to pause the subscription
182
+ # - :resume_at [String] new date/time to resume the subscription
183
+ # @return [Hash] updated pause schedule details
184
+ # @raise [InvalidRequestError] if subscription has no pause schedule or params are invalid
185
+ #
100
186
  def update_subscription_pause(subscription_id, params)
101
187
  patch("/api/v1/subscriptions/#{subscription_id}/pause-schedule", params)
102
188
  end
103
189
 
190
+ # Creates a pause schedule for a subscription.
191
+ # The subscription will be paused and resumed at the specified times.
192
+ #
193
+ # @param subscription_id [String] the unique subscription identifier
194
+ # @param params [Hash] pause schedule parameters:
195
+ # - :pause_at [String] date/time to pause the subscription
196
+ # - :resume_at [String] date/time to resume the subscription
197
+ # @return [Hash] created pause schedule details
198
+ # @raise [InvalidRequestError] if subscription is invalid or already has a pause schedule
199
+ #
104
200
  def create_subscription_pause(subscription_id, params)
105
201
  post("/api/v1/subscriptions/#{subscription_id}/pause-schedule", params)
106
202
  end
107
203
 
204
+ # Deletes/cancels a pending pause schedule for a subscription.
205
+ #
206
+ # @param subscription_id [String] the unique subscription identifier
207
+ # @return [Hash] confirmation of pause schedule deletion
208
+ # @raise [InvalidRequestError] if subscription has no pause schedule
209
+ #
108
210
  def delete_subscription_pause(subscription_id)
109
211
  delete("/api/v1/subscriptions/#{subscription_id}/pause-schedule")
110
212
  end
111
213
 
214
+ # Cancels an active subscription.
215
+ #
216
+ # @param params [Hash] cancellation parameters:
217
+ # - :subscription_id [String] the subscription to cancel
218
+ # - :cancel_at_period_end [Boolean] if true, cancel at end of current period
219
+ # - :reason [String] optional cancellation reason
220
+ # @return [Hash] cancelled subscription details
221
+ # @raise [InvalidRequestError] if subscription is invalid or already cancelled
222
+ #
112
223
  def cancel_subscription(params)
113
224
  post("/api/v1/subscription/cancel", params)
114
225
  end
115
226
 
227
+ # Creates a new product in the Solidgate catalog.
228
+ #
229
+ # @param params [Hash] product parameters:
230
+ # - :name [String] product name
231
+ # - :description [String] product description
232
+ # - :type [String] product type (e.g., 'subscription', 'one_time')
233
+ # @return [Hash] created product details including product_id
234
+ # @raise [InvalidRequestError] if product parameters are invalid
235
+ #
116
236
  def create_product(params)
117
237
  post("/api/v1/products", params)
118
238
  end
119
239
 
240
+ # Creates a new price for an existing product.
241
+ #
242
+ # @param product_id [String] the product to add pricing to
243
+ # @param params [Hash] price parameters:
244
+ # - :amount [Integer] price amount in minor units
245
+ # - :currency [String] three-letter ISO currency code
246
+ # - :interval [String] billing interval for subscriptions (e.g., 'month', 'year')
247
+ # @return [Hash] created price details including price_id
248
+ # @raise [InvalidRequestError] if product_id is invalid or price params are invalid
249
+ #
120
250
  def create_price(product_id, params)
121
251
  post("/api/v1/products/#{product_id}/prices", params)
122
252
  end
123
253
 
254
+ # Retrieves all products from the Solidgate catalog.
255
+ #
256
+ # @return [Hash] list of all products with their details
257
+ #
124
258
  def products
125
259
  get("/api/v1/products")
126
260
  end
127
261
 
262
+ # Retrieves all prices for a specific product.
263
+ #
264
+ # @param product_id [String] the product to retrieve prices for
265
+ # @return [Hash] list of prices associated with the product
266
+ # @raise [InvalidRequestError] if product_id is not found
267
+ #
128
268
  def product_prices(product_id)
129
269
  get("/api/v1/products/#{product_id}/prices")
130
270
  end
131
271
 
272
+ # Generates an encrypted payment intent for client-side payment form rendering.
273
+ # The encrypted intent is used with Solidgate's JavaScript SDK to securely
274
+ # initialize payment forms without exposing sensitive data.
275
+ #
276
+ # @param params [String] JSON string containing payment intent parameters:
277
+ # - order_id: unique order identifier
278
+ # - product_id: Solidgate product identifier
279
+ # - customer_account_id: unique customer identifier
280
+ # - order_description: description of the order
281
+ # - type: payment type ('auth' or 'sale')
282
+ # @return [String] Base64-encoded encrypted payment intent
283
+ #
284
+ # @example Generate payment intent for frontend
285
+ # intent_params = { order_id: 'ord_123', product_id: 'prod_456' }.to_json
286
+ # encrypted_intent = client.generate_intent(intent_params)
287
+ #
132
288
  def generate_intent(params)
133
289
  encrypt_payload(params)
134
290
  end
135
291
 
292
+ # Generates an HMAC-SHA512 signature for API request authentication.
293
+ # The signature is required for all API requests and webhook validation.
294
+ #
295
+ # @param json_string [String] the JSON payload to sign
296
+ # @param public_key [String] merchant public key (defaults to configured public_key)
297
+ # @param private_key [String] merchant private key (defaults to configured private_key)
298
+ # @return [String] Base64-encoded HMAC-SHA512 signature
299
+ #
300
+ # @example Generate signature for a payment intent
301
+ # signature = client.generate_signature(encrypted_intent)
302
+ #
136
303
  def generate_signature(json_string, public_key: config.public_key, private_key: config.private_key)
137
304
  digest = OpenSSL::Digest.new('sha512')
138
305
  instance = OpenSSL::HMAC.new(private_key, digest)
@@ -140,8 +307,31 @@ module Solidgate
140
307
  Base64.strict_encode64(instance.hexdigest)
141
308
  end
142
309
 
310
+ # Restores a previously cancelled subscription.
311
+ # Use this to reactivate a subscription that was cancelled but is still within
312
+ # the restoration period.
313
+ #
314
+ # @param params [Hash] restoration parameters:
315
+ # - :subscription_id [String] the subscription identifier to restore
316
+ # @return [Hash] restored subscription details including:
317
+ # - :id [String] subscription identifier
318
+ # - :status [String] new subscription status (typically 'active')
319
+ # @raise [InvalidRequestError] if subscription cannot be restored (expired, already active, etc.)
320
+ #
321
+ # @example Restore a cancelled subscription
322
+ # client.restore_subscription(subscription_id: 'sub_12345')
323
+ #
324
+ def restore_subscription(params)
325
+ post("/api/v1/subscription/restore", params)
326
+ end
327
+
143
328
  private
144
329
 
330
+ # Builds a Configuration object from the provided options.
331
+ #
332
+ # @param options [Configuration, Hash] configuration options
333
+ # @return [Configuration] the configuration object
334
+ #
145
335
  def build_config(options)
146
336
  if options.is_a?(Configuration)
147
337
  options
@@ -152,6 +342,10 @@ module Solidgate
152
342
  end
153
343
  end
154
344
 
345
+ # Creates and caches a Faraday HTTP connection.
346
+ #
347
+ # @return [Faraday::Connection] configured HTTP connection
348
+ #
155
349
  def connection
156
350
  @connection ||= Faraday.new(
157
351
  url: config.api_url,
@@ -167,6 +361,10 @@ module Solidgate
167
361
  end
168
362
  end
169
363
 
364
+ # Returns default HTTP headers for API requests.
365
+ #
366
+ # @return [Hash] default headers including Accept, Content-Type, and User-Agent
367
+ #
170
368
  def default_headers
171
369
  {
172
370
  "Accept" => "application/json",
@@ -175,22 +373,54 @@ module Solidgate
175
373
  }
176
374
  end
177
375
 
376
+ # Performs a GET request to the specified path.
377
+ #
378
+ # @param path [String] API endpoint path
379
+ # @return [Hash] parsed response body
380
+ #
178
381
  def get(path)
179
382
  request(:get, path)
180
383
  end
181
384
 
385
+ # Performs a POST request to the specified path.
386
+ #
387
+ # @param path [String] API endpoint path
388
+ # @param body [Hash] request body parameters
389
+ # @return [Hash] parsed response body
390
+ #
182
391
  def post(path, body = {})
183
392
  request(:post, path, body)
184
393
  end
185
394
 
395
+ # Performs a PATCH request to the specified path.
396
+ #
397
+ # @param path [String] API endpoint path
398
+ # @param body [Hash] request body parameters
399
+ # @return [Hash] parsed response body
400
+ #
186
401
  def patch(path, body = {})
187
402
  request(:patch, path, body)
188
403
  end
189
404
 
405
+ # Performs a DELETE request to the specified path.
406
+ #
407
+ # @param path [String] API endpoint path
408
+ # @return [Hash] parsed response body
409
+ #
190
410
  def delete(path)
191
411
  request(:delete, path)
192
412
  end
193
413
 
414
+ # Performs an HTTP request with authentication and signature.
415
+ #
416
+ # @param method [Symbol] HTTP method (:get, :post, :patch, :delete)
417
+ # @param path [String] API endpoint path
418
+ # @param body [Hash, nil] optional request body
419
+ # @return [Hash] parsed response body
420
+ # @raise [TimeoutError] if request times out
421
+ # @raise [ConnectionError] if connection fails
422
+ # @raise [Error] for other unexpected errors
423
+ #
194
424
  def request(method, path, body = nil)
195
425
  body_json = body ? JSON.generate(body) : ''
196
426
  signature = generate_signature(body_json)
@@ -211,6 +441,15 @@ module Solidgate
211
441
  raise Error, "Unexpected error: #{e.message}"
212
442
  end
213
443
 
444
+ # Handles HTTP response and raises appropriate errors for non-success statuses.
445
+ #
446
+ # @param response [Faraday::Response] the HTTP response object
447
+ # @return [Hash] parsed response body for successful requests
448
+ # @raise [InvalidRequestError] for 400 status
449
+ # @raise [AuthenticationError] for 401 status
450
+ # @raise [RateLimitError] for 429 status
451
+ # @raise [APIError] for 5xx statuses and unknown errors
452
+ #
214
453
  def handle_response(response)
215
454
  case response.status
216
455
  when 200..299
@@ -253,6 +492,11 @@ module Solidgate
253
492
  end
254
493
  end
255
494
 
495
+ # Extracts error message from API error response.
496
+ #
497
+ # @param response [Faraday::Response] the HTTP response object
498
+ # @return [String] error message or "Unknown error" if not found
499
+ #
256
500
  def extract_error_message(response)
257
501
  return "Unknown error" unless response.body.is_a?(Hash)
258
502
 
@@ -261,6 +505,11 @@ module Solidgate
261
505
  "Unknown error"
262
506
  end
263
507
 
508
+ # Extracts error code from API error response.
509
+ #
510
+ # @param response [Faraday::Response] the HTTP response object
511
+ # @return [String, nil] error code or nil if not found
512
+ #
264
513
  def extract_error_code(response)
265
514
  return nil unless response.body.is_a?(Hash)
266
515
 
@@ -269,6 +518,12 @@ module Solidgate
269
518
  nil
270
519
  end
271
520
 
521
+ # Encrypts payload using AES-256-CBC encryption for secure transmission.
522
+ # Uses the first 32 characters of the private key as the encryption key.
523
+ #
524
+ # @param attributes [String] JSON string to encrypt
525
+ # @return [String] URL-safe Base64-encoded encrypted payload (IV prepended)
526
+ #
272
527
  def encrypt_payload(attributes)
273
528
  key = config.private_key[0, KEY_LENGTH]
274
529
  iv = OpenSSL::Random.random_bytes(IV_LENGTH)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solidgate
4
- VERSION = "0.1.8"
4
+ VERSION = "0.1.9"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solidgate-ruby-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hector Carrillo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-01-30 00:00:00.000000000 Z
11
+ date: 2026-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday