abacatepay-ruby 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,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AbacatePay
4
+ module Enums
5
+ module Billing
6
+ # Enumeration defining billing methods.
7
+ #
8
+ # This enumeration is used to represent different payment methods available for billing.
9
+ class Methods
10
+ # PIX payment method.
11
+ # @return [String] Represents the PIX payment method, a popular instant payment system in Brazil
12
+ PIX = "PIX"
13
+
14
+ # Gets all valid method values
15
+ # @return [Array<String>] List of all valid payment methods
16
+ def self.values
17
+ [PIX]
18
+ end
19
+
20
+ # Validates if a given value is a valid method
21
+ # @param value [String] The value to validate
22
+ # @return [Boolean] true if valid, false otherwise
23
+ def self.valid?(value)
24
+ values.include?(value)
25
+ end
26
+
27
+ # Validates and returns the value if valid
28
+ # @param value [String] The value to validate
29
+ # @return [String] The validated value
30
+ # @raise [ArgumentError] if value is invalid
31
+ def self.validate!(value)
32
+ raise ArgumentError, "Invalid payment method: #{value}" unless valid?(value)
33
+ value
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AbacatePay
4
+ module Enums
5
+ module Billing
6
+ # Enumeration defining billing statuses.
7
+ #
8
+ # This enumeration is used to represent the various statuses that a billing process can have.
9
+ class Statuses
10
+ # Indicates that the billing is pending and has not yet been processed.
11
+ # @return [String]
12
+ PENDING = "PENDING"
13
+
14
+ # Indicates that the billing has expired and is no longer valid.
15
+ # @return [String]
16
+ EXPIRED = "EXPIRED"
17
+
18
+ # Indicates that the billing has been cancelled and will not be processed.
19
+ # @return [String]
20
+ CANCELLED = "CANCELLED"
21
+
22
+ # Indicates that the billing has been successfully paid.
23
+ # @return [String]
24
+ PAID = "PAID"
25
+
26
+ # Indicates that the billing has been refunded to the payer.
27
+ # @return [String]
28
+ REFUNDED = "REFUNDED"
29
+
30
+ # Gets all valid status values
31
+ # @return [Array<String>] List of all valid statuses
32
+ def self.values
33
+ [PENDING, EXPIRED, CANCELLED, PAID, REFUNDED]
34
+ end
35
+
36
+ # Validates if a given value is a valid status
37
+ # @param value [String] The value to validate
38
+ # @return [Boolean] true if valid, false otherwise
39
+ def self.valid?(value)
40
+ values.include?(value)
41
+ end
42
+
43
+ # Validates and returns the value if valid
44
+ # @param value [String] The value to validate
45
+ # @return [String] The validated value
46
+ # @raise [ArgumentError] if value is invalid
47
+ def self.validate!(value)
48
+ raise ArgumentError, "Invalid status: #{value}" unless valid?(value)
49
+ value
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "abacate_pay/enums/billing/frequencies"
4
+ require "abacate_pay/enums/billing/methods"
5
+ require "abacate_pay/enums/billing/statuses"
6
+
7
+ module AbacatePay
8
+ # The Enums module contains all enumeration classes used
9
+ # throughout the AbacatePay SDK.
10
+ module Enums
11
+ end
12
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AbacatePay
4
+ module Resources
5
+ module Billing
6
+ # Represents metadata for a billing resource in the AbacatePay system.
7
+ #
8
+ # This class contains additional information related to a billing resource,
9
+ # such as fee, return URL, and completion URL.
10
+ class Metadata < Resource
11
+ # @return [Integer, nil] Fee associated with the billing
12
+ attr_accessor :fee
13
+
14
+ # @return [String, nil] URL to redirect the user after payment is canceled or abandoned
15
+ attr_accessor :return_url
16
+
17
+ # @return [String, nil] URL to redirect the user after successful payment
18
+ attr_accessor :completion_url
19
+
20
+ # Creates a new Metadata instance
21
+ #
22
+ # @param data [Hash] The metadata properties
23
+ def initialize(data)
24
+ fill(data)
25
+ end
26
+
27
+ protected
28
+
29
+ def to_hash
30
+ super
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AbacatePay
4
+ module Resources
5
+ module Billing
6
+ # Represents a product in a billing resource in the AbacatePay system.
7
+ #
8
+ # This class contains information about a product, such as its identifier,
9
+ # name, description, quantity, and price.
10
+ class Product < Resource
11
+ # @return [String, nil] External identifier for the product
12
+ attr_accessor :external_id
13
+
14
+ # @return [String, nil] Internal identifier for the product in the system
15
+ attr_accessor :product_id
16
+
17
+ # @return [String, nil] Name of the product
18
+ attr_accessor :name
19
+
20
+ # @return [String, nil] Description of the product
21
+ attr_accessor :description
22
+
23
+ # @return [Integer, nil] Quantity of the product
24
+ attr_accessor :quantity
25
+
26
+ # @return [Integer, nil] Price of the product in smallest currency unit (e.g., cents)
27
+ attr_accessor :price
28
+
29
+ # Creates a new Product instance
30
+ #
31
+ # @param data [Hash] The product properties
32
+ def initialize(data)
33
+ fill(data)
34
+ end
35
+
36
+ protected
37
+
38
+ def to_hash
39
+ super
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "abacate_pay/resources/billing/metadata"
4
+ require "abacate_pay/resources/billing/product"
5
+
6
+ module AbacatePay
7
+ module Resources
8
+ # Represents a billing resource in the AbacatePay payment system.
9
+ #
10
+ # Manages billing-related data including payment methods, products, scheduling,
11
+ # and customer information for recurring and one-time payments.
12
+ class Billing < Resource
13
+ # Maps property names to their corresponding resource classes
14
+ RESOURCE_PROPERTIES = {
15
+ metadata: 'AbacatePay::Resources::Billing::Metadata',
16
+ customer: 'AbacatePay::Resources::Customer',
17
+ products: 'AbacatePay::Resources::Billing::Product'
18
+ }.freeze
19
+
20
+ # Maps property names to their corresponding enum classes
21
+ ENUM_PROPERTIES = {
22
+ status: 'AbacatePay::Enums::Billing::Statuses',
23
+ frequency: 'AbacatePay::Enums::Billing::Frequencies',
24
+ methods: 'AbacatePay::Enums::Billing::Methods'
25
+ }.freeze
26
+
27
+ # Properties that should be handled as DateTime objects
28
+ DATETIME_PROPERTIES = %w[
29
+ next_billing
30
+ created_at
31
+ updated_at
32
+ ].freeze
33
+
34
+ # Basic attributes
35
+ attr_reader :id, :account_id, :url, :dev_mode, :amount
36
+
37
+ # Complex attributes
38
+ attr_reader :methods, :products, :metadata, :customer
39
+
40
+ # Enum attributes
41
+ attr_reader :frequency, :status
42
+
43
+ # DateTime attributes
44
+ attr_reader :next_billing, :created_at, :updated_at
45
+
46
+ # Creates a new Billing instance
47
+ #
48
+ # @param data [Hash] The raw billing data
49
+ # @raise [ArgumentError] If the data is invalid
50
+ def initialize(data)
51
+ fill(data)
52
+ end
53
+
54
+ # Checks if billing is in development mode
55
+ #
56
+ # @return [Boolean, nil] True if in dev mode, false if not, or nil if not set
57
+ def dev_mode?
58
+ @dev_mode
59
+ end
60
+
61
+ private
62
+
63
+ # Process a value based on its property
64
+ #
65
+ # @param property [String] The property name
66
+ # @param value [Object] The value to process
67
+ # @return [Object] The processed value
68
+ def process_value(property, value)
69
+ return nil if value.nil?
70
+
71
+ if DATETIME_PROPERTIES.include?(property)
72
+ initialize_date_time(value)
73
+ elsif ENUM_PROPERTIES.key?(property.to_sym)
74
+ process_enum_value(property, value)
75
+ elsif RESOURCE_PROPERTIES.key?(property.to_sym)
76
+ process_resource_value(property, value)
77
+ else
78
+ value
79
+ end
80
+ end
81
+
82
+ # Process enum values
83
+ #
84
+ # @param property [String] The property name
85
+ # @param value [Object] The value to process
86
+ # @return [Object] The processed value
87
+ def process_enum_value(property, value)
88
+ enum_class = Object.const_get(ENUM_PROPERTIES[property.to_sym])
89
+
90
+ if value.is_a?(Array)
91
+ value.map { |item| initialize_enum(enum_class, item) }
92
+ else
93
+ initialize_enum(enum_class, value)
94
+ end
95
+ end
96
+
97
+ # Process resource values
98
+ #
99
+ # @param property [String] The property name
100
+ # @param value [Object] The value to process
101
+ # @return [Object] The processed value
102
+ def process_resource_value(property, value)
103
+ resource_class = Object.const_get(RESOURCE_PROPERTIES[property.to_sym])
104
+
105
+ if property.to_s == 'products' && value.is_a?(Array)
106
+ value.map { |item| initialize_resource(resource_class, item) }
107
+ else
108
+ initialize_resource(resource_class, value)
109
+ end
110
+ end
111
+
112
+ protected
113
+
114
+ # @!visibility private
115
+ attr_writer :id, :account_id, :url, :methods, :products,
116
+ :dev_mode, :amount, :metadata, :frequency, :status,
117
+ :customer, :next_billing, :created_at, :updated_at
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AbacatePay
4
+ module Resources
5
+ module Customer
6
+ # Represents metadata for a customer in the AbacatePay system.
7
+ #
8
+ # This class contains additional information about a customer, such as their name,
9
+ # contact details, and tax identification number.
10
+ class Metadata < Resource
11
+ # @return [String, nil] Customer's name
12
+ attr_accessor :name
13
+
14
+ # @return [String, nil] Customer's cellphone number
15
+ attr_accessor :cellphone
16
+
17
+ # @return [String, nil] Customer's email address
18
+ attr_accessor :email
19
+
20
+ # @return [String, nil] Customer's tax identification number
21
+ attr_accessor :tax_id
22
+
23
+ # Creates a new Metadata instance
24
+ #
25
+ # @param data [Hash] The metadata properties
26
+ def initialize(data)
27
+ fill(data)
28
+ end
29
+
30
+ protected
31
+
32
+ def to_hash
33
+ super
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "abacate_pay/resources/customer/metadata"
4
+
5
+ module AbacatePay
6
+ module Resources
7
+ # Represents a customer resource in the AbacatePay payment system.
8
+ #
9
+ # This class handles customer data including identification and metadata,
10
+ # providing a structured way to manage customer information within the system.
11
+ class Customer < Resource
12
+ # Maps property names to their corresponding resource classes
13
+ RESOURCE_PROPERTIES = {
14
+ metadata: 'AbacatePay::Resources::Customer::Metadata'
15
+ }.freeze
16
+
17
+ # @return [String, nil] The unique identifier for the customer
18
+ attr_reader :id
19
+
20
+ # @return [Metadata, nil] Additional customer information
21
+ attr_reader :metadata
22
+
23
+ # Creates a new Customer instance
24
+ #
25
+ # @param data [Hash] The raw customer data
26
+ # @raise [ArgumentError] If the data is invalid
27
+ def initialize(data)
28
+ fill(data)
29
+ end
30
+
31
+ private
32
+
33
+ # Process a value based on its property
34
+ #
35
+ # @param property [String] The property name
36
+ # @param value [Object] The value to process
37
+ # @return [Object] The processed value
38
+ def process_value(property, value)
39
+ return nil if value.nil?
40
+
41
+ if RESOURCE_PROPERTIES.key?(property.to_sym)
42
+ initialize_resource(
43
+ Object.const_get(RESOURCE_PROPERTIES[property.to_sym]),
44
+ value
45
+ )
46
+ else
47
+ value
48
+ end
49
+ end
50
+
51
+ protected
52
+
53
+ # @!visibility private
54
+ attr_writer :id, :metadata
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AbacatePay
4
+ module Resources
5
+ # Base class for resources in the AbacatePay system.
6
+ class Resource
7
+ private
8
+
9
+ # Initialize a DateTime object from a string or DateTime
10
+ #
11
+ # @param value [String, DateTime] The value to initialize
12
+ # @return [DateTime, nil] The initialized DateTime object or nil
13
+ # @raise [ArgumentError] If the value is invalid
14
+ def initialize_date_time(value)
15
+ return nil if value.nil? || value.empty?
16
+ return value.clone if value.is_a?(DateTime)
17
+
18
+ DateTime.parse(value)
19
+ rescue Date::Error
20
+ raise ArgumentError, "Invalid datetime value: #{value}"
21
+ end
22
+
23
+ # Initialize an enum from a string or enum object
24
+ #
25
+ # @param enum_class [Class] The enum class to initialize
26
+ # @param value [String, Object] The value to initialize
27
+ # @return [Object, nil] The initialized enum or nil
28
+ # @raise [ArgumentError] If the value is invalid
29
+ def initialize_enum(enum_class, value)
30
+ return nil if value.nil? || value.empty?
31
+
32
+ enum_class.validate!(value)
33
+ end
34
+
35
+ # Initialize a resource from a hash or resource object
36
+ #
37
+ # @param resource_class [Class] The resource class to initialize
38
+ # @param value [Hash, Object] The value to initialize
39
+ # @return [Object, nil] The initialized resource or nil
40
+ # @raise [ArgumentError] If the value is invalid
41
+ def initialize_resource(resource_class, value)
42
+ return nil if value.nil? || value.empty?
43
+ return value.clone if value.is_a?(resource_class)
44
+
45
+ unless value.is_a?(Hash)
46
+ raise ArgumentError, "Invalid resource value. Expected Hash or #{resource_class}, got #{value.class}"
47
+ end
48
+
49
+ resource_class.new(value)
50
+ end
51
+
52
+ # Fill the object with data
53
+ #
54
+ # @param data [Hash] The data to fill with
55
+ # @return [void]
56
+ def fill(data)
57
+ data.each do |key, value|
58
+ property = camel_to_snake(key)
59
+ next unless respond_to?("#{property}=", true)
60
+
61
+ send("#{property}=", process_value(property, value))
62
+ end
63
+ end
64
+
65
+ # Convert camelCase to snake_case
66
+ #
67
+ # @param str [String] The string to convert
68
+ # @return [String] The converted string
69
+ def camel_to_snake(str)
70
+ str.to_s
71
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
72
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
73
+ .downcase
74
+ end
75
+
76
+ # Convert snake_case to camelCase
77
+ #
78
+ # @param str [String] The string to convert
79
+ # @return [String] The converted string
80
+ def snake_to_camel(str)
81
+ str.split('_')
82
+ .map.with_index { |word, i| i.zero? ? word : word.capitalize }
83
+ .join
84
+ end
85
+
86
+ protected
87
+
88
+ # Convert the resource to a hash
89
+ #
90
+ # @return [Hash] The hash representation
91
+ def to_hash
92
+ instance_variables.each_with_object({}) do |var, hash|
93
+ next if var.to_s.start_with?('@__')
94
+
95
+ value = instance_variable_get(var)
96
+ key = snake_to_camel(var.to_s.delete('@'))
97
+
98
+ hash[key] = case value
99
+ when DateTime
100
+ value.iso8601
101
+ when Resource
102
+ value.to_hash
103
+ when Module
104
+ value.respond_to?(:value) ? value.value : value
105
+ when Array
106
+ value.map { |v| v.respond_to?(:to_hash) ? v.to_hash : v }
107
+ else
108
+ value
109
+ end
110
+ end.compact
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "abacate_pay/resources/resource"
4
+ require "abacate_pay/resources/billing"
5
+ require "abacate_pay/resources/customer"
6
+ require "abacate_pay/resources/billing/metadata"
7
+ require "abacate_pay/resources/billing/product"
8
+ require "abacate_pay/resources/customer/metadata"
9
+
10
+ module AbacatePay
11
+ # The Resources module contains all resource classes that
12
+ # represent the various entities in the AbacatePay system.
13
+ module Resources
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AbacatePay
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,6 @@
1
+ module Abacatepay
2
+ module Rails
3
+ VERSION: String
4
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
5
+ end
6
+ end