Class: Spree::Razorpay::WebhooksController

Inherits:
ActionController::API
  • Object
show all
Defined in:
app/controllers/spree/razorpay/webhooks_controller.rb

Instance Method Summary collapse

Instance Method Details

#createObject

Handles asynchronous background webhooks directly from Razorpay’s servers



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
# File 'app/controllers/spree/razorpay/webhooks_controller.rb', line 7

def create
  payload = request.body.read
  signature = request.headers['X-Razorpay-Signature']
  
  gateway = Spree::Gateway::RazorpayGateway.active.first
  return head :not_found unless gateway && gateway.preferred_webhook_secret.present?

  begin
    ::Razorpay::Utility.verify_webhook_signature(
      payload, 
      signature, 
      gateway.preferred_webhook_secret
    )
  rescue ::Razorpay::Errors::SignatureVerificationError => e
    Rails.logger.error("Razorpay Webhook Verification Failed: #{e.message}")
    return head :unauthorized
  end

  event = JSON.parse(payload)

  # Listen for 'payment.authorized' which fires immediately after OTP!
  if ['order.paid', 'payment.captured', 'payment.authorized'].include?(event['event'])
    ::SpreeRazorpayCheckout::HandleWebhookEventJob.perform_later(event)
  end

  head :ok
end

#verifyObject

Handles synchronous frontend verification from Next.js Storefront



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
66
67
68
# File 'app/controllers/spree/razorpay/webhooks_controller.rb', line 36

def verify
  razorpay_order_id = params[:razorpay_order_id]
  razorpay_payment_id = params[:razorpay_payment_id]
  razorpay_signature = params[:razorpay_signature]

  session = Spree::PaymentSession.find_by(external_id: razorpay_order_id)
  return head :not_found unless session
  
  # Initialize the Razorpay gem with your active API keys
  gateway = Spree::Gateway::RazorpayGateway.active.first
  return render json: { success: false, error: 'Gateway not configured' }, status: :internal_server_error unless gateway
  gateway.provider 

  begin
    # 1. Verify the signature securely on the server
    ::Razorpay::Utility.verify_payment_signature(
      razorpay_order_id: razorpay_order_id,
      razorpay_payment_id: razorpay_payment_id,
      razorpay_signature: razorpay_signature
    )
    
    # 2. Inject the signatures into the session's external_data
    session.external_data ||= {}
    session.external_data['razorpay_payment_id'] = razorpay_payment_id
    session.external_data['razorpay_signature'] = razorpay_signature
    session.save!

    render json: { success: true }
  rescue ::Razorpay::Errors::SignatureVerificationError => e
    Rails.logger.error("Razorpay Frontend Verification Failed: #{e.message}")
    render json: { success: false, error: e.message }, status: :unprocessable_entity
  end
end