inttegro 4.2.2 → 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 898d14cfaa38b878c20565b4522fe67d87147f01850656bf5a7817da99c955a2
4
- data.tar.gz: 32a2dc36592ebdfa52c4076687d7b5c4512ac887de57285fccb843815a0e64e7
3
+ metadata.gz: 86ef8bd75f65151aa6cd1f7d17702bfc1ba9eac446fe8d19196437e50904f561
4
+ data.tar.gz: e7a15368c96ded7010ccac121a70e8ae57df64503ff0fa470f754217c96efd12
5
5
  SHA512:
6
- metadata.gz: 5c3dff6b6e94712d541d1c4aabe3ee49227cd35ce1d4decc7656eff992be17ad0fec34177b5e7e3fd84514e0e79558f7ee552bb889f025cacb77b69381d9fbc2
7
- data.tar.gz: f55e5ed4ea3703b3ef98042add688bb97224dfcebe5c102455544a9984745bf7d855aa8bd3ae30f9971c3de2af1ecac68f11f5ebadafec2a4212c2b933c68ba1
6
+ metadata.gz: 64cafa969f9cd2019e88eb3e2d471bf62915bee400a4f8ce5e1ac5ca5347204eb4ce975c345ae017fd5c5be2bb7152c4be6f70e46826ddc4d46290a08dc66a5e
7
+ data.tar.gz: feb309c70b5ae2c7bf59633df20d79dc51cde49d3c7a6bf69132f3685e7d81721eed0d13a5a3465243a2afac6779dc5fd6f33654eac22ac22937588dd7a3919b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [4.3.1] - 2026-09-08
4
+
5
+ - Tightened financial-account and payment-method response models to exclude internal platform fields.
6
+
7
+ ## [4.3.0] - 2026-09-06
8
+
9
+ - Added opt-in, typed error reporting to application-owned collectors with privacy-safe payloads, stable fingerprints, isolated reporter failures, and no reporting work when unconfigured.
10
+
3
11
  ## [4.2.2] - 2026-09-04
4
12
 
5
13
  - Constrained OpenTelemetry dependencies to releases that preserve the SDK's Ruby 3.0 runtime support, while declaring `logger` for Ruby 4 compatibility.
data/README.md CHANGED
@@ -4,6 +4,8 @@
4
4
 
5
5
  The official Ruby client for building server-side Inttegro integrations.
6
6
 
7
+ [API documentation](https://ruby.inttegro.dev/) · [Integration guides](https://studio.inttegro.com/sdks/ruby)
8
+
7
9
  > **Fastest, most modern path:** connect an agent to [Inttegro MCP](https://studio.inttegro.com/inttegro-mcp) at `https://mcp.inttegro.com`, then ask it to run `design_integration`. It will produce an implementation and test plan for your application. Use this SDK when you are ready to connect that plan to your Ruby service.
8
10
 
9
11
  All official Inttegro SDKs expose the same API capabilities. This gem adds strict Sorbet types and Ruby-native resource methods.
@@ -87,6 +89,21 @@ inttegro = Inttegro::Client.new(api_key: ENV.fetch("INTTEGRO_API_KEY"))
87
89
 
88
90
  Spans are named after logical operations such as `inttegro.orders.create`. HTTP attempts, response receipt, and decoding are span events. API keys, bodies, resource IDs, dynamic URLs, and exception messages are never recorded. See [SDK observability](https://studio.inttegro.com/sdk-observability) for the complete contract and set `telemetry_enabled: false` when needed.
89
91
 
92
+ ### Report SDK failures
93
+
94
+ Provide an application-owned reporter to receive one immutable, typed, privacy-safe report after an SDK operation finally fails. The default `:unexpected` policy reports transport, timeout, decoding, SDK, `unknown_error`, and server-side failures while leaving normal 4xx API errors alone:
95
+
96
+ ```ruby
97
+ inttegro = Inttegro::Client.new(
98
+ api_key: ENV.fetch("INTTEGRO_API_KEY"),
99
+ error_reporter: ->(report) { ErrorCollector.enqueue(report.serialize) }
100
+ )
101
+ ```
102
+
103
+ Use `error_reporting_policy: :all` to include expected API failures; cancellations are never reported. Reports contain the logical operation, static route, server host, status and request IDs when available, duration, safe API error codes, SDK identity, stable fingerprint, exception type, and trace IDs when tracing is active. They exclude credentials, headers, bodies, resource IDs, dynamic URLs, exception messages, and stack traces. Reporter failures are isolated and the original SDK error is still raised.
104
+
105
+ Error reporting is completely opt-in. Without `error_reporter`, the SDK does not calculate report metadata, create an event ID or timestamp, allocate a report, or serialize a payload.
106
+
90
107
  ## Work with the API
91
108
 
92
109
  The SDK covers orders and checkout, customers, products and prices, purchase intents, payment methods, balances, payouts and refunds, notifications, files, application settings, keys, and country specifications. Resources use snake-case readers such as `purchase_intents` and `payment_methods`.
data/Rakefile CHANGED
@@ -6,9 +6,22 @@ require "minitest/test_task"
6
6
  Minitest::TestTask.create
7
7
 
8
8
  require "rubocop/rake_task"
9
+ require "yard"
10
+ require "yard/rake/yardoc_task"
9
11
 
10
12
  RuboCop::RakeTask.new
11
13
 
14
+ YARD::Rake::YardocTask.new(:docs) do |task|
15
+ task.files = ["lib/**/*.rb"]
16
+ task.options = [
17
+ "--no-private",
18
+ "--protected",
19
+ "--readme", "README.md",
20
+ "--title", "Inttegro Ruby SDK",
21
+ "--output-dir", "build/api-docs"
22
+ ]
23
+ end
24
+
12
25
  namespace :rbi do
13
26
  desc "Regenerate Sorbet declarations for models, enums, and resources"
14
27
  task :generate do
@@ -111,7 +111,9 @@ module Inttegro
111
111
  open_timeout: T.nilable(Numeric),
112
112
  adapter: T.nilable(Types::Adapter),
113
113
  telemetry_enabled: T::Boolean,
114
- tracer_provider: T.nilable(OpenTelemetry::Trace::TracerProvider)
114
+ tracer_provider: T.nilable(OpenTelemetry::Trace::TracerProvider),
115
+ error_reporter: T.nilable(ErrorReporter),
116
+ error_reporting_policy: Symbol
115
117
  ).void
116
118
  end
117
119
  def initialize(
@@ -123,7 +125,9 @@ module Inttegro
123
125
  open_timeout: 10,
124
126
  adapter: nil,
125
127
  telemetry_enabled: true,
126
- tracer_provider: nil
128
+ tracer_provider: nil,
129
+ error_reporter: nil,
130
+ error_reporting_policy: :unexpected
127
131
  )
128
132
  provided_token = token || token_value
129
133
  api_key ||= provided_token
@@ -134,7 +138,9 @@ module Inttegro
134
138
  open_timeout: open_timeout,
135
139
  adapter: adapter,
136
140
  telemetry_enabled: telemetry_enabled,
137
- tracer_provider: tracer_provider
141
+ tracer_provider: tracer_provider,
142
+ error_reporter: error_reporter,
143
+ error_reporting_policy: error_reporting_policy
138
144
  ), HTTPClient)
