genesis_ruby 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.kiro/specs/f2025112509-add_managed_recurring_api/.config.kiro +1 -0
  3. data/.kiro/specs/f2025112509-add_managed_recurring_api/design.md +332 -0
  4. data/.kiro/specs/f2025112509-add_managed_recurring_api/requirements.md +91 -0
  5. data/.kiro/specs/f2025112509-add_managed_recurring_api/tasks.md +139 -0
  6. data/.kiro/specs/f2025112603-add_reverify_endpoint_to_payee_account/.config.kiro +1 -0
  7. data/.kiro/specs/f2025112603-add_reverify_endpoint_to_payee_account/design.md +148 -0
  8. data/.kiro/specs/f2025112603-add_reverify_endpoint_to_payee_account/requirements.md +81 -0
  9. data/.kiro/specs/f2025112603-add_reverify_endpoint_to_payee_account/tasks.md +48 -0
  10. data/.kiro/specs/f2025112606-add_list_payees_trx_request/.config.kiro +1 -0
  11. data/.kiro/specs/f2025112606-add_list_payees_trx_request/design.md +112 -0
  12. data/.kiro/specs/f2025112606-add_list_payees_trx_request/requirements.md +74 -0
  13. data/.kiro/specs/f2025112606-add_list_payees_trx_request/tasks.md +38 -0
  14. data/.kiro/specs/f2025112609_update_payee_request_params/design.md +86 -0
  15. data/.kiro/specs/f2025112609_update_payee_request_params/requirements.md +86 -0
  16. data/.kiro/specs/f2025112609_update_payee_request_params/tasks.md +40 -0
  17. data/.kiro/specs/f2025112612-add_payee_owner_documents_and_verification_requests/.config.kiro +1 -0
  18. data/.kiro/specs/f2025112612-add_payee_owner_documents_and_verification_requests/design.md +246 -0
  19. data/.kiro/specs/f2025112612-add_payee_owner_documents_and_verification_requests/requirements.md +287 -0
  20. data/.kiro/specs/f2025112612-add_payee_owner_documents_and_verification_requests/tasks.md +76 -0
  21. data/.kiro/specs/f2025112614-add_money_transfer_payout_attributes_to_payout_rq/design.md +84 -0
  22. data/.kiro/specs/f2025112614-add_money_transfer_payout_attributes_to_payout_rq/requirements.md +88 -0
  23. data/.kiro/specs/f2025112614-add_money_transfer_payout_attributes_to_payout_rq/tasks.md +38 -0
  24. data/.kiro/steering/product.md +15 -0
  25. data/.kiro/steering/spec-folder-naming.md +16 -0
  26. data/.kiro/steering/structure.md +96 -0
  27. data/.kiro/steering/tech.md +66 -0
  28. data/CHANGELOG.md +23 -0
  29. data/Gemfile.lock +4 -4
  30. data/README.md +33 -0
  31. data/VERSION +1 -1
  32. data/lib/genesis_ruby/api/constants/non_financial/kyc/address_document_supported_types.rb +81 -0
  33. data/lib/genesis_ruby/api/constants/non_financial/payee/document_types.rb +57 -0
  34. data/lib/genesis_ruby/api/constants/non_financial/payee/owner_types.rb +30 -0
  35. data/lib/genesis_ruby/api/constants/transactions/parameters/money_transfer/purpose_of_payments.rb +50 -0
  36. data/lib/genesis_ruby/api/constants/transactions/parameters/money_transfer/sender_account_number_types.rb +50 -0
  37. data/lib/genesis_ruby/api/constants/transactions/parameters/money_transfer/source_of_funds.rb +44 -0
  38. data/lib/genesis_ruby/api/constants/transactions/parameters/money_transfer/types.rb +26 -0
  39. data/lib/genesis_ruby/api/constants/transactions/parameters/non_financial/billing_api/statement_response_fields.rb +37 -0
  40. data/lib/genesis_ruby/api/mixins/requests/financial/cards/mpi_attributes.rb +0 -10
  41. data/lib/genesis_ruby/api/mixins/requests/financial/money_transfer_payout_attributes.rb +131 -0
  42. data/lib/genesis_ruby/api/mixins/requests/non_financial/date_attributes.rb +87 -5
  43. data/lib/genesis_ruby/api/mixins/requests/non_financial/kyc/business_attributes.rb +42 -0
  44. data/lib/genesis_ruby/api/mixins/requests/non_financial/kyc/document_attributes.rb +8 -7
  45. data/lib/genesis_ruby/api/request.rb +15 -9
  46. data/lib/genesis_ruby/api/requests/base/non_financial/billing_api/base.rb +108 -0
  47. data/lib/genesis_ruby/api/requests/base/non_financial/payee/base.rb +54 -0
  48. data/lib/genesis_ruby/api/requests/financial/cards/authorize3d.rb +1 -3
  49. data/lib/genesis_ruby/api/requests/financial/cards/payout.rb +3 -1
  50. data/lib/genesis_ruby/api/requests/financial/cards/sale3d.rb +1 -3
  51. data/lib/genesis_ruby/api/requests/non_financial/billing_api/statement.rb +170 -0
  52. data/lib/genesis_ruby/api/requests/non_financial/billing_api/transactions.rb +20 -60
  53. data/lib/genesis_ruby/api/requests/non_financial/kyc/business/create.rb +45 -0
  54. data/lib/genesis_ruby/api/requests/non_financial/kyc/business/document.rb +60 -0
  55. data/lib/genesis_ruby/api/requests/non_financial/kyc/business/document_list.rb +59 -0
  56. data/lib/genesis_ruby/api/requests/non_financial/kyc/business/verification.rb +52 -0
  57. data/lib/genesis_ruby/api/requests/non_financial/kyc/verifications/address_by_document_proof.rb +92 -0
  58. data/lib/genesis_ruby/api/requests/non_financial/kyc/verifications/create.rb +4 -1
  59. data/lib/genesis_ruby/api/requests/non_financial/managed_recurring/cancel.rb +63 -0
  60. data/lib/genesis_ruby/api/requests/non_financial/managed_recurring/fetch.rb +63 -0
  61. data/lib/genesis_ruby/api/requests/non_financial/managed_recurring/fetch_all.rb +37 -0
  62. data/lib/genesis_ruby/api/requests/non_financial/payee/account/reverify.rb +61 -0
  63. data/lib/genesis_ruby/api/requests/non_financial/payee/associate_payee_with_owners.rb +105 -0
  64. data/lib/genesis_ruby/api/requests/non_financial/payee/create.rb +37 -7
  65. data/lib/genesis_ruby/api/requests/non_financial/payee/create_payee_document.rb +61 -0
  66. data/lib/genesis_ruby/api/requests/non_financial/payee/dissociate_payee_with_owners.rb +94 -0
  67. data/lib/genesis_ruby/api/requests/non_financial/payee/list.rb +38 -0
  68. data/lib/genesis_ruby/api/requests/non_financial/payee/list_payee_documents.rb +57 -0
  69. data/lib/genesis_ruby/api/requests/non_financial/payee/list_payee_owners.rb +70 -0
  70. data/lib/genesis_ruby/api/requests/non_financial/payee/owners/associate_owner_with_owners.rb +109 -0
  71. data/lib/genesis_ruby/api/requests/non_financial/payee/owners/create.rb +71 -0
  72. data/lib/genesis_ruby/api/requests/non_financial/payee/owners/create_owner_document.rb +63 -0
  73. data/lib/genesis_ruby/api/requests/non_financial/payee/owners/delete.rb +54 -0
  74. data/lib/genesis_ruby/api/requests/non_financial/payee/owners/dissociate_owners.rb +96 -0
  75. data/lib/genesis_ruby/api/requests/non_financial/payee/owners/list_owner_documents.rb +59 -0
  76. data/lib/genesis_ruby/api/requests/non_financial/payee/owners/list_owners.rb +46 -0
  77. data/lib/genesis_ruby/api/requests/non_financial/payee/owners/retrieve.rb +59 -0
  78. data/lib/genesis_ruby/api/requests/non_financial/payee/owners/retrieve_owner_document.rb +62 -0
  79. data/lib/genesis_ruby/api/requests/non_financial/payee/owners/update.rb +66 -0
  80. data/lib/genesis_ruby/api/requests/non_financial/payee/retrieve_payee_document.rb +60 -0
  81. data/lib/genesis_ruby/api/requests/non_financial/payee/update.rb +34 -4
  82. data/lib/genesis_ruby/api/requests/non_financial/payee/verifications/create_payee_verification.rb +58 -0
  83. data/lib/genesis_ruby/api/requests/non_financial/payee/verifications/list_payee_verifications.rb +59 -0
  84. data/lib/genesis_ruby/api/requests/non_financial/payee/verifications/retrieve_payee_verification.rb +62 -0
  85. data/lib/genesis_ruby/api/requests/non_financial/tokenization/retokenize.rb +45 -0
  86. data/lib/genesis_ruby/api/requests/wpf/create.rb +19 -0
  87. data/lib/genesis_ruby/api/response.rb +15 -0
  88. data/lib/genesis_ruby/dependencies.rb +2 -0
  89. data/lib/genesis_ruby/network/adapter/net_http_adapter.rb +31 -5
  90. data/lib/genesis_ruby/network/base_network.rb +5 -0
  91. data/lib/genesis_ruby/network/net_http.rb +16 -4
  92. data/lib/genesis_ruby/utils/options/api_config.rb +43 -32
  93. data/lib/genesis_ruby/utils/options/network_adapter_config.rb +1 -1
  94. data/lib/genesis_ruby/version.rb +1 -1
  95. metadata +72 -3
