abacatepay-ruby 0.1.0 → 1.0.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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +125 -0
  3. data/CHANGELOG.md +121 -1
  4. data/README.md +408 -87
  5. data/Rakefile +1 -1
  6. data/abacatepay-ruby.gemspec +16 -10
  7. data/lib/abacate_pay/clients/billing_client.rb +80 -0
  8. data/lib/abacate_pay/clients/checkout_client.rb +70 -0
  9. data/lib/{abacatepay → abacate_pay}/clients/client.rb +20 -7
  10. data/lib/abacate_pay/clients/coupon_client.rb +57 -0
  11. data/lib/abacate_pay/clients/customer_client.rb +58 -0
  12. data/lib/abacate_pay/clients/payment_link_client.rb +71 -0
  13. data/lib/abacate_pay/clients/payout_client.rb +41 -0
  14. data/lib/abacate_pay/clients/pix_client.rb +47 -0
  15. data/lib/abacate_pay/clients/product_client.rb +54 -0
  16. data/lib/abacate_pay/clients/store_client.rb +40 -0
  17. data/lib/abacate_pay/clients/subscription_client.rb +55 -0
  18. data/lib/abacate_pay/clients/transparent_client.rb +73 -0
  19. data/lib/abacate_pay/clients/webhook_client.rb +82 -0
  20. data/lib/abacate_pay/clients.rb +24 -0
  21. data/lib/abacate_pay/configuration.rb +67 -0
  22. data/lib/{abacatepay/enums/billing → abacate_pay/enums/billings}/frequencies.rb +9 -3
  23. data/lib/{abacatepay/enums/billing → abacate_pay/enums/billings}/methods.rb +5 -3
  24. data/lib/{abacatepay/enums/billing → abacate_pay/enums/billings}/statuses.rb +3 -2
  25. data/lib/abacate_pay/enums/checkouts/statuses.rb +29 -0
  26. data/lib/abacate_pay/enums/coupons/discount_kinds.rb +26 -0
  27. data/lib/abacate_pay/enums/coupons/statuses.rb +27 -0
  28. data/lib/abacate_pay/enums/payouts/statuses.rb +29 -0
  29. data/lib/abacate_pay/enums/pix/key_types.rb +30 -0
  30. data/lib/abacate_pay/enums/products/cycles.rb +28 -0
  31. data/lib/abacate_pay/enums/transfers/statuses.rb +30 -0
  32. data/lib/abacate_pay/enums/webhooks/event_types.rb +43 -0
  33. data/lib/abacate_pay/enums.rb +20 -0
  34. data/lib/{abacatepay/resources/billing → abacate_pay/resources/billings}/metadata.rb +2 -8
  35. data/lib/{abacatepay/resources/billing → abacate_pay/resources/billings}/product.rb +2 -8
  36. data/lib/{abacatepay/resources/billing.rb → abacate_pay/resources/billings.rb} +16 -16
  37. data/lib/abacate_pay/resources/checkouts.rb +76 -0
  38. data/lib/abacate_pay/resources/coupons.rb +41 -0
  39. data/lib/{abacatepay/resources/customer → abacate_pay/resources/customers}/metadata.rb +2 -8
  40. data/lib/{abacatepay/resources/customer.rb → abacate_pay/resources/customers.rb} +5 -5
  41. data/lib/abacate_pay/resources/payouts.rb +40 -0
  42. data/lib/abacate_pay/resources/pix_transfers.rb +41 -0
  43. data/lib/abacate_pay/resources/products.rb +40 -0
  44. data/lib/{abacatepay → abacate_pay}/resources/resource.rb +33 -21
  45. data/lib/abacate_pay/resources/store/balance.rb +20 -0
  46. data/lib/abacate_pay/resources/store.rb +36 -0
  47. data/lib/abacate_pay/resources/subscriptions.rb +72 -0
  48. data/lib/abacate_pay/resources/transparents.rb +46 -0
  49. data/lib/abacate_pay/resources/webhook_endpoints.rb +49 -0
  50. data/lib/abacate_pay/resources.rb +27 -0
  51. data/lib/{abacatepay → abacate_pay}/version.rb +2 -2
  52. data/lib/abacate_pay/webhooks/event.rb +20 -0
  53. data/lib/abacate_pay/webhooks.rb +100 -0
  54. data/lib/abacate_pay.rb +111 -4
  55. metadata +69 -56
  56. data/lib/abacatepay/clients/billing_client.rb +0 -60
  57. data/lib/abacatepay/clients/customer_client.rb +0 -39
  58. data/lib/abacatepay/clients.rb +0 -12
  59. data/lib/abacatepay/configuration.rb +0 -56
  60. data/lib/abacatepay/enums.rb +0 -12
  61. data/lib/abacatepay/resources.rb +0 -15
  62. data/sig/abacatepay/rails.rbs +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ec476ed39de31a64c6de7517af308b971922f06a8a554de6764ea4992052b641
