polar-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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +50 -0
- data/DEVELOPMENT.md +329 -0
- data/EXAMPLES.md +385 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +115 -0
- data/LICENSE +23 -0
- data/PROJECT_SUMMARY.md +256 -0
- data/README.md +635 -0
- data/Rakefile +24 -0
- data/examples/demo.rb +106 -0
- data/lib/polar/authentication.rb +83 -0
- data/lib/polar/client.rb +144 -0
- data/lib/polar/configuration.rb +46 -0
- data/lib/polar/customer_portal/benefit_grants.rb +41 -0
- data/lib/polar/customer_portal/customers.rb +69 -0
- data/lib/polar/customer_portal/license_keys.rb +70 -0
- data/lib/polar/customer_portal/orders.rb +82 -0
- data/lib/polar/customer_portal/subscriptions.rb +51 -0
- data/lib/polar/errors.rb +96 -0
- data/lib/polar/http_client.rb +150 -0
- data/lib/polar/pagination.rb +133 -0
- data/lib/polar/resources/base.rb +47 -0
- data/lib/polar/resources/benefits.rb +64 -0
- data/lib/polar/resources/checkouts.rb +75 -0
- data/lib/polar/resources/customers.rb +120 -0
- data/lib/polar/resources/events.rb +45 -0
- data/lib/polar/resources/files.rb +57 -0
- data/lib/polar/resources/license_keys.rb +81 -0
- data/lib/polar/resources/metrics.rb +30 -0
- data/lib/polar/resources/oauth2.rb +61 -0
- data/lib/polar/resources/orders.rb +54 -0
- data/lib/polar/resources/organizations.rb +41 -0
- data/lib/polar/resources/payments.rb +29 -0
- data/lib/polar/resources/products.rb +58 -0
- data/lib/polar/resources/subscriptions.rb +55 -0
- data/lib/polar/resources/webhooks.rb +81 -0
- data/lib/polar/version.rb +5 -0
- data/lib/polar/webhooks.rb +174 -0
- data/lib/polar.rb +65 -0
- metadata +239 -0
data/examples/demo.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Demo script showing the Polar Ruby SDK in action
|
3
|
+
|
4
|
+
require_relative '../lib/polar'
|
5
|
+
|
6
|
+
puts 'š»āāļø Polar Ruby SDK Demo'
|
7
|
+
puts '=' * 50
|
8
|
+
|
9
|
+
# Configuration example
|
10
|
+
puts "\nš Configuration Examples:"
|
11
|
+
puts "- Production client: Polar.new(access_token: 'polar_oat_...') "
|
12
|
+
puts "- Sandbox client: Polar.new(access_token: 'polar_oat_...', server: :sandbox)"
|
13
|
+
puts "- With customer session: Polar.new(customer_session: 'customer_session_...')"
|
14
|
+
|
15
|
+
# Create a demo client (without real credentials)
|
16
|
+
puts "\nš§ Creating client instance..."
|
17
|
+
client = Polar.new
|
18
|
+
|
19
|
+
puts 'ā
Client created successfully!'
|
20
|
+
puts 'Available resources:'
|
21
|
+
|
22
|
+
# List all available resources
|
23
|
+
resources = %w[
|
24
|
+
organizations products customers orders payments subscriptions
|
25
|
+
checkouts benefits license_keys files metrics events webhooks oauth2
|
26
|
+
]
|
27
|
+
|
28
|
+
resources.each do |resource|
|
29
|
+
puts " ⢠#{resource}: #{client.send(resource).class.name}"
|
30
|
+
end
|
31
|
+
|
32
|
+
puts "\nš„ Customer Portal resources:"
|
33
|
+
customer_portal_resources = %w[customers orders subscriptions benefit_grants license_keys]
|
34
|
+
customer_portal_resources.each do |resource|
|
35
|
+
puts " ⢠#{resource}: #{client.customer_portal.send(resource).class.name}"
|
36
|
+
end
|
37
|
+
|
38
|
+
# Configuration demonstration
|
39
|
+
puts "\nāļø Configuration examples:"
|
40
|
+
Polar.configure do |config|
|
41
|
+
config.server = :sandbox
|
42
|
+
config.timeout = 60
|
43
|
+
config.retries = 5
|
44
|
+
config.debug = false
|
45
|
+
end
|
46
|
+
|
47
|
+
puts 'Global configuration set:'
|
48
|
+
puts " ⢠Server: #{Polar.configuration.server}"
|
49
|
+
puts " ⢠Timeout: #{Polar.configuration.timeout}s"
|
50
|
+
puts " ⢠Retries: #{Polar.configuration.retries}"
|
51
|
+
puts " ⢠Debug: #{Polar.configuration.debug}"
|
52
|
+
|
53
|
+
# Error handling demonstration
|
54
|
+
puts "\nšØ Error handling capabilities:"
|
55
|
+
error_classes = [
|
56
|
+
Polar::HTTPError, Polar::NotFoundError, Polar::UnauthorizedError,
|
57
|
+
Polar::ValidationError, Polar::WebhookVerificationError, Polar::TimeoutError
|
58
|
+
]
|
59
|
+
|
60
|
+
error_classes.each do |error_class|
|
61
|
+
puts " ⢠#{error_class.name}"
|
62
|
+
end
|
63
|
+
|
64
|
+
# Webhook verification demo
|
65
|
+
puts "\nš Webhook verification example:"
|
66
|
+
payload = '{"type":"order.created","id":"evt_123","data":{"id":"order_123"}}'
|
67
|
+
timestamp = Time.now.to_i.to_s
|
68
|
+
secret = 'demo_webhook_secret'
|
69
|
+
|
70
|
+
signature = Polar::Webhooks.compute_signature(payload, timestamp, secret)
|
71
|
+
puts " ⢠Computed signature: #{signature[0..20]}..."
|
72
|
+
|
73
|
+
# Event parsing
|
74
|
+
event = Polar::Webhooks::Event.new(payload)
|
75
|
+
puts " ⢠Event type: #{event.type}"
|
76
|
+
puts " ⢠Event ID: #{event.id}"
|
77
|
+
puts " ⢠Is order event: #{event.order_event?}"
|
78
|
+
|
79
|
+
puts "\nšÆ Usage patterns:"
|
80
|
+
puts ' ⢠List with pagination: client.customers.list.each { |customer| ... }'
|
81
|
+
puts ' ⢠Auto-paginate: client.orders.list.auto_paginate'
|
82
|
+
puts " ⢠Single resource: client.products.get('prod_123')"
|
83
|
+
puts " ⢠Create resource: client.customers.create(email: '...', name: '...')"
|
84
|
+
|
85
|
+
puts "\n⨠Key features:"
|
86
|
+
puts ' ā
Complete API coverage'
|
87
|
+
puts ' ā
Type-safe error handling'
|
88
|
+
puts ' ā
Automatic pagination'
|
89
|
+
puts ' ā
Retry logic with backoff'
|
90
|
+
puts ' ā
Webhook verification'
|
91
|
+
puts ' ā
Customer portal support'
|
92
|
+
puts ' ā
Environment switching (prod/sandbox)'
|
93
|
+
puts ' ā
Ruby 2.7+ compatibility'
|
94
|
+
|
95
|
+
puts "\nš For detailed usage examples, see:"
|
96
|
+
puts ' ⢠README.md - Main documentation'
|
97
|
+
puts ' ⢠EXAMPLES.md - Comprehensive usage examples'
|
98
|
+
puts ' ⢠DEVELOPMENT.md - Development guide'
|
99
|
+
|
100
|
+
puts "\nš Resources:"
|
101
|
+
puts ' ⢠Polar.sh Documentation: https://polar.sh/docs'
|
102
|
+
puts ' ⢠API Reference: https://polar.sh/docs/api-reference'
|
103
|
+
puts ' ⢠Discord Community: https://discord.gg/polar'
|
104
|
+
|
105
|
+
puts "\nš SDK loaded and validated successfully!"
|
106
|
+
puts 'Ready to integrate with Polar.sh payment infrastructure.'
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Polar
|
4
|
+
module Authentication
|
5
|
+
# Organization Access Token authentication
|
6
|
+
class OATAuth
|
7
|
+
attr_reader :access_token
|
8
|
+
|
9
|
+
def initialize(access_token)
|
10
|
+
@access_token = access_token
|
11
|
+
validate_token!
|
12
|
+
end
|
13
|
+
|
14
|
+
def headers
|
15
|
+
{
|
16
|
+
'Authorization' => "Bearer #{access_token}",
|
17
|
+
'Content-Type' => 'application/json',
|
18
|
+
'Accept' => 'application/json'
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def valid?
|
23
|
+
!access_token.nil? && !access_token.empty? && access_token.start_with?('polar_oat_')
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def validate_token!
|
29
|
+
return if valid?
|
30
|
+
|
31
|
+
raise AuthenticationError, 'Access token is required' if access_token.nil? || access_token.empty?
|
32
|
+
|
33
|
+
return if access_token.start_with?('polar_oat_')
|
34
|
+
|
35
|
+
raise AuthenticationError,
|
36
|
+
"Invalid Organization Access Token format. Expected token to start with 'polar_oat_'"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Customer Access Token authentication
|
41
|
+
class CustomerAuth
|
42
|
+
attr_reader :customer_session
|
43
|
+
|
44
|
+
def initialize(customer_session)
|
45
|
+
@customer_session = customer_session
|
46
|
+
validate_token!
|
47
|
+
end
|
48
|
+
|
49
|
+
def headers
|
50
|
+
{
|
51
|
+
'Authorization' => "Bearer #{customer_session}",
|
52
|
+
'Content-Type' => 'application/json',
|
53
|
+
'Accept' => 'application/json'
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def valid?
|
58
|
+
!customer_session.nil? && !customer_session.empty?
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def validate_token!
|
64
|
+
return if valid?
|
65
|
+
|
66
|
+
raise AuthenticationError, 'Customer session token is required'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Factory for creating appropriate authentication based on token type
|
71
|
+
class AuthFactory
|
72
|
+
def self.create(token)
|
73
|
+
return nil if token.nil? || token.empty?
|
74
|
+
|
75
|
+
if token.start_with?('polar_oat_')
|
76
|
+
OATAuth.new(token)
|
77
|
+
else
|
78
|
+
CustomerAuth.new(token)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/polar/client.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Polar
|
4
|
+
class Client
|
5
|
+
include Pagination
|
6
|
+
|
7
|
+
attr_reader :configuration, :auth, :http_client
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@configuration = build_configuration(options)
|
11
|
+
@auth = build_authentication(options)
|
12
|
+
@http_client = HTTPClient.new(@configuration, @auth)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Core API Resources
|
16
|
+
def organizations
|
17
|
+
@organizations ||= Resources::Organizations.new(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
def products
|
21
|
+
@products ||= Resources::Products.new(self)
|
22
|
+
end
|
23
|
+
|
24
|
+
def customers
|
25
|
+
@customers ||= Resources::Customers.new(self)
|
26
|
+
end
|
27
|
+
|
28
|
+
def orders
|
29
|
+
@orders ||= Resources::Orders.new(self)
|
30
|
+
end
|
31
|
+
|
32
|
+
def payments
|
33
|
+
@payments ||= Resources::Payments.new(self)
|
34
|
+
end
|
35
|
+
|
36
|
+
def subscriptions
|
37
|
+
@subscriptions ||= Resources::Subscriptions.new(self)
|
38
|
+
end
|
39
|
+
|
40
|
+
def checkouts
|
41
|
+
@checkouts ||= Resources::Checkouts.new(self)
|
42
|
+
end
|
43
|
+
|
44
|
+
def benefits
|
45
|
+
@benefits ||= Resources::Benefits.new(self)
|
46
|
+
end
|
47
|
+
|
48
|
+
def license_keys
|
49
|
+
@license_keys ||= Resources::LicenseKeys.new(self)
|
50
|
+
end
|
51
|
+
|
52
|
+
def files
|
53
|
+
@files ||= Resources::Files.new(self)
|
54
|
+
end
|
55
|
+
|
56
|
+
def metrics
|
57
|
+
@metrics ||= Resources::Metrics.new(self)
|
58
|
+
end
|
59
|
+
|
60
|
+
def events
|
61
|
+
@events ||= Resources::Events.new(self)
|
62
|
+
end
|
63
|
+
|
64
|
+
def webhooks
|
65
|
+
@webhooks ||= Resources::Webhooks.new(self)
|
66
|
+
end
|
67
|
+
|
68
|
+
def oauth2
|
69
|
+
@oauth2 ||= Resources::OAuth2.new(self)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Customer Portal API
|
73
|
+
def customer_portal
|
74
|
+
@customer_portal ||= CustomerPortalClient.new(self)
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def build_configuration(options)
|
80
|
+
config = Configuration.new
|
81
|
+
|
82
|
+
# Set from options
|
83
|
+
config.access_token = options[:access_token] || ENV['POLAR_ACCESS_TOKEN']
|
84
|
+
config.server = options[:server] || :production
|
85
|
+
config.base_url = options[:base_url] if options[:base_url]
|
86
|
+
config.timeout = options[:timeout] if options[:timeout]
|
87
|
+
config.retries = options[:retries] if options[:retries]
|
88
|
+
config.logger = options[:logger] if options[:logger]
|
89
|
+
config.debug = options[:debug] || ENV['POLAR_DEBUG'] == 'true'
|
90
|
+
|
91
|
+
# Apply global configuration
|
92
|
+
global_config = Polar.configuration
|
93
|
+
config.access_token ||= global_config.access_token
|
94
|
+
config.server = global_config.server if global_config.server && !options.key?(:server)
|
95
|
+
config.base_url ||= global_config.base_url
|
96
|
+
config.timeout = global_config.timeout if global_config.timeout && !options.key?(:timeout)
|
97
|
+
config.retries = global_config.retries if global_config.retries && !options.key?(:retries)
|
98
|
+
config.logger ||= global_config.logger
|
99
|
+
config.debug = global_config.debug if global_config.debug && !options.key?(:debug)
|
100
|
+
|
101
|
+
config
|
102
|
+
end
|
103
|
+
|
104
|
+
def build_authentication(options)
|
105
|
+
token = options[:access_token] || @configuration.access_token
|
106
|
+
customer_session = options[:customer_session]
|
107
|
+
|
108
|
+
if customer_session
|
109
|
+
Authentication::CustomerAuth.new(customer_session)
|
110
|
+
elsif token
|
111
|
+
Authentication::AuthFactory.create(token)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Customer Portal specific client wrapper
|
117
|
+
class CustomerPortalClient
|
118
|
+
attr_reader :client
|
119
|
+
|
120
|
+
def initialize(client)
|
121
|
+
@client = client
|
122
|
+
end
|
123
|
+
|
124
|
+
def customers
|
125
|
+
@customers ||= CustomerPortal::Customers.new(@client)
|
126
|
+
end
|
127
|
+
|
128
|
+
def orders
|
129
|
+
@orders ||= CustomerPortal::Orders.new(@client)
|
130
|
+
end
|
131
|
+
|
132
|
+
def subscriptions
|
133
|
+
@subscriptions ||= CustomerPortal::Subscriptions.new(@client)
|
134
|
+
end
|
135
|
+
|
136
|
+
def benefit_grants
|
137
|
+
@benefit_grants ||= CustomerPortal::BenefitGrants.new(@client)
|
138
|
+
end
|
139
|
+
|
140
|
+
def license_keys
|
141
|
+
@license_keys ||= CustomerPortal::LicenseKeys.new(@client)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Polar
|
4
|
+
class Configuration
|
5
|
+
attr_accessor :access_token, :server, :base_url, :timeout, :retries, :logger, :debug
|
6
|
+
|
7
|
+
# Server environments
|
8
|
+
PRODUCTION_SERVER = 'https://api.polar.sh/v1'
|
9
|
+
SANDBOX_SERVER = 'https://sandbox-api.polar.sh/v1'
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@server = :production
|
13
|
+
@timeout = 30
|
14
|
+
@retries = 3
|
15
|
+
@debug = false
|
16
|
+
@logger = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def base_url
|
20
|
+
@base_url || server_url
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_writer :base_url
|
24
|
+
|
25
|
+
def server=(environment)
|
26
|
+
unless %i[production sandbox].include?(environment.to_sym)
|
27
|
+
raise ArgumentError, 'Invalid server environment. Must be :production or :sandbox'
|
28
|
+
end
|
29
|
+
|
30
|
+
@server = environment.to_sym
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def server_url
|
36
|
+
case @server
|
37
|
+
when :production
|
38
|
+
PRODUCTION_SERVER
|
39
|
+
when :sandbox
|
40
|
+
SANDBOX_SERVER
|
41
|
+
else
|
42
|
+
raise ArgumentError, "Unknown server environment: #{@server}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../resources/base'
|
4
|
+
|
5
|
+
module Polar
|
6
|
+
module CustomerPortal
|
7
|
+
class BenefitGrants < Resources::Base
|
8
|
+
# List customer benefit grants
|
9
|
+
# @param params [Hash] Query parameters
|
10
|
+
# @param customer_session [String] Customer session token
|
11
|
+
# @option params [Integer] :page Page number
|
12
|
+
# @option params [Integer] :limit Items per page
|
13
|
+
# @return [PaginatedResponse] Paginated list of benefit grants
|
14
|
+
def list(params = {}, customer_session:)
|
15
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
16
|
+
paginate('/customer-portal/benefit-grants', params, headers)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get customer benefit grant
|
20
|
+
# @param id [String] Benefit grant ID
|
21
|
+
# @param customer_session [String] Customer session token
|
22
|
+
# @return [Hash] Benefit grant data
|
23
|
+
def get(id, customer_session:)
|
24
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
25
|
+
response = get("/customer-portal/benefit-grants/#{id}", {}, headers)
|
26
|
+
response.body
|
27
|
+
end
|
28
|
+
|
29
|
+
# Update customer benefit grant
|
30
|
+
# @param id [String] Benefit grant ID
|
31
|
+
# @param attributes [Hash] Updated attributes
|
32
|
+
# @param customer_session [String] Customer session token
|
33
|
+
# @return [Hash] Updated benefit grant
|
34
|
+
def update(id, attributes, customer_session:)
|
35
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
36
|
+
response = patch("/customer-portal/benefit-grants/#{id}", attributes, headers)
|
37
|
+
response.body
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../resources/base'
|
4
|
+
|
5
|
+
module Polar
|
6
|
+
module CustomerPortal
|
7
|
+
class Customers < Resources::Base
|
8
|
+
# Get authenticated customer information
|
9
|
+
# @param customer_session [String] Customer session token
|
10
|
+
# @return [Hash] Customer data
|
11
|
+
def get(customer_session:)
|
12
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
13
|
+
response = get('/customer-portal/customers/me', {}, headers)
|
14
|
+
response.body
|
15
|
+
end
|
16
|
+
|
17
|
+
# Update authenticated customer
|
18
|
+
# @param attributes [Hash] Updated customer attributes
|
19
|
+
# @param customer_session [String] Customer session token
|
20
|
+
# @return [Hash] Updated customer
|
21
|
+
def update(attributes, customer_session:)
|
22
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
23
|
+
response = patch('/customer-portal/customers/me', attributes, headers)
|
24
|
+
response.body
|
25
|
+
end
|
26
|
+
|
27
|
+
# List customer payment methods
|
28
|
+
# @param customer_session [String] Customer session token
|
29
|
+
# @return [Array] List of payment methods
|
30
|
+
def list_payment_methods(customer_session:)
|
31
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
32
|
+
response = get('/customer-portal/customers/me/payment-methods', {}, headers)
|
33
|
+
response.body
|
34
|
+
end
|
35
|
+
|
36
|
+
# Add customer payment method
|
37
|
+
# @param payment_method_data [Hash] Payment method data
|
38
|
+
# @param customer_session [String] Customer session token
|
39
|
+
# @return [Hash] Payment method creation response
|
40
|
+
def add_payment_method(payment_method_data, customer_session:)
|
41
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
42
|
+
response = post('/customer-portal/customers/me/payment-methods', payment_method_data, headers)
|
43
|
+
response.body
|
44
|
+
end
|
45
|
+
|
46
|
+
# Confirm customer payment method
|
47
|
+
# @param payment_method_id [String] Payment method ID
|
48
|
+
# @param confirmation_data [Hash] Confirmation data
|
49
|
+
# @param customer_session [String] Customer session token
|
50
|
+
# @return [Hash] Confirmation response
|
51
|
+
def confirm_payment_method(payment_method_id, confirmation_data, customer_session:)
|
52
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
53
|
+
path = "/customer-portal/customers/me/payment-methods/#{payment_method_id}/confirm"
|
54
|
+
response = post(path, confirmation_data, headers)
|
55
|
+
response.body
|
56
|
+
end
|
57
|
+
|
58
|
+
# Delete customer payment method
|
59
|
+
# @param payment_method_id [String] Payment method ID
|
60
|
+
# @param customer_session [String] Customer session token
|
61
|
+
# @return [Boolean] Success status
|
62
|
+
def delete_payment_method(payment_method_id, customer_session:)
|
63
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
64
|
+
delete("/customer-portal/customers/me/payment-methods/#{payment_method_id}", headers)
|
65
|
+
true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../resources/base'
|
4
|
+
|
5
|
+
module Polar
|
6
|
+
module CustomerPortal
|
7
|
+
class LicenseKeys < Resources::Base
|
8
|
+
# List customer license keys
|
9
|
+
# @param params [Hash] Query parameters
|
10
|
+
# @param customer_session [String] Customer session token
|
11
|
+
# @option params [Integer] :page Page number
|
12
|
+
# @option params [Integer] :limit Items per page
|
13
|
+
# @return [PaginatedResponse] Paginated list of license keys
|
14
|
+
def list(params = {}, customer_session:)
|
15
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
16
|
+
paginate('/customer-portal/license-keys', params, headers)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get customer license key
|
20
|
+
# @param id [String] License key ID
|
21
|
+
# @param customer_session [String] Customer session token
|
22
|
+
# @return [Hash] License key data
|
23
|
+
def get(id, customer_session:)
|
24
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
25
|
+
response = get("/customer-portal/license-keys/#{id}", {}, headers)
|
26
|
+
response.body
|
27
|
+
end
|
28
|
+
|
29
|
+
# Validate a license key (no authentication required)
|
30
|
+
# @param key [String] License key
|
31
|
+
# @param activation_id [String, nil] Optional activation ID
|
32
|
+
# @return [Hash] Validation result
|
33
|
+
def validate(key, activation_id: nil)
|
34
|
+
body = { key: key }
|
35
|
+
body[:activation_id] = activation_id if activation_id
|
36
|
+
|
37
|
+
response = post('/customer-portal/license-keys/validate', body)
|
38
|
+
response.body
|
39
|
+
end
|
40
|
+
|
41
|
+
# Activate a license key (no authentication required)
|
42
|
+
# @param key [String] License key
|
43
|
+
# @param activation_data [Hash] Activation data
|
44
|
+
# @param customer_session [String, nil] Optional customer session token
|
45
|
+
# @option activation_data [String] :label Activation label
|
46
|
+
# @option activation_data [Hash] :metadata Activation metadata
|
47
|
+
# @return [Hash] Activation result
|
48
|
+
def activate(key, activation_data = {}, customer_session: nil)
|
49
|
+
body = { key: key }.merge(activation_data)
|
50
|
+
headers = customer_session ? { 'Authorization' => "Bearer #{customer_session}" } : {}
|
51
|
+
|
52
|
+
response = post('/customer-portal/license-keys/activate', body, headers)
|
53
|
+
response.body
|
54
|
+
end
|
55
|
+
|
56
|
+
# Deactivate a license key (no authentication required)
|
57
|
+
# @param key [String] License key
|
58
|
+
# @param activation_id [String] Activation ID
|
59
|
+
# @param customer_session [String, nil] Optional customer session token
|
60
|
+
# @return [Boolean] Success status
|
61
|
+
def deactivate(key, activation_id, customer_session: nil)
|
62
|
+
body = { key: key, activation_id: activation_id }
|
63
|
+
headers = customer_session ? { 'Authorization' => "Bearer #{customer_session}" } : {}
|
64
|
+
|
65
|
+
post('/customer-portal/license-keys/deactivate', body, headers)
|
66
|
+
true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../resources/base'
|
4
|
+
|
5
|
+
module Polar
|
6
|
+
module CustomerPortal
|
7
|
+
class Orders < Resources::Base
|
8
|
+
# List customer orders
|
9
|
+
# @param params [Hash] Query parameters
|
10
|
+
# @param customer_session [String] Customer session token
|
11
|
+
# @option params [Integer] :page Page number
|
12
|
+
# @option params [Integer] :limit Items per page
|
13
|
+
# @return [PaginatedResponse] Paginated list of orders
|
14
|
+
def list(params = {}, customer_session:)
|
15
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
16
|
+
paginate('/customer-portal/orders', params, headers)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get customer order
|
20
|
+
# @param id [String] Order ID
|
21
|
+
# @param customer_session [String] Customer session token
|
22
|
+
# @return [Hash] Order data
|
23
|
+
def get(id, customer_session:)
|
24
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
25
|
+
response = get("/customer-portal/orders/#{id}", {}, headers)
|
26
|
+
response.body
|
27
|
+
end
|
28
|
+
|
29
|
+
# Update customer order
|
30
|
+
# @param id [String] Order ID
|
31
|
+
# @param attributes [Hash] Updated attributes
|
32
|
+
# @param customer_session [String] Customer session token
|
33
|
+
# @return [Hash] Updated order
|
34
|
+
def update(id, attributes, customer_session:)
|
35
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
36
|
+
response = patch("/customer-portal/orders/#{id}", attributes, headers)
|
37
|
+
response.body
|
38
|
+
end
|
39
|
+
|
40
|
+
# Generate invoice for customer order
|
41
|
+
# @param id [String] Order ID
|
42
|
+
# @param customer_session [String] Customer session token
|
43
|
+
# @return [Hash] Invoice generation result
|
44
|
+
def generate_invoice(id, customer_session:)
|
45
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
46
|
+
response = post("/customer-portal/orders/#{id}/invoice", {}, headers)
|
47
|
+
response.body
|
48
|
+
end
|
49
|
+
|
50
|
+
# Get customer order invoice
|
51
|
+
# @param id [String] Order ID
|
52
|
+
# @param customer_session [String] Customer session token
|
53
|
+
# @return [Hash] Invoice data
|
54
|
+
def invoice(id, customer_session:)
|
55
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
56
|
+
response = get("/customer-portal/orders/#{id}/invoice", {}, headers)
|
57
|
+
response.body
|
58
|
+
end
|
59
|
+
|
60
|
+
# Get order payment status
|
61
|
+
# @param id [String] Order ID
|
62
|
+
# @param customer_session [String] Customer session token
|
63
|
+
# @return [Hash] Payment status
|
64
|
+
def get_payment_status(id, customer_session:)
|
65
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
66
|
+
response = get("/customer-portal/orders/#{id}/payment-status", {}, headers)
|
67
|
+
response.body
|
68
|
+
end
|
69
|
+
|
70
|
+
# Confirm retry payment for order
|
71
|
+
# @param id [String] Order ID
|
72
|
+
# @param payment_data [Hash] Payment confirmation data
|
73
|
+
# @param customer_session [String] Customer session token
|
74
|
+
# @return [Hash] Payment confirmation result
|
75
|
+
def confirm_retry_payment(id, payment_data, customer_session:)
|
76
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
77
|
+
response = post("/customer-portal/orders/#{id}/confirm-retry-payment", payment_data, headers)
|
78
|
+
response.body
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../resources/base'
|
4
|
+
|
5
|
+
module Polar
|
6
|
+
module CustomerPortal
|
7
|
+
class Subscriptions < Resources::Base
|
8
|
+
# List customer subscriptions
|
9
|
+
# @param params [Hash] Query parameters
|
10
|
+
# @param customer_session [String] Customer session token
|
11
|
+
# @option params [Integer] :page Page number
|
12
|
+
# @option params [Integer] :limit Items per page
|
13
|
+
# @return [PaginatedResponse] Paginated list of subscriptions
|
14
|
+
def list(params = {}, customer_session:)
|
15
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
16
|
+
paginate('/customer-portal/subscriptions', params, headers)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get customer subscription
|
20
|
+
# @param id [String] Subscription ID
|
21
|
+
# @param customer_session [String] Customer session token
|
22
|
+
# @return [Hash] Subscription data
|
23
|
+
def get(id, customer_session:)
|
24
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
25
|
+
response = get("/customer-portal/subscriptions/#{id}", {}, headers)
|
26
|
+
response.body
|
27
|
+
end
|
28
|
+
|
29
|
+
# Update customer subscription
|
30
|
+
# @param id [String] Subscription ID
|
31
|
+
# @param attributes [Hash] Updated attributes
|
32
|
+
# @param customer_session [String] Customer session token
|
33
|
+
# @return [Hash] Updated subscription
|
34
|
+
def update(id, attributes, customer_session:)
|
35
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
36
|
+
response = patch("/customer-portal/subscriptions/#{id}", attributes, headers)
|
37
|
+
response.body
|
38
|
+
end
|
39
|
+
|
40
|
+
# Cancel customer subscription
|
41
|
+
# @param id [String] Subscription ID
|
42
|
+
# @param customer_session [String] Customer session token
|
43
|
+
# @return [Hash] Cancelled subscription
|
44
|
+
def cancel(id, customer_session:)
|
45
|
+
headers = { 'Authorization' => "Bearer #{customer_session}" }
|
46
|
+
response = post("/customer-portal/subscriptions/#{id}/cancel", {}, headers)
|
47
|
+
response.body
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|