spree_razorpay_checkout 0.0.5 → 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.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/payment_icons/razorpay.svg +1 -0
  3. data/app/assets/javascripts/spree/frontend/process_razorpay.js +40 -0
  4. data/app/assets/javascripts/spree/frontend/spree_razorpay.js +33 -0
  5. data/app/controllers/concerns/spree/razor_pay.rb +18 -0
  6. data/app/controllers/spree/razorpay_controller.rb +105 -0
  7. data/app/models/spree/gateway/razorpay_gateway.rb +120 -0
  8. data/app/models/spree/razorpay_checkout.rb +4 -0
  9. data/app/models/spree_razorpay_checkout/configuration.rb +13 -0
  10. data/app/models/spree_razorpay_checkout/spree/order_decorator.rb +33 -0
  11. data/app/models/spree_razorpay_checkout/spree/refund_decorator.rb +36 -0
  12. data/app/services/razorpay/base.rb +17 -0
  13. data/app/services/razorpay/rp_order/api.rb +43 -0
  14. data/app/services/razorpay_refund.rb +31 -0
  15. data/app/views/spree/admin/payment_methods/configuration_guides/_razorpay.html.erb +6 -0
  16. data/app/views/spree/admin/payment_methods/descriptions/_razorpay.html.erb +15 -0
  17. data/app/views/spree/checkout/payment/_razorpay.html.erb +190 -0
  18. data/config/initializers/assets.rb +4 -0
  19. data/config/locales/en.yml +13 -0
  20. data/config/routes.rb +5 -0
  21. data/db/migrate/20220816080140_create_spree_razorpay_checkouts.rb +20 -0
  22. data/lib/generators/spree_razorpay_checkout/install/install_generator.rb +2 -2
  23. data/lib/spree_razorpay_checkout/configuration.rb +10 -0
  24. data/lib/spree_razorpay_checkout/engine.rb +3 -0
  25. data/lib/spree_razorpay_checkout/factories.rb +1 -1
  26. data/lib/spree_razorpay_checkout/version.rb +1 -1
  27. metadata +32 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1951bcb23b0a2a7f766cd926211440f923b40e50d976e72677893e0332de40d
4
- data.tar.gz: bc343c46c13893807e544e168ae9f8899fba0de37b691092402d5e03b096d7e7
3
+ metadata.gz: a4d76121b7886a9c83e9b776340876ba0e95576521dbe2e7cf3b29702a6be65a
4
+ data.tar.gz: 8c4cc0283ec0333f52a296ed0c71c81c5d95f8efb2bd38c54a66613abe0d3869
5
5
  SHA512:
