diff --git a/README.md b/README.md index cce6f33..0c0961e 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ You can also use a card token rather than a card hash ##### Delete a card given a customer and a token This method will raise an exception if attempting to remove the user's primary card - + customer_token = 'customer_token' card_token = 'card_token' Pin::Customer.delete_card(customer_token, card_token) @@ -258,6 +258,38 @@ A bank account token can only be used once to create a recipient. The token auto `Pin::BankAccounts.create(options) ` +## Webhook Endpoints +The Webhook Endpoints API allows you to create and view your webhook endpoints to enable your website to receive push notifications of events that occur on your Pin Payments account. + +##### Create a new webhook endpoint and returns its details. +`options = { url: "http://example.com/webhooks/" }` + +`Pin::WebhookEndpoints.create(options)` + +##### Get a paginated list of all webhook endpoints. +`Pin::WebhookEndpoints.all` + +##### Get the details of a webhook endpoint. +`Pin::WebhookEndpoints.find(token)` + +##### Delete a webhook endpoint and all of its webhook requests. You will not be able to recover them. +`token = "whe_foobar"` +`Pin::WebhookEndpoints.delete(token)` + +## Webhooks +The webhooks API allows you to view and replay webhooks—requests that have been sent to your webhook endpoints. When an event occurs, Pin Payments creates a webhook record and sends a web request to each of your endpoints. + +Replaying a webhook causes Pin Payments to request the URL again. It will not repeat other webhook requests for the same event. Replaying a webhook will reset the error information recorded during the original request and record any new errors that occur during the replay. + +##### Get a paginated list of all webhooks. +`Pin::Webhooks.all` + +##### Get the details of a webhook. +`Pin::Webhooks.find(token)` + +##### Replay a webhook. +`Pin::Webhooks.replay(token)` + ## Receipts Receipts have been extracted out into their [own gem](https://github.com/dNitza/pin_up_receipts) diff --git a/lib/pin_up.rb b/lib/pin_up.rb index 39ffbd4..58f5882 100644 --- a/lib/pin_up.rb +++ b/lib/pin_up.rb @@ -12,6 +12,7 @@ require 'pin_up/recipient' require 'pin_up/refund' require 'pin_up/transfer' +require 'pin_up/webhooks' require 'pin_up/webhook_endpoints' require 'pin_up/pin_errors' diff --git a/lib/pin_up/pin_errors.rb b/lib/pin_up/pin_errors.rb index a1d6370..0a9d424 100644 --- a/lib/pin_up/pin_errors.rb +++ b/lib/pin_up/pin_errors.rb @@ -18,6 +18,8 @@ def self.handle_error(http_status, response) case response['error'] when 'cannot_delete_primary_card' raise Pin::InvalidResource.new(response, response['error_description']) + when 'cannot_replay_webhook' + raise Pin::CannotReplayWebhook.new(response, response['error_description']) else raise Pin::ChargeError.new(response) end @@ -75,6 +77,9 @@ class ResourceNotFound < SimpleError class InvalidResource < SimpleError end + class CannotReplayWebhook < SimpleError + end + class ChargeError < StandardError attr_accessor :response, :message def initialize(response) diff --git a/lib/pin_up/webhooks.rb b/lib/pin_up/webhooks.rb new file mode 100644 index 0000000..9d95057 --- /dev/null +++ b/lib/pin_up/webhooks.rb @@ -0,0 +1,35 @@ +module Pin + ## + # This class models Pin's WebhookEndpoints API + class Webhooks < Base + ## + # Lists all webhooks + # args: page (Fixnum), pagination (Boolean) + # returns: a collection of webhook objects + # + # if pagination is passed, access the response hash with [:response] + # and the pagination hash with [:pagination] + # + # https://pin.net.au/docs/api/webhooks#get-webhooks + def self.all(page = nil, pagination = false) + build_collection_response(make_request(:get, {url: "webhooks?page=#{page}" } ), pagination) + end + + ## + # Find a webhook for your account given a token + # args: token (String) + # returns: a webhook object + # https://pin.net.au/docs/api/webhooks#get-webhook + def self.find(token) + build_response(make_request(:get, {url: "webhooks/#{token}" } )) + end + + ## + # Replays a webhook + # args: token (String) + # https://pin.net.au/docs/api/webhooks#put-webhook-replay + def self.replay(token) + build_response(make_request(:put, {url: "webhooks/#{token}/replay" } )) + end + end +end diff --git a/spec/errors_spec.rb b/spec/errors_spec.rb index 18d14e9..f677621 100644 --- a/spec/errors_spec.rb +++ b/spec/errors_spec.rb @@ -117,4 +117,9 @@ end end + it 'should raise a CannotReplayWebhook error when event can\'t be replayed' do + token = Pin::Webhooks.all(1, true)[:response].last['token'] + expect { Pin::Webhooks.replay(token) }.to raise_error Pin::CannotReplayWebhook + end + end diff --git a/spec/webhooks_spec.rb b/spec/webhooks_spec.rb new file mode 100644 index 0000000..c767c90 --- /dev/null +++ b/spec/webhooks_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +RSpec.describe 'Webhooks', :vcr, class: Pin::Webhooks do + before(:each) do + Pin::Base.new(ENV['PIN_SECRET'], :test) + end + + it 'should list webhooks' do + request = Pin::Webhooks.all(1, true) + expect(request[:response]).to_not eq [] + end + + it 'should show a webhook given a token' do + token = Pin::Webhooks.all(1, true)[:response].first['token'] + expect(Pin::Webhooks.find(token)['token']).to eq token + end + + it 'replays a webhook given a token' do + skip 'TODO: Come back to this when I can work out a way to make it reliable' + token = Pin::Webhooks.all(1, true)[:response].last['token'] + expect(Pin::Webhooks.replay(token)['token']).to eq token + end + +end