frame_payments 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,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Frame
4
+ class Refund < APIResource
5
+ extend Frame::APIOperations::Create
6
+ extend Frame::APIOperations::List
7
+
8
+ OBJECT_NAME = "refund"
9
+
10
+ def self.object_name
11
+ OBJECT_NAME
12
+ end
13
+
14
+ def self.create(params = {}, opts = {})
15
+ request_object(
16
+ :post,
17
+ "/v1/refunds",
18
+ params,
19
+ opts
20
+ )
21
+ end
22
+
23
+ def self.list(params = {}, opts = {})
24
+ request_object(
25
+ :get,
26
+ "/v1/refunds",
27
+ params,
28
+ opts
29
+ )
30
+ end
31
+
32
+ def self.retrieve(id, opts = {})
33
+ id = Util.normalize_id(id)
34
+ request_object(
35
+ :get,
36
+ "/v1/refunds/#{CGI.escape(id)}",
37
+ {},
38
+ opts
39
+ )
40
+ end
41
+
42
+ def cancel(params = {}, opts = {})
43
+ request_object(
44
+ :post,
45
+ "/v1/refunds/#{CGI.escape(self["id"])}/cancel",
46
+ params,
47
+ opts
48
+ )
49
+ end
50
+
51
+ def self.cancel(id, params = {}, opts = {})
52
+ request_object(
53
+ :post,
54
+ "/v1/refunds/#{CGI.escape(id)}/cancel",
55
+ params,
56
+ opts
57
+ )
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Frame
4
+ class Subscription < APIResource
5
+ extend Frame::APIOperations::Create
6
+ extend Frame::APIOperations::List
7
+ include Frame::APIOperations::Delete
8
+ include Frame::APIOperations::Save
9
+
10
+ OBJECT_NAME = "subscription"
11
+
12
+ def self.object_name
13
+ OBJECT_NAME
14
+ end
15
+
16
+ def self.create(params = {}, opts = {})
17
+ request_object(
18
+ :post,
19
+ "/v1/subscriptions",
20
+ params,
21
+ opts
22
+ )
23
+ end
24
+
25
+ def self.list(params = {}, opts = {})
26
+ request_object(
27
+ :get,
28
+ "/v1/subscriptions",
29
+ params,
30
+ opts
31
+ )
32
+ end
33
+
34
+ def self.retrieve(id, opts = {})
35
+ id = Util.normalize_id(id)
36
+ request_object(
37
+ :get,
38
+ "/v1/subscriptions/#{CGI.escape(id)}",
39
+ {},
40
+ opts
41
+ )
42
+ end
43
+
44
+ def self.delete(id, params = {}, opts = {})
45
+ request_object(
46
+ :delete,
47
+ "/v1/subscriptions/#{CGI.escape(id)}",
48
+ params,
49
+ opts
50
+ )
51
+ end
52
+
53
+ def save(params = {}, opts = {})
54
+ values = serialize_params(self).merge(params)
55
+
56
+ if values.empty?
57
+ return self
58
+ end
59
+
60
+ updated = request_object(
61
+ :patch,
62
+ "/v1/subscriptions/#{CGI.escape(self["id"])}",
63
+ values,
64
+ opts
65
+ )
66
+
67
+ initialize_from(updated)
68
+ self
69
+ end
70
+
71
+ def delete(params = {}, opts = {})
72
+ request_object(
73
+ :delete,
74
+ "/v1/subscriptions/#{CGI.escape(self["id"])}",
75
+ params,
76
+ opts
77
+ )
78
+ end
79
+
80
+ def cancel(params = {}, opts = {})
81
+ request_object(
82
+ :post,
83
+ "/v1/subscriptions/#{CGI.escape(self["id"])}/cancel",
84
+ params,
85
+ opts
86
+ )
87
+ end
88
+
89
+ def self.cancel(id, params = {}, opts = {})
90
+ request_object(
91
+ :post,
92
+ "/v1/subscriptions/#{CGI.escape(id)}/cancel",
93
+ params,
94
+ opts
95
+ )
96
+ end
97
+
98
+ def resume(params = {}, opts = {})
99
+ request_object(
100
+ :post,
101
+ "/v1/subscriptions/#{CGI.escape(self["id"])}/resume",
102
+ params,
103
+ opts
104
+ )
105
+ end
106
+
107
+ def self.resume(id, params = {}, opts = {})
108
+ request_object(
109
+ :post,
110
+ "/v1/subscriptions/#{CGI.escape(id)}/resume",
111
+ params,
112
+ opts
113
+ )
114
+ end
115
+
116
+ def pause(params = {}, opts = {})
117
+ request_object(
118
+ :post,
119
+ "/v1/subscriptions/#{CGI.escape(self["id"])}/pause",
120
+ params,
121
+ opts
122
+ )
123
+ end
124
+
125
+ def self.pause(id, params = {}, opts = {})
126
+ request_object(
127
+ :post,
128
+ "/v1/subscriptions/#{CGI.escape(id)}/pause",
129
+ params,
130
+ opts
131
+ )
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Frame
4
+ class SubscriptionPhase < APIResource
5
+ extend Frame::APIOperations::Create
6
+ extend Frame::APIOperations::List
7
+ include Frame::APIOperations::Delete
8
+ include Frame::APIOperations::Save
9
+
10
+ OBJECT_NAME = "subscription_phase"
11
+
12
+ def self.object_name
13
+ OBJECT_NAME
14
+ end
15
+
16
+ def self.create(params = {}, opts = {})
17
+ request_object(
18
+ :post,
19
+ "/v1/subscription_phases",
20
+ params,
21
+ opts
22
+ )
23
+ end
24
+
25
+ def self.list(params = {}, opts = {})
26
+ request_object(
27
+ :get,
28
+ "/v1/subscription_phases",
29
+ params,
30
+ opts
31
+ )
32
+ end
33
+
34
+ def self.retrieve(id, opts = {})
35
+ id = Util.normalize_id(id)
36
+ request_object(
37
+ :get,
38
+ "/v1/subscription_phases/#{CGI.escape(id)}",
39
+ {},
40
+ opts
41
+ )
42
+ end
43
+
44
+ def self.delete(id, params = {}, opts = {})
45
+ request_object(
46
+ :delete,
47
+ "/v1/subscription_phases/#{CGI.escape(id)}",
48
+ params,
49
+ opts
50
+ )
51
+ end
52
+
53
+ def save(params = {}, opts = {})
54
+ values = serialize_params(self).merge(params)
55
+
56
+ if values.empty?
57
+ return self
58
+ end
59
+
60
+ updated = request_object(
61
+ :patch,
62
+ "/v1/subscription_phases/#{CGI.escape(self["id"])}",
63
+ values,
64
+ opts
65
+ )
66
+
67
+ initialize_from(updated)
68
+ self
69
+ end
70
+
71
+ def delete(params = {}, opts = {})
72
+ request_object(
73
+ :delete,
74
+ "/v1/subscription_phases/#{CGI.escape(self["id"])}",
75
+ params,
76
+ opts
77
+ )
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Frame
4
+ class WebhookEndpoint < APIResource
5
+ extend Frame::APIOperations::Create
6
+ extend Frame::APIOperations::List
7
+ include Frame::APIOperations::Delete
8
+ include Frame::APIOperations::Save
9
+
10
+ OBJECT_NAME = "webhook_endpoint"
11
+
12
+ def self.object_name
13
+ OBJECT_NAME
14
+ end
15
+
16
+ def self.create(params = {}, opts = {})
17
+ request_object(
18
+ :post,
19
+ "/v1/webhook_endpoints",
20
+ params,
21
+ opts
22
+ )
23
+ end
24
+
25
+ def self.list(params = {}, opts = {})
26
+ request_object(
27
+ :get,
28
+ "/v1/webhook_endpoints",
29
+ params,
30
+ opts
31
+ )
32
+ end
33
+
34
+ def self.retrieve(id, opts = {})
35
+ id = Util.normalize_id(id)
36
+ request_object(
37
+ :get,
38
+ "/v1/webhook_endpoints/#{CGI.escape(id)}",
39
+ {},
40
+ opts
41
+ )
42
+ end
43
+
44
+ def self.delete(id, params = {}, opts = {})
45
+ request_object(
46
+ :delete,
47
+ "/v1/webhook_endpoints/#{CGI.escape(id)}",
48
+ params,
49
+ opts
50
+ )
51
+ end
52
+
53
+ def save(params = {}, opts = {})
54
+ values = serialize_params(self).merge(params)
55
+
56
+ if values.empty?
57
+ return self
58
+ end
59
+
60
+ updated = request_object(
61
+ :patch,
62
+ "/v1/webhook_endpoints/#{CGI.escape(self["id"])}",
63
+ values,
64
+ opts
65
+ )
66
+
67
+ initialize_from(updated)
68
+ self
69
+ end
70
+
71
+ def delete(params = {}, opts = {})
72
+ request_object(
73
+ :delete,
74
+ "/v1/webhook_endpoints/#{CGI.escape(self["id"])}",
75
+ params,
76
+ opts
77
+ )
78
+ end
79
+
80
+ def enable(params = {}, opts = {})
81
+ request_object(
82
+ :post,
83
+ "/v1/webhook_endpoints/#{CGI.escape(self["id"])}/enable",
84
+ params,
85
+ opts
86
+ )
87
+ end
88
+
89
+ def self.enable(id, params = {}, opts = {})
90
+ request_object(
91
+ :post,
92
+ "/v1/webhook_endpoints/#{CGI.escape(id)}/enable",
93
+ params,
94
+ opts
95
+ )
96
+ end
97
+
98
+ def disable(params = {}, opts = {})
99
+ request_object(
100
+ :post,
101
+ "/v1/webhook_endpoints/#{CGI.escape(self["id"])}/disable",
102
+ params,
103
+ opts
104
+ )
105
+ end
106
+
107
+ def self.disable(id, params = {}, opts = {})
108
+ request_object(
109
+ :post,
110
+ "/v1/webhook_endpoints/#{CGI.escape(id)}/disable",
111
+ params,
112
+ opts
113
+ )
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file loads all Frame Payments API resources.
4
+ # Resources are organized alphabetically for maintainability.
5
+
6
+ # Customer management
7
+ require "frame/resources/customer"
8
+ require "frame/resources/customer_identity_verification"
9
+
10
+ # Payment processing
11
+ require "frame/resources/charge_intent"
12
+ require "frame/resources/payment_method"
13
+ require "frame/resources/refund"
14
+
15
+ # Invoicing
16
+ require "frame/resources/invoice"
17
+ require "frame/resources/invoice_line_item"
18
+
19
+ # Subscriptions
20
+ require "frame/resources/product"
21
+ require "frame/resources/product_phase"
22
+ require "frame/resources/subscription"
23
+ require "frame/resources/subscription_phase"
24
+
25
+ # Webhooks
26
+ require "frame/resources/webhook_endpoint"
data/lib/frame/util.rb ADDED
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Frame
4
+ module Util
5
+ OBJECT_CLASSES = {
6
+ "customer" => "Customer",
7
+ "charge_intent" => "ChargeIntent",
8
+ "payment_method" => "PaymentMethod",
9
+ "refund" => "Refund",
10
+ "invoice" => "Invoice",
11
+ "invoice_line_item" => "InvoiceLineItem",
12
+ "subscription" => "Subscription",
13
+ "subscription_phase" => "SubscriptionPhase",
14
+ "product" => "Product",
15
+ "product_phase" => "ProductPhase",
16
+ "webhook_endpoint" => "WebhookEndpoint",
17
+ "customer_identity_verification" => "CustomerIdentityVerification",
18
+ "list" => "ListObject"
19
+ }.freeze
20
+
21
+ def self.object_classes
22
+ OBJECT_CLASSES
23
+ end
24
+
25
+ def self.convert_to_frame_object(resp, opts = {})
26
+ case resp
27
+ when Array
28
+ resp.map { |i| convert_to_frame_object(i, opts) }
29
+ when Hash
30
+ # Try converting to a specific object class if this is a response with an object key
31
+ object_name = resp[:object]
32
+
33
+ if object_name && object_classes[object_name]
34
+ klass = object_classes_to_constants[object_name]
35
+ klass.construct_from(resp, opts)
36
+ elsif resp[:data]&.is_a?(Array)
37
+ # This is a list object
38
+ ListObject.construct_from(resp, opts)
39
+ else
40
+ FrameObject.construct_from(resp, opts)
41
+ end
42
+ else
43
+ resp
44
+ end
45
+ end
46
+
47
+ def self.symbolize_names(object)
48
+ case object
49
+ when Hash
50
+ new_hash = {}
51
+ object.each do |key, value|
52
+ key = begin
53
+ key.to_sym
54
+ rescue
55
+ key
56
+ end || key
57
+ new_hash[key] = symbolize_names(value)
58
+ end
59
+ new_hash
60
+ when Array
61
+ object.map { |value| symbolize_names(value) }
62
+ else
63
+ object
64
+ end
65
+ end
66
+
67
+ def self.normalize_id(id)
68
+ id&.to_s
69
+ end
70
+
71
+ def self.normalize_opts(opts)
72
+ opts.clone
73
+ end
74
+
75
+ def self.object_classes_to_constants
76
+ @object_classes_to_constants ||= begin
77
+ constants = {}
78
+ object_classes.each do |object_name, class_name|
79
+ # Store with both string and symbol keys for flexibility
80
+ constants[object_name] = Frame.const_get(class_name, false)
81
+ constants[object_name.to_sym] = Frame.const_get(class_name, false)
82
+ end
83
+ constants
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Frame
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Core dependencies
4
+ require "json"
5
+ require "logger"
6
+ require "uri"
7
+ require "cgi"
8
+ require "forwardable"
9
+ require "faraday"
10
+
11
+ # Frame SDK core components
12
+ require "frame/version"
13
+ require "frame/error"
14
+ require "frame/util"
15
+ require "frame/configuration"
16
+ require "frame/frame_client"
17
+ require "frame/frame_object"
18
+
19
+ # API operation modules (must be loaded before classes that use them)
20
+ require "frame/api_operations/create"
21
+ require "frame/api_operations/delete"
22
+ require "frame/api_operations/list"
23
+ require "frame/api_operations/request"
24
+ require "frame/api_operations/save"
25
+
26
+ # Core resource classes
27
+ require "frame/list_object"
28
+ require "frame/api_resource"
29
+
30
+ # All API resources
31
+ require "frame/resources"
32
+
33
+ # Main Frame module
34
+ #
35
+ # The Frame module provides the main interface for interacting with the Frame Payments API.
36
+ # Configure your API key and start making requests:
37
+ #
38
+ # Frame.api_key = 'your_api_key_here'
39
+ # customer = Frame::Customer.create(name: 'John Doe', email: 'john@example.com')
40
+ #
41
+ # @see https://docs.framepayments.com for API documentation
42
+ module Frame
43
+ @config = Configuration.setup
44
+
45
+ class << self
46
+ extend Forwardable
47
+
48
+ # @return [Configuration] the current configuration object
49
+ attr_reader :config
50
+
51
+ # Delegates to the configuration object for easy access to settings
52
+ def_delegators :@config, :api_key, :api_key=
53
+ def_delegators :@config, :api_base, :api_base=
54
+ def_delegators :@config, :open_timeout, :open_timeout=
55
+ def_delegators :@config, :read_timeout, :read_timeout=
56
+ def_delegators :@config, :verify_ssl_certs, :verify_ssl_certs=
57
+ def_delegators :@config, :log_level, :log_level=
58
+ def_delegators :@config, :logger, :logger=
59
+ end
60
+ end
data/sig/frame.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module Frame
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: frame_payments
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Frame Payments
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2026-01-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: webmock
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.14'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.14'
55
+ description: A Ruby library for Frame Payments API that provides a convenient interface
56
+ for making requests and handling responses.
57
+ email:
58
+ - support@framepayments.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".standard.yml"
64
+ - CHANGELOG.md
65
+ - CODE_OF_CONDUCT.md
66
+ - LICENSE.txt
67
+ - PRODUCTION_READINESS.md
68
+ - README.md
69
+ - Rakefile
70
+ - lib/frame/api_operations/create.rb
71
+ - lib/frame/api_operations/delete.rb
72
+ - lib/frame/api_operations/list.rb
73
+ - lib/frame/api_operations/request.rb
74
+ - lib/frame/api_operations/save.rb
75
+ - lib/frame/api_resource.rb
76
+ - lib/frame/configuration.rb
77
+ - lib/frame/error.rb
78
+ - lib/frame/frame_client.rb
79
+ - lib/frame/frame_object.rb
80
+ - lib/frame/list_object.rb
81
+ - lib/frame/resources.rb
82
+ - lib/frame/resources/charge_intent.rb
83
+ - lib/frame/resources/customer.rb
84
+ - lib/frame/resources/customer_identity_verification.rb
85
+ - lib/frame/resources/invoice.rb
86
+ - lib/frame/resources/invoice_line_item.rb
87
+ - lib/frame/resources/payment_method.rb
88
+ - lib/frame/resources/product.rb
89
+ - lib/frame/resources/product_phase.rb
90
+ - lib/frame/resources/refund.rb
91
+ - lib/frame/resources/subscription.rb
92
+ - lib/frame/resources/subscription_phase.rb
93
+ - lib/frame/resources/webhook_endpoint.rb
94
+ - lib/frame/util.rb
95
+ - lib/frame/version.rb
96
+ - lib/frame_payments.rb
97
+ - sig/frame.rbs
98
+ homepage: https://github.com/framepayments/frame-ruby
99
+ licenses:
100
+ - MIT
101
+ metadata:
102
+ homepage_uri: https://github.com/framepayments/frame-ruby
103
+ source_code_uri: https://github.com/framepayments/frame-ruby
104
+ changelog_uri: https://github.com/framepayments/frame-ruby/blob/main/CHANGELOG.md
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: 3.1.0
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubygems_version: 3.5.3
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: Ruby bindings for the Frame Payments API
124
+ test_files: []