139
145
 
140
146
  @orders = T.let(Resources::Orders.new(@http), Resources::Orders)
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ require "sorbet-runtime"
5
+
6
+ module Inttegro
7
+ # SDK identity included in an ErrorReport.
8
+ class SDKReportContext < T::Struct
9
+ const :language, String
10
+ const :version, String
11
+ end
12
+
13
+ # Bounded HTTP metadata included in an ErrorReport.
14
+ class HTTPReportContext < T::Struct
15
+ const :request_method, String
16
+ const :server_address, String
17
+ const :duration_ms, Integer
18
+ const :route, T.nilable(String), default: nil
19
+ const :status_code, T.nilable(Integer), default: nil
20
+ const :request_id, T.nilable(String), default: nil
21
+ end
22
+
23
+ # Machine-readable API error metadata included in an ErrorReport.
24
+ class APIErrorReportContext < T::Struct
25
+ const :type, T.nilable(String), default: nil
26
+ const :code, T.nilable(String), default: nil
27
+ const :fix_code, T.nilable(String), default: nil
28
+ end
29
+
30
+ # Trace identifiers included when application tracing is enabled.
31
+ class TraceReportContext < T::Struct
32
+ const :trace_id, String
33
+ const :span_id, String
34
+ end
35
+
36
+ # Privacy-safe description of a failed Inttegro SDK operation.
37
+ class ErrorReport < T::Struct
38
+ const :schema_version, Integer
39
+ const :event_id, String
40
+ const :occurred_at, String
41
+ const :severity, String
42
+ const :category, String
43
+ const :operation, String
44
+ const :sdk, SDKReportContext
45
+ const :http, HTTPReportContext
46
+ const :exception_type, String
47
+ const :fingerprint, String
48
+ const :api_error, T.nilable(APIErrorReportContext), default: nil
49
+ const :trace, T.nilable(TraceReportContext), default: nil
50
+ end
51
+
52
+ ErrorReporter = T.type_alias { T.proc.params(report: ErrorReport).void }
53
+ end
@@ -4,9 +4,21 @@
4
4
  require "sorbet-runtime"
5
5
 
6
6
  require_relative "types"
7
+ require_relative "error_reporting"
7
8
 
8
9
  module Inttegro
9
- class Error < StandardError; end
10
+ class Error < StandardError
11
+ extend T::Sig
12
+
13
+ sig { returns(T.nilable(ErrorReport)) }
14
+ attr_accessor :report
15
+
16
+ sig { params(message: String).void }
17
+ def initialize(message)
18
+ super(message)
19
+ @report = T.let(nil, T.nilable(ErrorReport))
20
+ end
21
+ end
10
22
 
11
23
  class NetworkError < Error
12
24
  extend T::Sig
@@ -30,7 +42,7 @@ module Inttegro
30
42
  attr_reader :status
31
43
 
32
44
  sig { returns(T.nilable(String)) }
33
- attr_reader :code, :type, :url, :detail, :fix_code, :cause, :body
45
+ attr_reader :code, :type, :url, :detail, :fix_code, :cause, :body, :request_id
34
46
 
35
47
  sig { returns(Types::WireValue) }
36
48
  attr_reader :data
@@ -46,7 +58,8 @@ module Inttegro
46
58
  fix_code: T.nilable(String),
47
59
  cause: T.nilable(String),
48
60
  body: T.nilable(String),
49
- data: Types::WireValue
61
+ data: Types::WireValue,
62
+ request_id: T.nilable(String)
50
63
  ).void
51
64
  end
52
65
  def initialize(
@@ -59,7 +72,8 @@ module Inttegro
59
72
  fix_code: nil,
60
73
  cause: nil,
61
74
  body: nil,
62
- data: nil
75
+ data: nil,
76
+ request_id: nil
63
77
  )
64
78
  super(message)
65
79
  @status = status
@@ -71,6 +85,7 @@ module Inttegro
71
85
  @cause = cause
72
86
  @body = body
73
87
  @data = data
88
+ @request_id = request_id
74
89
  end
75
90
  end
76
91
 
@@ -94,7 +109,8 @@ module Inttegro
94
109
  cause: T.nilable(String),
95
110
  body: T.nilable(String),
96
111
  data: Types::WireValue,
97
- retry_after: T.nilable(Integer)
112
+ retry_after: T.nilable(Integer),
113
+ request_id: T.nilable(String)
98
114
  ).void
99
115
  end
100
116
  def initialize(
@@ -108,7 +124,8 @@ module Inttegro
108
124
  cause: nil,
109
125
  body: nil,
110
126
  data: nil,
111
- retry_after: nil
127
+ retry_after: nil,
128
+ request_id: nil
112
129
  )
113
130
  super(
114
131
  message,
@@ -120,7 +137,8 @@ module Inttegro
120
137
  fix_code: fix_code,
121
138
  cause: cause,
122
139
  body: body,
123
- data: data
140
+ data: data,
141
+ request_id: request_id
124
142
  )
125
143
  @retry_after = retry_after
126
144
  end
@@ -64,8 +64,6 @@ module Inttegro
64
64
 
65
65
  class PaymentMethod < T::Struct
66
66
  const :active, T::Boolean
67
- const :app_customer_local_fingerprint, T.nilable(String), default: nil
68
- const :app_local_fingerprint, T.nilable(String), default: nil
69
67
  const :archived_at, T.nilable(String), default: nil
70
68
  const :bank_account, T.nilable(Inttegro::PaymentMethodBankAccount), default: nil
71
69
  const :created_at, String
@@ -78,7 +76,6 @@ module Inttegro
78
76
  const :owner, T.nilable(Inttegro::PaymentMethodOwner), default: nil
79
77
  const :type, Inttegro::PaymentMethodType
80
78
  const :supplied, T.nilable(Inttegro::PaymentMethodSupplied), default: nil
81
- const :universal_fingerprint, T.nilable(String), default: nil
82
79
  const :verification, T.nilable(Inttegro::PaymentMethodVerification), default: nil
83
80
  const :verified_at, T.nilable(String), default: nil
84
81
  end
@@ -250,12 +247,8 @@ module Inttegro
250
247
  const :reserved, Inttegro::CurrencyBalanceSnapshotReserved
251
248
  end
252
249
 
253
- class BalanceSnapshotBalances < T::Struct
254
- const :ghs, Inttegro::CurrencyBalanceSnapshot
255
- end
256
-
257
250
  class BalanceSnapshot < T::Struct
258
- const :balances, Inttegro::BalanceSnapshotBalances
251
+ const :balances, T::Hash[String, Inttegro::CurrencyBalanceSnapshot]
259
252
  end
260
253
 
261
254
  class BalanceTransactionAmount < T::Struct
@@ -642,7 +635,7 @@ module Inttegro
642
635
 
643
636
  class InlineProductDetails < T::Struct
644
637
  const :about, T.nilable(String), default: nil
645
- const :custom_data, T.nilable(T::Hash[String, Object]), default: nil
638
+ const :custom_data, T.nilable(T::Hash[String, String]), default: nil
646
639
  const :name, String
647
640
  const :price, Inttegro::PriceParams
648
641
  const :quantity, Integer
@@ -663,7 +656,7 @@ module Inttegro
663
656
  const :label, T.nilable(String), default: nil
664
657
  const :tax_code, T.nilable(String), default: nil
665
658
  const :description, T.nilable(String), default: nil
666
- const :custom_data, T.nilable(T::Hash[String, Object]), default: nil
659
+ const :custom_data, T.nilable(T::Hash[String, String]), default: nil
667
660
  const :amount, Inttegro::AmountParams
668
661
  end
669
662
 
@@ -675,7 +668,7 @@ module Inttegro
675
668
  class ShippingDetails < T::Struct
676
669
  const :id, T.nilable(String), default: nil
677
670
  const :tax_code, T.nilable(String), default: nil
678
- const :custom_data, T.nilable(T::Hash[String, Object]), default: nil
671
+ const :custom_data, T.nilable(T::Hash[String, String]), default: nil
679
672
  const :fee, Inttegro::AmountParams
680
673
  end
681
674
 
@@ -1114,10 +1107,6 @@ module Inttegro
1114
1107
  const :status, T.nilable(String), default: nil
1115
1108
  end
1116
1109
 
1117
- class PaymentNextActionExecute < T::Struct
1118
- # This object intentionally has no fields.
1119
- end
1120
-
1121
1110
  class PaymentNextActionRedirectLatestVisit < T::Struct
1122
1111
  const :user_agent, T.nilable(String), default: nil
1123
1112
  const :ip_address, T.nilable(String), default: nil
@@ -1139,7 +1128,7 @@ module Inttegro
1139
1128
  class PaymentNextAction < T::Struct
1140
1129
  const :type, Inttegro::PaymentNextActionType
1141
1130
  const :confirm_payment, T.nilable(Inttegro::PaymentNextActionConfirmPayment), default: nil
1142
- const :execute, T.nilable(Inttegro::PaymentNextActionExecute), default: nil
1131
+ const :execute, T.nilable(T::Hash[String, Object]), default: nil
1143
1132
  const :redirect, T.nilable(Inttegro::PaymentNextActionRedirect), default: nil
1144
1133
  const :authorize, T.nilable(Inttegro::PaymentNextActionAuthorize), default: nil
1145
1134
  end
@@ -1174,12 +1163,17 @@ module Inttegro
1174
1163
  const :payout_configuration, T.nilable(Inttegro::PaymentPayoutConfiguration), default: nil
1175
1164
  end
1176
1165
 
1177
- class OrderPayoutSettings < T::Struct
1178
- # This object intentionally has no fields.
1166
+ class OrderPayoutSettingsRequestDestination < T::Struct
1167
+ const :financial_account_id, String
1179
1168
  end
1180
1169
 
1181
- class OrderShipping < T::Struct
1182
- # This object intentionally has no fields.
1170
+ class OrderPayoutSettingsRequest < T::Struct
1171
+ const :destination, T.nilable(Inttegro::OrderPayoutSettingsRequestDestination), default: nil
1172
+ const :enable_fx, T.nilable(T::Boolean), default: nil
1173
+ end
1174
+
1175
+ class Shipping < T::Struct
1176
+ const :address, Inttegro::Address
1183
1177
  end
1184
1178
 
1185
1179
  class Order < T::Struct
@@ -1203,9 +1197,9 @@ module Inttegro
1203
1197
  const :payment, T.nilable(Inttegro::Payment), default: nil
1204
1198
  const :paid_at, T.nilable(String), default: nil
1205
1199
  const :payment_due_at, T.nilable(String), default: nil
1206
- const :payout_settings, T.nilable(Inttegro::OrderPayoutSettings), default: nil
1200
+ const :payout_settings, T.nilable(Inttegro::OrderPayoutSettingsRequest), default: nil
1207
1201
  const :reference, T.nilable(String), default: nil
1208
- const :shipping, T.nilable(Inttegro::OrderShipping), default: nil
1202
+ const :shipping, T.nilable(Inttegro::Shipping), default: nil
1209
1203
  end
1210
1204
 
1211
1205
  class CompleteOrderEnvelope < T::Struct
@@ -1251,7 +1245,7 @@ module Inttegro
1251
1245
  const :type, String
1252
1246
  end
1253
1247
 
1254
- class FinancialAccountPullConfigurationMandate < T::Struct
1248
+ class FinancialAccountMandate < T::Struct
1255
1249
  const :created_at, String
1256
1250
  const :id, String
1257
1251
  const :ip_address, String
@@ -1260,7 +1254,7 @@ module Inttegro
1260
1254
 
1261
1255
  class FinancialAccountPullConfiguration < T::Struct
1262
1256
  const :enabled_at, String
1263
- const :mandate, Inttegro::FinancialAccountPullConfigurationMandate
1257
+ const :mandate, Inttegro::FinancialAccountMandate
1264
1258
  end
1265
1259
 
1266
1260
  class FinancialAccountPushConfiguration < T::Struct
@@ -1276,8 +1270,16 @@ module Inttegro
1276
1270
  const :supplied_at, String
1277
1271
  end
1278
1272
 
1279
- class FinancialAccountDetailsVerification < T::Struct
1280
- # This object intentionally has no fields.
1273
+ class FinancialAccountVerificationRequest < T::Struct
1274
+ const :id, T.nilable(String), default: nil
1275
+ const :mechanism, T.nilable(String), default: nil
1276
+ const :type, T.nilable(String), default: nil
1277
+ end
1278
+
1279
+ class FinancialAccountVerification < T::Struct
1280
+ const :initiated_at, String
1281
+ const :completed_at, T.nilable(String), default: nil
1282
+ const :request, Inttegro::FinancialAccountVerificationRequest
1281
1283
  end
1282
1284
 
1283
1285
  class FinancialAccountAddress < T::Struct
@@ -1310,7 +1312,7 @@ module Inttegro
1310
1312
  const :ghana_bank_account, T.nilable(Inttegro::GhanaBankAccount), default: nil
1311
1313
  end
1312
1314
 
1313
- class ConnectedFinancialAccountDoshAccount < T::Struct
1315
+ class DoshAccount < T::Struct
1314
1316
  # This object intentionally has no fields.
1315
1317
  end
1316
1318
 
@@ -1326,8 +1328,6 @@ module Inttegro
1326
1328
  end
1327
1329
 
1328
1330
  class ConnectedFinancialAccount < T::Struct
1329
- const :app_customer_local_fingerprint, T.nilable(String), default: nil
1330
- const :app_local_fingerprint, T.nilable(String), default: nil
1331
1331
  const :archived_at, T.nilable(String), default: nil
1332
1332
  const :created_at, String
1333
1333
  const :currency, String
@@ -1341,10 +1341,9 @@ module Inttegro
1341
1341
  const :reference, T.nilable(String), default: nil
1342
1342
  const :supplied, T.nilable(Inttegro::ResourceSupply), default: nil
1343
1343
  const :type, Inttegro::FinancialAccountType
1344
- const :universal_fingerprint, T.nilable(String), default: nil
1345
- const :verification, T.nilable(Inttegro::FinancialAccountDetailsVerification), default: nil
1344
+ const :verification, T.nilable(Inttegro::FinancialAccountVerification), default: nil
1346
1345
  const :bank_account, T.nilable(Inttegro::FinancialAccountBank), default: nil
1347
- const :dosh_account, T.nilable(Inttegro::ConnectedFinancialAccountDoshAccount), default: nil
1346
+ const :dosh_account, T.nilable(Inttegro::DoshAccount), default: nil
1348
1347
  const :owner, T.nilable(Inttegro::FinancialAccountOwner), default: nil
1349
1348
  const :wallet, T.nilable(Inttegro::FinancialAccountWallet), default: nil
1350
1349
  end
@@ -1538,8 +1537,6 @@ module Inttegro
1538
1537
  end
1539
1538
 
1540
1539
  class CreatedFinancialAccount < T::Struct
1541
- const :app_customer_local_fingerprint, T.nilable(String), default: nil
1542
- const :app_local_fingerprint, T.nilable(String), default: nil
1543
1540
  const :archived_at, T.nilable(String), default: nil
1544
1541
  const :created_at, String
1545
1542
  const :currency, String
@@ -1553,8 +1550,7 @@ module Inttegro
1553
1550
  const :reference, T.nilable(String), default: nil
1554
1551
  const :supplied, T.nilable(Inttegro::ResourceSupply), default: nil
1555
1552
  const :type, Inttegro::FinancialAccountType
1556
- const :universal_fingerprint, T.nilable(String), default: nil
1557
- const :verification, T.nilable(Inttegro::FinancialAccountDetailsVerification), default: nil
1553
+ const :verification, T.nilable(Inttegro::FinancialAccountVerification), default: nil
1558
1554
  const :bank_account, T.nilable(Inttegro::CreatedFinancialAccountBank), default: nil
1559
1555
  const :owner, T.nilable(Inttegro::CreatedFinancialAccountOwner), default: nil
1560
1556
  const :wallet, T.nilable(Inttegro::FinancialAccountWallet), default: nil
@@ -1599,19 +1595,6 @@ module Inttegro
1599
1595
  const :cancel_url, T.nilable(String), default: nil
1600
1596
  end
1601
1597
 
1602
- class OrderPayoutSettingsRequestDestination < T::Struct
1603
- const :financial_account_id, String
1604
- end
1605
-
1606
- class OrderPayoutSettingsRequest < T::Struct
1607
- const :destination, T.nilable(Inttegro::OrderPayoutSettingsRequestDestination), default: nil
1608
- const :enable_fx, T.nilable(T::Boolean), default: nil
1609
- end
1610
-
1611
- class Shipping < T::Struct
1612
- const :address, Inttegro::Address
1613
- end
1614
-
1615
1598
  class CreateOrderExistingCustomer < T::Struct
1616
1599
  const :customer_id, String
1617
1600
  const :payment_method_id, T.nilable(String), default: nil
@@ -2176,13 +2159,7 @@ module Inttegro
2176
2159
  const :order_id, String
2177
2160
  end
2178
2161
 
2179
- class FinancialAccountDoshAccount < T::Struct
2180
- # This object intentionally has no fields.
2181
- end
2182
-
2183
2162
  class FinancialAccount < T::Struct
2184
- const :app_customer_local_fingerprint, T.nilable(String), default: nil
2185
- const :app_local_fingerprint, T.nilable(String), default: nil
2186
2163
  const :archived_at, T.nilable(String), default: nil
2187
2164
  const :created_at, String
2188
2165
  const :currency, String
@@ -2196,11 +2173,10 @@ module Inttegro
2196
2173
  const :reference, T.nilable(String), default: nil
2197
2174
  const :supplied, T.nilable(Inttegro::ResourceSupply), default: nil
2198
2175
  const :type, Inttegro::FinancialAccountType
2199
- const :universal_fingerprint, T.nilable(String), default: nil
2200
- const :verification, T.nilable(Inttegro::FinancialAccountDetailsVerification), default: nil
2176
+ const :verification, T.nilable(Inttegro::FinancialAccountVerification), default: nil
2201
2177
  const :bank_account, T.nilable(Inttegro::FinancialAccountBank), default: nil
2202
2178
  const :disconnected_at, T.nilable(String), default: nil
2203
- const :dosh_account, T.nilable(Inttegro::FinancialAccountDoshAccount), default: nil
2179
+ const :dosh_account, T.nilable(Inttegro::DoshAccount), default: nil
2204
2180
  const :owner, T.nilable(Inttegro::FinancialAccountOwner), default: nil
2205
2181
  const :wallet, T.nilable(Inttegro::FinancialAccountWallet), default: nil
2206
2182
  end
@@ -2277,10 +2253,6 @@ module Inttegro
2277
2253
  const :wallet, Inttegro::FinancialAccountWalletRequestWallet
2278
2254
  end
2279
2255
 
2280
- class FinancialAccountDoshRequestDoshAccount < T::Struct
2281
- # This object intentionally has no fields.
2282
- end
2283
-
2284
2256
  class FinancialAccountDoshRequest < T::Struct
2285
2257
  const :currency, String
2286
2258
  const :custom_data, T.nilable(T::Hash[String, Object]), default: nil
@@ -2291,14 +2263,12 @@ module Inttegro
2291
2263
  const :push_configuration, T.nilable(Inttegro::FinancialAccountRequestBasePushConfiguration), default: nil
2292
2264
  const :reference, String
2293
2265
  const :type, Inttegro::FinancialAccountDoshRequestType
2294
- const :dosh_account, Inttegro::FinancialAccountDoshRequestDoshAccount
2266
+ const :dosh_account, Inttegro::DoshAccount
2295
2267
  end
2296
2268
 
2297
2269
  FinancialAccountCreateRequest = T.type_alias { T.any(Inttegro::FinancialAccountWalletRequest, Inttegro::FinancialAccountBankRequest, Inttegro::FinancialAccountDoshRequest) }
2298
2270
 
2299
2271
  class FinancialAccountDetails < T::Struct
2300
- const :app_customer_local_fingerprint, T.nilable(String), default: nil
2301
- const :app_local_fingerprint, T.nilable(String), default: nil
2302
2272
  const :archived_at, T.nilable(String), default: nil
2303
2273
  const :created_at, String
2304
2274
  const :currency, String
@@ -2312,8 +2282,7 @@ module Inttegro
2312
2282
  const :reference, T.nilable(String), default: nil
2313
2283
  const :supplied, T.nilable(Inttegro::ResourceSupply), default: nil
2314
2284
  const :type, Inttegro::FinancialAccountType
2315
- const :universal_fingerprint, T.nilable(String), default: nil
2316
- const :verification, T.nilable(Inttegro::FinancialAccountDetailsVerification), default: nil
2285
+ const :verification, T.nilable(Inttegro::FinancialAccountVerification), default: nil
2317
2286
  end
2318
2287
 
2319
2288
  class FinancialAccountDisableRequest < T::Struct
@@ -2893,33 +2862,13 @@ module Inttegro
2893
2862
  const :nominal, Inttegro::Amount
2894
2863
  end
2895
2864
 
2896
- class ProductShipmentDelivery < T::Struct
2897
- # This object intentionally has no fields.
2898
- end
2899
-
2900
- class ProductShipmentDownload < T::Struct
2901
- # This object intentionally has no fields.
2902
- end
2903
-
2904
- class ProductShipmentRender < T::Struct
2905
- # This object intentionally has no fields.
2906
- end
2907
-
2908
- class ProductShipmentService < T::Struct
2909
- # This object intentionally has no fields.
2910
- end
2911
-
2912
- class ProductShipmentStream < T::Struct
2913
- # This object intentionally has no fields.
2914
- end
2915
-
2916
2865
  class ProductShipment < T::Struct
2917
2866
  const :type, Inttegro::ProductShipmentType
2918
- const :delivery, T.nilable(Inttegro::ProductShipmentDelivery), default: nil
2919
- const :download, T.nilable(Inttegro::ProductShipmentDownload), default: nil
2920
- const :render, T.nilable(Inttegro::ProductShipmentRender), default: nil
2921
- const :service, T.nilable(Inttegro::ProductShipmentService), default: nil
2922
- const :stream, T.nilable(Inttegro::ProductShipmentStream), default: nil
2867
+ const :delivery, T.nilable(T::Hash[String, Object]), default: nil
2868
+ const :download, T.nilable(T::Hash[String, Object]), default: nil
2869
+ const :render, T.nilable(T::Hash[String, Object]), default: nil
2870
+ const :service, T.nilable(T::Hash[String, Object]), default: nil
2871
+ const :stream, T.nilable(T::Hash[String, Object]), default: nil
2923
2872
  end
2924
2873
 
2925
2874
  class Product < T::Struct
@@ -3008,7 +2957,6 @@ module Inttegro
3008
2957
  end
3009
2958
 
3010
2959
  class PurchaseIntentMerchant < T::Struct
3011
- const :app_id, T.nilable(String), default: nil
3012
2960
  const :app_name, T.nilable(String), default: nil
3013
2961
  const :organization_id, T.nilable(String), default: nil
3014
2962
  const :organization_name, T.nilable(String), default: nil
@@ -3098,7 +3046,6 @@ module Inttegro
3098
3046
  class PurchaseIntent < T::Struct
3099
3047
  const :activity, T.nilable(Inttegro::PurchaseIntentActivityInline), default: nil
3100
3048
  const :allow_variants, T::Boolean
3101
- const :application_id, String
3102
3049
  const :created_at, String
3103
3050
  const :expires_at, T.nilable(String), default: nil
3104
3051
  const :id, String
@@ -3533,10 +3480,6 @@ module Inttegro
3533
3480
  const :ghana_bank_account, T.nilable(Inttegro::UpdatedGhanaBankAccount), default: nil
3534
3481
  end
3535
3482
 
3536
- class UpdatedFinancialAccountDoshAccount < T::Struct
3537
- # This object intentionally has no fields.
3538
- end
3539
-
3540
3483
  class UpdatedFinancialAccountAddress < T::Struct
3541
3484
  const :city, String
3542
3485
  const :country, String
@@ -3561,8 +3504,6 @@ module Inttegro
3561
3504
  end
3562
3505
 
3563
3506
  class UpdatedFinancialAccount < T::Struct
3564
- const :app_customer_local_fingerprint, T.nilable(String), default: nil
3565
- const :app_local_fingerprint, T.nilable(String), default: nil
3566
3507
  const :archived_at, T.nilable(String), default: nil
3567
3508
  const :created_at, String
3568
3509
  const :currency, String
@@ -3576,11 +3517,10 @@ module Inttegro
3576
3517
  const :reference, T.nilable(String), default: nil
3577
3518
  const :supplied, T.nilable(Inttegro::ResourceSupply), default: nil
3578
3519
  const :type, Inttegro::FinancialAccountType
3579
- const :universal_fingerprint, T.nilable(String), default: nil
3580
- const :verification, T.nilable(Inttegro::FinancialAccountDetailsVerification), default: nil
3520
+ const :verification, T.nilable(Inttegro::FinancialAccountVerification), default: nil
3581
3521
  const :bank_account, T.nilable(Inttegro::UpdatedFinancialAccountBank), default: nil
3582
3522
  const :disconnected_at, T.nilable(String), default: nil
3583
- const :dosh_account, T.nilable(Inttegro::UpdatedFinancialAccountDoshAccount), default: nil
3523
+ const :dosh_account, T.nilable(Inttegro::DoshAccount), default: nil
3584
3524
  const :owner, T.nilable(Inttegro::UpdatedFinancialAccountOwner), default: nil
3585
3525
  const :wallet, T.nilable(Inttegro::UpdatedFinancialAccountWallet), default: nil
3586
3526
  end
@@ -3640,7 +3580,7 @@ module Inttegro
3640
3580
 
3641
3581
  class UpdatePaymentMethodRequest < T::Struct
3642
3582
  const :payment_method_id, String
3643
- const :custom_data, T.nilable(T::Hash[String, T.nilable(String)]), default: nil
3583
+ const :custom_data, T.nilable(T::Hash[String, Object]), default: nil
3644
3584
  const :active, T.nilable(T::Boolean), default: nil
3645
3585
  const :archived, T.nilable(T::Boolean), default: nil
3646
3586
  const :owner, T.nilable(Inttegro::UpdatePaymentMethodRequestOwner), default: nil
@@ -37,7 +37,9 @@ module Inttegro
37
37
  open_timeout: T.nilable(Numeric),
38
38
  adapter: T.nilable(Types::Adapter),
39
39
  telemetry_enabled: T::Boolean,
40
- tracer_provider: T.nilable(OpenTelemetry::Trace::TracerProvider)
40
+ tracer_provider: T.nilable(OpenTelemetry::Trace::TracerProvider),
41
+ error_reporter: T.nilable(ErrorReporter),
42
+ error_reporting_policy: Symbol
41
43
  ).void
42
44
  end
43
45
  def initialize(
@@ -47,7 +49,9 @@ module Inttegro
47
49
  open_timeout: 10,
48
50
  adapter: nil,
49
51
  telemetry_enabled: true,
50
- tracer_provider: nil
52
+ tracer_provider: nil,
53
+ error_reporter: nil,
54
+ error_reporting_policy: :unexpected
51
55
  )
52
56
  @api_key = T.let(api_key || "", String)
53
57
  raise ArgumentError, "api_key is required" if @api_key.strip.empty?
@@ -60,7 +64,13 @@ module Inttegro
60
64
  @open_timeout = T.let(open_timeout, T.nilable(Numeric))
61
65
  @adapter = T.let(adapter, T.nilable(Types::Adapter))
62
66
  @telemetry = T.let(
63
- Telemetry.new(Inttegro::VERSION, enabled: telemetry_enabled, tracer_provider: tracer_provider),
67
+ Telemetry.new(
68
+ Inttegro::VERSION,
69
+ enabled: telemetry_enabled,
70
+ tracer_provider: tracer_provider,
71
+ error_reporter: error_reporter,
72
+ error_reporting_policy: error_reporting_policy
73
+ ),
64
74
  Telemetry
65
75
  )
66
76
  end
@@ -504,6 +514,7 @@ module Inttegro
504
514
  detail = payload[:detail]
505
515
  fix_code = payload[:fix_code]
506
516
  cause = payload[:cause]
517
+ request_id = response["x-request-id"] || response["X-Request-Id"]
507
518
 
508
519
  case status
509
520
  when 401
@@ -517,7 +528,8 @@ module Inttegro
517
528
  fix_code: fix_code,
518
529
  cause: cause,
519
530
  body: body,
520
- data: data
531
+ data: data,
532
+ request_id: request_id
521
533
  )
522
534
  when 429
523
535
  retry_after = response["Retry-After"]&.to_i
@@ -532,7 +544,8 @@ module Inttegro
532
544
  cause: cause,
533
545
  body: body,
534
546
  data: data,
535
- retry_after: retry_after
547
+ retry_after: retry_after,
548
+ request_id: request_id
536
549
  )
537
550
  else
538
551
  raise APIError.new(
@@ -545,7 +558,8 @@ module Inttegro
545
558
  fix_code: fix_code,
546
559
  cause: cause,
547
560
  body: body,
548
- data: data
561
+ data: data,
562
+ request_id: request_id
549
563
  )
550
564
  end
551
565
  end
@@ -3,9 +3,12 @@
3
3
 
4
4
  require "opentelemetry-api"
5
5
  require "sorbet-runtime"
6
+ require "securerandom"
7
+ require "time"
6
8
  require "uri"
7
9
 
8
10
  require_relative "errors"
11
+ require_relative "error_reporting"
9
12
 
10
13
  module Inttegro
11
14
  # Emits redacted SDK spans to the application's OpenTelemetry provider.
@@ -30,11 +33,17 @@ module Inttegro
30
33
  params(
31
34
  version: String,
32
35
  enabled: T::Boolean,
33
- tracer_provider: T.nilable(OpenTelemetry::Trace::TracerProvider)
36
+ tracer_provider: T.nilable(OpenTelemetry::Trace::TracerProvider),
37
+ error_reporter: T.nilable(ErrorReporter),
38
+ error_reporting_policy: Symbol
34
39
  ).void
35
40
  end
36
- def initialize(version, enabled: true, tracer_provider: nil)
41
+ def initialize(version, enabled: true, tracer_provider: nil, error_reporter: nil, error_reporting_policy: :unexpected)
37
42
  @enabled = T.let(enabled, T::Boolean)
43
+ raise ArgumentError, "error_reporting_policy must be :unexpected or :all" unless %i[unexpected all].include?(error_reporting_policy)
44
+
45
+ @error_reporter = T.let(error_reporter, T.nilable(ErrorReporter))
46
+ @error_reporting_policy = T.let(error_reporting_policy, Symbol)
38
47
  provider = tracer_provider || OpenTelemetry.tracer_provider
39
48
  @tracer = T.let(provider.tracer("inttegro", version), OpenTelemetry::Trace::Tracer)
40
49
  end
@@ -52,9 +61,18 @@ module Inttegro
52
61
  .returns(T.type_parameter(:Result))
53
62
  end
54
63
  def in_span(path_or_url, method, base_url, version, operation_override = nil, &block)
55
- return yield(nil) unless @enabled
64
+ return yield(nil) unless @enabled || @error_reporter
56
65
 
57
66
  operation, route, server_address = request_details(path_or_url, base_url, operation_override)
67
+ started_at = T.let(@error_reporter ? monotonic_milliseconds : nil, T.nilable(Float))
68
+ unless @enabled
69
+ begin
70
+ return yield(nil)
71
+ rescue StandardError => e
72
+ report_failure(e, operation, route, server_address, method, version, started_at, nil)
73
+ raise
74
+ end
75
+ end
58
76
  attributes = {
59
77
  "inttegro.operation.name" => operation,
60
78
  "inttegro.sdk.language" => "ruby",
@@ -72,6 +90,7 @@ module Inttegro
72
90
  span.set_attribute("error.type", error_type)
73
91
  span.status = OpenTelemetry::Trace::Status.error
74
92
  span.add_event("inttegro.request.failed", attributes: { "error.type" => error_type })
93
+ report_failure(e, operation, route, server_address, method, version, started_at, span)
75
94
  raise
76
95
  ensure
77
96
  span.finish
@@ -125,6 +144,71 @@ module Inttegro
125
144
 
126
145
  private
127
146
 
147
+ sig do
148
+ params(
149
+ error: StandardError,
150
+ operation: String,
151
+ route: T.nilable(String),
152
+ server_address: String,
153
+ method: T.any(String, Symbol),
154
+ version: String,
155
+ started_at: T.nilable(Float),
156
+ span: T.nilable(OpenTelemetry::Trace::Span)
157
+ ).void
158
+ end
159
+ def report_failure(error, operation, route, server_address, method, version, started_at, span)
160
+ reporter = @error_reporter
161
+ return unless reporter
162
+
163
+ begin
164
+ category = classify_error(error)
165
+ return if category == "canceled"
166
+ if @error_reporting_policy == :unexpected && error.is_a?(APIError)
167
+ return unless error.status >= 500 || error.type == "unknown_error"
168
+ end
169
+
170
+ api_error = T.let(error.is_a?(APIError) ? error : nil, T.nilable(APIError))
171
+ api_context = if api_error && (api_error.type || api_error.code || api_error.fix_code)
172
+ APIErrorReportContext.new(type: api_error.type, code: api_error.code, fix_code: api_error.fix_code)
173
+ end
174
+ span_context = span&.context
175
+ trace_context = if span_context&.valid?
176
+ TraceReportContext.new(trace_id: span_context.hex_trace_id, span_id: span_context.hex_span_id)
177
+ end
178
+ status_code = api_error&.status
179
+ report = ErrorReport.new(
180
+ schema_version: 1,
181
+ event_id: SecureRandom.uuid,
182
+ occurred_at: Time.now.utc.iso8601(6),
183
+ severity: "error",
184
+ category: category,
185
+ operation: operation,
186
+ sdk: SDKReportContext.new(language: "ruby", version: version),
187
+ http: HTTPReportContext.new(
188
+ request_method: method.to_s.upcase,
189
+ route: route,
190
+ server_address: server_address,
191
+ status_code: status_code,
192
+ request_id: api_error&.request_id,
193
+ duration_ms: [(monotonic_milliseconds - (started_at || monotonic_milliseconds)).round, 0].max
194
+ ),
195
+ api_error: api_context,
196
+ trace: trace_context,
197
+ exception_type: (error.class.name || "StandardError").split("::").last || "StandardError",
198
+ fingerprint: ["inttegro", "ruby", operation, category, status_code || "none"].join(":")
199
+ )
200
+ error.report = report if error.is_a?(Error)
201
+ reporter.call(report)
202
+ rescue StandardError
203
+ # Report preparation and delivery must never replace the original failure.
204
+ end
205
+ end
206
+
207
+ sig { returns(Float) }
208
+ def monotonic_milliseconds
209
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond).to_f
210
+ end
211
+
128
212
  sig do
129
213
  params(path_or_url: String, base_url: String, override: T.nilable(String))
130
214
  .returns([String, T.nilable(String), String])
@@ -2,5 +2,5 @@
2
2
  # typed: strict
3
3
 
4
4
  module Inttegro
5
- VERSION = "4.2.2"
5
+ VERSION = "4.3.1"
6
6
  end
data/lib/inttegro.rb CHANGED
@@ -6,6 +6,7 @@ require "sorbet-runtime"
6
6
  require_relative "inttegro/types"
7
7
  require_relative "inttegro/client"
8
8
  require_relative "inttegro/errors"
9
+ require_relative "inttegro/error_reporting"
9
10
  require_relative "inttegro/enums"
10
11
  require_relative "inttegro/models"
11
12
  require_relative "inttegro/version"
@@ -56,6 +56,9 @@ module OpenTelemetry
56
56
  end
57
57
 
58
58
  class Span
59
+ sig { returns(SpanContext) }
60
+ def context; end
61
+
59
62
  sig { params(key: String, value: Object).returns(Span) }
60
63
  def set_attribute(key, value); end
61
64
 
@@ -69,6 +72,17 @@ module OpenTelemetry
69
72
  def finish; end
70
73
  end
71
74
 
75
+ class SpanContext
76
+ sig { returns(T::Boolean) }
77
+ def valid?; end
78
+
79
+ sig { returns(String) }
80
+ def hex_trace_id; end
81
+
82
+ sig { returns(String) }
83
+ def hex_span_id; end
84
+ end
85
+
72
86
  class Status
73
87
  sig { params(description: String).returns(Status) }
74
88
  def self.error(description = ""); end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inttegro
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.2
4
+ version: 4.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Inttegro Engineering
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-09-04 00:00:00.000000000 Z
11
+ date: 2026-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet-runtime
@@ -82,6 +82,7 @@ files:
82
82
  - lib/inttegro.rb
83
83
  - lib/inttegro/client.rb
84
84
  - lib/inttegro/enums.rb
85
+ - lib/inttegro/error_reporting.rb
85
86
  - lib/inttegro/errors.rb
86
87
  - lib/inttegro/file_download.rb
87
88
  - lib/inttegro/generated/enums.rb
@@ -125,6 +126,7 @@ licenses:
125
126
  metadata:
126
127
  homepage_uri: https://studio.inttegro.com
127
128
  source_code_uri: https://github.com/zebodotdev/inttegro-sdk-ruby
129
+ documentation_uri: https://ruby.inttegro.dev/
128
130
  changelog_uri: https://github.com/zebodotdev/inttegro-sdk-ruby/blob/master/CHANGELOG.md
129
131
  github_repo: ssh://github.com/zebodotdev/inttegro-sdk-ruby
130
132
  rubygems_mfa_required: 'true'