4
- data.tar.gz: cf82e3363dfa431419b29b120fcabddb671d91e3789ec90880dd131b46a08684
3
+ metadata.gz: 8249cc166bb8f5534c7299d4da8aac7c08193e8a33df8e7a7618737adb44a08c
4
+ data.tar.gz: f939f4979946f82d9e5a189d634ca4a7c99aa11e555646aec213b2f34dd4b817
5
5
  SHA512:
6
- metadata.gz: 84f338ecbd8a318c44987d7417579f812b5002c66eb04929e59511b61a4de9a378df861449ce98d7d24753cf4ef8bd373886b6ce602fd53c500bcca5f5254274
7
- data.tar.gz: 7e87dd6972d35d967bb1cece1e825579f96a26b0da3f624ead50734195bcf15c193674a5c0e6cbffd1e167ea28a8ee2fb63f6d78ec4151633ed4037445b0825d
6
+ metadata.gz: 4a14de54241b2901c7873becb95bab7bcceee8e7208b60b02114138eba6c72b1b6c16d5167c9f26f1b96fa9343bbe40097153f8b801b927b5c5dff02b3c0585c
7
+ data.tar.gz: e70fc7b7efea2223fbe1093f6f792e394f697da22fe92f01c738bec6a016df8116d09c5d4eec56accd4dbd5cd63a4628a8b6bb721742b76695f1436edc1139e7
data/.rubocop.yml CHANGED
@@ -0,0 +1,125 @@
1
+ plugins:
2
+ - rubocop-rspec
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 3.2
6
+ NewCops: enable
7
+ SuggestExtensions: false
8
+ Exclude:
9
+ - "vendor/**/*"
10
+ - "pkg/**/*"
11
+ - "tmp/**/*"
12
+ - "sig/**/*"
13
+
14
+ # The codebase uses double quotes consistently (Bundler gem template default).
15
+ Style/StringLiterals:
16
+ EnforcedStyle: double_quotes
17
+
18
+ Style/StringLiteralsInInterpolation:
19
+ EnforcedStyle: double_quotes
20
+
21
+ Layout/LineLength:
22
+ Max: 120
23
+
24
+ # Resources subclass Resource, which intentionally has no #initialize —
25
+ # it is a behaviour mixin, not a stateful base class. Calling super would
26
+ # only reach Object#initialize, which is a no-op.
27
+ Lint/MissingSuper:
28
+ Exclude:
29
+ - "lib/abacate_pay/resources/**/*.rb"
30
+ - "spec/**/*"
31
+
32
+ # Test doubles exist precisely to expose or stub inherited behaviour.
33
+ Lint/UselessMethodDefinition:
34
+ Exclude:
35
+ - "spec/**/*"
36
+
37
+ RSpec/MultipleMemoizedHelpers:
38
+ Max: 10
39
+
40
+ # Enums expose a `.values` class method returning an Array. The cop assumes a
41
+ # Hash and would rewrite it to `each_value`, which does not exist there.
42
+ Style/HashEachMethods:
43
+ AllowedReceivers:
44
+ - described_class
45
+
46
+ # Enum modules are self-documenting constant tables; a doc comment per
47
+ # module adds noise without adding information.
48
+ Style/Documentation:
49
+ Exclude:
50
+ - "lib/abacate_pay/enums/**/*.rb"
51
+
52
+ Naming/MethodParameterName:
53
+ AllowedNames:
54
+ - id
55
+
56
+ # `verify!` raises on failure and returns true on success — the bang, not a
57
+ # question mark, is the right signal. `valid?` is the predicate counterpart.
58
+ Naming/PredicateMethod:
59
+ AllowedMethods:
60
+ - verify!
61
+
62
+ # Faraday errors carry a response payload, not just a message; the compact
63
+ # form is how Faraday itself documents constructing them.
64
+ Style/RaiseArgs:
65
+ AllowedCompactTypes:
66
+ - Faraday::ConnectionFailed
67
+ - Faraday::TimeoutError
68
+ - Faraday::ClientError
69
+ - Faraday::ServerError
70
+
71
+ # Development dependencies live in the gemspec so a single file describes the
72
+ # gem completely.
73
+ Gemspec/DevelopmentDependencies:
74
+ EnforcedStyle: gemspec
75
+
76
+ Metrics/MethodLength:
77
+ Max: 25
78
+ Exclude:
79
+ - "spec/**/*"
80
+
81
+ Metrics/AbcSize:
82
+ Max: 25
83
+ Exclude:
84
+ - "spec/**/*"
85
+
86
+ Metrics/CyclomaticComplexity:
87
+ Max: 12
88
+
89
+ Metrics/PerceivedComplexity:
90
+ Max: 12
91
+
92
+ Metrics/ClassLength:
93
+ Max: 200
94
+ Exclude:
95
+ - "spec/**/*"
96
+
97
+ # RSpec describe/context blocks are naturally long; length is not a
98
+ # meaningful signal there.
99
+ Metrics/BlockLength:
100
+ Exclude:
101
+ - "spec/**/*"
102
+ - "*.gemspec"
103
+
104
+ Metrics/ParameterLists:
105
+ Exclude:
106
+ - "lib/abacate_pay/resources/**/*.rb"
107
+
108
+ RSpec/ExampleLength:
109
+ Max: 20
110
+
111
+ RSpec/MultipleExpectations:
112
+ Max: 10
113
+
114
+ RSpec/NestedGroups:
115
+ Max: 4
116
+
117
+ RSpec/SpecFilePathFormat:
118
+ Enabled: false
119
+
120
+ # These specs deliberately cut across the whole library rather than describing
121
+ # a single class.
122
+ RSpec/DescribeClass:
123
+ Exclude:
124
+ - "spec/clients/request_contract_spec.rb"
125
+ - "spec/packaging_spec.rb"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,125 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
1
8
  ## [Unreleased]