@@ -0,0 +1,148 @@
1
+ # Design Document
2
+
3
+ ## Overview
4
+
5
+ This design adds a `Reverify` request class to the `GenesisRuby::Api::Requests::NonFinancial::Payee::Account` module. The class sends a `POST` request to `/payee/:payee_unique_id/account/:account_unique_id/reverify` with an empty JSON body `{}`, allowing SDK consumers to retry failed Payee Account verifications.
6
+
7
+ The implementation follows the established patterns of the existing Account request classes (Create, Retrieve, Update, List) — inheriting from `Base::Versioned`, using the JSON builder, performing path-token substitution in `process_request_parameters`, and configuring the API service endpoint without a terminal token.
8
+
9
+ ## Architecture
10
+
11
+ The Reverify class slots into the existing request hierarchy with no new abstractions:
12
+
13
+ ```mermaid
14
+ classDiagram
15
+ class Request {
16
+ <<abstract>>
17
+ #init_configuration()
18
+ #process_request_parameters()
19
+ #init_api_service_configuration()
20
+ +build_document()
21
+ }
22
+ class Versioned {
23
+ <<abstract>>
24
+ #request_path
25
+ #request_structure()
26
+ #init_json_configuration()
27
+ }
28
+ class Reverify {
29
+ +payee_unique_id
30
+ +account_unique_id
31
+ #init_field_validations()
32
+ #request_structure()
33
+ #process_request_parameters()
34
+ }
35
+
36
+ Request <|-- Versioned
37
+ Versioned <|-- Reverify
38
+ ```
39
+
40
+ The class uses the default `POST` HTTP method provided by `Base::Versioned` (via `init_json_configuration`). No HTTP method override is needed — unlike Retrieve/List (which override to `GET`) or Update (which overrides to `PATCH`).
41
+
42
+ ## Components and Interfaces
43
+
44
+ ### New File
45
+
46
+ `lib/genesis_ruby/api/requests/non_financial/payee/account/reverify.rb`
47
+
48
+ ### Class: `GenesisRuby::Api::Requests::NonFinancial::Payee::Account::Reverify`
49
+
50
+ **Superclass:** `GenesisRuby::Api::Requests::Base::Versioned`
51
+
52
+ **Public interface:**
53
+
54
+ | Member | Type | Description |
55
+ |---|---|---|
56
+ | `payee_unique_id` | `attr_accessor` | The unique identifier of the Payee |
57
+ | `account_unique_id` | `attr_accessor` | The unique identifier of the Account |
58
+ | `initialize(configuration, _builder_interface = nil)` | constructor | Sets `request_path` to `payee/:payee_unique_id/account/:account_unique_id/reverify` |
59
+
60
+ **Protected methods:**
61
+
62
+ | Method | Description |
63
+ |---|---|
64
+ | `init_field_validations` | Pushes `payee_unique_id` and `account_unique_id` onto `required_fields` |
65
+ | `request_structure` | Returns `{}` (empty hash) |
66
+ | `process_request_parameters` | Substitutes path tokens and calls `init_api_service_configuration` with `include_token: false` |
67
+
68
+ ### Auto-loading
69
+
70
+ The file path `lib/genesis_ruby/api/requests/non_financial/payee/account/reverify.rb` matches the existing glob in `dependencies.rb`:
71
+
72
+ ```ruby
73
+ Dir["#{File.dirname(__FILE__)}/api/requests/*financial/**/*.rb"].sort.each { |file| require file }
74
+ ```
75
+
76
+ No changes to `dependencies.rb` are needed.
77
+
78
+ ### New Test File
79
+
80
+ `spec/genesis_ruby/api/requests/non_financial/payee/account/reverify_spec.rb`
81
+
82
+ Follows the same structure as the existing Account specs (Retrieve, Create, Update) — config setup, sample data with `Faker::Internet.uuid`, valid/invalid request contexts, and shared example inclusion.
83
+
84
+ ## Data Models
85
+
86
+ No new data models are introduced. The request uses two string attributes (`payee_unique_id`, `account_unique_id`) and produces an empty JSON body.
87
+
88
+ **Request body:**
89
+
90
+ ```json
91
+ {}
92
+ ```
93
+
94
+ **Key design decision:** The `request_structure` returns `{}` (empty hash), consistent with the PHP SDK implementation. The reverify endpoint does not require any body parameters — the payee and account identifiers are conveyed entirely through the URL path.
95
+
96
+ ## Correctness Properties
97
+
98
+ *A property is a characteristic or behavior that should hold true across all valid executions of a system — essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
99
+
100
+ ### Property 1: URL path substitution preserves identifiers
101
+
102
+ *For any* pair of valid `payee_unique_id` and `account_unique_id` strings, building the request document SHALL produce an endpoint URL that contains both identifiers in the correct path positions: `/payee/{payee_unique_id}/account/{account_unique_id}/reverify`.
103
+
104
+ **Validates: Requirements 3.2, 3.3, 3.4**
105
+
106
+ ## Error Handling
107
+
108
+ Error handling is delegated entirely to the existing `Base::Versioned` → `Request` validation framework:
109
+
110
+ | Condition | Error | Mechanism |
111
+ |---|---|---|
112
+ | `payee_unique_id` is nil or empty | `GenesisRuby::ParameterError` | `required_fields` validation in `check_requirements` |
113
+ | `account_unique_id` is nil or empty | `GenesisRuby::ParameterError` | `required_fields` validation in `check_requirements` |
114
+ | Configuration endpoint not set | `GenesisRuby::EndpointNotSetError` | `build_request_url` in base `Request` |
115
+ | Invalid API version | `GenesisRuby::InvalidArgumentError` | `version=` setter in `Base::Versioned` |
116
+
117
+ No custom error handling is needed in the Reverify class.
118
+
119
+ ## Testing Strategy
120
+
121
+ ### Dual Testing Approach
122
+
123
+ **Unit tests (example-based):** Verify specific behaviors with concrete values — JSON body content, HTTP method, endpoint URL format, required field validation errors, and shared example compliance.
124
+
125
+ **Property tests:** Verify the URL path substitution property across many randomly generated identifier pairs.
126
+
127
+ ### Unit Test Plan
128
+
129
+ Located at `spec/genesis_ruby/api/requests/non_financial/payee/account/reverify_spec.rb`:
130
+
131
+ 1. **JSON body** — build document and verify `JSON.parse` output equals `{}`
132
+ 2. **Endpoint URL** — build document and verify `api_config['url']` matches expected pattern with substituted UUIDs
133
+ 3. **HTTP method** — verify `api_config['type']` equals `'POST'`
134
+ 4. **Happy path** — `build_document` with all fields does not raise
135
+ 5. **Nil payee_unique_id** — raises `GenesisRuby::ParameterError`
136
+ 6. **Empty payee_unique_id** — raises `GenesisRuby::ParameterError`
137
+ 7. **Nil account_unique_id** — raises `GenesisRuby::ParameterError`
138
+ 8. **Empty account_unique_id** — raises `GenesisRuby::ParameterError`
139
+ 9. **Shared examples** — `base request examples`, `versioned request examples`
140
+
141
+ ### Property Test Plan
142
+
143
+ **Library:** `rspec-propcheck` or equivalent Ruby PBT library (e.g., using `Faker` for randomized UUID generation across 100+ iterations).
144
+
145
+ **Property 1 test:** Generate random UUID pairs, set them on the request, build the document, and assert the resulting URL contains both UUIDs at the correct path positions ending with `/reverify`.
146
+
147
+ - Minimum 100 iterations
148
+ - Tag: `Feature: payee-reverify-account, Property 1: URL path substitution preserves identifiers`
@@ -0,0 +1,81 @@
1
+ # Requirements Document
2
+
3
+ ## Introduction
4
+
5
+ Add a "Reverify Payee Account" endpoint to the genesis_ruby SDK. This endpoint allows retrying failed Account verifications by sending a POST request to `/payee/:payee_unique_id/account/:account_unique_id/reverify`. The implementation follows the existing Payee Account request patterns (Create, Retrieve, Update, List) in the SDK.
6
+
7
+ ## Glossary
8
+
9
+ - **SDK**: The genesis_ruby Ruby gem that provides a client library for the Genesis Payment Processing Gateway.
10
+ - **Reverify_Request**: The new `GenesisRuby::Api::Requests::NonFinancial::Payee::Account::Reverify` class that sends a POST request to reverify a Payee Account.
11
+ - **Payee**: An entity in the Genesis Payment Gateway identified by a `payee_unique_id`.
12
+ - **Account**: A financial account belonging to a Payee, identified by an `account_unique_id`.
13
+ - **Base_Versioned**: The `GenesisRuby::Api::Requests::Base::Versioned` abstract base class for versioned JSON API requests.
14
+ - **Request_Path**: The URL path template used by the request, with placeholder tokens for dynamic identifiers.
15
+ - **Request_Structure**: The Ruby hash that defines the JSON body of the request.
16
+ - **Field_Validations**: The set of required field and value constraints enforced before a request is sent.
17
+
18
+ ## Requirements
19
+
20
+ ### Requirement 1: Reverify Request Class
21
+
22
+ **User Story:** As a developer integrating with the Genesis Payment Gateway, I want a Reverify request class for Payee Accounts, so that I can retry failed account verifications through the SDK.
23
+
24
+ #### Acceptance Criteria
25
+
26
+ 1. THE Reverify_Request SHALL inherit from Base_Versioned.
27
+ 2. THE Reverify_Request SHALL be defined in the `GenesisRuby::Api::Requests::NonFinancial::Payee::Account` module.
28
+ 3. THE Reverify_Request SHALL be located at `lib/genesis_ruby/api/requests/non_financial/payee/account/reverify.rb`.
29
+ 4. THE Reverify_Request SHALL be auto-loaded by the existing glob pattern in `dependencies.rb` without manual require statements.
30
+
31
+ ### Requirement 2: Request Parameters
32
+
33
+ **User Story:** As a developer, I want to specify the Payee and Account identifiers for the reverify request, so that the correct account verification is retried.
34
+
35
+ #### Acceptance Criteria
36
+
37
+ 1. THE Reverify_Request SHALL expose a `payee_unique_id` attribute via `attr_accessor`.
38
+ 2. THE Reverify_Request SHALL expose an `account_unique_id` attribute via `attr_accessor`.
39
+ 3. WHEN `payee_unique_id` is nil or empty, THE Reverify_Request SHALL raise a `GenesisRuby::ParameterError`.
40
+ 4. WHEN `account_unique_id` is nil or empty, THE Reverify_Request SHALL raise a `GenesisRuby::ParameterError`.
41
+
42
+ ### Requirement 3: HTTP Endpoint Configuration
43
+
44
+ **User Story:** As a developer, I want the reverify request to target the correct API endpoint, so that the Gateway processes the reverification.
45
+
46
+ #### Acceptance Criteria
47
+
48
+ 1. THE Reverify_Request SHALL use the POST HTTP method.
49
+ 2. THE Reverify_Request SHALL set the Request_Path to `payee/:payee_unique_id/account/:account_unique_id/reverify`.
50
+ 3. WHEN `process_request_parameters` is called, THE Reverify_Request SHALL substitute `:payee_unique_id` in the Request_Path with the value of the `payee_unique_id` attribute.
51
+ 4. WHEN `process_request_parameters` is called, THE Reverify_Request SHALL substitute `:account_unique_id` in the Request_Path with the value of the `account_unique_id` attribute.
52
+ 5. WHEN `process_request_parameters` is called, THE Reverify_Request SHALL invoke `init_api_service_configuration` with `include_token: false`.
53
+
54
+ ### Requirement 4: Request Body Structure
55
+
56
+ **User Story:** As a developer, I want the reverify request to send an empty JSON body, so that the Gateway accepts the reverification request.
57
+
58
+ #### Acceptance Criteria
59
+
60
+ 1. THE Reverify_Request SHALL define a `request_structure` method that returns an empty hash `{}`.
61
+ 2. WHEN the request document is built, THE Reverify_Request SHALL produce an empty JSON body `{}`.
62
+
63
+ ### Requirement 5: RSpec Test Coverage
64
+
65
+ **User Story:** As a developer, I want comprehensive tests for the Reverify request, so that the implementation is verified against the expected behavior.
66
+
67
+ #### Acceptance Criteria
68
+
69
+ 1. THE test file SHALL be located at `spec/genesis_ruby/api/requests/non_financial/payee/account/reverify_spec.rb`.
70
+ 2. THE test file SHALL start with the `# frozen_string_literal: true` comment.
71
+ 3. THE test suite SHALL verify that the built document produces an empty JSON body `{}`.
72
+ 4. THE test suite SHALL verify that the endpoint URL resolves to `https://staging.api.emerchantpay.net:443/payee/{payee_unique_id}/account/{account_unique_id}/reverify`.
73
+ 5. THE test suite SHALL verify that the HTTP method is POST.
74
+ 6. THE test suite SHALL verify that building the document with all required fields does not raise an error.
75
+ 7. THE test suite SHALL verify that a nil `payee_unique_id` raises a `GenesisRuby::ParameterError`.
76
+ 8. THE test suite SHALL verify that an empty `payee_unique_id` raises a `GenesisRuby::ParameterError`.
77
+ 9. THE test suite SHALL verify that a nil `account_unique_id` raises a `GenesisRuby::ParameterError`.
78
+ 10. THE test suite SHALL verify that an empty `account_unique_id` raises a `GenesisRuby::ParameterError`.
79
+ 11. THE test suite SHALL include the `base request examples` shared example group.
80
+ 12. THE test suite SHALL include the `versioned request examples` shared example group.
81
+ 13. THE test suite SHALL use `to_not` (not `not_to`) per the RuboCop configuration.
@@ -0,0 +1,48 @@
1
+ # Implementation Plan: Reverify Payee Account
2
+
3
+ ## Overview
4
+
5
+ Implement the `Reverify` request class for the Payee Account module following the established patterns of sibling classes (Create, Retrieve, Update). The class inherits from `Base::Versioned`, uses POST, sends an empty JSON body `{}`, and substitutes path tokens for `payee_unique_id` and `account_unique_id`. Auto-loading via the existing glob in `dependencies.rb` means no manual require is needed.
6
+
7
+ ## Tasks
8
+
9
+ - [x] 1. Create the Reverify request class
10
+ - [x] 1.1 Create `lib/genesis_ruby/api/requests/non_financial/payee/account/reverify.rb`
11
+ - Define `GenesisRuby::Api::Requests::NonFinancial::Payee::Account::Reverify` inheriting from `Base::Versioned`
12
+ - Add `attr_accessor :payee_unique_id, :account_unique_id`
13
+ - In `initialize`, call `super configuration` and set `self.request_path = 'payee/:payee_unique_id/account/:account_unique_id/reverify'`
14
+ - Implement `init_field_validations` pushing `payee_unique_id` and `account_unique_id` onto `required_fields`
15
+ - Implement `request_structure` returning `{}`
16
+ - Implement `process_request_parameters` substituting both path tokens via `gsub` and calling `init_api_service_configuration` with `include_token: false`
17
+ - _Requirements: 1.1, 1.2, 1.3, 1.4, 2.1, 2.2, 2.3, 2.4, 3.1, 3.2, 3.3, 3.4, 3.5, 4.1, 4.2_
18
+
19
+ - [x] 2. Create the RSpec test suite
20
+ - [x] 2.1 Create `spec/genesis_ruby/api/requests/non_financial/payee/account/reverify_spec.rb`
21
+ - Set up `config`, `sample_data` (using `Faker::Internet.uuid`), and `request` let blocks following the Retrieve spec pattern
22
+ - Define `test_required_fields` as `%i[payee_unique_id account_unique_id]`
23
+ - Test that built document JSON equals `{}`
24
+ - Test that endpoint URL resolves to `https://staging.api.emerchantpay.net:443/payee/{payee_unique_id}/account/{account_unique_id}/reverify`
25
+ - Test that HTTP method is `POST`
26
+ - Test that `build_document` with all fields does not raise
27
+ - Test that nil `payee_unique_id` raises `GenesisRuby::ParameterError`
28
+ - Test that empty `payee_unique_id` raises `GenesisRuby::ParameterError`
29
+ - Test that nil `account_unique_id` raises `GenesisRuby::ParameterError`
30
+ - Test that empty `account_unique_id` raises `GenesisRuby::ParameterError`
31
+ - Include `base request examples` and `versioned request examples` shared example groups
32
+ - Use `to_not` (not `not_to`) per RuboCop configuration
33
+ - _Requirements: 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 5.10, 5.11, 5.12, 5.13_
34
+
35
+ - [x] 2.2 Write property test for URL path substitution
36
+ - **Property 1: URL path substitution preserves identifiers**
37
+ - Generate 100+ random UUID pairs using `Faker::Internet.uuid`, set them on the request, build the document, and assert the resulting URL contains both UUIDs at the correct path positions ending with `/reverify`
38
+ - **Validates: Requirements 3.2, 3.3, 3.4**
39
+
40
+ - [x] 3. Checkpoint — Verify implementation
41
+ - Ensure all tests pass, ask the user if questions arise.
42
+
43
+ ## Notes
44
+
45
+ - Tasks marked with `*` are optional and can be skipped for faster MVP
46
+ - Each task references specific requirements for traceability
47
+ - The file is auto-loaded by the glob pattern in `dependencies.rb` — no manual require needed
48
+ - Property test validates the URL path substitution correctness property from the design
@@ -0,0 +1 @@
1
+ {"specId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "workflowType": "requirements-first", "specType": "feature"}
@@ -0,0 +1,112 @@
1
+ # Design Document
2
+
3
+ ## Overview
4
+
5
+ This design adds a `List` request class to the `GenesisRuby::Api::Requests::NonFinancial::Payee` module. The class sends a `GET` request to `/payee` with an empty JSON body `{}`, allowing SDK consumers to retrieve the details of all Payees.
6
+
7
+ The implementation follows the established patterns of the existing Payee request classes (Create, Retrieve, Update) — inheriting from `Base::Versioned`, using the JSON builder, and configuring the API service endpoint without a terminal token. This is the simplest Payee request since it has no required fields and no path token substitution.
8
+
9
+ ## Architecture
10
+
11
+ The List class slots into the existing request hierarchy with no new abstractions:
12
+
13
+ ```mermaid
14
+ classDiagram
15
+ class Request {
16
+ <<abstract>>
17
+ #init_configuration()
18
+ #process_request_parameters()
19
+ #init_api_service_configuration()
20
+ +build_document()
21
+ }
22
+ class Versioned {
23
+ <<abstract>>
24
+ #request_path
25
+ #request_structure()
26
+ #init_json_configuration()
27
+ }
28
+ class List {
29
+ #init_configuration()
30
+ #request_structure()
31
+ #process_request_parameters()
32
+ }
33
+
34
+ Request <|-- Versioned
35
+ Versioned <|-- List
36
+ ```
37
+
38
+ The class overrides `init_configuration` to call `init_get_configuration` (switching from the default POST to GET), matching the pattern used by `Payee::Retrieve` and `Payee::Account::List`.
39
+
40
+ ## Components and Interfaces
41
+
42
+ ### New File
43
+
44
+ `lib/genesis_ruby/api/requests/non_financial/payee/list.rb`
45
+
46
+ ### Class: `GenesisRuby::Api::Requests::NonFinancial::Payee::List`
47
+
48
+ **Superclass:** `GenesisRuby::Api::Requests::Base::Versioned`
49
+
50
+ **Public interface:**
51
+
52
+ | Member | Type | Description |
53
+ |---|---|---|
54
+ | `initialize(configuration, _builder_interface = nil)` | constructor | Sets `request_path` to `payee` |
55
+
56
+ **Protected methods:**
57
+
58
+ | Method | Description |
59
+ |---|---|
60
+ | `init_configuration` | Calls `super`, then `init_get_configuration` to switch to GET |
61
+ | `request_structure` | Returns `{}` (empty hash) |
62
+ | `process_request_parameters` | Calls `init_api_service_configuration` with `request_path` and `include_token: false`, then `super` |
63
+
64
+ ### Auto-loading
65
+
66
+ The file path `lib/genesis_ruby/api/requests/non_financial/payee/list.rb` matches the existing glob in `dependencies.rb`:
67
+
68
+ ```ruby
69
+ Dir["#{File.dirname(__FILE__)}/api/requests/*financial/**/*.rb"].sort.each { |file| require file }
70
+ ```
71
+
72
+ No changes to `dependencies.rb` are needed.
73
+
74
+ ### New Test File
75
+
76
+ `spec/genesis_ruby/api/requests/non_financial/payee/list_spec.rb`
77
+
78
+ Follows the same structure as the existing Payee::Retrieve spec — config setup, request let block, and shared example inclusion. Simpler than Retrieve since there are no required fields or path token substitution.
79
+
80
+ ## Data Models
81
+
82
+ No new data models are introduced. The request has no attributes and produces an empty JSON body.
83
+
84
+ **Request body:**
85
+
86
+ ```json
87
+ {}
88
+ ```
89
+
90
+ ## Error Handling
91
+
92
+ Error handling is delegated entirely to the existing `Base::Versioned` → `Request` validation framework:
93
+
94
+ | Condition | Error | Mechanism |
95
+ |---|---|---|
96
+ | Configuration endpoint not set | `GenesisRuby::EndpointNotSetError` | `build_request_url` in base `Request` |
97
+ | Invalid API version | `GenesisRuby::InvalidArgumentError` | `version=` setter in `Base::Versioned` |
98
+
99
+ No custom error handling is needed in the List class. There are no required fields to validate.
100
+
101
+ ## Testing Strategy
102
+
103
+ ### Unit Test Plan
104
+
105
+ Located at `spec/genesis_ruby/api/requests/non_financial/payee/list_spec.rb`:
106
+
107
+ 1. **JSON body** — build document and verify `JSON.parse` output equals `{}`
108
+ 2. **Endpoint URL** — build document and verify `api_config['url']` equals `https://staging.api.emerchantpay.net:443/payee`
109
+ 3. **HTTP method** — verify `api_config['type']` equals `'GET'`
110
+ 4. **Token exclusion** — verify `api_config['token']` is nil
111
+ 5. **Happy path** — `build_document` without any attributes does not raise
112
+ 6. **Shared examples** — `base request examples`, `versioned request examples`
@@ -0,0 +1,74 @@
1
+ # Requirements Document
2
+
3
+ ## Introduction
4
+
5
+ Add a "List Payees" endpoint to the genesis_ruby SDK. This endpoint retrieves the details of all Payees by sending a GET request to `/payee`. The implementation follows the existing Payee request patterns (Create, Retrieve, Update) in the SDK.
6
+
7
+ API Reference: [Payee API — List Payees](https://emerchantpay.github.io/gateway-api-docs/#payee-api-list-payees)
8
+
9
+ ## Glossary
10
+
11
+ - **SDK**: The genesis_ruby Ruby gem that provides a client library for the Genesis Payment Processing Gateway.
12
+ - **List_Request**: The new `GenesisRuby::Api::Requests::NonFinancial::Payee::List` class that sends a GET request to list all Payees.
13
+ - **Payee**: An entity in the Genesis Payment Gateway identified by a `unique_id`.
14
+ - **Base_Versioned**: The `GenesisRuby::Api::Requests::Base::Versioned` abstract base class for versioned JSON API requests.
15
+ - **Request_Path**: The URL path used by the request.
16
+ - **Request_Structure**: The Ruby hash that defines the JSON body of the request.
17
+
18
+ ## Requirements
19
+
20
+ ### Requirement 1: List Payees Request Class
21
+
22
+ **User Story:** As a developer integrating with the Genesis Payment Gateway, I want a List Payees request class, so that I can retrieve the details of all Payees through the SDK.
23
+
24
+ #### Acceptance Criteria
25
+
26
+ 1. THE List_Request SHALL inherit from Base_Versioned.
27
+ 2. THE List_Request SHALL be defined in the `GenesisRuby::Api::Requests::NonFinancial::Payee` module.
28
+ 3. THE List_Request SHALL be located at `lib/genesis_ruby/api/requests/non_financial/payee/list.rb`.
29
+ 4. THE List_Request SHALL be auto-loaded by the existing glob pattern in `dependencies.rb` without manual require statements.
30
+
31
+ ### Requirement 2: HTTP Endpoint Configuration
32
+
33
+ **User Story:** As a developer, I want the list payees request to target the correct API endpoint, so that the Gateway returns all Payee records.
34
+
35
+ #### Acceptance Criteria
36
+
37
+ 1. THE List_Request SHALL use the GET HTTP method.
38
+ 2. THE List_Request SHALL set the Request_Path to `payee`.
39
+ 3. WHEN `process_request_parameters` is called, THE List_Request SHALL invoke `init_api_service_configuration` with `request_path: request_path` and `include_token: false`.
40
+
41
+ ### Requirement 3: Request Body Structure
42
+
43
+ **User Story:** As a developer, I want the list payees request to send an empty JSON body, so that the Gateway accepts the request.
44
+
45
+ #### Acceptance Criteria
46
+
47
+ 1. THE List_Request SHALL define a `request_structure` method that returns an empty hash `{}`.
48
+ 2. WHEN the request document is built, THE List_Request SHALL produce an empty JSON body `{}`.
49
+
50
+ ### Requirement 4: No Required Fields
51
+
52
+ **User Story:** As a developer, I want the list payees request to work without any required parameters, since the endpoint lists all payees without filters.
53
+
54
+ #### Acceptance Criteria
55
+
56
+ 1. THE List_Request SHALL NOT define any required fields.
57
+ 2. WHEN `build_document` is called without setting any attributes, THE List_Request SHALL NOT raise an error.
58
+
59
+ ### Requirement 5: RSpec Test Coverage
60
+
61
+ **User Story:** As a developer, I want comprehensive tests for the List Payees request, so that the implementation is verified against the expected behavior.
62
+
63
+ #### Acceptance Criteria
64
+
65
+ 1. THE test file SHALL be located at `spec/genesis_ruby/api/requests/non_financial/payee/list_spec.rb`.
66
+ 2. THE test file SHALL start with the `# frozen_string_literal: true` comment.
67
+ 3. THE test suite SHALL verify that the built document produces an empty JSON body `{}`.
68
+ 4. THE test suite SHALL verify that the endpoint URL resolves to `https://staging.api.emerchantpay.net:443/payee`.
69
+ 5. THE test suite SHALL verify that the HTTP method is GET.
70
+ 6. THE test suite SHALL verify that the token is not included in the configuration.
71
+ 7. THE test suite SHALL verify that building the document without any attributes does not raise an error.
72
+ 8. THE test suite SHALL include the `base request examples` shared example group.
73
+ 9. THE test suite SHALL include the `versioned request examples` shared example group.
74
+ 10. THE test suite SHALL use `to_not` (not `not_to`) per the RuboCop configuration.
@@ -0,0 +1,38 @@
1
+ # Implementation Plan: List Payees
2
+
3
+ ## Overview
4
+
5
+ Implement the `List` request class for the Payee module following the established patterns of sibling classes (Create, Retrieve, Update). The class inherits from `Base::Versioned`, uses GET, sends an empty JSON body `{}`, and targets the `/payee` endpoint. Auto-loading via the existing glob in `dependencies.rb` means no manual require is needed.
6
+
7
+ ## Tasks
8
+
9
+ - [x] 1. Create the List Payees request class
10
+ - [x] 1.1 Create `lib/genesis_ruby/api/requests/non_financial/payee/list.rb`
11
+ - Define `GenesisRuby::Api::Requests::NonFinancial::Payee::List` inheriting from `Base::Versioned`
12
+ - In `initialize`, call `super configuration` and set `self.request_path = 'payee'`
13
+ - Override `init_configuration` to call `super` then `init_get_configuration`
14
+ - Implement `request_structure` returning `{}`
15
+ - Implement `process_request_parameters` calling `init_api_service_configuration` with `request_path: request_path` and `include_token: false`, then `super`
16
+ - _Requirements: 1.1, 1.2, 1.3, 1.4, 2.1, 2.2, 2.3, 3.1, 3.2, 4.1, 4.2_
17
+
18
+ - [x] 2. Create the RSpec test suite
19
+ - [x] 2.1 Create `spec/genesis_ruby/api/requests/non_financial/payee/list_spec.rb`
20
+ - Set up `config` and `request` let blocks following the Retrieve spec pattern
21
+ - Test that built document JSON equals `{}`
22
+ - Test that endpoint URL resolves to `https://staging.api.emerchantpay.net:443/payee`
23
+ - Test that HTTP method is `GET`
24
+ - Test that token is not included in configuration
25
+ - Test that `build_document` without any attributes does not raise
26
+ - Include `base request examples` and `versioned request examples` shared example groups
27
+ - Use `to_not` (not `not_to`) per RuboCop configuration
28
+ - _Requirements: 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 5.10_
29
+
30
+ - [x] 3. Checkpoint — Verify implementation
31
+ - Run `bundle exec rspec spec/genesis_ruby/api/requests/non_financial/payee/list_spec.rb` and ensure all tests pass
32
+ - Run `bundle exec rubocop lib/genesis_ruby/api/requests/non_financial/payee/list.rb spec/genesis_ruby/api/requests/non_financial/payee/list_spec.rb` and ensure no offenses
33
+
34
+ ## Notes
35
+
36
+ - Each task references specific requirements for traceability
37
+ - The file is auto-loaded by the glob pattern in `dependencies.rb` — no manual require needed
38
+ - This is the simplest Payee request — no required fields, no path token substitution, no query parameters
@@ -0,0 +1,86 @@
1
+ # Design Document
2
+
3
+ ## Overview
4
+
5
+ Extend the existing `Payee::Create` and `Payee::Update` request classes with additional accessors and a nested address structure, following the established SDK patterns.
6
+
7
+ ## Architecture
8
+
9
+ ### Approach
10
+
11
+ The implementation adds new `attr_accessor` fields to the existing classes and introduces a private `payee_address_structure` method that builds the nested address hash. The SDK's existing `deep_compact!` mechanism automatically removes nil values and empty hashes, ensuring the `address` key is omitted when all address fields are nil.
12
+
13
+ ### Files Modified
14
+
15
+ | File | Change |
16
+ |---|---|
17
+ | `lib/genesis_ruby/api/requests/non_financial/payee/create.rb` | Add accessors, address validation, nested structure |
18
+ | `lib/genesis_ruby/api/requests/non_financial/payee/update.rb` | Add accessors, address validation, nested structure |
19
+ | `spec/genesis_ruby/api/requests/non_financial/payee/create_spec.rb` | Add tests for new fields |
20
+ | `spec/genesis_ruby/api/requests/non_financial/payee/update_spec.rb` | Add tests for new fields |
21
+
22
+ ### Design Decisions
23
+
24
+ 1. **Prefixed accessors** (`payee_address_city` instead of `address_city`) — consistent with existing naming in the SDK (e.g., `payee_name`, `payee_country`, `payee_account_type`)
25
+
26
+ 2. **Private helper method** (`payee_address_structure`) — keeps `request_structure` clean and isolates the nested hash construction
27
+
28
+ 3. **Optional address validation** — `payee_address_country` is added to `field_values` for ISO validation but is not in `required_fields`, so it's only validated when set (non-nil)
29
+
30
+ 4. **No mixin** — the address structure is specific to Payee requests and simple enough not to warrant a shared mixin. The existing `AddressInfoAttributes` mixin is designed for billing/shipping addresses with different field names.
31
+
32
+ 5. **deep_compact! handles nil removal** — no custom logic needed; when all address fields are nil, the hash becomes `{}` after compaction, and empty hashes are then removed from the parent
33
+
34
+ ## Expected JSON Payloads
35
+
36
+ ### Payee Create (full)
37
+ ```json
38
+ {
39
+ "payee": {
40
+ "type": "company",
41
+ "name": "Office LTD",
42
+ "country": "GB",
43
+ "date": "1990-01-01",
44
+ "notification_url": "https://example.com/notifications",
45
+ "registration_number": "123456789",
46
+ "address": {
47
+ "city": "London",
48
+ "street": "Test 12",
49
+ "state": "London",
50
+ "country": "GB",
51
+ "zip_code": "1234"
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ ### Payee Update (full)
58
+ ```json
59
+ {
60
+ "payee": {
61
+ "name": "Office LTD",
62
+ "country": "GB",
63
+ "date": "1990-01-01",
64
+ "notification_url": "https://example.com/notifications",
65
+ "registration_number": "123456789",
66
+ "address": {
67
+ "city": "London",
68
+ "street": "Test 12",
69
+ "state": "London",
70
+ "country": "GB",
71
+ "zip_code": "1234"
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ ### Payee Create (minimal — no address)
78
+ ```json
79
+ {
80
+ "payee": {
81
+ "type": "company",
82
+ "name": "Office LTD",
83
+ "country": "GB"
84
+ }
85
+ }
86
+ ```