6
- metadata.gz: e990f2c51d6cca246939f0ea33af1c44f2949631c013cf2b738d1cf445e19f7605475580c25e9262c1aab1fb5fc639a7a33d1295bd5b18fe5eb308d5c9387ac6
7
- data.tar.gz: 7d6706c9ca2afea782a7ffd60bb6441e38ca6fc79f885eff2730f95d52734540515dccc22a46b5074ef7eb261f49034f4831b794bc050b38977ffffe037933d8
6
+ metadata.gz: b2566259b590a119fa88ff3b58e50ebe875b8bfa66b0fadcf2bde579ced610e3e249d77567211295f3d5f1a13e152e5bd4b52a4c75abe0cef306be0ced7df11b
7
+ data.tar.gz: d407724116949e1c8c78d534269ab1fc8c9022b489eca2a554ca640951e1a2bdc318db49b529fd85bcad849ef1f55070e5c5a62fcc8ef376257ccf7592c22607
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 38 24" width="38" height="24" aria-labelledby="pi-payu"><path opacity=".07" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3"/><path fill="#fff" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2z"/><style>.st0{opacity:7.000000e-02;enable-background:new}.st1{fill:#fff}</style><path class="st0" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3"/><path class="st1" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2z"/><path class="st0" d="M35 0H3C1.3 0 0 1.3 0 3v18c0 1.7 1.4 3 3 3h32c1.7 0 3-1.3 3-3V3c0-1.7-1.4-3-3-3"/><path class="st1" d="M35 1c1.1 0 2 .9 2 2v18c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V3c0-1.1.9-2 2-2z"/><g transform="matrix(.85 0 0 .85 4.5 1.8)"><path id="Fill-17" style="fill-rule:evenodd;clip-rule:evenodd;fill:#3395ff" d="m16.2 9-.9 3 4.8-3-3 11.6h3.1l4.6-17.2z"/><path id="Fill-19" d="m11.1 15.7-1.4 4.9h6.5l2.6-10z" style="fill-rule:evenodd;clip-rule:evenodd;fill:#072654"/></g></svg>
@@ -0,0 +1,40 @@
1
+ //= require spree/frontend
2
+
3
+ var RAZOR_PAY_OPTIONS = '#razor-pay-options'
4
+ var RAZOR_PAY_BUTTON = '#razorpay-button'
5
+
6
+ Spree.ready(function ($) {
7
+
8
+ let razor_pay = $(RAZOR_PAY_BUTTON)
9
+
10
+ var options = {
11
+ "key": $(RAZOR_PAY_OPTIONS).data('razor-pay-key'),
12
+ "amount": $(RAZOR_PAY_OPTIONS).data('razor-pay-amount'),
13
+ "currency": $(RAZOR_PAY_OPTIONS).data('razor-pay-currency'),
14
+ "name": $(RAZOR_PAY_OPTIONS).data('razor-pay-name'),
15
+ "description": $(RAZOR_PAY_OPTIONS).data('razor-pay-description'),
16
+ "callback_url": $(RAZOR_PAY_OPTIONS).data('razor-pay-callback-url'),
17
+ "redirect": $(RAZOR_PAY_OPTIONS).data('razor-pay-redirect'),
18
+ "order_id": $(RAZOR_PAY_OPTIONS).data('razor-pay-order-id'),
19
+ "prefill": {
20
+ "name": $(RAZOR_PAY_OPTIONS).data('razor-pay-prefill-name'),
21
+ "email": $(RAZOR_PAY_OPTIONS).data('razor-pay-prefill-email'),
22
+ "contact": $(RAZOR_PAY_OPTIONS).data('razor-pay-prefill-contact')
23
+ },
24
+ "notes": {
25
+ "address": $(RAZOR_PAY_OPTIONS).data('razor-pay-notes-address')
26
+ },
27
+ "theme": {
28
+ "color": $(RAZOR_PAY_OPTIONS).data('razor-pay-theme-color')
29
+ }
30
+ };
31
+
32
+ if ( razor_pay.length > 0 ) {
33
+ var rzp1 = new Razorpay(options);
34
+ }
35
+
36
+ $( RAZOR_PAY_BUTTON ).on( "click", function(e) {
37
+ rzp1.open();
38
+ e.preventDefault();
39
+ });
40
+ })
@@ -0,0 +1,33 @@
1
+ //= require spree/frontend
2
+
3
+
4
+ var paymentMethodID = $("#payment-method-container").data("payment-method-id");
5
+ SpreeRazorpayCheckout = {
6
+ updateSaveAndContinueVisibility: function() {
7
+ if (this.isButtonHidden()) {
8
+ $(this).trigger('hideSaveAndContinue')
9
+ } else {
10
+ $(this).trigger('showSaveAndContinue')
11
+ }
12
+ },
13
+ isButtonHidden: function () {
14
+ paymentMethod = this.checkedPaymentMethod();
15
+ return (!$('#use_existing_card_yes:checked').length && paymentMethodID && paymentMethod.val() == paymentMethodID);
16
+ },
17
+ checkedPaymentMethod: function() {
18
+ return $('div[data-hook="checkout_payment_step"] input[type="radio"][name="order[payments_attributes][][payment_method_id]"]:checked');
19
+ },
20
+ hideSaveAndContinue: function() {
21
+ $("#checkout_form_payment [data-hook=buttons]").hide();
22
+ },
23
+ showSaveAndContinue: function() {
24
+ $("#checkout_form_payment [data-hook=buttons]").show();
25
+ }
26
+ }
27
+
28
+ $(document).ready(function() {
29
+ SpreeRazorpayCheckout.updateSaveAndContinueVisibility();
30
+ paymentMethods = $('div[data-hook="checkout_payment_step"] input[type="radio"]').click(function (e) {
31
+ SpreeRazorpayCheckout.updateSaveAndContinueVisibility();
32
+ });
33
+ })
@@ -0,0 +1,18 @@
1
+ module Spree
2
+ module RazorPay
3
+ extend ActiveSupport::Concern
4
+
5
+ def update_razorpay_checkout
6
+ razorpay_checkout = Spree::RazorpayCheckout.find_or_initialize_by(order_id: order.try(:id))
7
+ razorpay_checkout.update_columns(update_razorpay_response)
8
+ end
9
+
10
+ def update_razorpay_response
11
+ {
12
+ razorpay_payment_id: params['razorpay_payment_id'],
13
+ razorpay_order_id: params['razorpay_order_id'],
14
+ razorpay_signature: params['razorpay_signature']
15
+ }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,105 @@
1
+ module Spree
2
+ class RazorpayController < StoreController
3
+ skip_before_action :verify_authenticity_token
4
+
5
+ include Spree::RazorPay
6
+
7
+ #Step 1: Create Razorpay Order before payment
8
+ def create_order
9
+ razorpay_order_id = ::Razorpay::RpOrder::Api.new.create(params[:order_id])
10
+
11
+ if razorpay_order_id.present?
12
+ render json: { success: true, razorpay_order_id: razorpay_order_id }
13
+ else
14
+ render json: { success: false, error: "Failed to create Razorpay order" }, status: :unprocessable_entity
15
+ end
16
+ end
17
+
18
+ #Step 2: Razorpay callback after payment
19
+ def razor_response
20
+ if valid_signature? && razorpay_payment_id.present?
21
+ begin
22
+ gateway.verify_and_capture_razorpay_payment(order, razorpay_payment_id)
23
+
24
+ #Update the record created during create_order
25
+ checkout_record = Spree::RazorpayCheckout.find_by(
26
+ order_id: order.id,
27
+ razorpay_order_id: params[:razorpay_order_id]
28
+ )
29
+
30
+ if checkout_record
31
+ checkout_record.update!(
32
+ razorpay_payment_id: razorpay_payment_id,
33
+ razorpay_signature: params[:razorpay_signature],
34
+ status: razorpay_payment.status,
35
+ payment_method: razorpay_payment.method,
36
+ card_id: razorpay_payment.card_id,
37
+ bank: razorpay_payment.bank,
38
+ wallet: razorpay_payment.wallet,
39
+ vpa: razorpay_payment.vpa,
40
+ email: razorpay_payment.email,
41
+ contact: razorpay_payment.contact
42
+ )
43
+ else
44
+ Rails.logger.warn("RazorpayCheckout record not found for order #{order.id}")
45
+ end
46
+
47
+ # Add payment to Spree order
48
+ order.razor_payment(razorpay_payment, payment_method, params[:razorpay_signature])
49
+ order.next
50
+
51
+ flash['order_completed'] = true if order.completed?
52
+ redirect_to checkout_state_path_or_completion and return
53
+ rescue StandardError => e
54
+ Rails.logger.error("Razorpay Error: #{e.message}")
55
+ flash[:error] = "Razorpay Error: #{e.message}"
56
+ end
57
+ else
58
+ flash[:error] = 'Razorpay payment verification failed'
59
+ end
60
+
61
+ redirect_to checkout_state_path(order.state)
62
+ end
63
+
64
+ private
65
+
66
+ def razorpay_payment_id
67
+ params[:razorpay_payment_id]
68
+ end
69
+
70
+ def razorpay_payment
71
+ @razorpay_payment ||= Razorpay::Payment.fetch(razorpay_payment_id)
72
+ end
73
+
74
+ def valid_signature?
75
+ Razorpay::Utility.verify_payment_signature(
76
+ razorpay_order_id: params[:razorpay_order_id],
77
+ razorpay_payment_id: params[:razorpay_payment_id],
78
+ razorpay_signature: params[:razorpay_signature]
79
+ )
80
+ rescue Razorpay::Error => e
81
+ Rails.logger.error("Razorpay signature verification failed: #{e.message}")
82
+ false
83
+ end
84
+
85
+ def order
86
+ @order ||= Spree::Order.find_by(number: params[:order_id])
87
+ end
88
+
89
+ def payment_method
90
+ @payment_method ||= Spree::PaymentMethod.find(params[:payment_method_id])
91
+ end
92
+
93
+ def gateway
94
+ @gateway ||= payment_method
95
+ end
96
+
97
+ def checkout_state_path_or_completion
98
+ order.completed? ? completion_route : checkout_state_path(order.state)
99
+ end
100
+
101
+ def completion_route
102
+ order_path(order)
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,120 @@
1
+ require 'razorpay'
2
+
3
+ module Spree
4
+ class Gateway::RazorpayGateway < Gateway
5
+ preference :key_id, :string
6
+ preference :key_secret, :string
7
+ preference :test_key_id, :string
8
+ preference :test_key_secret, :string
9
+ preference :test_mode, :boolean, default: false
10
+ preference :merchant_name, :string, default: 'Razorpay'
11
+ preference :merchant_description, :text, default: 'Razorpay Payment Gateway'
12
+ preference :merchant_address, :string, default: 'Razorpay, Bangalore, India'
13
+ preference :theme_color, :string, default: '#F37254'
14
+
15
+ def supports?(_source)
16
+ true
17
+ end
18
+
19
+ def source_required?
20
+ false
21
+ end
22
+
23
+ def payment_source_class
24
+ nil
25
+ end
26
+
27
+ def payment_icon_name
28
+ 'razorpay'
29
+ end
30
+
31
+ def description_partial_name
32
+ 'razorpay'
33
+ end
34
+
35
+ def configuration_guide_partial_name
36
+ 'razorpay'
37
+ end
38
+
39
+ def provider_class
40
+ self
41
+ end
42
+
43
+ def provider
44
+ Razorpay.setup(current_key_id, current_key_secret)
45
+ end
46
+
47
+ def current_key_id
48
+ preferred_test_mode ? preferred_test_key_id : preferred_key_id
49
+ end
50
+
51
+ def current_key_secret
52
+ preferred_test_mode ? preferred_test_key_secret : preferred_key_secret
53
+ end
54
+
55
+ def auto_capture?
56
+ true
57
+ end
58
+
59
+ def method_type
60
+ 'razorpay'
61
+ end
62
+
63
+ def request_type
64
+ 'DEFAULT'
65
+ end
66
+
67
+ def actions
68
+ %w[capture void]
69
+ end
70
+
71
+ def can_capture?(payment)
72
+ %w[checkout pending].include?(payment.state)
73
+ end
74
+
75
+ def can_void?(payment)
76
+ payment.state != 'void'
77
+ end
78
+
79
+ def purchase(_amount, _transaction_details, _gateway_options = {})
80
+ ActiveMerchant::Billing::Response.new(true, 'Razorpay success')
81
+ end
82
+
83
+ def capture(*)
84
+ simulated_successful_billing_response
85
+ end
86
+
87
+ def void(*)
88
+ simulated_successful_billing_response
89
+ end
90
+
91
+ def credit(_credit_cents, _payment_id, _options)
92
+ ActiveMerchant::Billing::Response.new(true, 'Refund successful')
93
+ end
94
+
95
+ def verify_and_capture_razorpay_payment(order, razorpay_payment_id)
96
+ Razorpay.setup(current_key_id, current_key_secret)
97
+
98
+ begin
99
+ payment = Razorpay::Payment.fetch(razorpay_payment_id)
100
+
101
+ unless payment.status == 'authorized'
102
+ raise Spree::Core::GatewayError, 'Payment not authorized'
103
+ end
104
+
105
+ # Capture only if you're not using auto-capture (your setting says auto_capture = true)
106
+ payment.capture(amount: (order.total * 100).to_i)
107
+ payment
108
+
109
+ rescue Razorpay::Error => e
110
+ raise Spree::Core::GatewayError, "Razorpay error: #{e.message}"
111
+ end
112
+ end
113
+
114
+ private
115
+
116
+ def simulated_successful_billing_response
117
+ ActiveMerchant::Billing::Response.new(true, '', {}, {})
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,4 @@
1
+ module Spree
2
+ class RazorpayCheckout < ActiveRecord::Base
3
+ end
4
+ end
@@ -0,0 +1,13 @@
1
+ module SpreeRazorpayCheckout
2
+ class Configuration < ::Spree::Preferences::Configuration
3
+
4
+ # Some example preferences are shown below, for more information visit:
5
+ # https://dev-docs.spreecommerce.org/internals/preferences
6
+
7
+ preference :enabled, :boolean, default: true
8
+ # preference :dark_chocolate, :boolean, default: true
9
+ # preference :color, :string, default: 'Red'
10
+ # preference :favorite_number, :integer
11
+ # preference :supported_locales, :array, default: [:en]
12
+ end
13
+ end
@@ -0,0 +1,33 @@
1
+ module SpreeRazorpayCheckout
2
+ module Spree
3
+ module OrderDecorator
4
+ def inr_amt_in_paise
5
+ (total.to_f * 100).to_i
6
+ end
7
+
8
+ def razor_payment(payment_object, payment_method, razorpay_signature)
9
+ payments.create!(
10
+ source: ::Spree::RazorpayCheckout.create!(
11
+ order_id: id,
12
+ razorpay_payment_id: payment_object.id,
13
+ razorpay_order_id: payment_object.order_id,
14
+ razorpay_signature: razorpay_signature,
15
+ status: payment_object.status,
16
+ payment_method: payment_object.method,
17
+ card_id: payment_object.card_id,
18
+ bank: payment_object.bank,
19
+ wallet: payment_object.wallet,
20
+ vpa: payment_object.vpa,
21
+ email: payment_object.email,
22
+ contact: payment_object.contact
23
+ ),
24
+ payment_method: payment_method,
25
+ amount: total,
26
+ response_code: payment_object.status
27
+ )
28
+ end
29
+
30
+ ::Spree::Order.prepend SpreeRazorpayCheckout::Spree::OrderDecorator
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,36 @@
1
+ module SpreeRazorpayCheckout
2
+ module Spree
3
+ module RefundDecorator
4
+ def process!(credit_cents)
5
+ response = if payment.payment_method.payment_profiles_supported?
6
+ payment.payment_method.credit(
7
+ credit_cents,
8
+ payment.source,
9
+ payment.transaction_id,
10
+ originator: self
11
+ )
12
+ else
13
+ razorpay_payment_id = payment.source&.razorpay_payment_id || payment.transaction_id
14
+ payment.payment_method.credit(
15
+ credit_cents,
16
+ razorpay_payment_id,
17
+ originator: self
18
+ )
19
+ end
20
+
21
+ unless response.success?
22
+ Rails.logger.error(Spree.t(:gateway_error) + " #{response.to_yaml}")
23
+ text = response.params['message'] || response.params['response_reason_text'] || response.message
24
+ raise Core::GatewayError, text
25
+ end
26
+
27
+ response
28
+ rescue ActiveMerchant::ConnectionError => e
29
+ Rails.logger.error(Spree.t(:gateway_error) + " #{e.inspect}")
30
+ raise Core::GatewayError, Spree.t(:unable_to_connect_to_gateway)
31
+ end
32
+
33
+ ::Spree::Refund.prepend SpreeRazorpayCheckout::Spree::RefundDecorator
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ module Razorpay
2
+ class Base
3
+ def initialize
4
+ setup_razorpay
5
+ end
6
+
7
+ private
8
+
9
+ def find_payment_gateway
10
+ Spree::PaymentMethod.find_by(type: 'Spree::Gateway::RazorpayGateway')
11
+ end
12
+
13
+ def setup_razorpay
14
+ find_payment_gateway.provider
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,43 @@
1
+ module Razorpay
2
+ module RpOrder
3
+ class Api < Razorpay::Base
4
+ attr_reader :order
5
+
6
+ def create(order_id)
7
+ @order = Spree::Order.find_by(id: order_id)
8
+
9
+ razorpay_order = Razorpay::Order.create(order_create_params)
10
+
11
+ if razorpay_order.try(:id).present?
12
+ log_order_in_db(razorpay_order.id)
13
+ return razorpay_order.id
14
+ end
15
+
16
+ ''
17
+ rescue StandardError => e
18
+ Rails.logger.error("Razorpay Order create failed: #{e.message}")
19
+ ''
20
+ end
21
+
22
+ private
23
+
24
+ def order_create_params
25
+ {
26
+ amount: order.inr_amt_in_paise,
27
+ currency: order.currency,
28
+ receipt: order.number
29
+ }
30
+ end
31
+
32
+ def log_order_in_db(rzp_order_id)
33
+ Spree::RazorpayCheckout.create!(
34
+ order_id: order.id,
35
+ razorpay_order_id: rzp_order_id,
36
+ status: 'created'
37
+ )
38
+ rescue StandardError => e
39
+ Rails.logger.error("Failed to log Razorpay Order in DB: #{e.message}")
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,31 @@
1
+ require "uri"
2
+ require "json"
3
+ require "net/http"
4
+ require 'base64'
5
+
6
+ class RazorpayRefund
7
+ def perform(credit_cents, razorpay_payment_id)
8
+ url = URI("https://api.razorpay.com/v1/payments/#{razorpay_payment_id}/refund")
9
+
10
+ https = Net::HTTP.new(url.host, url.port)
11
+ https.use_ssl = true
12
+ https.verify_mode = OpenSSL::SSL::VERIFY_NONE
13
+ gateway = Spree::Gateway.find_by(type:"Spree::Gateway::RazorpayGateway")
14
+ key_id = gateway.preferred_key_id
15
+ key_secret = gateway.preferred_key_secret
16
+ encoded_key = Base64.strict_encode64("#{key_id}:#{key_secret}")
17
+ authorization_header = "Basic #{encoded_key}"
18
+
19
+ request = Net::HTTP::Post.new(url)
20
+ request["Content-Type"] = "application/json"
21
+ request["Authorization"] = authorization_header
22
+ request.body = JSON.dump({
23
+ "amount": credit_cents,
24
+ "speed": "optimum"
25
+ })
26
+
27
+ response = https.request(request)
28
+ response
29
+ end
30
+ end
31
+
@@ -0,0 +1,6 @@
1
+ <div class="alert alert-info">
2
+ <p class="mb-0">
3
+ To find your <strong>Key</strong> and <strong>Key Secret</strong>, go to the
4
+ <%= external_link_to 'Razorpay dashboard', 'https://dashboard.razorpay.com/app/website-app-settings/api-keys', class: 'alert-link' %>
5
+ </p>
6
+ </div>
@@ -0,0 +1,15 @@
1
+ <p class="mb-1">
2
+ Razorpay is the only payments solution in India that allows businesses to accept, process and disburse payments with its product suite.
3
+ </p>
4
+
5
+ <div class="d-flex align-items-center">
6
+ <%= payment_method_icon_tag 'visa', class: 'm-1' %>
7
+ <%= payment_method_icon_tag 'master', class: 'm-1' %>
8
+ <%= payment_method_icon_tag 'google_pay', class: 'm-1' %>
9
+ <%= payment_method_icon_tag 'amazon', class: 'm-1' %>
10
+ <%= payment_method_icon_tag 'mobikwik', class: 'm-1' %>
11
+ <%= payment_method_icon_tag 'upi', class: 'm-1' %>
12
+ <%= payment_method_icon_tag 'rupay', class: 'm-1' %>
13
+ <%= payment_method_icon_tag 'paytm', class: 'm-1' %>
14
+ <%= payment_method_icon_tag 'payzapp', class: 'm-1' %>
15
+ </div>
@@ -0,0 +1,190 @@
1
+ <script>
2
+ document.addEventListener("turbo:load", setupRazorpay);
3
+ document.addEventListener("turbo:frame-load", function (e) {
4
+ if (e.target.id === "checkout_payment_methods") setupRazorpay();
5
+ });
6
+
7
+ function setupRazorpay() {
8
+ const razorpayMethodId = "<%= payment_method.id %>";
9
+ const form = document.querySelector("#checkout_form_payment");
10
+ const payBtn = document.getElementById("checkout-payment-submit");
11
+ const razorpayBtn = document.getElementById("razorpay-custom-button");
12
+
13
+ if (!form || !payBtn || !razorpayBtn) return;
14
+
15
+ let razorpayCompleted = false;
16
+
17
+ function getSelectedPaymentMethodId() {
18
+ const selected = document.querySelector('input[name="order[payments_attributes][][payment_method_id]"]:checked');
19
+ const fallback = document.querySelector('input[type="hidden"][name="order[payments_attributes][][payment_method_id]"]');
20
+ return selected?.value || fallback?.value;
21
+ }
22
+
23
+ function toggleButtons() {
24
+ const selectedId = getSelectedPaymentMethodId();
25
+ const isRazorpay = selectedId === razorpayMethodId;
26
+
27
+ if (isRazorpay) {
28
+ payBtn.classList.add("hidden");
29
+ razorpayBtn.classList.remove("hidden");
30
+ } else {
31
+ razorpayBtn.classList.add("hidden");
32
+ payBtn.classList.remove("hidden");
33
+ }
34
+ }
35
+
36
+ toggleButtons();
37
+
38
+ document.querySelectorAll('input[name="order[payments_attributes][][payment_method_id]"]').forEach((radio) => {
39
+ radio.addEventListener("change", toggleButtons);
40
+ });
41
+
42
+ form.addEventListener("submit", function (e) {
43
+ const selectedId = getSelectedPaymentMethodId();
44
+ if (selectedId === razorpayMethodId && !razorpayCompleted) {
45
+ e.preventDefault();
46
+ alert("Please complete the Razorpay payment first.");
47
+ }
48
+ });
49
+
50
+ razorpayBtn.addEventListener("click", function () {
51
+ fetch("/razorpay/create_order", {
52
+ method: "POST",
53
+ headers: {
54
+ "Content-Type": "application/json",
55
+ "X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content
56
+ },
57
+ body: JSON.stringify({ order_id: "<%= @order.id %>" })
58
+ })
59
+ .then(response => response.json())
60
+ .then(data => {
61
+ if (!data.success) {
62
+ alert("Failed to initiate Razorpay payment. Please try again.");
63
+ return;
64
+ }
65
+
66
+ const options = {
67
+ key: "<%= payment_method.current_key_id %>",
68
+ order_id: data.razorpay_order_id,
69
+ amount: data.amount,
70
+ currency: "INR",
71
+ name: "<%= payment_method.preferred_merchant_name.presence || 'Razorpay Store' %>",
72
+ description: "<%= payment_method.preferred_merchant_description.presence || 'Order Payment' %>",
73
+ handler: function (response) {
74
+ razorpayCompleted = true;
75
+ document.getElementById("razorpay_payment_id").value = response.razorpay_payment_id;
76
+ document.getElementById("razorpay_order_id").value = response.razorpay_order_id;
77
+ document.getElementById("razorpay_signature").value = response.razorpay_signature;
78
+ form.requestSubmit();
79
+ },
80
+ modal: {
81
+ ondismiss: function () {
82
+ razorpayCompleted = false;
83
+ }
84
+ },
85
+ prefill: {
86
+ name: "<%= @order.bill_address&.firstname %> <%= @order.bill_address&.lastname %>",
87
+ email: "<%= @order.email %>",
88
+ contact: "<%= @order.bill_address&.phone %>"
89
+ },
90
+ theme: {
91
+ color: "<%= payment_method.preferred_theme_color.presence || '#3399cc' %>"
92
+ }
93
+ };
94
+ delete options.session;
95
+
96
+ const rzp = new Razorpay(options);
97
+ rzp.open();
98
+ })
99
+ .catch(() => {
100
+ alert("Error creating Razorpay order. Please refresh and try again.");
101
+ });
102
+ });
103
+ }
104
+ </script>
105
+
106
+ <style>
107
+ #razorpay-custom-button {
108
+ background: black !important;
109
+ color: #bababa !important;
110
+ border: none !important;
111
+ padding: 12px !important;
112
+ font-size: 0.8rem !important;
113
+ font-style: italic !important;
114
+ font-weight: 300 !important;
115
+ border-radius: 100px !important;
116
+ cursor: pointer !important;
117
+ width: 100% !important;
118
+ margin: 15px 0 !important;
119
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4) !important;
120
+ }
121
+ #razorpay-custom-button:active {
122
+ background: linear-gradient(104deg, rgb(19, 100, 241), rgb(0, 17, 173) 30%) !important;
123
+ }
124
+ </style>
125
+
126
+ <script src="https://checkout.razorpay.com/v1/checkout.js"></script>
127
+ <div style="display: flex; justify-content: center;">
128
+ <svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 232.55 132.88" width="160" height="160">
129
+ <defs>
130
+ <style>
131
+ .cls-1 {
132
+ stroke-miterlimit: 10;
133
+ }
134
+
135
+ .cls-1, .cls-2 {
136
+ fill: none;
137
+ stroke: #bababa;
138
+ stroke-linecap: round;
139
+ stroke-width: 3px;
140
+ }
141
+
142
+ .cls-3 {
143
+ fill: #bababa;
144
+ }
145
+
146
+ .cls-2 {
147
+ stroke-linejoin: round;
148
+ }
149
+ </style>
150
+ </defs>
151
+ <g id="Layer_1-2" data-name="Layer 1">
152
+ <polyline class="cls-1" points="1.5 18.16 203.71 18.16 203.71 65.59"/>
153
+ <polyline class="cls-2" points="171.76 72.65 231.05 72.65 225.69 65.59 231.05 72.65 225.69 79.71"/>
154
+ <circle class="cls-3" cx="9.57" cy="10.07" r="2.95"/>
155
+ <circle class="cls-3" cx="18.79" cy="10.07" r="2.95"/>
156
+ <circle class="cls-3" cx="27.84" cy="10.07" r="2.95"/>
157
+ <path class="cls-1" d="m203.71,18.16V4.81c0-1.83-1.48-3.31-3.31-3.31H4.81c-1.83,0-3.31,1.48-3.31,3.31v123.27c0,1.83,1.48,3.31,3.31,3.31h195.59c1.83,0,3.31-1.48,3.31-3.31v-48.36"/>
158
+ </g>
159
+ </svg>
160
+ </div>
161
+ <p style="max-width: 600px; margin: 10px auto; text-align: center;">
162
+ After clicking “Complete order”, you will be redirected to <br>
163
+ Razorpay Secure (UPI, Cards, Wallets, NetBanking) to complete <br>
164
+ your purchase securely.
165
+ </p>
166
+
167
+ <!-- Hidden Razorpay input field -->
168
+ <input type="hidden" name="payment_source[<%= payment_method.id %>][razorpay_payment_id]" id="razorpay_payment_id" value="">
169
+ <input type="hidden" name="payment_source[<%= payment_method.id %>][razorpay_order_id]" id="razorpay_order_id" value="">
170
+ <input type="hidden" name="payment_source[<%= payment_method.id %>][razorpay_signature]" id="razorpay_signature" value="">
171
+
172
+ <!-- Custom Razorpay Button -->
173
+ <button id="razorpay-custom-button" type="button">
174
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="500 0 400 400" width="160" height="25" style="vertical-align: bottom; margin-right: 50%; margin-left: 40%; justify-self: center !important;">
175
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
176
+ <g id="Group">
177
+ <path d="M451.9209,151.4937 C448.9309,162.6497 443.1359,170.8377 434.5349,176.0657 C425.9239,181.2927 413.8469,183.9117 398.2689,183.9117 L348.7769,183.9117 L366.1509,119.0807 L415.6429,119.0807 C431.2089,119.0807 441.8959,121.6947 447.7019,126.9217 C453.4969,132.1547 454.9109,140.3437 451.9209,151.4937 M503.1739,150.0967 C509.4679,126.6377 506.8589,108.6267 495.3509,96.0797 C483.8409,83.5327 463.6739,77.2627 434.8709,77.2627 L324.3909,77.2627 L257.8969,325.4027 L311.5719,325.4027 L338.3809,225.3777 L373.5809,225.3777 C381.4739,225.3777 387.6869,226.6577 392.2309,229.2137 C396.7849,231.7747 399.4509,236.3067 400.2739,242.8037 L409.8479,325.4027 L467.3589,325.4027 L458.0289,248.3847 C456.1279,231.1897 448.2589,221.0827 434.4309,218.0637 C452.0599,212.9577 466.8259,204.4677 478.7179,192.6167 C490.5989,180.7717 498.7579,166.6017 503.1739,150.0967" id="Fill-1" fill="#fff"></path>
178
+ <path d="M633.625,236.533 C629.14,253.258 622.231,266.042 612.901,274.868 C603.56,283.7 592.386,288.111 579.382,288.111 C566.122,288.111 557.128,283.758 552.387,275.042 C547.623,266.332 547.461,253.733 551.889,237.228 C556.305,220.735 563.352,207.841 573.053,198.539 C582.742,189.255 594.09,184.602 607.105,184.602 C620.11,184.602 628.919,189.082 633.485,198.024 C638.053,206.966 638.11,219.802 633.625,236.533 L633.625,236.533 Z M657.153,148.706 L650.431,173.8 C647.521,164.736 641.9,157.538 633.578,152.195 C625.245,146.852 614.918,144.174 602.608,144.174 C587.506,144.174 572.983,148.069 559.052,155.852 C545.12,163.64 532.938,174.617 522.519,188.786 C512.099,202.961 504.461,219.107 499.604,237.228 C494.748,255.356 493.774,271.328 496.695,285.149 C499.616,298.977 505.944,309.605 515.691,317.04 C525.428,324.481 537.969,328.19 553.303,328.19 C565.612,328.19 577.342,325.635 588.469,320.523 C599.595,315.418 609.041,308.325 616.818,299.266 L609.807,325.403 L661.731,325.403 L709.079,148.706 L657.153,148.706 Z" id="Fill-3" fill="#fff"></path>
179
+ <polygon id="Fill-5" fill="#fff" points="895.79 148.7061 744.882 148.7061 734.334 188.0911 822.155 188.0911 706.042 288.4581 696.132 325.4031 851.92 325.4031 862.478 286.0241 768.388 286.0241 886.263 184.2541"></polygon>
180
+ <path d="M1028.6514,236.1853 C1023.9804,253.6053 1017.0604,266.6273 1007.9044,275.2223 C998.7484,283.8163 987.6674,288.1103 974.6634,288.1103 C947.4714,288.1103 938.5234,270.8113 947.7964,236.1853 C952.4094,218.9903 959.3634,206.0383 968.6594,197.3283 C977.9654,188.6123 989.2324,184.2543 1002.4804,184.2543 C1015.4844,184.2543 1024.2584,188.6123 1028.7794,197.3283 C1033.2984,206.0383 1033.2644,218.9903 1028.6514,236.1853 M1059.0304,155.3243 C1047.0804,147.8943 1031.8154,144.1743 1013.2244,144.1743 C994.4014,144.1743 976.9694,147.8943 960.9174,155.3243 C944.8644,162.7653 931.1984,173.4523 919.9214,187.3893 C908.6314,201.3323 900.4954,217.5943 895.5114,236.1853 C890.5274,254.7763 889.9484,271.0323 893.7734,284.9753 C897.5864,298.9183 905.5144,309.6053 917.5914,317.0403 C929.6574,324.4813 945.0954,328.1903 963.9194,328.1903 C982.5094,328.1903 999.7674,324.4813 1015.7054,317.0403 C1031.6184,309.6053 1045.2374,298.9183 1056.5264,284.9753 C1067.8034,271.0323 1075.9404,254.7763 1080.9244,236.1853 C1085.9084,217.5943 1086.4884,201.3323 1082.6744,187.3893 C1078.8494,173.4523 1070.9674,162.7653 1059.0304,155.3243" id="Fill-7" fill="#fff"></path>
181
+ <path d="M1602.1367,236.533 C1597.6517,253.258 1590.7427,266.042 1581.4127,274.868 C1572.0817,283.7 1560.8857,288.111 1547.8817,288.111 C1534.6457,288.111 1525.6397,283.758 1520.8987,275.042 C1516.1347,266.332 1515.9727,253.733 1520.4007,237.228 C1524.8167,220.735 1531.8637,207.841 1541.5647,198.539 C1551.2537,189.255 1562.6017,184.602 1575.6167,184.602 C1588.6217,184.602 1597.4307,189.082 1601.9967,198.024 C1606.5647,206.966 1606.6217,219.802 1602.1367,236.533 L1602.1367,236.533 Z M1625.6647,148.706 L1618.9427,173.8 C1616.0327,164.736 1610.4117,157.538 1602.0897,152.195 C1593.7567,146.852 1583.4297,144.174 1571.1197,144.174 C1556.0177,144.174 1541.4947,148.069 1527.5637,155.852 C1513.6317,163.64 1501.4497,174.617 1491.0307,188.786 C1480.6107,202.961 1472.9717,219.107 1468.1157,237.228 C1463.2597,255.356 1462.2967,271.328 1465.2067,285.149 C1468.1267,298.977 1474.4447,309.605 1484.2027,317.04 C1493.9397,324.481 1506.4807,328.19 1521.8147,328.19 C1534.1227,328.19 1545.8537,325.635 1556.9797,320.523 C1568.1067,315.418 1577.5527,308.325 1585.3297,299.266 L1578.3187,325.403 L1630.2427,325.403 L1677.5907,148.706 L1625.6647,148.706 Z" id="Fill-9" fill="#fff"></path>
182
+ <path d="M1244.165,196.1055 L1257.401,148.0105 C1252.904,145.6865 1246.946,144.5225 1239.517,144.5225 C1227.66,144.5225 1216.243,147.4835 1205.244,153.4115 C1195.798,158.4975 1187.754,165.6365 1180.962,174.5815 L1187.847,148.6815 L1172.813,148.7065 L1135.938,148.7065 L1088.227,325.4025 L1140.87,325.4025 L1165.616,233.0505 C1169.221,219.5765 1175.688,209.0635 1185.042,201.5125 C1194.372,193.9615 1206.02,190.1825 1219.964,190.1825 C1228.563,190.1825 1236.619,192.1585 1244.165,196.1055" id="Fill-11" fill="#fff"></path>
183
+ <path d="M1390.6973,237.2256 C1386.2693,253.7306 1379.4083,266.3296 1370.1123,275.0396 C1360.7943,283.7556 1349.6433,288.1076 1336.6393,288.1076 C1323.6233,288.1076 1314.7573,283.6976 1310.0393,274.8656 C1305.3103,266.0396 1305.1943,253.2606 1309.6793,236.5296 C1314.1653,219.7996 1321.1423,206.9626 1330.6243,198.0206 C1340.1043,189.0786 1351.3593,184.5986 1364.3753,184.5986 C1377.1473,184.5986 1385.8293,189.2526 1390.4303,198.5426 C1395.0203,207.8376 1395.1133,220.7376 1390.6973,237.2256 M1427.4853,155.8486 C1417.7153,148.0656 1405.2783,144.1776 1390.1873,144.1776 C1376.9393,144.1776 1364.3293,147.1966 1352.3903,153.2356 C1340.4183,159.2856 1330.7173,167.5206 1323.2753,177.9806 L1323.4433,176.8216 L1332.2873,148.6786 L1322.1103,148.6786 L1322.1103,148.7036 L1280.9003,148.7036 L1267.8153,197.5656 C1267.6643,198.1336 1267.5373,198.6636 1267.3853,199.2376 L1213.4093,400.6806 L1266.0423,400.6806 L1293.2213,299.2696 C1295.8863,308.3216 1301.4273,315.4146 1309.8193,320.5206 C1318.2103,325.6316 1328.5603,328.1876 1340.8813,328.1876 C1356.2163,328.1876 1370.7963,324.4786 1384.6463,317.0376 C1398.4863,309.6076 1410.5163,298.9736 1420.7173,285.1466 C1430.9273,271.3306 1438.4623,255.3526 1443.3183,237.2256 C1448.1753,219.1036 1449.1823,202.9586 1446.3663,188.7836 C1443.5503,174.6136 1437.2443,163.6376 1427.4853,155.8486" id="Fill-13" fill="#fff"></path>
184
+ <path d="M1895.5381,148.7554 L1895.5721,148.7064 L1863.6921,148.7064 C1862.6731,148.7064 1861.7741,148.7354 1860.8421,148.7554 L1844.2961,148.7554 L1835.8351,160.5434 C1835.1571,161.4314 1834.4791,162.3254 1833.7491,163.3624 L1832.8271,164.7274 L1765.5851,258.3754 L1751.6421,148.7064 L1696.5641,148.7064 L1724.4561,315.3544 L1662.8591,400.6834 L1664.6151,400.6834 L1696.0651,400.6834 L1717.7341,400.6834 L1732.6621,379.5374 C1733.1021,378.9074 1733.4791,378.3914 1733.9491,377.7254 L1751.3691,353.0284 L1751.8681,352.3214 L1829.8131,241.8274 L1895.4851,148.8284 L1895.5721,148.7554 L1895.5381,148.7554 Z" id="Fill-15" fill="#fff"></path>
185
+ <polygon id="Fill-17" fill="#3395FF" points="122.6338 105.6902 106.8778 163.6732 197.0338 105.3642 138.0748 325.3482 197.9478 325.4032 285.0458 0.4822"></polygon>
186
+ <path d="M25.5947,232.9246 L0.8077,325.4026 L123.5337,325.4026 C123.5337,325.4026 173.7317,137.3196 173.7457,137.2656 C173.6987,137.2956 25.5947,232.9246 25.5947,232.9246" id="Fill-19" fill="#fff"></path>
187
+ </g>
188
+ </g>
189
+ </svg>
190
+ </button>
@@ -0,0 +1,4 @@
1
+ # Logo Location
2
+ Rails.application.config.assets.precompile += %w[
3
+ payment_icons/razorpay.svg
4
+ ]
@@ -0,0 +1,13 @@
1
+ en:
2
+ spree:
3
+ preferences:
4
+ razorpay_gateway:
5
+ key_id: "Key"
6
+ key_secret: "Key Secret"
7
+ test_key_id: "Test Key"
8
+ test_key_secret: "Test Key Secret"
9
+ test_mode: "Enable Test Mode"
10
+ merchant_name: "Merchant Name"
11
+ merchant_description: "Merchant Description"
12
+ merchant_address: "Merchant Address"
13
+ theme_color: "Theme"
data/config/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ Spree::Core::Engine.add_routes do
2
+ # Add your extension routes here
3
+ post '/razorpay/create_order', to: 'razorpay#create_order'
4
+ post '/razorpay/response', to: 'razorpay#razor_response', as: :razorpay_response
5
+ end
@@ -0,0 +1,20 @@
1
+ class CreateSpreeRazorpayCheckouts < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table :spree_razorpay_checkouts do |t|
4
+ t.string :order_id
5
+ t.string :razorpay_payment_id
6
+ t.string :razorpay_order_id
7
+ t.string :razorpay_signature
8
+ t.string :status
9
+ t.string :payment_method
10
+ t.string :card_id
11
+ t.string :bank
12
+ t.string :wallet
13
+ t.string :vpa
14
+ t.string :email
15
+ t.string :contact
16
+
17
+ t.timestamps
18
+ end
19
+ end
20
+ end
@@ -5,8 +5,8 @@ module SpreeRazorpayCheckout
5
5
  class_option :migrate, type: :boolean, default: true
