Skip to content

Instantly share code, notes, and snippets.

@clemens
Created June 11, 2014 13:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save clemens/819ca167580f734b9e26 to your computer and use it in GitHub Desktop.
Save clemens/819ca167580f734b9e26 to your computer and use it in GitHub Desktop.
if Rails.env.test?
# inspired by Braintree's original WebhookTestingGateway, but with way more flexibility and complete data
class BraintreeWebhookTestingGateway
class << self
def register_notification(identifier, kind = nil, &builder)
@notifications ||= {}
kind ||= identifier
@notifications[identifier] = [kind, builder]
end
def get_notification(identifier)
raise ArgumentError.new("Notification '#{identifier}' is not registered. Register it using #register_notification.") unless @notifications[identifier]
@notifications[identifier]
end
end
def initialize(gateway)
@gateway = gateway
@config = gateway.config
end
def register_notification(identifier, kind, &builder)
self.class.register_notification(identifier, kind, &builder)
end
def sample_notification(identifier, data)
payload = Base64.encode64(_sample_xml(identifier, data))
signature_string = "#{Braintree::Configuration.public_key}|#{Braintree::Digest.hexdigest(Braintree::Configuration.private_key, payload)}"
return signature_string, payload
end
def _sample_xml(identifier, data)
kind, builder = self.class.get_notification(identifier)
<<-XML
<notification>
<timestamp type="datetime">#{Time.now.utc.iso8601}</timestamp>
<kind>#{kind}</kind>
<subject>
#{builder.call(data)}
</subject>
</notification>
XML
end
end
module Braintree
Gateway.class_eval do
def webhook_testing
@webhook_testing_gateway ||= BraintreeWebhookTestingGateway.new(self)
end
end
WebhookTesting.instance_eval do
def register_notification(identifier, kind = nil, &builder)
Configuration.gateway.webhook_testing.register_notification(identifier, kind, &builder)
end
end
end
Braintree::WebhookTesting.register_notification(:subscription_charged_successfully) do |data|
<<-XML
<subscription>
<id>#{data[:subscription_id]}</id>
<transactions type="array">
<transaction>
<id>#{data[:transaction_id]}</id>
<created_at type="datetime">#{(data[:transaction_created_at] || Time.now).utc.iso8601}</created_at>
<amount>#{data[:transaction_amount]}</amount>
<customer>
<id>#{data[:customer_id]}</id>
</customer>
<discounts type="array">
#{%(<discount><id>#{Discount.braintree_coupon_discount_id}</id><amount>#{data[:discount_amount]}</amount></discount>) if data[:discount_amount]}
</discounts>
<subscription>
<billing_period_start_date type="date">#{(data[:subscription_billing_period_start_date] || Date.current).iso8601}</billing_period_start_date>
<billing_period_end_date type="date">#{(data[:subscription_billing_period_end_date] || 1.month.from_now.to_date).iso8601}</billing_period_end_date>
</subscription>
</transaction>
</transactions>
<add_ons type="array"></add_ons>
<discounts type="array"></discounts>
</subscription>
XML
end
Braintree::WebhookTesting.register_notification(:subscription_charged_unsuccessfully) do |data|
<<-XML
<subscription>
<id>#{data[:subscription_id]}</id>
<failure_count>#{data[:failure_count]}</failure_count>
<transactions type="array">
<transaction>
<id>#{data[:transaction_id]}</id>
<status>#{data[:transaction_status] || 'failed'}</status>
<customer>
<id>#{data[:customer_id]}</id>
</customer>
</transaction>
</transactions>
<add_ons type="array"></add_ons>
<discounts type="array"></discounts>
</subscription>
XML
end
Braintree::WebhookTesting.register_notification(:subscription_canceled) do |data|
<<-XML
<subscription>
<id>#{data[:subscription_id]}</id>
<transactions type="array">
<transaction>
<id>#{data[:transaction_id]}</id>
<status>#{data[:transaction_status] || 'failed'}</status>
<customer>
<id>#{data[:customer_id]}</id>
</customer>
</transaction>
</transactions>
<add_ons type="array"></add_ons>
<discounts type="array"></discounts>
</subscription>
XML
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment