app_manager 1.2.7 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/Gemfile.lock +4 -4
- data/app/controllers/app_manager/charges_controller.rb +157 -157
- data/app/controllers/app_manager/plans_controller.rb +209 -206
- data/app/model/app_manager/app.rb +5 -0
- data/app/model/app_manager/app_manager_record.rb +7 -0
- data/app/model/app_manager/app_structure.rb +5 -0
- data/app/model/app_manager/charge.rb +6 -0
- data/app/model/app_manager/discount_plan.rb +5 -0
- data/app/model/app_manager/extend_trial.rb +5 -0
- data/app/model/app_manager/plan.rb +6 -0
- data/app/model/app_manager/plan_user.rb +5 -0
- data/app_manager.gemspec +1 -1
- data/lib/app_manager/client/connection.rb +5 -7
- data/lib/app_manager/client/plans.rb +34 -34
- data/lib/app_manager/client.rb +21 -23
- data/lib/app_manager/fail_safe.rb +460 -528
- data/lib/app_manager/graphql_helper.rb +1 -1
- data/lib/app_manager/model.rb +188 -200
- data/lib/app_manager/tasks/sync/local_app_manager.rake +2 -3
- data/lib/app_manager/version.rb +1 -1
- data/lib/app_manager.rb +3 -3
- data/lib/generators/app_manager/install/install_generator.rb +40 -31
- data/lib/generators/app_manager/install/templates/failsafe_tables.erb +90 -0
- metadata +11 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ccc14af26b2bc149bba059ef2c7d45e58bc0d8460f02141d26edce1ba465aaeb
|
4
|
+
data.tar.gz: 51da1f98e7d8bb114e3adbf80cfe510fd66caa7965525adf0cb98c8ad4fa5ca0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13238860ae46955c3c6fa71e304d0be8e29b30c2940d29ff07e8b31e724bf887349f4148c452e137b4b5d0f551e1e047f9ca16a413cb09788795dacc304dbc75
|
7
|
+
data.tar.gz: 18d9de82d48bcaa9dd9dff5a4cc8473d704c06096228e3a2148a26d2022ef6b8c71a6bb45cf877f9296ed391e33508fa7368ecc0b77eac8ed77c2dc25d100129
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
app_manager (1.
|
4
|
+
app_manager (1.3.0)
|
5
5
|
httparty
|
6
6
|
kaminari (>= 0.16.3)
|
7
7
|
rails (>= 5.2.0)
|
8
|
-
sqlite3 (~> 1.4.4)
|
9
8
|
|
10
9
|
GEM
|
11
10
|
remote: https://rubygems.org/
|
@@ -118,6 +117,7 @@ GEM
|
|
118
117
|
mime-types-data (~> 3.2015)
|
119
118
|
mime-types-data (3.2022.0105)
|
120
119
|
mini_mime (1.1.2)
|
120
|
+
mini_portile2 (2.8.0)
|
121
121
|
minitest (5.16.2)
|
122
122
|
multi_xml (0.6.0)
|
123
123
|
net-imap (0.2.3)
|
@@ -135,7 +135,8 @@ GEM
|
|
135
135
|
net-protocol
|
136
136
|
timeout
|
137
137
|
nio4r (2.5.8)
|
138
|
-
nokogiri (1.13.6
|
138
|
+
nokogiri (1.13.6)
|
139
|
+
mini_portile2 (~> 2.8.0)
|
139
140
|
racc (~> 1.4)
|
140
141
|
pry (0.14.1)
|
141
142
|
coderay (~> 1.1)
|
@@ -188,7 +189,6 @@ GEM
|
|
188
189
|
diff-lcs (>= 1.2.0, < 2.0)
|
189
190
|
rspec-support (~> 3.11.0)
|
190
191
|
rspec-support (3.11.0)
|
191
|
-
sqlite3 (1.4.4)
|
192
192
|
strscan (3.0.3)
|
193
193
|
thor (1.2.1)
|
194
194
|
timeout (0.3.0)
|
@@ -1,166 +1,166 @@
|
|
1
1
|
require_dependency "app_manager/application_controller"
|
2
2
|
module AppManager
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
66
|
-
else
|
67
|
-
raise Error, "Missing Shop domain or plan id in params"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
|
72
|
-
def callback
|
73
|
-
if params[:charge_id].present? && params[:shop].present? && params[:plan].present?
|
74
|
-
@shop = shop_data
|
75
|
-
shopify_token = @field_names['shopify_token']
|
76
|
-
shopify_domain = @field_names['name']
|
77
|
-
if !@shop.nil?
|
78
|
-
headers = {"X-Shopify-Access-Token" => @shop[shopify_token]}
|
79
|
-
charges = HTTParty.get('https://'+@shop[shopify_domain]+'/admin/api/'+@api_version+'/recurring_application_charges/'+params[:charge_id]+'.json', :headers => headers)
|
80
|
-
|
81
|
-
if charges.parsed_response && charges.parsed_response.is_a?(Hash) && charges.parsed_response.has_key?('recurring_application_charge')
|
82
|
-
|
83
|
-
plan_obj = AppManager::Client.new
|
84
|
-
plan_data = plan_obj.get_plan(params[:plan],params[:shop])
|
85
|
-
|
86
|
-
charge = charges.parsed_response['recurring_application_charge']
|
87
|
-
charge['charge_id'] = charge['id']
|
88
|
-
charge['type'] = 'recurring'
|
89
|
-
charge['plan_id'] = params[:plan]
|
90
|
-
charge['shop_domain'] = params[:shop]
|
91
|
-
charge['interval'] = plan_data['interval']['value']
|
92
|
-
|
93
|
-
if !@plan_field.nil?
|
94
|
-
begin
|
95
|
-
plan_obj.cancel_charge(@shop[shopify_domain],@shop[@plan_field])
|
96
|
-
rescue Exception => e
|
97
|
-
Rails.logger.info "APP MANAGER >>>> #{e.inspect}"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
charge_ob = AppManager::Client.new(nil,json_req=true)
|
102
|
-
response = charge_ob.store_charge(charge.to_json)
|
103
|
-
|
104
|
-
if response['message'] == "success"
|
105
|
-
AppManager.clear_cache
|
106
|
-
@shop.update(@plan_field => params[:plan])
|
107
|
-
charge_data = plan_obj.get_charge(@shop[shopify_domain])
|
108
|
-
begin
|
109
|
-
AppManager::EventHandler.new('charge_created',{
|
110
|
-
"plan" => plan_data,
|
111
|
-
"charge" => charge,
|
112
|
-
"previous_charge" => charge_data ? (charge_data['cancelled_charge'] || nil) : nil,
|
113
|
-
"shopify_domain" => params[:shop]
|
114
|
-
})
|
115
|
-
rescue Exception => e
|
116
|
-
Rails.logger.info "APP MANAGER >>>> #{e.inspect}"
|
117
|
-
end
|
118
|
-
end
|
119
|
-
redirect_to "#{app_url}?shop=#{params[:shop]}", :status => 301 and return
|
120
|
-
else
|
121
|
-
raise Error, "Invalid shopify charge #{charges.insect}"
|
122
|
-
end
|
123
|
-
else
|
124
|
-
raise ModelNotFound, "Shop not found"
|
125
|
-
end
|
126
|
-
else
|
127
|
-
raise Error, "Invalid params, must have charge_id,shop && plan"
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
private
|
132
|
-
|
133
|
-
def params_permit
|
134
|
-
params.permit!
|
135
|
-
end
|
136
|
-
|
137
|
-
def model
|
138
|
-
@models = ActiveRecord::Base.connection.tables
|
139
|
-
@config_table = AppManager.configuration.shopify_table_name
|
140
|
-
@shopify_domain = AppManager.configuration.shopify_domain_field
|
141
|
-
@plan_field = AppManager.configuration.plan_id_or_name_field
|
142
|
-
@field_names = AppManager.configuration.field_names
|
143
|
-
@api_version = AppManager.configuration.shopify_api_version
|
144
|
-
if @models.include?(@config_table) && !@plan_field.nil?
|
145
|
-
return @config_table.classify.constantize
|
146
|
-
else
|
147
|
-
return nil
|
148
|
-
end
|
3
|
+
class ChargesController < ApplicationController
|
4
|
+
include HTTParty
|
5
|
+
skip_before_action :verify_authenticity_token, :only => [:process_plan]
|
6
|
+
before_action :params_permit
|
7
|
+
require 'time'
|
8
|
+
require 'rack'
|
9
|
+
|
10
|
+
def process_plan
|
11
|
+
if params[:shop].present? && params[:plan_id].present?
|
12
|
+
@shop = shop_data
|
13
|
+
if !@shop.nil?
|
14
|
+
plan_obj = AppManager::Client.new
|
15
|
+
plan_data = plan_obj.get_plan(params[:plan_id], params[:shop])
|
16
|
+
# render json: plan_data and return #use this to test plan failsafe api
|
17
|
+
if plan_data.present? && plan_data.is_a?(Hash)
|
18
|
+
if plan_data['price'] == 0
|
19
|
+
active_charge_data = plan_obj.get_charge(params[:shop])
|
20
|
+
begin
|
21
|
+
if active_charge_data && active_charge_data.any? && !active_charge_data['active_charge'].nil? && !active_charge_data['active_charge']['charge_id'].nil?
|
22
|
+
gq_obj = AppManager::GraphqlHelper.new(@shop.shopify_domain, @shop.shopify_token)
|
23
|
+
rec_cancel_data = gq_obj.recurring_charge_cancel_api_call(active_charge_data['active_charge']['charge_id'], @shop)
|
24
|
+
if !rec_cancel_data["errors"].present? && (rec_cancel_data["data"].present? && rec_cancel_data["data"]["appSubscriptionCancel"].present? && !rec_cancel_data["data"]["appSubscriptionCancel"]["userErrors"].any? && (rec_cancel_data["data"]["appSubscriptionCancel"]["appSubscription"]["status"] == 'CANCELLED'))
|
25
|
+
cancelled_charge_id = rec_cancel_data["data"]["appSubscriptionCancel"]["appSubscription"]["id"].split('/')[-1]
|
26
|
+
plan_obj.cancel_charge(params[:shop], cancelled_charge_id)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
rescue Exception => e
|
30
|
+
Rollbar.error("APP MANAGER Process Plan Failed #{e}")
|
31
|
+
end
|
32
|
+
|
33
|
+
if @shop.update(@plan_field => params[:plan_id])
|
34
|
+
begin
|
35
|
+
AppManager::EventHandler.new('charge_created', {
|
36
|
+
"plan" => plan_data,
|
37
|
+
"charge" => nil,
|
38
|
+
"previous_charge" => nil,
|
39
|
+
"shopify_domain" => params[:shop]
|
40
|
+
})
|
41
|
+
rescue Exception => e
|
42
|
+
Rollbar.error("APP MANAGER Error in Process Plan #{e}")
|
43
|
+
end
|
44
|
+
AppManager.clear_cache
|
45
|
+
render json: {'redirect_url' => "#{app_url}?shop=#{params[:shop]}"} and return true
|
46
|
+
else
|
47
|
+
raise Error, "Invalid charge"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
request_data = {'shop' => @shop.shopify_domain, 'timestamp' => Time.now.to_i, 'plan' => params[:plan_id]}
|
51
|
+
return_url = "#{app_url}#{plan_callback_path}?#{Rack::Utils.build_query(request_data)}"
|
52
|
+
gq_obj = AppManager::GraphqlHelper.new(@shop.shopify_domain, @shop.shopify_token)
|
53
|
+
data = gq_obj.recurring_charge_api_call(plan_data, return_url, @shop)
|
54
|
+
if !data["errors"].present? && (data["data"].present? && data["data"]["appSubscriptionCreate"].present? && (!data["data"]["appSubscriptionCreate"]["userErrors"].any? && data["data"]["appSubscriptionCreate"]["confirmationUrl"]))
|
55
|
+
redirect_charge = data["data"]["appSubscriptionCreate"]["confirmationUrl"]
|
56
|
+
render json: {'redirect_url' => redirect_charge}
|
57
|
+
else
|
58
|
+
raise Error, "#{data["errors"].as_json}"
|
59
|
+
end
|
60
|
+
else
|
61
|
+
raise Error, "#{data["errors"]}"
|
62
|
+
end
|
63
|
+
else
|
64
|
+
raise ModelNotFound, "Shop not found"
|
149
65
|
end
|
66
|
+
else
|
67
|
+
raise Error, "Missing Shop domain or plan id in params"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
def callback
|
73
|
+
if params[:charge_id].present? && params[:shop].present? && params[:plan].present?
|
74
|
+
@shop = shop_data
|
75
|
+
shopify_token = @field_names['shopify_token']
|
76
|
+
shopify_domain = @field_names['name']
|
77
|
+
grandfathered_field = @field_names['grandfathered']
|
78
|
+
if !@shop.nil?
|
79
|
+
headers = {"X-Shopify-Access-Token" => @shop[shopify_token]}
|
80
|
+
charges = HTTParty.get('https://' + @shop[shopify_domain] + '/admin/api/' + @api_version + '/recurring_application_charges/' + params[:charge_id] + '.json', :headers => headers)
|
81
|
+
|
82
|
+
if charges.parsed_response && charges.parsed_response.is_a?(Hash) && charges.parsed_response.has_key?('recurring_application_charge')
|
83
|
+
|
84
|
+
plan_obj = AppManager::Client.new
|
85
|
+
plan_data = plan_obj.get_plan(params[:plan], params[:shop])
|
86
|
+
|
87
|
+
charge = charges.parsed_response['recurring_application_charge']
|
88
|
+
charge['charge_id'] = charge['id']
|
89
|
+
charge['type'] = 'recurring'
|
90
|
+
charge['plan_id'] = params[:plan]
|
91
|
+
charge['shop_domain'] = params[:shop]
|
92
|
+
charge['interval'] = plan_data['interval']['value']
|
93
|
+
|
94
|
+
if !@plan_field.nil?
|
95
|
+
begin
|
96
|
+
plan_obj.cancel_charge(@shop[shopify_domain], @shop[@plan_field])
|
97
|
+
rescue Exception => e
|
98
|
+
Rollbar.error("APP MANAGER Error in Cancel charge >>>> #{e.inspect}")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
charge_ob = AppManager::Client.new(nil, json_req = true)
|
103
|
+
response = charge_ob.store_charge(charge.to_json)
|
104
|
+
|
105
|
+
if response['message'] == "success"
|
106
|
+
AppManager.clear_cache
|
107
|
+
@shop.update(@plan_field => params[:plan],grandfathered_field => 0)
|
108
|
+
charge_data = plan_obj.get_charge(@shop[shopify_domain])
|
109
|
+
begin
|
110
|
+
AppManager::EventHandler.new('charge_created', {
|
111
|
+
"plan" => plan_data,
|
112
|
+
"charge" => charge,
|
113
|
+
"previous_charge" => charge_data ? (charge_data['cancelled_charge'] || nil) : nil,
|
114
|
+
"shopify_domain" => params[:shop]
|
115
|
+
})
|
116
|
+
rescue Exception => e
|
117
|
+
Rollbar.error("Error in APP MANAGER Charge Created Callback >>>> #{e.inspect}")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
redirect_to "#{app_url}?shop=#{params[:shop]}", :status => 301 and return
|
121
|
+
else
|
122
|
+
raise Error, "Invalid shopify charge #{charges.insect}"
|
123
|
+
end
|
124
|
+
else
|
125
|
+
raise ModelNotFound, "Shop not found"
|
126
|
+
end
|
127
|
+
else
|
128
|
+
raise Error, "Invalid params, must have charge_id,shop && plan"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def params_permit
|
135
|
+
params.permit!
|
136
|
+
end
|
150
137
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
138
|
+
def model
|
139
|
+
@models = ActiveRecord::Base.connection.tables
|
140
|
+
@config_table = AppManager.configuration.shopify_table_name
|
141
|
+
@shopify_domain = AppManager.configuration.shopify_domain_field
|
142
|
+
@plan_field = AppManager.configuration.plan_id_or_name_field
|
143
|
+
@field_names = AppManager.configuration.field_names
|
144
|
+
@api_version = AppManager.configuration.shopify_api_version
|
145
|
+
if @models.include?(@config_table) && !@plan_field.nil?
|
146
|
+
return @config_table.classify.constantize
|
147
|
+
else
|
148
|
+
return nil
|
149
|
+
end
|
150
|
+
end
|
158
151
|
|
159
|
-
|
160
|
-
|
161
|
-
|
152
|
+
def shop_data
|
153
|
+
if model
|
154
|
+
return model.where(@shopify_domain => params[:shop]).first rescue nil
|
155
|
+
else
|
156
|
+
return nil
|
157
|
+
end
|
158
|
+
end
|
162
159
|
|
160
|
+
def app_url
|
161
|
+
AppManager.configuration.app_url
|
162
|
+
end
|
163
163
|
|
164
164
|
|
165
|
-
|
165
|
+
end
|
166
166
|
end
|