6
6
 
7
7
  def add_javascripts
8
- append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/spree_razorpay\n"
9
- append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/process_razorpay\n"
8
+ #append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/spree_razorpay_checkout\n"
9
+ #append_file 'vendor/assets/javascripts/spree/frontend/all.js', "//= require spree/frontend/process_razorpay\n"
10
10
  end
11
11
 
12
12
  def add_migrations
@@ -0,0 +1,10 @@
1
+ module SpreeRazorpayCheckout
2
+ class Configuration
3
+ # Define settings here as needed, e.g.:
4
+ attr_accessor :some_setting
5
+
6
+ def initialize
7
+ @some_setting = 'default_value'
8
+ end
9
+ end
10
+ end
@@ -1,9 +1,12 @@
1
+
1
2
  module SpreeRazorpayCheckout
2
3
  class Engine < Rails::Engine
3
4
  require 'spree/core'
4
5
  isolate_namespace Spree
5
6
  engine_name 'spree_razorpay_checkout'
6
7
 
8
+ require 'spree_razorpay_checkout/configuration'
9
+
7
10
  # use rspec for tests
8
11
  config.generators do |g|
9
12
  g.test_framework :rspec
@@ -2,5 +2,5 @@ FactoryBot.define do
2
2
  # Define your Spree extensions Factories within this file to enable applications, and other extensions to use and override them.