2
9
 
3
- ## [0.1.0] - 2024-12-11
10
+ ## [1.0.0] - 2026-08-05
11
+
12
+ First stable release. The public surface is now covered by CI on four Ruby
13
+ versions and will not change without a major bump.
14
+
15
+ ### Added
16
+
17
+ - Full API coverage: checkouts, coupons, customers, payouts, PIX transfers,
18
+ products, store, subscriptions and transparent checkout.
19
+ - `AbacatePay::Webhooks.construct_event` — verifies the signature and parses the
20
+ body in a single call, so an unverified payload cannot be acted on.
21
+ - `AbacatePay::Webhooks::PayloadError` for malformed or non-object webhook bodies.
22
+ - `PaymentLinkClient` (`AbacatePay.payment_links`) — reusable multi-payment links.
23
+ - `WebhookClient` (`AbacatePay.webhook_endpoints`) — webhook endpoint registration,
24
+ with local HTTPS validation so a bad endpoint fails before the round trip.
25
+ - `CheckoutClient#refund`, `TransparentClient#refund`, `PaymentLinkClient#refund` —
26
+ refunds were previously impossible through the SDK.
27
+ - `SubscriptionClient#cancel` — a subscription created through the SDK could not
28
+ be cancelled through it.
29
+ - CI workflow running the suite on Ruby 3.2, 3.3, 3.4 and 4.0, plus RuboCop, a
30
+ dependency audit and a gem build check on every pull request.
31
+ - Request-contract specs that let the client build its own connection, asserting
32
+ the real endpoint path, bearer token, timeout and outgoing JSON body. The
33
+ existing client specs injected their own Faraday connection, so a wrong
34
+ endpoint path could not fail them.
35
+ - Coverage measurement: simplecov has been a declared dependency since 0.1.0
36
+ without ever being loaded. Line coverage is now 99.13% with a 90% floor.
37
+ - Dependabot for bundler and GitHub Actions.
38
+
39
+ ### Fixed
40
+
41
+ - **The SDK routed to a retired API.** `api_url` derived the version from the
42
+ token prefix and fell back to `/v1` for any format it did not recognise. The
43
+ v1 prefix has been retired and answers
44
+ `{"success":false,"data":null,"error":"Not found"}` on every path, so anyone
45
+ holding a token in an older format failed 100% of calls with a message that
46
+ did not point at the cause. There is one base URL now:
47
+ `https://api.abacatepay.com/v2`.
48
+ - **Three source files were missing from the built gem.** The gemspec builds its
49
+ file list from `git ls-files`, so a file nobody had staged was silently
50
+ dropped from the package; because the manifests require every component
51
+ explicitly, `require "abacate_pay"` then raised `LoadError` on the installed
52
+ gem while the whole suite stayed green against the working tree. A packaging
53
+ spec now asserts that every file under `lib/` ships.
54
+ - **Using the SDK before calling `configure` raised `NoMethodError`.** The most
55
+ common first-run mistake surfaced as `undefined method 'api_url' for nil` from
56
+ inside the client instead of naming the missing call. It is now a
57
+ `ConfigurationError` that says what to do.
58
+ - **Assigning `AbacatePay.configuration` directly left stale clients behind.**
59
+ `configure` discarded memoized clients but the raw writer did not, so a client
60
+ built against replaced credentials outlived them.
61
+ - **Webhook verification crashed on a missing signature header.** A request
62
+ without `X-Webhook-Signature` reached `secure_compare` as `nil` and raised
63
+ `NoMethodError`, so `valid?` returned neither `true` nor `false` and the
64
+ endpoint returned a server error instead of rejecting the request. Missing and
65
+ empty signatures — and a missing secret — are now `SignatureError`.
66
+ - **`Webhooks.parse` leaked parser internals.** Malformed JSON raised
67
+ `JSON::ParserError` and a non-object JSON body raised `TypeError`; both now
68
+ raise `PayloadError`.
69
+ - **`config.timeout` was dead configuration.** It was documented and settable but
70
+ never reached Faraday, so a hung gateway blocked the calling thread forever.
71
+ It now sets both the read and open timeout.
72
+ - **Changing the token at runtime had no effect.** Clients were memoized on first
73
+ use and never rebuilt, so `AbacatePay.configure` after a first API call kept
74
+ sending the previous bearer token. `configure` now discards memoized clients.
75
+ - `Configuration#api_url` was declared twice — as an `attr_reader` and as a
76
+ method. The dead reader has been removed.
77
+ - `CustomerClient#get` and `#delete` had no test coverage at all.
78
+ - The `customer` and `billing` specs stubbed singular endpoint paths while the
79
+ clients call the plural ones; the specs never noticed because they bypassed
80
+ connection building.
81
+ - Component loading no longer depends on a `Dir` glob whose correctness rested on
82
+ alphabetical ordering placing `client.rb` before its subclasses. The three
83
+ manifest files were also missing every class added after 0.1.0.
84
+
85
+ ### Security
86
+
87
+ - **faraday is now `~> 2.14, >= 2.14.3`**, excluding CVE-2026-54297 (High): an
88
+ uncontrolled recursion in `NestedParamsEncoder` allowing stack-exhaustion DoS
89
+ via deeply nested query parameters. The previous `~> 2.9` constraint let
90
+ consumers resolve to a vulnerable version.
91
+ - Webhook handling no longer crashes on unauthenticated input (see Fixed).
92
+
93
+ ### Changed
94
+
95
+ - **BREAKING: `required_ruby_version` is now `>= 3.2.0`** (was `>= 2.6.0`). The
96
+ old floor was never installable — faraday 2.x requires Ruby 3.0 or newer — so
97
+ no working installation is losing support, but a `bundle update` on Ruby 2.6
98
+ or 3.1 will now refuse to resolve instead of failing later.
99
+ - **`config.environment` is deprecated and now warns.** It was declared,
100
+ defaulted, and validated, but read by nothing. Per AbacatePay's own
101
+ documentation the environment is decided by the API key — Dev mode keys
102
+ simulate transactions — so the setting could never have worked. It is kept as
103
+ an accepted no-op so existing initializers keep loading.
104
+ - `validate!` no longer rejects unknown `environment` values, and now rejects an
105
+ empty or whitespace-only token.
106
+ - Releases publish from a `v*` tag instead of every push to `main`, and verify
107
+ that the tag matches `AbacatePay::VERSION` before publishing.
108
+ - Publishing uses RubyGems Trusted Publishing (OIDC) instead of a long-lived API
109
+ key written to `~/.gem/credentials`.
110
+ - `rubygems_mfa_required` is enabled on the gem.
111
+
112
+ ### Removed
113
+
114
+ - Publishing to GitHub Packages. The step never executed successfully in any run
115
+ and nothing consumed the gem from that registry.
116
+ - `sig/abacatepay/rails.rbs`. Leftover `bundle gem` scaffolding declaring an
117
+ `Abacatepay::Rails` module that does not exist in this codebase — and it was
118
+ shipping inside the published gem, where a type checker would read it.
119
+
120
+ ## [0.1.0] - 2024-12-13
4
121
 
5
122
  - Initial release
123
+
124
+ [1.0.0]: https://github.com/AbacatePay/abacatepay-ruby-sdk/releases/tag/v1.0.0
125
+ [0.1.0]: https://github.com/AbacatePay/abacatepay-ruby-sdk/releases/tag/v0.1.0