wordjelly-auth 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (275) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +35 -0
  5. data/app/assets/images/auth/activity.jpg +0 -0
  6. data/app/assets/images/auth/facebook.svg +1 -0
  7. data/app/assets/images/auth/google_oauth2.svg +1 -0
  8. data/app/assets/images/auth/js_pic3.jpg +0 -0
  9. data/app/assets/images/auth/profile.jpg +0 -0
  10. data/app/assets/javascripts/auth/admin_create_users.js +2 -0
  11. data/app/assets/javascripts/auth/application.js +20 -0
  12. data/app/assets/javascripts/auth/auth_dependencies.js +12 -0
  13. data/app/assets/javascripts/auth/auth_modals_and_navbar.js +218 -0
  14. data/app/assets/javascripts/auth/clients.js +2 -0
  15. data/app/assets/javascripts/auth/search.js +2 -0
  16. data/app/assets/javascripts/auth/shopping/discounts.js +2 -0
  17. data/app/assets/javascripts/auth/users/profiles.js +188 -0
  18. data/app/assets/stylesheets/auth/admin_create_users.css +4 -0
  19. data/app/assets/stylesheets/auth/application.scss +14 -0
  20. data/app/assets/stylesheets/auth/auth_default_css.scss +13 -0
  21. data/app/assets/stylesheets/auth/common-styles.scss +579 -0
  22. data/app/assets/stylesheets/auth/overrides.scss +26 -0
  23. data/app/assets/stylesheets/auth/search.css +4 -0
  24. data/app/assets/stylesheets/auth/shopping/discounts.css +4 -0
  25. data/app/assets/stylesheets/auth/users/profiles.scss +40 -0
  26. data/app/assets/stylesheets/scaffold.css +56 -0
  27. data/app/controllers/auth/admin_create_users_controller.rb +89 -0
  28. data/app/controllers/auth/application_controller.rb +97 -0
  29. data/app/controllers/auth/clients_controller.rb +105 -0
  30. data/app/controllers/auth/concerns/activity_controller_concern.rb +32 -0
  31. data/app/controllers/auth/concerns/devise_concern.rb +193 -0
  32. data/app/controllers/auth/concerns/omni_concern.rb +310 -0
  33. data/app/controllers/auth/concerns/otp_concern.rb +251 -0
  34. data/app/controllers/auth/concerns/shopping/cart_controller_concern.rb +105 -0
  35. data/app/controllers/auth/concerns/shopping/cart_item_controller_concern.rb +150 -0
  36. data/app/controllers/auth/concerns/shopping/discount_controller_concern.rb +97 -0
  37. data/app/controllers/auth/concerns/shopping/pay_u_money_controller_concern.rb +38 -0
  38. data/app/controllers/auth/concerns/shopping/payment_controller_concern.rb +101 -0
  39. data/app/controllers/auth/concerns/shopping/product_controller_concern.rb +68 -0
  40. data/app/controllers/auth/concerns/token_concern.rb +187 -0
  41. data/app/controllers/auth/confirmations_controller.rb +3 -0
  42. data/app/controllers/auth/mailgun_controller.rb +8 -0
  43. data/app/controllers/auth/omniauth_callbacks_controller.rb +6 -0
  44. data/app/controllers/auth/passwords_controller.rb +4 -0
  45. data/app/controllers/auth/profiles_controller.rb +156 -0
  46. data/app/controllers/auth/registrations_controller.rb +99 -0
  47. data/app/controllers/auth/search_controller.rb +61 -0
  48. data/app/controllers/auth/sessions_controller.rb +20 -0
  49. data/app/controllers/auth/shopping/cart_items_controller.rb +14 -0
  50. data/app/controllers/auth/shopping/carts_controller.rb +13 -0
  51. data/app/controllers/auth/shopping/discounts_controller.rb +19 -0
  52. data/app/controllers/auth/shopping/payments_controller.rb +13 -0
  53. data/app/controllers/auth/shopping/products_controller.rb +17 -0
  54. data/app/controllers/auth/shopping/shopping_controller.rb +86 -0
  55. data/app/controllers/auth/unlocks_controller.rb +3 -0
  56. data/app/controllers/auth/webhooks_controller.rb +3 -0
  57. data/app/helpers/auth/admin_create_users_helper.rb +2 -0
  58. data/app/helpers/auth/application_helper.rb +136 -0
  59. data/app/helpers/auth/clients_helper.rb +4 -0
  60. data/app/helpers/auth/resource_helper.rb +10 -0
  61. data/app/helpers/auth/search_helper.rb +2 -0
  62. data/app/helpers/auth/shopping/cart_items/cart_items_helper.rb +29 -0
  63. data/app/helpers/auth/shopping/carts/carts_helper.rb +25 -0
  64. data/app/helpers/auth/shopping/discounts/discounts_helper.rb +39 -0
  65. data/app/helpers/auth/shopping/payments/pay_u_money_helper.rb +56 -0
  66. data/app/helpers/auth/shopping/payments/payments_helper.rb +54 -0
  67. data/app/helpers/auth/shopping/products/products_helper.rb +52 -0
  68. data/app/helpers/auth/shopping/shopping_helper.rb +3 -0
  69. data/app/helpers/auth/users/profiles_helper.rb +12 -0
  70. data/app/jobs/otp_job.rb +92 -0
  71. data/app/mailers/application_mailer.rb +4 -0
  72. data/app/mailers/auth/notifier.rb +9 -0
  73. data/app/models/auth/admin_create_user.rb +3 -0
  74. data/app/models/auth/client.rb +52 -0
  75. data/app/models/auth/concerns/activity_concern.rb +112 -0
  76. data/app/models/auth/concerns/chief_model_concern.rb +73 -0
  77. data/app/models/auth/concerns/es_concern.rb +21 -0
  78. data/app/models/auth/concerns/notification_concern.rb +232 -0
  79. data/app/models/auth/concerns/notification_response_concern.rb +71 -0
  80. data/app/models/auth/concerns/owner_concern.rb +81 -0
  81. data/app/models/auth/concerns/shopping/cart_concern.rb +329 -0
  82. data/app/models/auth/concerns/shopping/cart_item_concern.rb +437 -0
  83. data/app/models/auth/concerns/shopping/discount_concern.rb +482 -0
  84. data/app/models/auth/concerns/shopping/discount_flow.txt +11 -0
  85. data/app/models/auth/concerns/shopping/pay_u_money_concern.rb +184 -0
  86. data/app/models/auth/concerns/shopping/payment_concern.rb +613 -0
  87. data/app/models/auth/concerns/shopping/product_concern.rb +102 -0
  88. data/app/models/auth/concerns/sms_otp_concern.rb +68 -0
  89. data/app/models/auth/concerns/user_concern.rb +788 -0
  90. data/app/models/auth/identity.rb +23 -0
  91. data/app/models/auth/shopping/cart.rb +3 -0
  92. data/app/models/auth/shopping/cart_item.rb +6 -0
  93. data/app/models/auth/shopping/cart_item_payment_result.rb +7 -0
  94. data/app/models/auth/shopping/discount.rb +4 -0
  95. data/app/models/auth/shopping/payment.rb +5 -0
  96. data/app/models/auth/shopping/product.rb +5 -0
  97. data/app/models/auth/user.rb +3 -0
  98. data/app/views/auth/admin_create_users/_admin_actions.html.erb +46 -0
  99. data/app/views/auth/admin_create_users/_form.html.erb +19 -0
  100. data/app/views/auth/admin_create_users/edit.html.erb +6 -0
  101. data/app/views/auth/admin_create_users/index.html.erb +25 -0
  102. data/app/views/auth/admin_create_users/new.html.erb +5 -0
  103. data/app/views/auth/admin_create_users/show.html.erb +8 -0
  104. data/app/views/auth/clients/_form.html.erb +41 -0
  105. data/app/views/auth/clients/edit.html.erb +6 -0
  106. data/app/views/auth/clients/index.html.erb +33 -0
  107. data/app/views/auth/clients/new.html.erb +5 -0
  108. data/app/views/auth/clients/show.html.erb +21 -0
  109. data/app/views/auth/confirmations/_enter_otp.html.erb +27 -0
  110. data/app/views/auth/confirmations/_get_otp_status.html.erb +25 -0
  111. data/app/views/auth/confirmations/_new_otp_input.js.erb +11 -0
  112. data/app/views/auth/confirmations/_resend_otp.js.erb +8 -0
  113. data/app/views/auth/confirmations/_resend_sms_otp.html.erb +18 -0
  114. data/app/views/auth/confirmations/_verify_otp.js.erb +64 -0
  115. data/app/views/auth/confirmations/create.js.erb +8 -0
  116. data/app/views/auth/confirmations/enter_otp.html.erb +7 -0
  117. data/app/views/auth/confirmations/get_otp_status.html.erb +3 -0
  118. data/app/views/auth/confirmations/new.html.erb +1 -0
  119. data/app/views/auth/confirmations/new.js.erb +16 -0
  120. data/app/views/auth/confirmations/otp_status_result.html.erb +20 -0
  121. data/app/views/auth/mailer/confirmation_instructions.html.erb +5 -0
  122. data/app/views/auth/mailer/password_change.html.erb +3 -0
  123. data/app/views/auth/mailer/reset_password_instructions.html.erb +8 -0
  124. data/app/views/auth/mailer/unlock_instructions.html.erb +7 -0
  125. data/app/views/auth/modals/_ajax_error_modal.html.erb +3 -0
  126. data/app/views/auth/modals/_ajax_error_modal_content.html.erb +0 -0
  127. data/app/views/auth/modals/_edit_account_content.html.erb +68 -0
  128. data/app/views/auth/modals/_edit_account_success_content.html.erb +5 -0
  129. data/app/views/auth/modals/_error_notification.html.erb +8 -0
  130. data/app/views/auth/modals/_forgot_password_content.html.erb +18 -0
  131. data/app/views/auth/modals/_forgot_password_success_content.html.erb +8 -0
  132. data/app/views/auth/modals/_login_default_content.html.erb +3 -0
  133. data/app/views/auth/modals/_login_forms.html.erb +13 -0
  134. data/app/views/auth/modals/_login_navigation_options.html.erb +12 -0
  135. data/app/views/auth/modals/_new_otp_input.html.erb +28 -0
  136. data/app/views/auth/modals/_oauth_and_submit.html.erb +21 -0
  137. data/app/views/auth/modals/_recaptcha_tags.html.erb +4 -0
  138. data/app/views/auth/modals/_resend_confirmation_content.html.erb +17 -0
  139. data/app/views/auth/modals/_resend_confirmation_success_content.html.erb +8 -0
  140. data/app/views/auth/modals/_resend_otp.html.erb +23 -0
  141. data/app/views/auth/modals/_resource_errors.js.erb +24 -0
  142. data/app/views/auth/modals/_sign_in_inputs.html.erb +10 -0
  143. data/app/views/auth/modals/_sign_in_needed_modal.html.erb +3 -0
  144. data/app/views/auth/modals/_sign_in_success_content.html.erb +5 -0
  145. data/app/views/auth/modals/_sign_up_inputs.html.erb +9 -0
  146. data/app/views/auth/modals/_sign_up_success_content.html.erb +1 -0
  147. data/app/views/auth/modals/_sign_up_success_inactive_content.html.erb +2 -0
  148. data/app/views/auth/modals/_unlock_content.html.erb +17 -0
  149. data/app/views/auth/modals/_verify_otp.html.erb +1 -0
  150. data/app/views/auth/modals/base_modal/_base.html.erb +25 -0
  151. data/app/views/auth/modals/login.js.erb +120 -0
  152. data/app/views/auth/modals/unlock_success_content.html.erb +8 -0
  153. data/app/views/auth/notifier/_email.html.erb +3 -0
  154. data/app/views/auth/notifier/notification.html.erb +2 -0
  155. data/app/views/auth/notifier/notification.text.erb +1 -0
  156. data/app/views/auth/omniauth_callbacks/failure.html.erb +4 -0
  157. data/app/views/auth/passwords/create.js.erb +12 -0
  158. data/app/views/auth/passwords/edit.html.erb +25 -0
  159. data/app/views/auth/passwords/new.html.erb +16 -0
  160. data/app/views/auth/passwords/new.js.erb +19 -0
  161. data/app/views/auth/profiles/_proxy_resource.html.erb +5 -0
  162. data/app/views/auth/profiles/set_proxy_resource.js.erb +1 -0
  163. data/app/views/auth/profiles/show.html.erb +8 -0
  164. data/app/views/auth/registrations/create.js.erb +40 -0
  165. data/app/views/auth/registrations/edit.html.erb +2 -0
  166. data/app/views/auth/registrations/edit.js.erb +5 -0
  167. data/app/views/auth/registrations/new.html.erb +33 -0
  168. data/app/views/auth/registrations/update.js.erb +47 -0
  169. data/app/views/auth/search/_search_bar.html.erb +11 -0
  170. data/app/views/auth/search/_search_result.html.erb +7 -0
  171. data/app/views/auth/search/_search_results.html.erb +4 -0
  172. data/app/views/auth/search/authenticated_user_search.js.erb +45 -0
  173. data/app/views/auth/search/authenticated_user_search.json +7 -0
  174. data/app/views/auth/sessions/create.js.erb +5 -0
  175. data/app/views/auth/sessions/new.html.erb +4 -0
  176. data/app/views/auth/sessions/new.js.erb +20 -0
  177. data/app/views/auth/shared/_devise_error_messages.html.erb +9 -0
  178. data/app/views/auth/shared/_links.html.erb +25 -0
  179. data/app/views/auth/shared/_object_errors.html.erb +12 -0
  180. data/app/views/auth/shared/_proxy_resource.html.erb +18 -0
  181. data/app/views/auth/shopping/cart_items/_form.html.erb +34 -0
  182. data/app/views/auth/shopping/cart_items/_show_cart_items_collection.html.erb +31 -0
  183. data/app/views/auth/shopping/cart_items/create_multiple.html.erb +6 -0
  184. data/app/views/auth/shopping/cart_items/create_multiple.json.erb +9 -0
  185. data/app/views/auth/shopping/cart_items/edit.html.erb +6 -0
  186. data/app/views/auth/shopping/cart_items/index.html.erb +52 -0
  187. data/app/views/auth/shopping/cart_items/new.html.erb +5 -0
  188. data/app/views/auth/shopping/cart_items/show.html.erb +13 -0
  189. data/app/views/auth/shopping/carts/_form.html.erb +35 -0
  190. data/app/views/auth/shopping/carts/_payment_links.html.erb +27 -0
  191. data/app/views/auth/shopping/carts/_remove_cart_item.html.erb +11 -0
  192. data/app/views/auth/shopping/carts/_show_cart_balance_info.html.erb +35 -0
  193. data/app/views/auth/shopping/carts/edit.html.erb +6 -0
  194. data/app/views/auth/shopping/carts/index.html.erb +43 -0
  195. data/app/views/auth/shopping/carts/new.html.erb +5 -0
  196. data/app/views/auth/shopping/carts/show.html.erb +46 -0
  197. data/app/views/auth/shopping/discounts/_form.html.erb +18 -0
  198. data/app/views/auth/shopping/discounts/_form_for_create_multiple_cart_items.html.erb +17 -0
  199. data/app/views/auth/shopping/discounts/_show_pending_discount_request.html.erb +17 -0
  200. data/app/views/auth/shopping/discounts/destroy.html.erb +2 -0
  201. data/app/views/auth/shopping/discounts/edit.html.erb +29 -0
  202. data/app/views/auth/shopping/discounts/index.html.erb +40 -0
  203. data/app/views/auth/shopping/discounts/new.html.erb +1 -0
  204. data/app/views/auth/shopping/discounts/show.html.erb +18 -0
  205. data/app/views/auth/shopping/discounts/update.html.erb +2 -0
  206. data/app/views/auth/shopping/payments/_approve_payment.html.erb +7 -0
  207. data/app/views/auth/shopping/payments/_cash_card_cheque.html.erb +24 -0
  208. data/app/views/auth/shopping/payments/_create_discount_coupon.html.erb +5 -0
  209. data/app/views/auth/shopping/payments/_form.html.erb +19 -0
  210. data/app/views/auth/shopping/payments/_gateway.html.erb +21 -0
  211. data/app/views/auth/shopping/payments/_proceed_to_gateway_or_verify_payment.html.erb +18 -0
  212. data/app/views/auth/shopping/payments/_refresh_payment.html.erb +7 -0
  213. data/app/views/auth/shopping/payments/_refund.html.erb +10 -0
  214. data/app/views/auth/shopping/payments/_show_payment_receipt.html.erb +12 -0
  215. data/app/views/auth/shopping/payments/edit.html.erb +6 -0
  216. data/app/views/auth/shopping/payments/index.html.erb +43 -0
  217. data/app/views/auth/shopping/payments/new.html.erb +13 -0
  218. data/app/views/auth/shopping/payments/show.html.erb +36 -0
  219. data/app/views/auth/shopping/products/_form.html.erb +27 -0
  220. data/app/views/auth/shopping/products/edit.html.erb +6 -0
  221. data/app/views/auth/shopping/products/index.html.erb +48 -0
  222. data/app/views/auth/shopping/products/index.json.erb +7 -0
  223. data/app/views/auth/shopping/products/new.html.erb +5 -0
  224. data/app/views/auth/shopping/products/show.html.erb +12 -0
  225. data/app/views/auth/shopping/products/show.json.erb +1 -0
  226. data/app/views/auth/unlocks/create.js.erb +12 -0
  227. data/app/views/auth/unlocks/new.html.erb +14 -0
  228. data/app/views/auth/unlocks/new.js.erb +17 -0
  229. data/app/views/auth/users/_search_result.html.erb +8 -0
  230. data/app/views/auth/users/profiles/_user_data.html.erb +4 -0
  231. data/app/views/auth/users/profiles/show.html.erb +54 -0
  232. data/app/views/layouts/auth/_modals.html.erb +2 -0
  233. data/app/views/layouts/auth/application.html.erb +17 -0
  234. data/app/views/layouts/auth/navbar/_navbar.html.erb +49 -0
  235. data/app/views/layouts/auth/navbar/_personalization.html.erb +17 -0
  236. data/app/views/layouts/auth/navbar/_progress_spinner.html.erb +11 -0
  237. data/app/views/layouts/mailer.html.erb +5 -0
  238. data/app/views/layouts/mailer.text.erb +1 -0
  239. data/config/initializers/active_model.rb +36 -0
  240. data/config/initializers/devise.rb +623 -0
  241. data/config/initializers/json.rb +10 -0
  242. data/config/initializers/omniauth.rb +447 -0
  243. data/config/initializers/redis.rb +2 -0
  244. data/config/initializers/redis.yml +14 -0
  245. data/config/locales/devise.en.yml +63 -0
  246. data/config/routes.rb +1 -0
  247. data/lib/assets/javascripts/data.js +126 -0
  248. data/lib/assets/javascripts/jquery.calendario.js +394 -0
  249. data/lib/assets/javascripts/jquery.tagcloud.js +92 -0
  250. data/lib/assets/javascripts/leanModal.js +236 -0
  251. data/lib/assets/javascripts/main.js +668 -0
  252. data/lib/assets/javascripts/modernizr.custom.63321.js +4 -0
  253. data/lib/assets/javascripts/payumoney.js +9 -0
  254. data/lib/assets/javascripts/search.js +36 -0
  255. data/lib/assets/javascripts/spinner.js +77 -0
  256. data/lib/assets/javascripts/trianglify.min.js +2 -0
  257. data/lib/assets/javascripts/you_need_to_sign_in.js.erb +478 -0
  258. data/lib/assets/stylesheets/calendar.css +111 -0
  259. data/lib/assets/stylesheets/calendar_modifications.scss +276 -0
  260. data/lib/auth.rb +32 -0
  261. data/lib/auth/custom_failure.rb +3 -0
  262. data/lib/auth/engine.rb +231 -0
  263. data/lib/auth/job_exception_handler.rb +7 -0
  264. data/lib/auth/mailgun.rb +28 -0
  265. data/lib/auth/notify.rb +8 -0
  266. data/lib/auth/omniauth/path.rb +104 -0
  267. data/lib/auth/partials.rb +12 -0
  268. data/lib/auth/rails/routes.rb +169 -0
  269. data/lib/auth/search/main.rb +97 -0
  270. data/lib/auth/sidekiq_up.rb +16 -0
  271. data/lib/auth/two_factor_otp.rb +202 -0
  272. data/lib/auth/url_shortener.rb +29 -0
  273. data/lib/auth/version.rb +3 -0
  274. data/lib/tasks/auth_tasks.rake +4 -0
  275. metadata +863 -0
@@ -0,0 +1,11 @@
1
+ 1)after a payment is created -> the option is provided to create a discount coupon -> clicking on that will take you to "new" action for discount coupon -> passing in the cart id, here you can decide the other things like required_verificatino as well as the
2
+
3
+ 2)viewing a discount item should provide a link to create an entire cart using that discount -> should do a post to create multiple cart items -> should then give a link to create a cart -> and there the discount_code should be present -> with a link to create a payment using that discount id.
4
+
5
+ 3)on creating a payment with the discount id it should -> give the message that the verification si pending
6
+
7
+ 4)on viewing the discount object it should show all the pending discounts -> and provide an option to mark each as accepted or declined
8
+
9
+ 5)on refreshing the payment -> by passing is verify payment as true -> should now set the payment as successfull.
10
+
11
+ 6)end.
@@ -0,0 +1,184 @@
1
+ module Auth::Concerns::Shopping::PayUMoneyConcern
2
+
3
+ extend ActiveSupport::Concern
4
+
5
+ include Auth::Concerns::ChiefModelConcern
6
+
7
+ included do
8
+ field :firstname, type: String
9
+ field :email, type: String
10
+ field :phone, type: String
11
+ ##same as the payment id.
12
+ field :txnid, type: String
13
+ field :surl, type: String
14
+ field :furl, type: String
15
+ ##same as the cart name
16
+ field :productinfo, type: String
17
+ ##amount is not added here, because it is already a part of the payment_concern
18
+ ##the hash calculated by using the payumoney library.
19
+ field :hast, type: String
20
+
21
+
22
+
23
+
24
+
25
+ ##remember to set the default_url_options in the dummy app routes file.
26
+ before_create do |document|
27
+ if document.is_gateway?
28
+
29
+ document.surl = document.furl = Rails.application.routes.url_helpers.shopping_payment_url(document.id.to_s)
30
+ document.txnid = document.id.to_s
31
+ #document.txnid = "a#{Random.new.rand(1..50)}"
32
+ document.calculate_hash
33
+ end
34
+ end
35
+
36
+
37
+ ##add a validation, that checks that each of the 7 required fields are present, before create, only when the payment_type is gateway.
38
+ ##the is_gateway? method is defined in payment_concern.
39
+ ##these validations are run before the before_save is called.
40
+ ##so will throw an error if either of the following are not present.
41
+ validates_presence_of :firstname, if: :is_gateway?
42
+ validates_presence_of :email, if: :is_gateway?
43
+ validates_presence_of :phone, if: :is_gateway?
44
+ validates_presence_of :productinfo, if: :is_gateway?
45
+
46
+ end
47
+
48
+ ##needs to use the payumoney library.
49
+ def calculate_hash
50
+ options = {:firstname => firstname, :email => email, :phone => phone, :txnid => txnid, :surl => surl, :furl => furl, :productinfo => productinfo, :amount => amount}
51
+ service = PayuIndia::Helper.new(payment_gateway_key, payment_gateway_salt, options)
52
+ self.hast = service.generate_checksum
53
+ end
54
+
55
+
56
+
57
+
58
+ def verify_payment
59
+
60
+ if self.new_record?
61
+
62
+ return nil
63
+ else
64
+
65
+ if self.is_verify_payment == "true"
66
+ #puts "yes is verify payment."
67
+ #puts the payment is not getting set as pending.
68
+ ## that is the problem.
69
+ if self.payment_pending
70
+
71
+ if self.is_gateway?
72
+ #puts "came to is gateway"
73
+ options = {:var1 => self.txnid, :command => 'verify_payment'}
74
+ webservice = PayuIndia::WebService.new(payment_gateway_key,payment_gateway_salt,options)
75
+ sha_hash = webservice.generate_checksum
76
+ if resp = Typhoeus.post(PayuIndia.webservice_url, body:
77
+ { key: payment_gateway_key, command: 'verify_payment', hash: sha_hash, var1: self.txnid}, headers: {'Content-Type' => 'application/x-www-form-urlencoded'})
78
+ Rails.logger.info(resp.body + ":transaction_id:" + self.id.to_s)
79
+ begin
80
+ details = JSON.parse(resp.body)
81
+
82
+ if status = details["status"].to_s
83
+ self.payment_status = 0 if (status == "0")
84
+
85
+ if status == "1"
86
+ if details["transaction_details"]
87
+ if transaction_details =
88
+ details["transaction_details"][txnid.to_s]
89
+
90
+ if transaction_details["status"]
91
+
92
+ self.payment_status = 1 if transaction_details["status"].to_s.downcase == "success"
93
+ self.payment_status = 0 if transaction_details["status"].to_s.downcase =~/pending|failure/
94
+ if payment_status_changed?
95
+ ## prevents recursive callbacks, after save.
96
+ self.is_verify_payment = "false"
97
+ self.save
98
+ else
99
+ self.errors.add(:payment_status,"transaction status was something other than failed|success|pending")
100
+ end
101
+ else
102
+ self.errors.add(:payment_status,"transaction details does not have the status key. Please try to verify your payment later, or contact Support for more help.")
103
+ end
104
+ else
105
+ self.errors.add(:payment_status,"transaction details does not have the transaction id. Please try to verify your payment later, or contact Support for more help.")
106
+
107
+ end
108
+ else
109
+ self.errors.add(:payment_status,"transaction details key missing from response")
110
+
111
+ end
112
+ else
113
+ self.errors.add(:payment_status,"status key is neither 1 not 0 : Please try to verify your payment later, or contact Support for more help.")
114
+
115
+ end
116
+
117
+ else
118
+ self.errors.add(:payment_status,"no status key in payment verification response. Please try to verify your payment later, or contact Support for more help.")
119
+
120
+ end
121
+
122
+ rescue => e
123
+ Rails.logger.error(e.to_s)
124
+ self.errors.add(:payment_status,"failure parsing payment response. Please try to verify your payment later, or contact Support for more help.")
125
+ end
126
+ else
127
+ ## does nothing, the caller has to check the payment_status to infer that the call was not successfull.
128
+ self.errors.add(:payment_status,"no response from verify endpoint. Please try to verify your payment later, or contact Support for more help.")
129
+ end
130
+
131
+ end
132
+
133
+ return true
134
+ else
135
+
136
+ puts "not pending"
137
+ return nil
138
+ end
139
+ else
140
+ puts "is not verify payment."
141
+ return nil
142
+ end
143
+ end
144
+
145
+ end
146
+
147
+
148
+ def payment_gateway_key
149
+ Auth.configuration.payment_gateway_info[:key]
150
+ end
151
+
152
+
153
+ def payment_gateway_salt
154
+ Auth.configuration.payment_gateway_info[:salt]
155
+ end
156
+
157
+
158
+ ##this method is overriden here from the payment_concern.
159
+ ##suppose the user is calling refresh_payment, basically an update call, then the mihpayid wont be present so the gateway callback becomes pointless.
160
+ ## and then we just let verify payment handle the situation.
161
+ def gateway_callback(pr,&block)
162
+
163
+
164
+ return if (self.new_record? || self.is_verify_payment == "true")
165
+
166
+ =begin
167
+ notification = PayuIndia::Notification.new("", options = {:key => Auth.configuration.payment_gateway_info[:key], :salt => Auth.configuration.payment_gateway_info[:salt], :params => pr})
168
+ self.payment_status = 0
169
+ if(notification.acknowledge && notification.complete?)
170
+ self.payment_status = 1
171
+ end
172
+ =end
173
+
174
+ ## we should just set, gateway callback complete as true, and based on that never show the pay with payumoney link again in the show action.
175
+
176
+ ## just looking to see if
177
+ if (pr["mihpayid"] && pr["hash"] && (pr["txnid"] == self.id.to_s))
178
+ self.gateway_callback_called = true
179
+ end
180
+ yield if block_given?
181
+ return true
182
+ end
183
+
184
+ end
@@ -0,0 +1,613 @@
1
+ ##NEED A SEPERATE MODEL THAT IMPLEMENTS IT
2
+ module Auth::Concerns::Shopping::PaymentConcern
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ include Auth::Concerns::ChiefModelConcern
7
+ include Auth::Concerns::OwnerConcern
8
+
9
+ included do
10
+
11
+ FAILED = "Failed"
12
+ SUCCESS = "Success"
13
+ PENDING = "You need to complete this payment"
14
+
15
+
16
+
17
+ ## the params that are passed into the payment controller at create or update.
18
+ ## used in the before_update callback
19
+ ## for the gateway_callback
20
+ ## in that callback we need access
21
+ ## to the full params hash.
22
+ ## so this accessor is set in the controller #update
23
+ ## and #create methods.
24
+ attr_accessor :payment_params
25
+
26
+
27
+ ## this is expected to be passed into the params by the user, when he is calling refresh_payment.
28
+ ## expected to be a string
29
+ ## can be "true" or "false"
30
+ ## if true -> gateway_callback is ignored, and verify payment is done, and vice versa.
31
+ attr_accessor :is_verify_payment
32
+
33
+ ##the amount for this payment
34
+ field :amount, type: Float
35
+
36
+ ##gateway
37
+ ##card
38
+ ##cash
39
+ ##cheque
40
+ field :payment_type, type: String
41
+
42
+ ## gateway callback called
43
+ field :gateway_callback_called, type: Boolean, default: false
44
+
45
+
46
+ ##the id of the cart for which this payment was made
47
+ field :cart_id, type: String
48
+
49
+ ## success : 1
50
+ ## fail : 0
51
+ ## pending : null.
52
+ field :payment_status, type: Integer
53
+
54
+ ## payment ack proof.
55
+ field :payment_ack_proof, type: String
56
+
57
+
58
+ ## is it a refund?
59
+ ## true if it is a refund, false otherwise.
60
+ field :refund, type: Boolean
61
+
62
+ ## the cart associated with this payment
63
+ attr_accessor :cart
64
+
65
+ ## Hash with two keys:
66
+ ## cart => with all its attributes
67
+ ## payment => with an array of cart_item objects accepted due to it.
68
+ attr_accessor :payment_receipt
69
+
70
+ ##
71
+ ## how much change should be given to the customer.
72
+ ##
73
+ field :cash_change, type: Float, default: 0
74
+
75
+ validates_presence_of :cart_id
76
+ validates_presence_of :resource_id
77
+ validates_presence_of :amount
78
+ validates_presence_of :payment_type
79
+ validates_presence_of :resource_class
80
+
81
+ ## only applicable if not already approved.
82
+ ## only applicalbe if we are not changing the payment_status to not approved from approved.
83
+ validate :cheque_or_card_payment_not_excessive, if: Proc.new{|a| a.payment_status.nil?}
84
+
85
+
86
+ validates :amount, numericality: { :greater_than => 0.00 }, unless: Proc.new { |document| document.refund }
87
+
88
+
89
+ ## payment is invalid if the minimum payable amount of the cart is not satisfied.
90
+
91
+
92
+ validate :cart_not_empty
93
+
94
+ validate :refund_created_or_approved_only_if_balance_is_negative
95
+
96
+ validate :refund_created_or_approved_only_if_sum_of_discount_payments_does_not_cover_cart_pending_balance
97
+
98
+ validate :refund_approved_if_cart_pending_balance_is_equal_to_refund_amount
99
+
100
+ validate :update_cart_items_accepted
101
+
102
+
103
+ ### only applicable if not already accepted,
104
+ ### also not applicable, if we are deeming this payment status as failed from approved.
105
+ ## this basically does not do the validation if the payment status is already success or failed.
106
+ ## and also does not do the validation if we are going from success -> failed.
107
+ validate :payment_satisfies_minimum_payment_requirement, if: Proc.new{|a| a.payment_status.nil?}
108
+
109
+ ## if the payment is card or cheque and is being set as approved.
110
+ ## it must check that the url is present.
111
+ validate :card_and_cheque_payment_provides_proof, if: Proc.new{|a| a.payment_status_changed? && a.payment_status == 1 && (a.is_card? || a.is_cheque? || a.refund)}
112
+
113
+
114
+ validate :check_owner_matches
115
+
116
+
117
+ before_validation do |document|
118
+ puts "came to before validation."
119
+ document.set_cart(document.cart_id)
120
+
121
+ document.payment_callback(document.payment_type,document.payment_params)
122
+
123
+ ## we can hook the refresh into this.
124
+ document.refresh_refund
125
+
126
+ document.verify_payment
127
+ end
128
+
129
+ ## because the validation will not allow the payment status to be changed in case this is not an admin user, and we need to allow the user to refresh the payment state, in case of refunds which need to set as failed because some later refund was accepted but in that callback the nil refund was for some reason not set as failed.
130
+ ## also in case of gateway payments, we need to allow to see if it can be verified.
131
+ ## both these methods change the state of the payment suo moto. it is not necessary that the user should be an admin.
132
+ #after_validation do |document|
133
+ # if document.errors.full_messages.empty?
134
+
135
+ # end
136
+ #end
137
+
138
+ before_save do |document|
139
+ if !document.skip_callback?("before_save")
140
+
141
+ end
142
+ end
143
+
144
+ ## when a refund is accepted, any pening refund requests are considered to have failed, since this one has succeeded.
145
+ after_save do |document|
146
+ if !document.skip_callback?("after_save")
147
+
148
+
149
+ ## find all pending refunds and set them as failed.
150
+ if document.payment_status_changed? && document.payment_status == 1
151
+
152
+
153
+
154
+ if document.refund
155
+
156
+ ## find previous refunds.
157
+ any_pending_refunds = self.class.where(:refund => true, :payment_status => nil)
158
+
159
+
160
+ any_pending_refunds.each do |pen_ref|
161
+ pen_ref.signed_in_resource = document.signed_in_resource
162
+ pen_ref.refund_failed
163
+ ## so that it doesnt do this recursively for every refund.
164
+ pen_ref.skip_callbacks = {:after_save => true}
165
+ res = pen_ref.save
166
+
167
+ end
168
+
169
+
170
+ end
171
+
172
+ ## set the payment receipt
173
+ document.set_payment_receipt
174
+
175
+ end
176
+ end
177
+ end
178
+
179
+
180
+ #####################################################
181
+ ##
182
+ ##
183
+ ## DISCOUNT
184
+ ##
185
+ ##
186
+ #####################################################
187
+
188
+ ## id of discount coupon.
189
+ field :discount_id, type: String
190
+
191
+ ## the discount_object => set in the discount_callback.
192
+ attr_accessor :discount
193
+
194
+
195
+
196
+
197
+ end
198
+
199
+ module ClassMethods
200
+ def find_payments(resource,cart)
201
+ res = Auth.configuration.payment_class.constantize.where(:resource_id => resource.id.to_s, :cart_id => cart.id.to_s)
202
+ res.each do |p|
203
+ #puts "found payment: #{p.id.to_s}"
204
+ end
205
+ end
206
+
207
+ ## will return discount_payments of this cart id with a payments_status of 1.
208
+ def get_discount_payments(cart_id)
209
+
210
+ discount_payments = Auth.configuration.payment_class.constantize.where(:cart_id => cart_id, :discount_id.nin => ["", nil], :payment_status => 1)
211
+ discount_payments
212
+ end
213
+
214
+ ## will return the sum of the amounts of all successfull discount_payments.
215
+ def get_sum_of_discount_payments(cart_id)
216
+
217
+ sum_of_discount_payments = 0
218
+
219
+ get_discount_payments(cart_id).each do |dp|
220
+ sum_of_discount_payments+= dp.amount
221
+ end
222
+
223
+ sum_of_discount_payments
224
+ end
225
+
226
+ end
227
+
228
+
229
+
230
+
231
+ ## basically checks if there is any refund that was accepted after this refund_request was created. then in that case sets this refund as failed.
232
+ ## this is basically done because while normally, whenever a refund is accepted, all other pending refunds are updated as failed, but suppose that that operation does not complete and some refunds are left still pending.
233
+ ## then in the controller update action, this method is called on the payment.
234
+ def refresh_refund
235
+
236
+ if self.refund && self.payment_status.nil?
237
+
238
+ already_accepted_refunds = self.class.where(:refund => true, :payment_status => 1, :updated_at => { :$gte => self.created_at})
239
+
240
+ if already_accepted_refunds.size > 0
241
+
242
+ self.refund_failed
243
+ end
244
+ end
245
+ end
246
+
247
+ ## returns the cart_item ids which were accepted due to this payment.
248
+ ## called after_save callback.
249
+ ## called in show action of controller.
250
+ ## return[Array]
251
+ def set_payment_receipt
252
+ self.payment_receipt = {:current_payment => [], :cart => {}}
253
+ Auth.configuration.cart_item_class.constantize.where(:accepted_by_payment_id => self.id.to_s).each do |c_item|
254
+ self.payment_receipt[:current_payment] << c_item
255
+ end
256
+ set_cart(self.cart_id) if self.cart.nil?
257
+ self.payment_receipt[:cart] = self.cart.prepare_receipt
258
+ end
259
+
260
+ ##res : 59a5405c421aa90f732c9059
261
+ ##cart : 59a54d7a421aa9173c834728
262
+
263
+ ##used in pay_u_money_helper.rb
264
+ def get_cart_name
265
+ self.cart.nil? ? "shopping_cart" : (self.cart.name.nil? ? "shopping_cart" : self.cart.name)
266
+ end
267
+
268
+ def is_gateway?
269
+ payment_type && payment_type == "gateway"
270
+ end
271
+
272
+ def is_cash?
273
+ payment_type && payment_type == "cash"
274
+ end
275
+
276
+ def is_card?
277
+ payment_type && payment_type == "card"
278
+ end
279
+
280
+ def is_cheque?
281
+ payment_type && payment_type == "cheque"
282
+ end
283
+
284
+ def payment_callback(type,params,&block)
285
+
286
+ if self.refund
287
+ self.send("refund_callback",params,&block)
288
+ elsif self.discount_id
289
+ self.send("discount_callback",params,&block)
290
+ else
291
+ self.send("#{type}_callback",params,&block) if self.respond_to? "#{type}_callback"
292
+ end
293
+
294
+ yield if block_given?
295
+ end
296
+
297
+ def payment_excessive?
298
+ self.amount > self.cart.cart_pending_balance && self.amount > 0
299
+ end
300
+
301
+ ## the if new_record? is added so that the callback is done only when the payment is first made and not every time the payment is updated
302
+ ## calculate the change
303
+ ## make the amount equal to the pending balance if it is excesive.
304
+ def cash_callback(params,&block)
305
+ if self.new_record?
306
+ calculate_change
307
+ self.amount = self.cart.cart_pending_balance if payment_excessive?
308
+ end
309
+ end
310
+
311
+
312
+ ## sets the change to be given to the customer
313
+ ## @used_in : cash_callback
314
+ ## @return[nil] : returns nothing, just sets the cash_change attribute.
315
+ def calculate_change
316
+ ## by this point in time the cart has already been set, and prepared, so we know the total pending amount.
317
+ if self.amount > self.cart.cart_pending_balance
318
+ self.cash_change = self.amount - self.cart.cart_pending_balance
319
+ else
320
+ self.cash_change = 0
321
+ end
322
+ end
323
+
324
+ ## the if new_record? is added so that the callback is done only when the payment is first made and not every time the payment is updated
325
+ def cheque_callback(params,&block)
326
+
327
+ end
328
+
329
+
330
+ def refund_callback(params,&block)
331
+
332
+ end
333
+
334
+ def refund_success
335
+ self.amount = self.cart.refund_amount
336
+ self.payment_status = 1
337
+ end
338
+
339
+
340
+ def refund_failed
341
+ self.amount = 0
342
+ self.payment_status = 0
343
+ end
344
+
345
+ ## the if new_record? is added so that the callback is done only when the payment is first made and not every time the payment is updated
346
+ def card_callback(params,&block)
347
+
348
+ end
349
+
350
+ def payment_failed
351
+ payment_status && payment_status == 0
352
+ end
353
+
354
+ def payment_success
355
+ payment_status && payment_status == 1
356
+ end
357
+
358
+ def payment_pending
359
+ !payment_status
360
+ end
361
+
362
+ ##override this method depending upon the gateway that you use.
363
+ def gateway_callback(params,&block)
364
+ ## if its a new_record we don't do any callback, because the payment doesnt exist to check it .
365
+ ## if the user has passed in is_verify_payment, we still don;t do this callback, because
366
+ return if (self.new_record? || self.is_verify_payment == "true")
367
+
368
+ yield if block_given?
369
+ end
370
+
371
+ def discount_callback(params,&block)
372
+
373
+ ## the callback should fire on create/update, so new_record checking is not required.
374
+
375
+ ## first check if the discount id exists -> get the discount object.
376
+
377
+ #begin
378
+
379
+ self.discount = Auth.configuration.discount_class.constantize.find(discount_id)
380
+
381
+ #puts "discount is: #{self.discount}"
382
+
383
+
384
+ if self.discount.requires_verification == true
385
+ #puts "detected discount requires verification"
386
+ self.payment_status = Auth.configuration.discount_class.constantize.get_payment_status(self,discount_id)
387
+ #puts "the payment status is detected as: #{self.payment_status}"
388
+ else
389
+ ## what about floating discount codes?
390
+ ## can a user use them repeatedly?
391
+ self.payment_status = Auth.configuration.discount_class.constantize.use_discount(self.discount,self)
392
+ end
393
+
394
+ ## now also set the payment amount to be equal to the discount amount or the discount percentage whichever works out be greater.
395
+ ## first preference is given to check the discount amount.
396
+
397
+ if self.discount.discount_amount > 0
398
+ self.amount = self.discount.discount_amount
399
+
400
+ elsif self.discount.discount_percentage > 0
401
+ self.amount = self.cart.cart_pending_balance*self.discount.discount_percentage
402
+ else
403
+ self.amount = 0
404
+ end
405
+
406
+ ##finally ensure its not more than the cart_pending_balance
407
+ self.amount = self.cart.cart_pending_balance if self.amount > self.cart.cart_pending_balance
408
+
409
+ #rescue
410
+ # self.payment_status = 0
411
+ #end
412
+
413
+ end
414
+
415
+
416
+ def physical_payment?
417
+ is_card? || is_cash? || is_cheque?
418
+ end
419
+
420
+
421
+ def verify_payment
422
+
423
+
424
+ if self.new_record?
425
+ return nil
426
+ else
427
+ if self.is_verify_payment == "true"
428
+ if self.payment_pending
429
+ return true
430
+ else
431
+ return nil
432
+ end
433
+ else
434
+ return nil
435
+ end
436
+ end
437
+
438
+ end
439
+
440
+ ## finds the cart that this payment refers to
441
+ ## sets it to an attr_accessor called cart
442
+ ## prepares the cart(refer to cart concern for a description of this method)
443
+ def set_cart(cart_id)
444
+
445
+
446
+ self.cart = Auth.configuration.cart_class.constantize.find(cart_id)
447
+
448
+
449
+ self.cart.prepare_cart
450
+
451
+
452
+ end
453
+
454
+ ## is called on payment_status_changed
455
+ ## check whether this payment was already registered on the cart as success or failed.
456
+ ## and then debit/credit.
457
+ ## return[Boolean] : true/false depending on whether all the cart items could be successfully updated or not.
458
+ def update_cart_items_accepted
459
+
460
+ if payment_status_changed?
461
+
462
+ if payment_status == 1
463
+ self.cart.cart_credit+= self.amount
464
+ elsif payment_status == 0 && payment_status_was == 1
465
+
466
+ self.cart.cart_credit-= self.amount
467
+ else
468
+
469
+ end
470
+
471
+
472
+
473
+ cart_item_update_results = self.cart.get_cart_items.map{|cart_item|
474
+ cart_item.signed_in_resource = self.signed_in_resource
475
+ ## first all the expected cart items should exist
476
+ ## then they should all get saved
477
+ ## none of them should be already accepted.
478
+ ## if all these conditions are satisfied.
479
+ ## then we can say that nothing else has happedn
480
+ ## we do an atomic request
481
+ ## where(item_id => whatever, accepted => false).set(accepted => true)
482
+ ## if this fails for even one, then the payment fails.
483
+ ## and all the remaining cart items -> can be refreshed to show that they are not accepted
484
+ ## refresh will say -> where(:payment_id => x, and status = acceptd)
485
+ ## so if some other payment gets in the way, either it will fail or this will fail, so it works.
486
+ cart_item.set_accepted(self,nil)
487
+ }.compact.uniq
488
+ self.errors.add(:cart,"cart item status could not be updated") if cart_item_update_results[0] == false
489
+
490
+ else
491
+ if (payment_status == 0 || payment_status == 1)
492
+ cart_item_update_results = self.cart.get_cart_items.map{|cart_item|
493
+ #puts "now mapping cart item"
494
+ #puts cart_item.id.to_s
495
+ cart_item.signed_in_resource = self.signed_in_resource
496
+ res = cart_item.set_accepted(self,nil)
497
+ res
498
+ }
499
+ end
500
+ end
501
+ end
502
+
503
+ #######################################################
504
+ ##
505
+ ## CUSTOM VALIDATION DEFS
506
+ ##
507
+ #######################################################
508
+
509
+ ## validation
510
+ def cheque_or_card_payment_not_excessive
511
+
512
+ self.errors.add(:amount,"payment is excessive") if payment_excessive? && (is_cheque? || is_card?) && !refund
513
+ end
514
+
515
+ ## validation
516
+ def cart_not_empty
517
+ return if self.refund == true
518
+ self.errors.add(:cart,"cart has to have some items in order to make a payment") if !self.cart.has_items?
519
+
520
+ end
521
+
522
+ =begin
523
+ ## not really a validation, basically doesnt allow any user provided attributes to be set if the user is not an admin and trying to update the document.
524
+ def document_updated_only_by_admin
525
+ if !new_record?
526
+ if !signed_in_resource.is_admin?
527
+ self.attributes.clear
528
+ end
529
+ end
530
+
531
+ end
532
+
533
+ ## validation
534
+ def document_status_set_only_by_admin
535
+ if payment_status_changed?
536
+ if !signed_in_resource.is_admin?
537
+ ## delete the payment_status if resource is not an admin, whether he is saving or updating the document.
538
+ self.attributes.delete("payment_status")
539
+ self.errors.add(:payment_status,"only admin can set or change the payment status")
540
+ end
541
+ end
542
+ end
543
+ =end
544
+
545
+ ## validation
546
+ def refund_created_or_approved_only_if_balance_is_negative
547
+ if refund
548
+ ## in case the admin wants to mark a refund as failed.
549
+ if payment_status == 0 && payment_status_changed?
550
+
551
+ else
552
+ self.errors.add("payment_status","you cannot authorize a refund since the pending balance is positive.") if self.cart.cart_pending_balance >= 0
553
+ end
554
+ end
555
+ end
556
+
557
+ ## validation
558
+ def refund_approved_if_cart_pending_balance_is_equal_to_refund_amount
559
+ if payment_status_changed? && payment_status == 1 && refund
560
+ self.errors.add("payment_status","you cannot authorize a refund since the amount you entered is wrong") if self.cart.cart_pending_balance != self.amount
561
+ end
562
+ end
563
+
564
+ ## validation
565
+ def refund_created_or_approved_only_if_sum_of_discount_payments_does_not_cover_cart_pending_balance
566
+
567
+ if refund
568
+
569
+ ## get the approved discount payments
570
+
571
+ ## then check the sum of those payments.
572
+ discount_sum = self.class.get_sum_of_discount_payments(self.cart_id)
573
+
574
+ if self.cart.cart_pending_balance < 0
575
+ if discount_sum > self.cart.cart_pending_balance*-1
576
+ self.errors.add("amount","the discounts you availed, cover the need for the refund.")
577
+ end
578
+ end
579
+
580
+ end
581
+
582
+ end
583
+
584
+ ## validation
585
+ def payment_satisfies_minimum_payment_requirement
586
+ self.cart.prepare_cart
587
+ puts "the minimum payment amoutn is:"
588
+ puts self.cart.cart_minimum_payable_amount
589
+ return if (self.refund == true || self.discount)
590
+ self.errors.add("amount","payment amount is not sufficient") if (self.cart.cart_minimum_payable_amount.nil? || (self.cart.cart_minimum_payable_amount > self.amount))
591
+ end
592
+
593
+ def card_and_cheque_payment_provides_proof
594
+ ## it is not directly possible to create a card / cheque payment as successfull even as an administrator
595
+ ## you have to first create an image resource, and it will check for that in this def, to exist
596
+ ## so search for an image resource, that has the payment id of this payment.
597
+ ## eg , add this error.
598
+
599
+ ##self.errors.add("payment_type","you have to upload an image of the card mahine receipt/cheque, to approve this payment.")
600
+ end
601
+
602
+ def check_owner_matches
603
+ self.errors.add("cart_id","the cart id and payment are being created by different users.") if (owner_matches(self.cart) == false)
604
+ end
605
+
606
+
607
+ def as_json(options={})
608
+ super(options).merge({:payment_receipt => self.payment_receipt,:cash_change => self.cash_change})
609
+ end
610
+
611
+ end
612
+
613
+