3
3
  #
4
4
  # Example adding this to your spec_helper will load these Factories for use:
5
- # require 'spree_razorpay/factories'
5
+ # require 'spree_razorpay_checkout/factories'
6
6
  end
@@ -1,5 +1,5 @@
1
1
  module SpreeRazorpayCheckout
2
- VERSION = '0.0.5'.freeze
2
+ VERSION = '0.1.0'.freeze
3
3
 
4
4
  module_function
5
5
 
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_razorpay_checkout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Umesh Ravani
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-08-06 00:00:00.000000000 Z
11
+ date: 2025-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: razorpay
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '3.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '3.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: spree
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 5.0.0
33
+ version: '5.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 5.0.0
40
+ version: '5.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: spree_backend
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -94,7 +94,7 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
- description: Seamless Razorpay checkout integration for Spree Commerce 5.x stores
97
+ description: Seamless Razorpay checkout integration for Spree Commerce 5.x stores.
98
98
  email:
99
99
  - umeshravani98@gmail.com
100
100
  executables: []
@@ -102,8 +102,29 @@ extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
104
  - README.md
105
+ - app/assets/images/payment_icons/razorpay.svg
106
+ - app/assets/javascripts/spree/frontend/process_razorpay.js
107
+ - app/assets/javascripts/spree/frontend/spree_razorpay.js
108
+ - app/controllers/concerns/spree/razor_pay.rb
109
+ - app/controllers/spree/razorpay_controller.rb
110
+ - app/models/spree/gateway/razorpay_gateway.rb
111
+ - app/models/spree/razorpay_checkout.rb
112
+ - app/models/spree_razorpay_checkout/configuration.rb
113
+ - app/models/spree_razorpay_checkout/spree/order_decorator.rb
114
+ - app/models/spree_razorpay_checkout/spree/refund_decorator.rb
115
+ - app/services/razorpay/base.rb
116
+ - app/services/razorpay/rp_order/api.rb
117
+ - app/services/razorpay_refund.rb
118
+ - app/views/spree/admin/payment_methods/configuration_guides/_razorpay.html.erb
119
+ - app/views/spree/admin/payment_methods/descriptions/_razorpay.html.erb
120
+ - app/views/spree/checkout/payment/_razorpay.html.erb
121
+ - config/initializers/assets.rb
122
+ - config/locales/en.yml
123
+ - config/routes.rb
124
+ - db/migrate/20220816080140_create_spree_razorpay_checkouts.rb
105
125
  - lib/generators/spree_razorpay_checkout/install/install_generator.rb
106
126
  - lib/spree_razorpay_checkout.rb
127
+ - lib/spree_razorpay_checkout/configuration.rb
107
128
  - lib/spree_razorpay_checkout/engine.rb
108
129
  - lib/spree_razorpay_checkout/factories.rb
109
130
  - lib/spree_razorpay_checkout/version.rb
@@ -111,7 +132,6 @@ homepage: https://github.com/umeshravani/spree_razorpay
111
132
  licenses:
112
133
  - BSD-3-Clause
113
134
  metadata:
114
- homepage_uri: https://github.com/umeshravani/spree_razorpay
115
135
  source_code_uri: https://github.com/umeshravani/spree_razorpay
116
136
  changelog_uri: https://github.com/umeshravani/spree_razorpay/blob/main/CHANGELOG.md
117
137
  post_install_message: