hcbv4 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,164 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCBV4
4
+ # An HCB organization (also called an "event").
5
+ # Holds funds, issues cards, and manages transactions.
6
+ Organization = Data.define(
7
+ :id, :name, :slug, :country, :icon, :background_image, :created_at,
8
+ :parent_id, :donation_page_available, :playground_mode,
9
+ :playground_mode_meeting_requested, :transparent, :fee_percentage,
10
+ :balance_cents, :fee_balance_cents, :total_spent_cents, :total_raised_cents,
11
+ :account_number, :routing_number, :swift_bic_code, :users, :_client
12
+ ) do
13
+ include Resource
14
+
15
+ # @param hash [Hash] API response
16
+ # @param client [Client, nil] for making subsequent requests
17
+ # @return [Organization]
18
+ def self.from_hash(hash, client: nil)
19
+ new(
20
+ id: hash["id"],
21
+ name: hash["name"],
22
+ slug: hash["slug"],
23
+ country: hash["country"],
24
+ icon: hash["icon"],
25
+ background_image: hash["background_image"],
26
+ created_at: hash["created_at"],
27
+ parent_id: hash["parent_id"],
28
+ donation_page_available: hash["donation_page_available"],
29
+ playground_mode: hash["playground_mode"],
30
+ playground_mode_meeting_requested: hash["playground_mode_meeting_requested"],
31
+ transparent: hash["transparent"],
32
+ fee_percentage: hash["fee_percentage"],
33
+ balance_cents: hash["balance_cents"],
34
+ fee_balance_cents: hash["fee_balance_cents"],
35
+ total_spent_cents: hash["total_spent_cents"],
36
+ total_raised_cents: hash["total_raised_cents"],
37
+ account_number: hash["account_number"],
38
+ routing_number: hash["routing_number"],
39
+ swift_bic_code: hash["swift_bic_code"],
40
+ users: hash["users"]&.map { |u| OrganizationUser.from_hash(u) },
41
+ _client: client
42
+ )
43
+ end
44
+
45
+ # Refreshes organization data from the API.
46
+ # @return [Organization]
47
+ def reload!
48
+ require_client!
49
+ _client.organization(id)
50
+ end
51
+
52
+ # @return [Array<CardGrant>]
53
+ def card_grants(expand: [])
54
+ require_client!
55
+ _client.organization_card_grants(id, expand:)
56
+ end
57
+
58
+ # @return [Array<StripeCard>]
59
+ def stripe_cards(expand: [])
60
+ require_client!
61
+ _client.organization_stripe_cards(id, expand:)
62
+ end
63
+
64
+ # @return [Array<Invoice>]
65
+ def invoices
66
+ require_client!
67
+ _client.invoices(event_id: id)
68
+ end
69
+
70
+ # @return [Array<Sponsor>]
71
+ def sponsors
72
+ require_client!
73
+ _client.sponsors(event_id: id)
74
+ end
75
+
76
+ # @return [Array<User>] users following this transparent org
77
+ def followers
78
+ require_client!
79
+ _client.organization_followers(id)
80
+ end
81
+
82
+ # Returns paginated transactions.
83
+ # @return [TransactionList]
84
+ def transactions(**opts)
85
+ require_client!
86
+ _client.transactions(id, **opts)
87
+ end
88
+
89
+ # @return [Array<Organization>] child organizations
90
+ def sub_organizations
91
+ require_client!
92
+ _client.sub_organizations(id)
93
+ end
94
+
95
+ # Creates a card grant for this organization.
96
+ # @return [CardGrant]
97
+ def create_card_grant(amount_cents:, email:, **opts)
98
+ require_client!
99
+ _client.create_card_grant(event_id: id, amount_cents:, email:, **opts)
100
+ end
101
+
102
+ # Creates an invoice for a sponsor.
103
+ # @return [Invoice]
104
+ def create_invoice(sponsor_id:, due_date:, item_description:, item_amount:)
105
+ require_client!
106
+ _client.create_invoice(event_id: id, sponsor_id:, due_date:, item_description:, item_amount:)
107
+ end
108
+
109
+ # Creates a sponsor record.
110
+ # @return [Sponsor]
111
+ def create_sponsor(name:, contact_email:, **address)
112
+ require_client!
113
+ _client.create_sponsor(event_id: id, name:, contact_email:, **address)
114
+ end
115
+
116
+ # Transfers funds to another organization.
117
+ # @return [Transfer]
118
+ def create_disbursement(to_organization_id:, amount_cents:, name:)
119
+ require_client!
120
+ _client.create_disbursement(event_id: id, to_organization_id:, amount_cents:, name:)
121
+ end
122
+
123
+ # Initiates an ACH bank transfer.
124
+ # @return [Hash]
125
+ def create_ach_transfer(routing_number:, account_number:, recipient_name:, amount_money:, payment_for:, **opts)
126
+ require_client!
127
+ _client.create_ach_transfer(event_id: id, routing_number:, account_number:, recipient_name:, amount_money:,
128
+ payment_for:, **opts)
129
+ end
130
+
131
+ # Records an in-person donation.
132
+ # @return [Donation]
133
+ def create_donation(amount_cents:, **opts)
134
+ require_client!
135
+ _client.create_donation(event_id: id, amount_cents:, **opts)
136
+ end
137
+
138
+ # Invites a user to this organization.
139
+ # @return [Invitation]
140
+ def create_invitation(email:, role: nil, **opts)
141
+ require_client!
142
+ _client.create_invitation(event_id: id, email:, role:, **opts)
143
+ end
144
+
145
+ # Creates a sub-organization under this one.
146
+ # @return [Organization]
147
+ def create_sub_organization(name:, email:, **opts)
148
+ require_client!
149
+ _client.create_sub_organization(id, name:, email:, **opts)
150
+ end
151
+
152
+ # @return [Boolean]
153
+ def donation_page_available? = !!donation_page_available
154
+
155
+ # @return [Boolean]
156
+ def playground_mode? = !!playground_mode
157
+
158
+ # @return [Boolean]
159
+ def playground_mode_meeting_requested? = !!playground_mode_meeting_requested
160
+
161
+ # @return [Boolean]
162
+ def transparent? = !!transparent
163
+ end
164
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCBV4
4
+ # A user with organization-specific membership info (role, join date).
5
+ # Returned when expanding :users on an organization.
6
+ # @attr_reader joined_at [String, nil] ISO timestamp when user joined the org
7
+ # @attr_reader role [String, nil] "member" or "manager"
8
+ class OrganizationUser < User
9
+ attr_reader :joined_at, :role
10
+
11
+ def initialize(id:, name: nil, email: nil, avatar: nil, admin: nil, auditor: nil, birthday: nil,
12
+ shipping_address: nil, joined_at: nil, role: nil)
13
+ super(id:, name:, email:, avatar:, admin:, auditor:, birthday:, shipping_address:)
14
+ @joined_at = joined_at
15
+ @role = role
16
+ end
17
+
18
+ # @param hash [Hash] API response
19
+ # @return [OrganizationUser]
20
+ def self.from_hash(hash)
21
+ new(
22
+ id: hash["id"],
23
+ name: hash["name"],
24
+ email: hash["email"],
25
+ avatar: hash["avatar"],
26
+ admin: hash["admin"],
27
+ auditor: hash["auditor"],
28
+ joined_at: hash["joined_at"],
29
+ role: hash["role"]
30
+ )
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCBV4
4
+ # An uploaded receipt image attached to a transaction.
5
+ Receipt = Data.define(:id, :created_at, :url, :preview_url, :filename, :uploader, :_client) do
6
+ include Resource
7
+
8
+ # @param hash [Hash] API response
9
+ # @param client [Client, nil]
10
+ # @return [Receipt]
11
+ def self.from_hash(hash, client: nil)
12
+ new(
13
+ id: hash["id"],
14
+ created_at: hash["created_at"],
15
+ url: hash["url"],
16
+ preview_url: hash["preview_url"],
17
+ filename: hash["filename"],
18
+ uploader: hash["uploader"] ? User.from_hash(hash["uploader"]) : nil,
19
+ _client: client
20
+ )
21
+ end
22
+
23
+ # Deletes this receipt.
24
+ # @return [nil]
25
+ def delete!
26
+ require_client!
27
+ _client.delete_receipt(id)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCBV4
4
+ module Resource
5
+ def require_client!
6
+ raise Error, "No client attached to this #{self.class.name.split("::").last}" unless _client
7
+ end
8
+
9
+ module ClassMethods
10
+ def of_id(id, client:, **extra)
11
+ attrs = members.to_h { |m| [m, nil] }
12
+ attrs[:id] = id
13
+ attrs[:_client] = client
14
+ attrs.merge!(extra.slice(*members))
15
+ new(**attrs)
16
+ end
17
+ end
18
+
19
+ def self.included(base)
20
+ base.extend(ClassMethods) if base.respond_to?(:members)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCBV4
4
+ # A sponsor or donor contact for invoicing.
5
+ Sponsor = Data.define(
6
+ :id, :name, :slug, :contact_email, :created_at, :event_id, :stripe_customer_id,
7
+ :address_line1, :address_line2, :address_city, :address_state,
8
+ :address_postal_code, :address_country, :_client
9
+ ) do
10
+ include Resource
11
+
12
+ # @param hash [Hash] API response
13
+ # @param client [Client, nil]
14
+ # @return [Sponsor]
15
+ def self.from_hash(hash, client: nil)
16
+ new(
17
+ id: hash["id"], name: hash["name"], slug: hash["slug"], contact_email: hash["contact_email"],
18
+ created_at: hash["created_at"], event_id: hash["event_id"], stripe_customer_id: hash["stripe_customer_id"],
19
+ address_line1: hash["address_line1"], address_line2: hash["address_line2"], address_city: hash["address_city"],
20
+ address_state: hash["address_state"], address_postal_code: hash["address_postal_code"],
21
+ address_country: hash["address_country"],
22
+ _client: client
23
+ )
24
+ end
25
+
26
+ # Refreshes sponsor data from the API.
27
+ # @return [Sponsor]
28
+ def reload!
29
+ require_client!
30
+ _client.sponsor(id)
31
+ end
32
+
33
+ # Creates an invoice for this sponsor.
34
+ # @param due_date [String] ISO date (YYYY-MM-DD)
35
+ # @param item_description [String]
36
+ # @param item_amount [Integer] amount in cents
37
+ # @return [Invoice]
38
+ def create_invoice(due_date:, item_description:, item_amount:)
39
+ require_client!
40
+ _client.create_invoice(event_id:, sponsor_id: id, due_date:, item_description:, item_amount:)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCBV4
4
+ # Physical card personalization (color, logo).
5
+ CardPersonalization = Data.define(:color, :logo_url) do
6
+ def self.from_hash(hash)
7
+ return nil unless hash
8
+
9
+ new(
10
+ color: hash["color"],
11
+ logo_url: hash["logo_url"]
12
+ )
13
+ end
14
+ end
15
+
16
+ # Shipping address for physical cards.
17
+ CardShippingAddress = Data.define(:line1, :line2, :city, :state, :country, :postal_code) do
18
+ def self.from_hash(hash)
19
+ return nil unless hash
20
+
21
+ new(
22
+ line1: hash["line1"],
23
+ line2: hash["line2"],
24
+ city: hash["city"],
25
+ state: hash["state"],
26
+ country: hash["country"],
27
+ postal_code: hash["postal_code"]
28
+ )
29
+ end
30
+ end
31
+
32
+ # Physical card shipping status and tracking.
33
+ CardShipping = Data.define(:status, :eta, :address) do
34
+ def self.from_hash(hash)
35
+ return nil unless hash
36
+
37
+ new(
38
+ status: hash["status"],
39
+ eta: hash["eta"],
40
+ address: CardShippingAddress.from_hash(hash["address"])
41
+ )
42
+ end
43
+ end
44
+
45
+ # A Stripe Issuing card (virtual or physical).
46
+ StripeCard = Data.define(
47
+ :id, :type, :status, :name, :last4, :exp_month, :exp_year, :created_at,
48
+ :total_spent_cents, :balance_available, :organization, :user,
49
+ :personalization, :shipping, :_client
50
+ ) do
51
+ include Resource
52
+
53
+ # @param hash [Hash] API response
54
+ # @param client [Client, nil]
55
+ # @return [StripeCard]
56
+ def self.from_hash(hash, client: nil)
57
+ new(
58
+ id: hash["id"],
59
+ type: hash["type"],
60
+ status: hash["status"],
61
+ name: hash["name"],
62
+ last4: hash["last4"],
63
+ exp_month: hash["exp_month"],
64
+ exp_year: hash["exp_year"],
65
+ created_at: hash["created_at"],
66
+ total_spent_cents: hash["total_spent_cents"],
67
+ balance_available: hash["balance_available"],
68
+ organization: hash["organization"] ? Organization.from_hash(hash["organization"]) : nil,
69
+ user: hash["user"] ? User.from_hash(hash["user"]) : nil,
70
+ personalization: CardPersonalization.from_hash(hash["personalization"]),
71
+ shipping: CardShipping.from_hash(hash["shipping"]),
72
+ _client: client
73
+ )
74
+ end
75
+
76
+ # Freezes the card, blocking new transactions.
77
+ # @return [StripeCard]
78
+ def freeze!
79
+ require_client!
80
+ _client.update_stripe_card(id, status: "frozen")
81
+ end
82
+
83
+ # Unfreezes a frozen card.
84
+ # @return [StripeCard]
85
+ def defrost!
86
+ require_client!
87
+ _client.update_stripe_card(id, status: "active")
88
+ end
89
+
90
+ # Permanently cancels the card.
91
+ # @return [Hash]
92
+ def cancel!
93
+ require_client!
94
+ _client.cancel_stripe_card(id)
95
+ end
96
+
97
+ # Refreshes card data from the API.
98
+ # @return [StripeCard]
99
+ def reload!
100
+ require_client!
101
+ _client.stripe_card(id)
102
+ end
103
+
104
+ # Activates a physical card after receiving it.
105
+ # @param last4 [String] last 4 digits printed on the card
106
+ # @return [StripeCard]
107
+ def activate!(last4:)
108
+ require_client!
109
+ _client.update_stripe_card(id, status: "active", last4:)
110
+ end
111
+
112
+ # Returns paginated transactions for this card.
113
+ # @return [TransactionList]
114
+ def transactions(**opts)
115
+ require_client!
116
+ _client.stripe_card_transactions(id, **opts)
117
+ end
118
+
119
+ # Returns Stripe ephemeral keys for revealing sensitive card details.
120
+ # @param nonce [String] one-time nonce
121
+ # @param stripe_version [String, nil]
122
+ # @return [Hash]
123
+ def ephemeral_keys(nonce:, stripe_version: nil)
124
+ require_client!
125
+ _client.stripe_card_ephemeral_keys(id, nonce:, stripe_version:)
126
+ end
127
+
128
+ # @return [Boolean]
129
+ def virtual? = type == "virtual"
130
+
131
+ # @return [Boolean]
132
+ def physical? = type == "physical"
133
+ end
134
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCBV4
4
+ # A tag applied to a transaction.
5
+ Tag = Data.define(:id, :label, :color, :emoji) do
6
+ # @param hash [Hash] API response
7
+ # @return [Tag]
8
+ def self.from_hash(hash)
9
+ new(id: hash["id"], label: hash["label"], color: hash["color"], emoji: hash["emoji"])
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCBV4
4
+ # A financial transaction on an organization's ledger.
5
+ # Contains type-specific details (card_charge, donation, transfer, etc.).
6
+ Transaction = Data.define(
7
+ :id, :date, :amount_cents, :memo, :has_custom_memo, :pending, :declined, :tags,
8
+ :code, :missing_receipt, :lost_receipt, :appearance,
9
+ :card_charge, :donation, :expense_payout, :invoice, :check, :transfer,
10
+ :ach_transfer, :check_deposit, :organization, :_client
11
+ ) do
12
+ include Resource
13
+ include TransactionType
14
+
15
+ # @param hash [Hash] API response
16
+ # @param client [Client, nil]
17
+ # @return [Transaction]
18
+ def self.from_hash(hash, client: nil)
19
+ organization = hash["organization"] ? Organization.from_hash(hash["organization"]) : nil
20
+
21
+ new(
22
+ id: hash["id"],
23
+ date: hash["date"],
24
+ amount_cents: hash["amount_cents"],
25
+ memo: hash["memo"],
26
+ has_custom_memo: hash["has_custom_memo"],
27
+ pending: hash["pending"],
28
+ declined: hash["declined"],
29
+ tags: hash["tags"]&.map { |t| Tag.from_hash(t) },
30
+ code: hash["code"],
31
+ missing_receipt: hash["missing_receipt"],
32
+ lost_receipt: hash["lost_receipt"],
33
+ appearance: hash["appearance"],
34
+ card_charge: hash["card_charge"] ? CardCharge.from_hash(hash["card_charge"]) : nil,
35
+ donation: hash["donation"] ? DonationTransaction.from_hash(hash["donation"]) : nil,
36
+ expense_payout: hash["expense_payout"] ? ExpensePayout.from_hash(hash["expense_payout"]) : nil,
37
+ invoice: hash["invoice"] ? InvoiceTransaction.from_hash(hash["invoice"]) : nil,
38
+ check: hash["check"] ? Check.from_hash(hash["check"]) : nil,
39
+ transfer: hash["transfer"] ? Transfer.from_hash(hash["transfer"], client:, organization:) : nil,
40
+ ach_transfer: hash["ach_transfer"] ? ACHTransfer.from_hash(hash["ach_transfer"]) : nil,
41
+ check_deposit: hash["check_deposit"] ? CheckDeposit.from_hash(hash["check_deposit"]) : nil,
42
+ organization:,
43
+ _client: client
44
+ )
45
+ end
46
+
47
+ # Returns the transaction type as a symbol.
48
+ # @return [Symbol] :card_charge, :donation, :transfer, :ach_transfer, etc.
49
+ def type
50
+ return :card_charge if card_charge
51
+ return :donation if donation
52
+ return :expense_payout if expense_payout
53
+ return :invoice if invoice
54
+ return :check if check
55
+ return :transfer if transfer
56
+ return :ach_transfer if ach_transfer
57
+ return :check_deposit if check_deposit
58
+
59
+ :unknown
60
+ end
61
+
62
+ # Returns the type-specific detail object.
63
+ # @return [CardCharge, DonationTransaction, Transfer, ACHTransfer, Check, nil]
64
+ def details
65
+ card_charge || donation || expense_payout || invoice || check || transfer || ach_transfer || check_deposit
66
+ end
67
+
68
+ # @return [Array<Comment>]
69
+ def comments
70
+ require_client!
71
+ _client.comments(organization_id: organization&.id, transaction_id: id)
72
+ end
73
+
74
+ # @return [Array<Receipt>]
75
+ def receipts
76
+ require_client!
77
+ _client.receipts(transaction_id: id)
78
+ end
79
+
80
+ # Refreshes transaction data from the API.
81
+ # @return [Transaction]
82
+ def reload!
83
+ require_client!
84
+ _client.transaction(id)
85
+ end
86
+
87
+ # Updates the transaction memo.
88
+ # @param memo [String]
89
+ # @return [Transaction]
90
+ def update!(memo:)
91
+ require_client!
92
+ _client.update_transaction(id, event_id: organization&.id, memo:)
93
+ end
94
+
95
+ # Adds a comment to this transaction.
96
+ # @param content [String]
97
+ # @param admin_only [Boolean]
98
+ # @param file [File, nil]
99
+ # @return [Comment]
100
+ def add_comment(content:, admin_only: false, file: nil)
101
+ require_client!
102
+ _client.create_comment(organization_id: organization&.id, transaction_id: id, content:, admin_only:, file:)
103
+ end
104
+
105
+ # Uploads a receipt and attaches it to this transaction.
106
+ # @param file [File]
107
+ # @return [Receipt]
108
+ def add_receipt(file:)
109
+ require_client!
110
+ _client.create_receipt(file:, transaction_id: id)
111
+ end
112
+
113
+ # Returns memo autocomplete suggestions based on past transaction memos.
114
+ # @return [Array<String>] suggested memo strings
115
+ def memo_suggestions
116
+ require_client!
117
+ _client.memo_suggestions(event_id: organization&.id, transaction_id: id)
118
+ end
119
+
120
+ # @return [Boolean]
121
+ def has_custom_memo? = !!has_custom_memo
122
+
123
+ # @return [Boolean]
124
+ def missing_receipt? = !!missing_receipt
125
+
126
+ # @return [Boolean]
127
+ def lost_receipt? = !!lost_receipt
128
+ end
129
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCBV4
4
+ # Paginated list of transactions. Implements Enumerable.
5
+ TransactionList = Data.define(:data, :total_count, :has_more, :_client, :_pagination_context) do
6
+ include Resource
7
+ include Enumerable
8
+
9
+ # @param hash [Hash] API response
10
+ # @param client [Client, nil]
11
+ # @param pagination_context [Hash, nil] internal pagination state
12
+ # @return [TransactionList]
13
+ def self.from_hash(hash, client: nil, pagination_context: nil)
14
+ new(
15
+ data: hash["data"]&.map { |t| Transaction.from_hash(t, client:) } || [],
16
+ total_count: hash["total_count"],
17
+ has_more: hash["has_more"],
18
+ _client: client,
19
+ _pagination_context: pagination_context
20
+ )
21
+ end
22
+
23
+ # Iterates over transactions in this page.
24
+ # @yield [Transaction]
25
+ def each(&block)
26
+ return enum_for(:each) unless block_given?
27
+
28
+ data.each(&block)
29
+ end
30
+
31
+ # @return [Boolean] true if more pages are available
32
+ def has_more? = !!has_more
33
+
34
+ # Fetches the next page of transactions.
35
+ # @return [TransactionList, nil]
36
+ def next_page
37
+ return nil unless has_more? && _client && _pagination_context
38
+
39
+ case _pagination_context[:type]
40
+ when :organization_transactions
41
+ _client.transactions(
42
+ _pagination_context[:organization_id],
43
+ limit: _pagination_context[:limit],
44
+ after: data.last&.id,
45
+ type: _pagination_context[:tx_type],
46
+ filters: _pagination_context[:filters],
47
+ expand: _pagination_context[:expand] || []
48
+ )
49
+ when :missing_receipt
50
+ _client.missing_receipt_transactions(
51
+ limit: _pagination_context[:limit],
52
+ after: data.last&.id
53
+ )
54
+ when :stripe_card_transactions
55
+ _client.stripe_card_transactions(
56
+ _pagination_context[:card_id],
57
+ limit: _pagination_context[:limit],
58
+ after: data.last&.id,
59
+ missing_receipts: _pagination_context[:missing_receipts]
60
+ )
61
+ end
62
+ end
63
+
64
+ # Iterates through all pages.
65
+ # @yield [TransactionList] each page
66
+ def each_page
67
+ return enum_for(:each_page) unless block_given?
68
+
69
+ page = self
70
+ loop do
71
+ yield page
72
+ break unless page.has_more?
73
+
74
+ page = page.next_page
75
+ break if page.nil?
76
+ end
77
+ end
78
+
79
+ # Lazily iterates through all transactions across pages.
80
+ # @param max_pages [Integer, nil] limit number of pages fetched
81
+ # @yield [Transaction]
82
+ def auto_paginate(max_pages: nil, &block)
83
+ return enum_for(:auto_paginate, max_pages:) unless block_given?
84
+
85
+ pages = 0
86
+ each_page do |page|
87
+ page.each(&block)
88
+ pages += 1
89
+ break if max_pages && pages >= max_pages
90
+ end
91
+ end
92
+
93
+ # Collects all transactions into an array.
94
+ # @param max_pages [Integer] safety limit (default 100)
95
+ # @return [Array<Transaction>]
96
+ def all(max_pages: 100)
97
+ auto_paginate(max_pages:).to_a
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HCBV4
4
+ module TransactionType
5
+ COMMON_FIELDS = %i[id amount_cents memo status].freeze
6
+
7
+ def transaction? = true
8
+ def pending? = respond_to?(:pending) && pending
9
+ def declined? = respond_to?(:declined) && declined
10
+ end
11
+ end