Each payment processor requires implementation of several things:
- Billable
- PaymentMethods
- Charge
- Subscription
- Webhooks
Pay instantiates Payment Processor classes to implement the API requests to the payment processor.
For example, a Pay::Charge.refund! will look up the payment processor (Stripe, for example) and instantiate Pay::Stripe::Charge with the Pay::Charge record. It will then call refund! allowing Pay::Stripe::Charge to handle the refund API request.
Each payment processor needs to implement the same classes in order to fulfill the hooks for making API requests.
We recommend copying FakeProcessor as the basis for your new payment processor and replacing each method with the appropriate API requests.
Each payment processer can define it's own controller for processing any required webhooks.
For example, stripe has app/controllers/pay/webhooks/stripe_controller.rb
See also config/routes.rb for defining routes.
The webhook controller is responsible for verifying the webhook payload for authenticity and then sending to the Pay Webhook Delegator
The Webhook Delegator is responsible for taking an event type and sending it for processing.
It uses ActiveSupport::Notifications to subscribe and instrument events.
Pay::Webhooks.configure do |events|
events.subscribe "stripe.charge.succeeded", Pay::Stripe::Webhooks::ChargeSucceeded.new
end
module Pay
module Stripe
module Webhooks
class ChargeSucceeded
def call(event)
# processing goes here
end
end
end
end
endFor example, when a stripe.charge.succeeded event gets processed, the webhook delegator sends the event to any classes that are subscribed to the event type.
Internally, these events are automatically prefaced with the pay namespace so they don't conflict with other events. stripe.charge.succeeded is internally routed as pay.stripe.charge.succeeded. Payment processors should not preface with pay. as it is automatically added.