inttegro 4.1.0 → 4.2.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 +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +15 -1
- data/lib/inttegro/client.rb +9 -3
- data/lib/inttegro/generated/enums.rb +44 -0
- data/lib/inttegro/generated/models.rb +250 -46
- data/lib/inttegro/generated/operations.rb +12 -0
- data/lib/inttegro/http_client.rb +101 -63
- data/lib/inttegro/resources/upload_requests.rb +2 -1
- data/lib/inttegro/telemetry.rb +156 -0
- data/lib/inttegro/version.rb +1 -1
- data/rbi/opentelemetry-api.rbi +77 -0
- metadata +18 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7b60affd2f9bc5ce1556ec7aeeacc26d0d52604d964df3c0ffd72ae034800130
|
|
4
|
+
data.tar.gz: 93520c2c26b96c4292eace71528343cd5ff5f33039e563132c3161d07dce03fe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 42d25f00a4b8d6ce066f044b2572fd31f3a49aaac7fb98085817673816695b2b69cb83e93e1381c685a5da73236cc9c663e8e493ab3e3118e28698b7e22e1cf9
|
|
7
|
+
data.tar.gz: 22b17729fa018888d51fc33945536a6624298f1b8b66a6a2599b3009fce8a79575e574dc4caefc531535e5812c64b397ce87ebd5f3eff908307890a12934f830
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [4.2.1] - 2026-09-04
|
|
4
|
+
|
|
5
|
+
- Aligned the SDK parity test with hosted-checkout routes that are intentionally handled by the client.
|
|
6
|
+
- Refreshed generated declarations from the OpenAPI commit pinned by CI and release automation.
|
|
7
|
+
|
|
8
|
+
## [4.2.0] - 2026-09-04
|
|
9
|
+
|
|
10
|
+
- Added vendor-neutral OpenTelemetry spans for logical SDK operations, HTTP attempts, response receipt, decoding, and safe failure categories.
|
|
11
|
+
- Added W3C trace-context propagation plus global or per-client tracer-provider configuration.
|
|
12
|
+
- Kept request bodies, credentials, resource identifiers, dynamic URLs, and exception details out of telemetry.
|
|
13
|
+
|
|
3
14
|
## [4.1.0] - 2026-09-03
|
|
4
15
|
|
|
5
16
|
- Added focused `Inttegro::Wallets` and `Inttegro::BankAccounts` modules for financial-account variants.
|
data/README.md
CHANGED
|
@@ -73,6 +73,20 @@ end
|
|
|
73
73
|
|
|
74
74
|
Amounts use integer minor units: `5000` GHS is GHS 50.00. Reuse the same idempotency key when retrying the same logical write. If you omit one, the SDK generates a UUIDv7 key for mutating calls.
|
|
75
75
|
|
|
76
|
+
## Observe SDK operations
|
|
77
|
+
|
|
78
|
+
The SDK emits vendor-neutral OpenTelemetry spans through your application's provider. It never configures an exporter or sends telemetry by itself. Configure OpenTelemetry before creating the client:
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
require "opentelemetry/sdk"
|
|
82
|
+
require "inttegro"
|
|
83
|
+
|
|
84
|
+
OpenTelemetry::SDK.configure
|
|
85
|
+
inttegro = Inttegro::Client.new(api_key: ENV.fetch("INTTEGRO_API_KEY"))
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
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
|
+
|
|
76
90
|
## Work with the API
|
|
77
91
|
|
|
78
92
|
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`.
|
|
@@ -95,7 +109,7 @@ The GitHub release for each version is the canonical record. It contains the exa
|
|
|
95
109
|
|
|
96
110
|
```bash
|
|
97
111
|
sha256sum --check SHA256SUMS
|
|
98
|
-
gh attestation verify inttegro-4.1.
|
|
112
|
+
gh attestation verify inttegro-4.2.1.gem \
|
|
99
113
|
--repo zebodotdev/inttegro-sdk-ruby
|
|
100
114
|
```
|
|
101
115
|
|
data/lib/inttegro/client.rb
CHANGED
|
@@ -109,7 +109,9 @@ module Inttegro
|
|
|
109
109
|
base_url: T.nilable(String),
|
|
110
110
|
read_timeout: T.nilable(Numeric),
|
|
111
111
|
open_timeout: T.nilable(Numeric),
|
|
112
|
-
adapter: T.nilable(Types::Adapter)
|
|
112
|
+
adapter: T.nilable(Types::Adapter),
|
|
113
|
+
telemetry_enabled: T::Boolean,
|
|
114
|
+
tracer_provider: T.nilable(OpenTelemetry::Trace::TracerProvider)
|
|
113
115
|
).void
|
|
114
116
|
end
|
|
115
117
|
def initialize(
|
|
@@ -119,7 +121,9 @@ module Inttegro
|
|
|
119
121
|
base_url: DEFAULT_BASE_URL,
|
|
120
122
|
read_timeout: 30,
|
|
121
123
|
open_timeout: 10,
|
|
122
|
-
adapter: nil
|
|
124
|
+
adapter: nil,
|
|
125
|
+
telemetry_enabled: true,
|
|
126
|
+
tracer_provider: nil
|
|
123
127
|
)
|
|
124
128
|
provided_token = token || token_value
|
|
125
129
|
api_key ||= provided_token
|
|
@@ -128,7 +132,9 @@ module Inttegro
|
|
|
128
132
|
base_url: base_url,
|
|
129
133
|
read_timeout: read_timeout,
|
|
130
134
|
open_timeout: open_timeout,
|
|
131
|
-
adapter: adapter
|
|
135
|
+
adapter: adapter,
|
|
136
|
+
telemetry_enabled: telemetry_enabled,
|
|
137
|
+
tracer_provider: tracer_provider
|
|
132
138
|
), HTTPClient)
|
|
133
139
|
|
|
134
140
|
@orders = T.let(Resources::Orders.new(@http), Resources::Orders)
|
|
@@ -47,6 +47,50 @@ module Inttegro
|
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
+
class CheckoutInvoiceViewStatus < T::Enum
|
|
51
|
+
enums do
|
|
52
|
+
DRAFT = new("draft")
|
|
53
|
+
REQUIRES_PAYMENT = new("requires_payment")
|
|
54
|
+
OVERDUE = new("overdue")
|
|
55
|
+
PAID = new("paid")
|
|
56
|
+
EXPIRED = new("expired")
|
|
57
|
+
CANCELED = new("canceled")
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
class CheckoutMobileMoneyDataNetwork < T::Enum
|
|
62
|
+
enums do
|
|
63
|
+
MTN = new("mtn")
|
|
64
|
+
VODAFONE = new("vodafone")
|
|
65
|
+
AIRTEL = new("airtel")
|
|
66
|
+
TELECEL = new("telecel")
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
class CheckoutOrderStatus < T::Enum
|
|
71
|
+
enums do
|
|
72
|
+
PREPARING = new("preparing")
|
|
73
|
+
REQUIRES_PAYMENT = new("requires_payment")
|
|
74
|
+
COMPLETED = new("completed")
|
|
75
|
+
PAID = new("paid")
|
|
76
|
+
CANCELED = new("canceled")
|
|
77
|
+
EXPIRED = new("expired")
|
|
78
|
+
UNKNOWN = new("unknown")
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
class CheckoutPayRequestPaymentMethodDataType < T::Enum
|
|
83
|
+
enums do
|
|
84
|
+
MOBILE_MONEY = new("mobile_money")
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
class CheckoutPaymentMethodDataType < T::Enum
|
|
89
|
+
enums do
|
|
90
|
+
MOBILE_MONEY = new("mobile_money")
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
50
94
|
class ChimeEmailSchemaKind < T::Enum
|
|
51
95
|
enums do
|
|
52
96
|
GMAIL_VIEW_ACTION = new("gmail_view_action")
|
|
@@ -562,6 +562,256 @@ module Inttegro
|
|
|
562
562
|
const :quantity, Integer
|
|
563
563
|
end
|
|
564
564
|
|
|
565
|
+
class CheckoutPaymentAddress < T::Struct
|
|
566
|
+
const :name, T.nilable(String), default: nil
|
|
567
|
+
const :phone_number, T.nilable(String), default: nil
|
|
568
|
+
const :line1, T.nilable(String), default: nil
|
|
569
|
+
const :line2, T.nilable(String), default: nil
|
|
570
|
+
const :city, T.nilable(String), default: nil
|
|
571
|
+
const :region, T.nilable(String), default: nil
|
|
572
|
+
const :post_code, T.nilable(String), default: nil
|
|
573
|
+
const :country, String
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
class CheckoutBillingDetails < T::Struct
|
|
577
|
+
const :name, String
|
|
578
|
+
const :phone_number, T.nilable(String), default: nil
|
|
579
|
+
const :address, Inttegro::CheckoutPaymentAddress
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
class CheckoutConfirmPaymentRequest < T::Struct
|
|
583
|
+
const :order_id, String
|
|
584
|
+
const :payment_id, T.nilable(String), default: nil
|
|
585
|
+
const :confirmation_id, T.nilable(String), default: nil
|
|
586
|
+
const :token, String
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
class CheckoutInvoiceViewFormatWeb < T::Struct
|
|
590
|
+
const :url, T.nilable(String), default: nil
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
class CheckoutInvoiceViewFormatPdf < T::Struct
|
|
594
|
+
const :url, T.nilable(String), default: nil
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
class CheckoutInvoiceViewFormatReceipt < T::Struct
|
|
598
|
+
const :url, T.nilable(String), default: nil
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
class CheckoutInvoiceViewFormat < T::Struct
|
|
602
|
+
const :web, T.nilable(Inttegro::CheckoutInvoiceViewFormatWeb), default: nil
|
|
603
|
+
const :pdf, T.nilable(Inttegro::CheckoutInvoiceViewFormatPdf), default: nil
|
|
604
|
+
const :receipt, T.nilable(Inttegro::CheckoutInvoiceViewFormatReceipt), default: nil
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
class CheckoutInvoiceViewBeneficiary < T::Struct
|
|
608
|
+
const :id, T.nilable(String), default: nil
|
|
609
|
+
const :legal_entity_type, T.nilable(String), default: nil
|
|
610
|
+
const :logo_url, T.nilable(String), default: nil
|
|
611
|
+
const :alias, T.nilable(String), default: nil
|
|
612
|
+
const :name, T.nilable(String), default: nil
|
|
613
|
+
const :support_email, T.nilable(String), default: nil
|
|
614
|
+
const :support_phone, T.nilable(String), default: nil
|
|
615
|
+
const :website_url, T.nilable(String), default: nil
|
|
616
|
+
const :accent_color, T.nilable(String), default: nil
|
|
617
|
+
const :invoice_support_line, T.nilable(String), default: nil
|
|
618
|
+
const :invoice_footer, T.nilable(String), default: nil
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
class CheckoutInvoiceView < T::Struct
|
|
622
|
+
const :id, String
|
|
623
|
+
const :application_id, T.nilable(String), default: nil
|
|
624
|
+
const :number, T.nilable(String), default: nil
|
|
625
|
+
const :status, T.nilable(Inttegro::CheckoutInvoiceViewStatus), default: nil
|
|
626
|
+
const :created_at, String
|
|
627
|
+
const :due_at, T.nilable(String), default: nil
|
|
628
|
+
const :format_value, Inttegro::CheckoutInvoiceViewFormat, name: "format"
|
|
629
|
+
const :beneficiary, T.nilable(Inttegro::CheckoutInvoiceViewBeneficiary), default: nil
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
class CheckoutMobileMoneyData < T::Struct
|
|
633
|
+
const :reference, T.nilable(String), default: nil
|
|
634
|
+
const :network, Inttegro::CheckoutMobileMoneyDataNetwork
|
|
635
|
+
const :account_number, String
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
class CheckoutOrderCheckoutSettings < T::Struct
|
|
639
|
+
const :redirect_url, T.nilable(String), default: nil
|
|
640
|
+
const :cancel_url, T.nilable(String), default: nil
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
class InlineProductDetails < T::Struct
|
|
644
|
+
const :about, T.nilable(String), default: nil
|
|
645
|
+
const :custom_data, T.nilable(T::Hash[String, Object]), default: nil
|
|
646
|
+
const :name, String
|
|
647
|
+
const :price, Inttegro::PriceParams
|
|
648
|
+
const :quantity, Integer
|
|
649
|
+
const :reference, T.nilable(String), default: nil
|
|
650
|
+
const :tax_code, T.nilable(String), default: nil
|
|
651
|
+
const :type, Inttegro::ProductType
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
ProductDetails = T.type_alias { T.any(Inttegro::InlineProductDetails, Inttegro::CatalogProductWithPriceData, Inttegro::CatalogProductWithPriceReference) }
|
|
655
|
+
|
|
656
|
+
class ProductLineItem < T::Struct
|
|
657
|
+
const :type, Inttegro::ProductLineItemType
|
|
658
|
+
const :product, Inttegro::ProductDetails
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
class FeeDetails < T::Struct
|
|
662
|
+
const :id, T.nilable(String), default: nil
|
|
663
|
+
const :label, T.nilable(String), default: nil
|
|
664
|
+
const :tax_code, T.nilable(String), default: nil
|
|
665
|
+
const :description, T.nilable(String), default: nil
|
|
666
|
+
const :custom_data, T.nilable(T::Hash[String, Object]), default: nil
|
|
667
|
+
const :amount, Inttegro::AmountParams
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
class FeeLineItem < T::Struct
|
|
671
|
+
const :type, Inttegro::FeeLineItemType
|
|
672
|
+
const :fee, Inttegro::FeeDetails
|
|
673
|
+
end
|
|
674
|
+
|
|
675
|
+
class ShippingDetails < T::Struct
|
|
676
|
+
const :id, T.nilable(String), default: nil
|
|
677
|
+
const :tax_code, T.nilable(String), default: nil
|
|
678
|
+
const :custom_data, T.nilable(T::Hash[String, Object]), default: nil
|
|
679
|
+
const :fee, Inttegro::AmountParams
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
class ShippingLineItem < T::Struct
|
|
683
|
+
const :type, Inttegro::ShippingLineItemType
|
|
684
|
+
const :shipping, Inttegro::ShippingDetails
|
|
685
|
+
end
|
|
686
|
+
|
|
687
|
+
LineItem = T.type_alias { T.any(Inttegro::ProductLineItem, Inttegro::FeeLineItem, Inttegro::ShippingLineItem) }
|
|
688
|
+
|
|
689
|
+
class CheckoutOrderLineItemGroup < T::Struct
|
|
690
|
+
const :line_items, T.nilable(T::Array[Inttegro::LineItem]), default: nil
|
|
691
|
+
const :total, T.nilable(Inttegro::Amount), default: nil
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
class CheckoutOrderCustomerBillingAddress < T::Struct
|
|
695
|
+
# This object intentionally has no fields.
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
class CheckoutOrderCustomerShippingAddress < T::Struct
|
|
699
|
+
# This object intentionally has no fields.
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
class CheckoutOrderCustomer < T::Struct
|
|
703
|
+
const :id, T.nilable(String), default: nil
|
|
704
|
+
const :guest, T.nilable(T::Boolean), default: nil
|
|
705
|
+
const :name, T.nilable(String), default: nil
|
|
706
|
+
const :email_address, T.nilable(String), default: nil
|
|
707
|
+
const :phone_number, T.nilable(String), default: nil
|
|
708
|
+
const :billing_address, T.nilable(Inttegro::CheckoutOrderCustomerBillingAddress), default: nil
|
|
709
|
+
const :shipping_address, T.nilable(Inttegro::CheckoutOrderCustomerShippingAddress), default: nil
|
|
710
|
+
end
|
|
711
|
+
|
|
712
|
+
class CheckoutOrderCreatedFrom < T::Struct
|
|
713
|
+
const :source, T.nilable(String), default: nil
|
|
714
|
+
const :resource_type, T.nilable(String), default: nil
|
|
715
|
+
const :resource_id, T.nilable(String), default: nil
|
|
716
|
+
end
|
|
717
|
+
|
|
718
|
+
class CheckoutOrderPaymentPaymentMethod < T::Struct
|
|
719
|
+
# This object intentionally has no fields.
|
|
720
|
+
end
|
|
721
|
+
|
|
722
|
+
class CheckoutOrderPaymentBillingDetails < T::Struct
|
|
723
|
+
# This object intentionally has no fields.
|
|
724
|
+
end
|
|
725
|
+
|
|
726
|
+
class CheckoutOrderPaymentLatestAttempt < T::Struct
|
|
727
|
+
# This object intentionally has no fields.
|
|
728
|
+
end
|
|
729
|
+
|
|
730
|
+
class CheckoutOrderPaymentNextAction < T::Struct
|
|
731
|
+
# This object intentionally has no fields.
|
|
732
|
+
end
|
|
733
|
+
|
|
734
|
+
class CheckoutOrderPaymentLatestError < T::Struct
|
|
735
|
+
# This object intentionally has no fields.
|
|
736
|
+
end
|
|
737
|
+
|
|
738
|
+
class CheckoutOrderPayment < T::Struct
|
|
739
|
+
const :id, T.nilable(String), default: nil
|
|
740
|
+
const :statement_descriptor, T.nilable(String), default: nil
|
|
741
|
+
const :payment_method_types, T.nilable(T::Array[String]), default: nil
|
|
742
|
+
const :payment_method, T.nilable(Inttegro::CheckoutOrderPaymentPaymentMethod), default: nil
|
|
743
|
+
const :billing_details, T.nilable(Inttegro::CheckoutOrderPaymentBillingDetails), default: nil
|
|
744
|
+
const :receipt, T.nilable(Inttegro::CheckoutInvoiceView), default: nil
|
|
745
|
+
const :latest_attempt, T.nilable(Inttegro::CheckoutOrderPaymentLatestAttempt), default: nil
|
|
746
|
+
const :amount, T.nilable(Inttegro::Amount), default: nil
|
|
747
|
+
const :next_action, T.nilable(Inttegro::CheckoutOrderPaymentNextAction), default: nil
|
|
748
|
+
const :latest_error, T.nilable(Inttegro::CheckoutOrderPaymentLatestError), default: nil
|
|
749
|
+
const :status, T.nilable(String), default: nil
|
|
750
|
+
const :initiated_at, T.nilable(String), default: nil
|
|
751
|
+
const :executed_at, T.nilable(String), default: nil
|
|
752
|
+
const :due_at, T.nilable(String), default: nil
|
|
753
|
+
const :canceled_at, T.nilable(String), default: nil
|
|
754
|
+
const :expired_at, T.nilable(String), default: nil
|
|
755
|
+
const :paid_at, T.nilable(String), default: nil
|
|
756
|
+
const :paid_offline, T.nilable(T::Boolean), default: nil
|
|
757
|
+
const :failed_at, T.nilable(String), default: nil
|
|
758
|
+
end
|
|
759
|
+
|
|
760
|
+
class CheckoutOrder < T::Struct
|
|
761
|
+
const :id, String
|
|
762
|
+
const :number, T.nilable(String), default: nil
|
|
763
|
+
const :receipt_number, T.nilable(String), default: nil
|
|
764
|
+
const :reference, T.nilable(String), default: nil
|
|
765
|
+
const :status, Inttegro::CheckoutOrderStatus
|
|
766
|
+
const :initiated_at, String
|
|
767
|
+
const :sealed_at, T.nilable(String), default: nil
|
|
768
|
+
const :completed_at, T.nilable(String), default: nil
|
|
769
|
+
const :paid_at, T.nilable(String), default: nil
|
|
770
|
+
const :canceled_at, T.nilable(String), default: nil
|
|
771
|
+
const :expires_at, T.nilable(String), default: nil
|
|
772
|
+
const :payment_due_at, T.nilable(String), default: nil
|
|
773
|
+
const :checkout_settings, T.nilable(Inttegro::CheckoutOrderCheckoutSettings), default: nil
|
|
774
|
+
const :line_item_group, T.nilable(Inttegro::CheckoutOrderLineItemGroup), default: nil
|
|
775
|
+
const :customer, Inttegro::CheckoutOrderCustomer
|
|
776
|
+
const :created_from, T.nilable(Inttegro::CheckoutOrderCreatedFrom), default: nil
|
|
777
|
+
const :payment, T.nilable(Inttegro::CheckoutOrderPayment), default: nil
|
|
778
|
+
const :invoice, T.nilable(Inttegro::CheckoutInvoiceView), default: nil
|
|
779
|
+
end
|
|
780
|
+
|
|
781
|
+
class CheckoutOrderReferenceRequest < T::Struct
|
|
782
|
+
const :order_id, String
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
class CheckoutOrderResponse < T::Struct
|
|
786
|
+
const :order, T.nilable(Inttegro::CheckoutOrder), default: nil
|
|
787
|
+
const :error, T.nilable(Inttegro::ErrorPayload), default: nil
|
|
788
|
+
end
|
|
789
|
+
|
|
790
|
+
class CheckoutPaymentMethodDataBillingDetails < T::Struct
|
|
791
|
+
const :name, String
|
|
792
|
+
const :phone_number, T.nilable(String), default: nil
|
|
793
|
+
const :address, Inttegro::CheckoutPaymentAddress
|
|
794
|
+
end
|
|
795
|
+
|
|
796
|
+
class CheckoutPayRequestPaymentMethodData < T::Struct
|
|
797
|
+
const :type, Inttegro::CheckoutPayRequestPaymentMethodDataType
|
|
798
|
+
const :mobile_money, Inttegro::CheckoutMobileMoneyData
|
|
799
|
+
const :billing_details, T.nilable(Inttegro::CheckoutPaymentMethodDataBillingDetails), default: nil
|
|
800
|
+
end
|
|
801
|
+
|
|
802
|
+
class CheckoutPayRequest < T::Struct
|
|
803
|
+
const :order_id, String
|
|
804
|
+
const :payment_method_id, T.nilable(String), default: nil
|
|
805
|
+
const :payment_method_data, T.nilable(Inttegro::CheckoutPayRequestPaymentMethodData), default: nil
|
|
806
|
+
const :save_payment_method, T.nilable(T::Boolean), default: nil
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
class CheckoutPaymentMethodData < T::Struct
|
|
810
|
+
const :type, Inttegro::CheckoutPaymentMethodDataType
|
|
811
|
+
const :mobile_money, Inttegro::CheckoutMobileMoneyData
|
|
812
|
+
const :billing_details, T.nilable(Inttegro::CheckoutPaymentMethodDataBillingDetails), default: nil
|
|
813
|
+
end
|
|
814
|
+
|
|
565
815
|
class ChimeRecipientDetailPhone < T::Struct
|
|
566
816
|
const :number, String
|
|
567
817
|
end
|
|
@@ -1358,52 +1608,6 @@ module Inttegro
|
|
|
1358
1608
|
const :enable_fx, T.nilable(T::Boolean), default: nil
|
|
1359
1609
|
end
|
|
1360
1610
|
|
|
1361
|
-
class InlineProductDetails < T::Struct
|
|
1362
|
-
const :about, T.nilable(String), default: nil
|
|
1363
|
-
const :custom_data, T.nilable(T::Hash[String, Object]), default: nil
|
|
1364
|
-
const :name, String
|
|
1365
|
-
const :price, Inttegro::PriceParams
|
|
1366
|
-
const :quantity, Integer
|
|
1367
|
-
const :reference, T.nilable(String), default: nil
|
|
1368
|
-
const :tax_code, T.nilable(String), default: nil
|
|
1369
|
-
const :type, Inttegro::ProductType
|
|
1370
|
-
end
|
|
1371
|
-
|
|
1372
|
-
ProductDetails = T.type_alias { T.any(Inttegro::InlineProductDetails, Inttegro::CatalogProductWithPriceData, Inttegro::CatalogProductWithPriceReference) }
|
|
1373
|
-
|
|
1374
|
-
class ProductLineItem < T::Struct
|
|
1375
|
-
const :type, Inttegro::ProductLineItemType
|
|
1376
|
-
const :product, Inttegro::ProductDetails
|
|
1377
|
-
end
|
|
1378
|
-
|
|
1379
|
-
class FeeDetails < T::Struct
|
|
1380
|
-
const :id, T.nilable(String), default: nil
|
|
1381
|
-
const :label, T.nilable(String), default: nil
|
|
1382
|
-
const :tax_code, T.nilable(String), default: nil
|
|
1383
|
-
const :description, T.nilable(String), default: nil
|
|
1384
|
-
const :custom_data, T.nilable(T::Hash[String, Object]), default: nil
|
|
1385
|
-
const :amount, Inttegro::AmountParams
|
|
1386
|
-
end
|
|
1387
|
-
|
|
1388
|
-
class FeeLineItem < T::Struct
|
|
1389
|
-
const :type, Inttegro::FeeLineItemType
|
|
1390
|
-
const :fee, Inttegro::FeeDetails
|
|
1391
|
-
end
|
|
1392
|
-
|
|
1393
|
-
class ShippingDetails < T::Struct
|
|
1394
|
-
const :id, T.nilable(String), default: nil
|
|
1395
|
-
const :tax_code, T.nilable(String), default: nil
|
|
1396
|
-
const :custom_data, T.nilable(T::Hash[String, Object]), default: nil
|
|
1397
|
-
const :fee, Inttegro::AmountParams
|
|
1398
|
-
end
|
|
1399
|
-
|
|
1400
|
-
class ShippingLineItem < T::Struct
|
|
1401
|
-
const :type, Inttegro::ShippingLineItemType
|
|
1402
|
-
const :shipping, Inttegro::ShippingDetails
|
|
1403
|
-
end
|
|
1404
|
-
|
|
1405
|
-
LineItem = T.type_alias { T.any(Inttegro::ProductLineItem, Inttegro::FeeLineItem, Inttegro::ShippingLineItem) }
|
|
1406
|
-
|
|
1407
1611
|
class Shipping < T::Struct
|
|
1408
1612
|
const :address, Inttegro::Address
|
|
1409
1613
|
end
|
|
@@ -31,6 +31,10 @@ module Inttegro
|
|
|
31
31
|
"/customers/lookup" => Inttegro::CustomerResponse,
|
|
32
32
|
"/customers/update" => Inttegro::CustomerResponse,
|
|
33
33
|
"/customers/page" => Inttegro::PageCustomersResponse,
|
|
34
|
+
"/checkout/lookup" => Inttegro::CheckoutOrderResponse,
|
|
35
|
+
"/checkout/pay" => Inttegro::CheckoutOrderResponse,
|
|
36
|
+
"/checkout/confirm_payment" => Inttegro::CheckoutOrderResponse,
|
|
37
|
+
"/checkout/request_confirmation" => Inttegro::CheckoutOrderResponse,
|
|
34
38
|
"/orders/create" => Inttegro::OrderEnvelope,
|
|
35
39
|
"/orders/lookup" => Inttegro::OrderEnvelope,
|
|
36
40
|
"/orders/update" => Inttegro::OrderEnvelope,
|
|
@@ -150,6 +154,10 @@ module Inttegro
|
|
|
150
154
|
"/customers/lookup" => "Inttegro::LookupCustomerRequest",
|
|
151
155
|
"/customers/update" => "Inttegro::UpdateCustomerRequest",
|
|
152
156
|
"/customers/page" => "Inttegro::PageCustomersRequest",
|
|
157
|
+
"/checkout/lookup" => "Inttegro::CheckoutOrderReferenceRequest",
|
|
158
|
+
"/checkout/pay" => "Inttegro::CheckoutPayRequest",
|
|
159
|
+
"/checkout/confirm_payment" => "Inttegro::CheckoutConfirmPaymentRequest",
|
|
160
|
+
"/checkout/request_confirmation" => "Inttegro::CheckoutOrderReferenceRequest",
|
|
153
161
|
"/orders/create" => "T.any(Inttegro::CreateOrderNewCustomer, Inttegro::CreateOrderExistingCustomer)",
|
|
154
162
|
"/orders/lookup" => "Inttegro::LookupOrderRequest",
|
|
155
163
|
"/orders/update" => "Inttegro::UpdateOrderRequest",
|
|
@@ -267,6 +275,10 @@ module Inttegro
|
|
|
267
275
|
"/customers/lookup" => "lookupCustomer",
|
|
268
276
|
"/customers/update" => "updateCustomer",
|
|
269
277
|
"/customers/page" => "pageCustomers",
|
|
278
|
+
"/checkout/lookup" => "lookupCheckoutOrder",
|
|
279
|
+
"/checkout/pay" => "payCheckoutOrder",
|
|
280
|
+
"/checkout/confirm_payment" => "confirmCheckoutPayment",
|
|
281
|
+
"/checkout/request_confirmation" => "requestCheckoutConfirmation",
|
|
270
282
|
"/orders/create" => "createOrder",
|
|
271
283
|
"/orders/lookup" => "lookupOrder",
|
|
272
284
|
"/orders/update" => "updateOrder",
|
data/lib/inttegro/http_client.rb
CHANGED
|
@@ -12,6 +12,7 @@ require_relative "models"
|
|
|
12
12
|
require_relative "generated/operations"
|
|
13
13
|
require_relative "response_object"
|
|
14
14
|
require_relative "transport_response"
|
|
15
|
+
require_relative "telemetry"
|
|
15
16
|
require_relative "types"
|
|
16
17
|
require_relative "version"
|
|
17
18
|
|
|
@@ -34,10 +35,20 @@ module Inttegro
|
|
|
34
35
|
base_url: T.nilable(String),
|
|
35
36
|
read_timeout: T.nilable(Numeric),
|
|
36
37
|
open_timeout: T.nilable(Numeric),
|
|
37
|
-
adapter: T.nilable(Types::Adapter)
|
|
38
|
+
adapter: T.nilable(Types::Adapter),
|
|
39
|
+
telemetry_enabled: T::Boolean,
|
|
40
|
+
tracer_provider: T.nilable(OpenTelemetry::Trace::TracerProvider)
|
|
38
41
|
).void
|
|
39
42
|
end
|
|
40
|
-
def initialize(
|
|
43
|
+
def initialize(
|
|
44
|
+
api_key:,
|
|
45
|
+
base_url: DEFAULT_BASE_URL,
|
|
46
|
+
read_timeout: 30,
|
|
47
|
+
open_timeout: 10,
|
|
48
|
+
adapter: nil,
|
|
49
|
+
telemetry_enabled: true,
|
|
50
|
+
tracer_provider: nil
|
|
51
|
+
)
|
|
41
52
|
@api_key = T.let(api_key || "", String)
|
|
42
53
|
raise ArgumentError, "api_key is required" if @api_key.strip.empty?
|
|
43
54
|
|
|
@@ -48,6 +59,10 @@ module Inttegro
|
|
|
48
59
|
@read_timeout = T.let(read_timeout, T.nilable(Numeric))
|
|
49
60
|
@open_timeout = T.let(open_timeout, T.nilable(Numeric))
|
|
50
61
|
@adapter = T.let(adapter, T.nilable(Types::Adapter))
|
|
62
|
+
@telemetry = T.let(
|
|
63
|
+
Telemetry.new(Inttegro::VERSION, enabled: telemetry_enabled, tracer_provider: tracer_provider),
|
|
64
|
+
Telemetry
|
|
65
|
+
)
|
|
51
66
|
end
|
|
52
67
|
|
|
53
68
|
sig { params(path: String, headers: Types::Headers, query: T.nilable(Types::Query)).returns(ResponseValue) }
|
|
@@ -165,16 +180,17 @@ module Inttegro
|
|
|
165
180
|
fields: Types::Payload,
|
|
166
181
|
files: Types::Payload,
|
|
167
182
|
headers: Types::Headers,
|
|
168
|
-
authenticated: T::Boolean
|
|
183
|
+
authenticated: T::Boolean,
|
|
184
|
+
operation: T.nilable(String)
|
|
169
185
|
)
|
|
170
186
|
.returns(T.type_parameter(:Model))
|
|
171
187
|
end
|
|
172
|
-
def post_multipart_model(path, model, fields: {}, files: {}, headers: {}, authenticated: true)
|
|
188
|
+
def post_multipart_model(path, model, fields: {}, files: {}, headers: {}, authenticated: true, operation: nil)
|
|
173
189
|
unless model <= T::Struct
|
|
174
190
|
raise TypeError, "response model for #{path} must inherit from T::Struct"
|
|
175
191
|
end
|
|
176
192
|
|
|
177
|
-
response = perform_multipart(path, fields, files, headers, authenticated, model)
|
|
193
|
+
response = perform_multipart(path, fields, files, headers, authenticated, model, operation)
|
|
178
194
|
return T.cast(response, T.type_parameter(:Model)) if response.is_a?(model)
|
|
179
195
|
|
|
180
196
|
raise TypeError, "expected #{model} from #{path}, got #{response.class}"
|
|
@@ -218,62 +234,76 @@ module Inttegro
|
|
|
218
234
|
files: Types::Payload,
|
|
219
235
|
headers: Types::Headers,
|
|
220
236
|
authenticated: T::Boolean,
|
|
221
|
-
model: T.nilable(T::Class[T::Struct])
|
|
237
|
+
model: T.nilable(T::Class[T::Struct]),
|
|
238
|
+
operation: T.nilable(String)
|
|
222
239
|
).returns(ResponseValue)
|
|
223
240
|
end
|
|
224
|
-
def perform_multipart(path, fields, files, headers, authenticated, model)
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
headers
|
|
233
|
-
|
|
234
|
-
|
|
241
|
+
def perform_multipart(path, fields, files, headers, authenticated, model, operation = nil)
|
|
242
|
+
@telemetry.in_span(path, :post, @base_url, Inttegro::VERSION, operation) do |span|
|
|
243
|
+
uri = build_uri(path, nil)
|
|
244
|
+
request = Net::HTTP::Post.new(uri)
|
|
245
|
+
request["Accept"] = "application/json"
|
|
246
|
+
request["User-Agent"] = USER_AGENT
|
|
247
|
+
request["Authorization"] = "Bearer #{@api_key}" if authenticated
|
|
248
|
+
headers = headers.dup
|
|
249
|
+
if authenticated && idempotent_mutation_path?(path) && !header_present?(headers, "Idempotency-Key")
|
|
250
|
+
headers["Idempotency-Key"] = generate_idempotency_key
|
|
251
|
+
end
|
|
252
|
+
headers.each { |key, value| request[key] = value }
|
|
235
253
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
254
|
+
form = []
|
|
255
|
+
fields.each do |key, value|
|
|
256
|
+
next if value.nil?
|
|
239
257
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
258
|
+
form << [key.to_s, value.is_a?(Hash) || value.is_a?(Array) ? JSON.generate(value) : value.to_s]
|
|
259
|
+
end
|
|
260
|
+
files.each do |key, file_path|
|
|
261
|
+
raise ArgumentError, "file path for #{key} must be a String" unless file_path.is_a?(String)
|
|
244
262
|
|
|
245
|
-
|
|
263
|
+
form << [key.to_s, File.open(file_path)]
|
|
264
|
+
end
|
|
265
|
+
request.set_form(form, "multipart/form-data")
|
|
266
|
+
@telemetry.prepare(span, request)
|
|
267
|
+
|
|
268
|
+
raw_response = @adapter ? @adapter.call(uri, request) : build_http(uri).request(request)
|
|
269
|
+
response = TransportResponse.new(raw_response)
|
|
270
|
+
@telemetry.response(span, response, decoded: false)
|
|
271
|
+
result = handle_response(path, response, model)
|
|
272
|
+
@telemetry.decoded(span)
|
|
273
|
+
result
|
|
246
274
|
end
|
|
247
|
-
request.set_form(form, "multipart/form-data")
|
|
248
|
-
|
|
249
|
-
raw_response = @adapter ? @adapter.call(uri, request) : build_http(uri).request(request)
|
|
250
|
-
response = TransportResponse.new(raw_response)
|
|
251
|
-
handle_response(path, response, model)
|
|
252
275
|
end
|
|
253
276
|
|
|
254
277
|
sig { params(path: String, body: Types::RequestBody).returns(FileDownload) }
|
|
255
278
|
def post_binary_json(path, body)
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
279
|
+
@telemetry.in_span(path, :post, @base_url, Inttegro::VERSION) do |span|
|
|
280
|
+
payload = with_request_meta_idempotency(:post, path, coerce_body(body), {})
|
|
281
|
+
response = raw_request(:post, path, JSON.dump(payload), {
|
|
282
|
+
"Accept" => "application/octet-stream",
|
|
283
|
+
"Content-Type" => "application/json",
|
|
284
|
+
"Authorization" => "Bearer #{@api_key}"
|
|
285
|
+
}, span)
|
|
286
|
+
@telemetry.response(span, response, decoded: false)
|
|
287
|
+
return FileDownload.new(response.body, response.headers) if response.code.to_i < 400
|
|
288
|
+
|
|
289
|
+
raise_response_error(response)
|
|
290
|
+
end
|
|
265
291
|
end
|
|
266
292
|
|
|
267
293
|
sig { params(url: String).returns(FileDownload) }
|
|
268
294
|
def get_binary_public(url)
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
295
|
+
@telemetry.in_span(url, :get, @base_url, Inttegro::VERSION, "file_links.download") do |span|
|
|
296
|
+
uri = build_uri(url, nil)
|
|
297
|
+
request = Net::HTTP::Get.new(uri)
|
|
298
|
+
request["User-Agent"] = USER_AGENT
|
|
299
|
+
@telemetry.prepare(span, request)
|
|
300
|
+
raw_response = @adapter ? @adapter.call(uri, request) : build_http(uri).request(request)
|
|
301
|
+
response = TransportResponse.new(raw_response)
|
|
302
|
+
@telemetry.response(span, response, decoded: false)
|
|
303
|
+
return FileDownload.new(response.body, response.headers) if response.code.to_i < 400
|
|
304
|
+
|
|
305
|
+
raise_response_error(response)
|
|
306
|
+
end
|
|
277
307
|
end
|
|
278
308
|
|
|
279
309
|
sig do
|
|
@@ -287,20 +317,26 @@ module Inttegro
|
|
|
287
317
|
).returns(ResponseValue)
|
|
288
318
|
end
|
|
289
319
|
def request(method, path, body: nil, headers: {}, query: nil, response_model: nil)
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
320
|
+
@telemetry.in_span(path, method, @base_url, Inttegro::VERSION) do |span|
|
|
321
|
+
uri = build_uri(path, query)
|
|
322
|
+
body = validate_body(path, coerce_body(body))
|
|
323
|
+
body = with_request_meta_idempotency(method, path, body, headers)
|
|
324
|
+
request = build_request(method, uri, body, headers)
|
|
325
|
+
@telemetry.prepare(span, request)
|
|
326
|
+
|
|
327
|
+
raw_response =
|
|
328
|
+
if @adapter
|
|
329
|
+
@adapter.call(uri, request)
|
|
330
|
+
else
|
|
331
|
+
http = build_http(uri)
|
|
332
|
+
http.request(request)
|
|
333
|
+
end
|
|
334
|
+
response = TransportResponse.new(raw_response)
|
|
335
|
+
@telemetry.response(span, response, decoded: false)
|
|
336
|
+
result = handle_response(path, response, response_model)
|
|
337
|
+
@telemetry.decoded(span)
|
|
338
|
+
result
|
|
339
|
+
end
|
|
304
340
|
rescue Timeout::Error, Errno::ETIMEDOUT => e
|
|
305
341
|
raise TimeoutError.new("Request timed out", e)
|
|
306
342
|
rescue SocketError, Errno::ECONNREFUSED, Errno::ECONNRESET => e
|
|
@@ -327,13 +363,15 @@ module Inttegro
|
|
|
327
363
|
method: T.any(String, Symbol),
|
|
328
364
|
path: String,
|
|
329
365
|
body: T.nilable(String),
|
|
330
|
-
headers: Types::Headers
|
|
366
|
+
headers: Types::Headers,
|
|
367
|
+
span: T.nilable(OpenTelemetry::Trace::Span)
|
|
331
368
|
).returns(TransportResponse)
|
|
332
369
|
end
|
|
333
|
-
def raw_request(method, path, body, headers)
|
|
370
|
+
def raw_request(method, path, body, headers, span = nil)
|
|
334
371
|
uri = build_uri(path, nil)
|
|
335
372
|
request = build_request(method, uri, nil, headers)
|
|
336
373
|
request.body = body if body
|
|
374
|
+
@telemetry.prepare(span, request)
|
|
337
375
|
raw_response = @adapter ? @adapter.call(uri, request) : build_http(uri).request(request)
|
|
338
376
|
TransportResponse.new(raw_response)
|
|
339
377
|
end
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# typed: strict
|
|
3
|
+
|
|
4
|
+
require "opentelemetry-api"
|
|
5
|
+
require "sorbet-runtime"
|
|
6
|
+
require "uri"
|
|
7
|
+
|
|
8
|
+
require_relative "errors"
|
|
9
|
+
|
|
10
|
+
module Inttegro
|
|
11
|
+
# Emits redacted SDK spans to the application's OpenTelemetry provider.
|
|
12
|
+
# This class never configures an exporter or sends telemetry to Inttegro.
|
|
13
|
+
class Telemetry
|
|
14
|
+
extend T::Sig
|
|
15
|
+
|
|
16
|
+
SAFE_RESOURCES = %w[
|
|
17
|
+
apps balance_transactions balances broadcasts checkout chimes customers file_links file_references files
|
|
18
|
+
financial_accounts keys message_templates orders otp payment_methods payouts ping prices products
|
|
19
|
+
purchase_intents refunds schedules sessions spec upload_requests
|
|
20
|
+
].freeze
|
|
21
|
+
SAFE_ACTIONS = %w[
|
|
22
|
+
activate add_price archive broadcast cancel complete confirm_payment confirm_verification connect contents
|
|
23
|
+
countries create deactivate delete destroy disable disable_fx disable_pull disable_push disactivate disconnect
|
|
24
|
+
enable enable_fx enable_pull enable_push finalize generate initiate lookup new open page pay publish reconcile
|
|
25
|
+
reconnect refund render_preview request_confirmation review revoke schedule send send_invoice send_receipt
|
|
26
|
+
set_default_unit_price set_destinations settings tokenize unarchive unpublish update upload usage verify
|
|
27
|
+
].freeze
|
|
28
|
+
|
|
29
|
+
sig do
|
|
30
|
+
params(
|
|
31
|
+
version: String,
|
|
32
|
+
enabled: T::Boolean,
|
|
33
|
+
tracer_provider: T.nilable(OpenTelemetry::Trace::TracerProvider)
|
|
34
|
+
).void
|
|
35
|
+
end
|
|
36
|
+
def initialize(version, enabled: true, tracer_provider: nil)
|
|
37
|
+
@enabled = T.let(enabled, T::Boolean)
|
|
38
|
+
provider = tracer_provider || OpenTelemetry.tracer_provider
|
|
39
|
+
@tracer = T.let(provider.tracer("inttegro", version), OpenTelemetry::Trace::Tracer)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
sig do
|
|
43
|
+
type_parameters(:Result)
|
|
44
|
+
.params(
|
|
45
|
+
path_or_url: String,
|
|
46
|
+
method: T.any(String, Symbol),
|
|
47
|
+
base_url: String,
|
|
48
|
+
version: String,
|
|
49
|
+
operation_override: T.nilable(String),
|
|
50
|
+
block: T.proc.params(span: T.nilable(OpenTelemetry::Trace::Span)).returns(T.type_parameter(:Result))
|
|
51
|
+
)
|
|
52
|
+
.returns(T.type_parameter(:Result))
|
|
53
|
+
end
|
|
54
|
+
def in_span(path_or_url, method, base_url, version, operation_override = nil, &block)
|
|
55
|
+
return yield(nil) unless @enabled
|
|
56
|
+
|
|
57
|
+
operation, route, server_address = request_details(path_or_url, base_url, operation_override)
|
|
58
|
+
attributes = {
|
|
59
|
+
"inttegro.operation.name" => operation,
|
|
60
|
+
"inttegro.sdk.language" => "ruby",
|
|
61
|
+
"inttegro.sdk.version" => version,
|
|
62
|
+
"http.request.method" => method.to_s.upcase,
|
|
63
|
+
"server.address" => server_address
|
|
64
|
+
}
|
|
65
|
+
attributes["url.template"] = route if route
|
|
66
|
+
span = @tracer.start_span("inttegro.#{operation}", kind: :client, attributes: attributes)
|
|
67
|
+
|
|
68
|
+
begin
|
|
69
|
+
OpenTelemetry::Trace.with_span(span) { |_active_span, _context| yield(span) }
|
|
70
|
+
rescue StandardError => e
|
|
71
|
+
error_type = classify_error(e)
|
|
72
|
+
span.set_attribute("error.type", error_type)
|
|
73
|
+
span.status = OpenTelemetry::Trace::Status.error
|
|
74
|
+
span.add_event("inttegro.request.failed", attributes: { "error.type" => error_type })
|
|
75
|
+
raise
|
|
76
|
+
ensure
|
|
77
|
+
span.finish
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
sig { params(span: T.nilable(OpenTelemetry::Trace::Span), request: Net::HTTPRequest).void }
|
|
82
|
+
def prepare(span, request)
|
|
83
|
+
if @enabled
|
|
84
|
+
carrier = T.let({}, T::Hash[String, String])
|
|
85
|
+
OpenTelemetry.propagation.inject(carrier)
|
|
86
|
+
carrier.each { |key, value| request[key] = value unless request[key] }
|
|
87
|
+
end
|
|
88
|
+
return unless span
|
|
89
|
+
|
|
90
|
+
span.add_event("inttegro.request.prepared")
|
|
91
|
+
span.add_event(
|
|
92
|
+
"inttegro.http.attempt.started",
|
|
93
|
+
attributes: { "http.request.resend_count" => 0 }
|
|
94
|
+
)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
sig do
|
|
98
|
+
params(
|
|
99
|
+
span: T.nilable(OpenTelemetry::Trace::Span),
|
|
100
|
+
response: TransportResponse,
|
|
101
|
+
decoded: T::Boolean
|
|
102
|
+
).void
|
|
103
|
+
end
|
|
104
|
+
def response(span, response, decoded:)
|
|
105
|
+
return unless span
|
|
106
|
+
|
|
107
|
+
status = response.code.to_i
|
|
108
|
+
span.set_attribute("http.response.status_code", status)
|
|
109
|
+
request_id = response["x-request-id"]
|
|
110
|
+
span.set_attribute("inttegro.request.id", request_id) if request_id && !request_id.empty?
|
|
111
|
+
span.add_event(
|
|
112
|
+
"inttegro.response.received",
|
|
113
|
+
attributes: {
|
|
114
|
+
"http.response.status_code" => status,
|
|
115
|
+
"http.request.resend_count" => 0
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
span.add_event("inttegro.response.decoded") if decoded
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
sig { params(span: T.nilable(OpenTelemetry::Trace::Span)).void }
|
|
122
|
+
def decoded(span)
|
|
123
|
+
span.add_event("inttegro.response.decoded") if span
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
private
|
|
127
|
+
|
|
128
|
+
sig do
|
|
129
|
+
params(path_or_url: String, base_url: String, override: T.nilable(String))
|
|
130
|
+
.returns([String, T.nilable(String), String])
|
|
131
|
+
end
|
|
132
|
+
def request_details(path_or_url, base_url, override)
|
|
133
|
+
uri = path_or_url.start_with?("http://", "https://") ? URI.parse(path_or_url) : URI.join("#{base_url}/", path_or_url.sub(%r{\A/}, ""))
|
|
134
|
+
segments = path_or_url.start_with?("http://", "https://") ? [] : T.must(uri.path).split("/").reject(&:empty?)
|
|
135
|
+
resource = segments[0]
|
|
136
|
+
action = segments[1]
|
|
137
|
+
known_route = !resource.nil? && segments.length <= 2 && SAFE_RESOURCES.include?(resource) &&
|
|
138
|
+
(action.nil? || SAFE_ACTIONS.include?(action))
|
|
139
|
+
route = known_route ? uri.path : nil
|
|
140
|
+
derived_operation = known_route ? "#{resource}.#{action || (resource == 'balances' ? 'lookup' : 'request')}" : "http.request"
|
|
141
|
+
[override || derived_operation, route, uri.host || "unknown"]
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
sig { params(error: StandardError).returns(String) }
|
|
145
|
+
def classify_error(error)
|
|
146
|
+
return "timeout" if error.is_a?(TimeoutError) || error.is_a?(Timeout::Error) || error.is_a?(Errno::ETIMEDOUT)
|
|
147
|
+
return "network_error" if error.is_a?(NetworkError) || error.is_a?(SocketError) || error.is_a?(SystemCallError)
|
|
148
|
+
return "http_#{error.status}" if error.is_a?(APIError)
|
|
149
|
+
return "decode_error" if error.is_a?(JSON::ParserError)
|
|
150
|
+
|
|
151
|
+
"unknown_error"
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
private_constant :Telemetry
|
|
156
|
+
end
|
data/lib/inttegro/version.rb
CHANGED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
|
|
3
|
+
# Minimal signatures for the opentelemetry-api surface used by this SDK.
|
|
4
|
+
module OpenTelemetry
|
|
5
|
+
sig { returns(Trace::TracerProvider) }
|
|
6
|
+
def self.tracer_provider; end
|
|
7
|
+
|
|
8
|
+
sig { returns(Context::Propagation::TextMapPropagator) }
|
|
9
|
+
def self.propagation; end
|
|
10
|
+
|
|
11
|
+
class Context
|
|
12
|
+
module Propagation
|
|
13
|
+
class TextMapPropagator
|
|
14
|
+
sig { params(carrier: T::Hash[String, String]).void }
|
|
15
|
+
def inject(carrier); end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
module Trace
|
|
21
|
+
sig do
|
|
22
|
+
type_parameters(:Result)
|
|
23
|
+
.params(
|
|
24
|
+
span: Span,
|
|
25
|
+
block: T.proc.params(span: Span, context: OpenTelemetry::Context).returns(T.type_parameter(:Result))
|
|
26
|
+
)
|
|
27
|
+
.returns(T.type_parameter(:Result))
|
|
28
|
+
end
|
|
29
|
+
def self.with_span(span, &block); end
|
|
30
|
+
|
|
31
|
+
class TracerProvider
|
|
32
|
+
sig do
|
|
33
|
+
params(
|
|
34
|
+
deprecated_name: T.nilable(String),
|
|
35
|
+
deprecated_version: T.nilable(String),
|
|
36
|
+
name: T.nilable(String),
|
|
37
|
+
version: T.nilable(String),
|
|
38
|
+
attributes: T.nilable(Object)
|
|
39
|
+
).returns(Tracer)
|
|
40
|
+
end
|
|
41
|
+
def tracer(deprecated_name = nil, deprecated_version = nil, name: nil, version: nil, attributes: nil); end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class Tracer
|
|
45
|
+
sig do
|
|
46
|
+
params(
|
|
47
|
+
name: String,
|
|
48
|
+
with_parent: T.nilable(Object),
|
|
49
|
+
attributes: T.nilable(Object),
|
|
50
|
+
links: T.nilable(Object),
|
|
51
|
+
start_timestamp: T.nilable(Time),
|
|
52
|
+
kind: T.nilable(Symbol)
|
|
53
|
+
).returns(Span)
|
|
54
|
+
end
|
|
55
|
+
def start_span(name, with_parent: nil, attributes: nil, links: nil, start_timestamp: nil, kind: nil); end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class Span
|
|
59
|
+
sig { params(key: String, value: Object).returns(Span) }
|
|
60
|
+
def set_attribute(key, value); end
|
|
61
|
+
|
|
62
|
+
sig { params(name: String, attributes: T.nilable(Object), timestamp: T.nilable(Time)).returns(Span) }
|
|
63
|
+
def add_event(name, attributes: nil, timestamp: nil); end
|
|
64
|
+
|
|
65
|
+
sig { params(status: Status).void }
|
|
66
|
+
def status=(status); end
|
|
67
|
+
|
|
68
|
+
sig { void }
|
|
69
|
+
def finish; end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
class Status
|
|
73
|
+
sig { params(description: String).returns(Status) }
|
|
74
|
+
def self.error(description = ""); end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
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.1
|
|
4
|
+
version: 4.2.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-
|
|
11
|
+
date: 2026-09-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: sorbet-runtime
|
|
@@ -24,6 +24,20 @@ dependencies:
|
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '0.6'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: opentelemetry-api
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '1.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '1.0'
|
|
27
41
|
description: First-party Ruby client for working with orders, payments, payouts, notifications,
|
|
28
42
|
and verification on Inttegro.
|
|
29
43
|
email:
|
|
@@ -73,10 +87,12 @@ files:
|
|
|
73
87
|
- lib/inttegro/resources/spec.rb
|
|
74
88
|
- lib/inttegro/resources/upload_requests.rb
|
|
75
89
|
- lib/inttegro/response_object.rb
|
|
90
|
+
- lib/inttegro/telemetry.rb
|
|
76
91
|
- lib/inttegro/transport_response.rb
|
|
77
92
|
- lib/inttegro/types.rb
|
|
78
93
|
- lib/inttegro/version.rb
|
|
79
94
|
- rbi/inttegro/generated.rbi
|
|
95
|
+
- rbi/opentelemetry-api.rbi
|
|
80
96
|
homepage: https://studio.inttegro.com
|
|
81
97
|
licenses:
|
|
82
98
|
- MIT
|