besepa 0.2

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 (40) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +46 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +132 -0
  6. data/Rakefile +1 -0
  7. data/besepa-ruby.gemspec +31 -0
  8. data/lib/besepa.rb +14 -0
  9. data/lib/besepa/activity.rb +11 -0
  10. data/lib/besepa/api_calls/create.rb +26 -0
  11. data/lib/besepa/api_calls/destroy.rb +15 -0
  12. data/lib/besepa/api_calls/list.rb +36 -0
  13. data/lib/besepa/api_calls/update.rb +23 -0
  14. data/lib/besepa/bank_account.rb +63 -0
  15. data/lib/besepa/business_account.rb +37 -0
  16. data/lib/besepa/customer.rb +134 -0
  17. data/lib/besepa/debit.rb +64 -0
  18. data/lib/besepa/errors/besepa_error.rb +28 -0
  19. data/lib/besepa/errors/invalid_resource_error.rb +11 -0
  20. data/lib/besepa/errors/resource_not_found_error.rb +11 -0
  21. data/lib/besepa/group.rb +27 -0
  22. data/lib/besepa/mandate.rb +18 -0
  23. data/lib/besepa/product.rb +19 -0
  24. data/lib/besepa/remittance.rb +32 -0
  25. data/lib/besepa/resource.rb +96 -0
  26. data/lib/besepa/subscription.rb +50 -0
  27. data/lib/besepa/utils/config.rb +51 -0
  28. data/lib/besepa/utils/connection.rb +27 -0
  29. data/lib/besepa/utils/request.rb +60 -0
  30. data/lib/besepa/utils/version.rb +6 -0
  31. data/lib/besepa/webhook.rb +16 -0
  32. data/spec/besepa/customer_spec.rb +119 -0
  33. data/spec/fixtures/customer.json +17 -0
  34. data/spec/fixtures/customer_add_debit.json +54 -0
  35. data/spec/fixtures/customer_bank_accounts.json +22 -0
  36. data/spec/fixtures/customer_debits.json +71 -0
  37. data/spec/fixtures/customer_removed.json +17 -0
  38. data/spec/fixtures/customers.json +20 -0
  39. data/spec/helper.rb +46 -0
  40. metadata +174 -0
@@ -0,0 +1,50 @@
1
+ module Besepa
2
+
3
+ class Subscription < Besepa::Resource
4
+
5
+ include Besepa::ApiCalls::List
6
+ include Besepa::ApiCalls::Create
7
+ include Besepa::ApiCalls::Destroy
8
+
9
+ FIELDS = [:id, :last_debit, :next_debit, :status, :metadata, :starts_at, :renew_at]
10
+
11
+
12
+ FIELDS.each do |f|
13
+ attr_accessor f
14
+ end
15
+
16
+ attr_accessor :debtor_bank_account, :product, :customer
17
+
18
+ def to_hash
19
+ values = {}
20
+ self.class::FIELDS.each do |key|
21
+ values[key] = self.send("#{key.to_s}")
22
+ end
23
+ values[:debtor_bank_account] = debtor_bank_account.to_hash if debtor_bank_account
24
+ values[:product] = product.to_hash if product
25
+ values[:customer] = customer.to_hash if customer
26
+ values
27
+ end
28
+
29
+ def self.api_path(filters={})
30
+ "#{Customer.api_path}/#{CGI.escape(filters[:customer_id])}/subscriptions"
31
+ end
32
+
33
+ def api_path(filters={})
34
+ "#{Customer.api_path}/#{CGI.escape(filters[:customer_id])}/subscriptions/#{CGI.escape(id)}"
35
+ end
36
+
37
+ def process_attributes(attrs)
38
+ self.class::FIELDS.each do |key|
39
+ self.send("#{key.to_s}=", attrs[key.to_s] || attrs[key.to_sym])
40
+ end
41
+ self.debtor_bank_account = Besepa::BankAccount.new(attrs['debtor_bank_account']) if attrs['debtor_bank_account']
42
+ self.product = Besepa::Product.new(attrs['product']) if attrs['product']
43
+ self.customer = Besepa::Customer.new(attrs['customer']) if attrs['customer']
44
+ process_activities(attrs)
45
+ self
46
+ end
47
+
48
+
49
+ end
50
+ end
@@ -0,0 +1,51 @@
1
+ module Besepa
2
+
3
+ module Utils
4
+
5
+ # Defines constants and methods related to configuration
6
+ module ApiConfig
7
+
8
+ # The consumer key if none is set
9
+ DEFAULT_API_KEY = nil
10
+
11
+ # The endpoint that will be used to connect if none is set
12
+ DEFAULT_ENDPOINT = 'https://sandbox.besepa.com'
13
+
14
+ # An array of valid keys in the options hash when configuring api objects
15
+ VALID_OPTIONS_KEYS = [
16
+ :api_key,
17
+ :endpoint,
18
+ :ssl
19
+ ]
20
+
21
+ attr_accessor *VALID_OPTIONS_KEYS
22
+
23
+ # When this module is extended, set all configuration options to their default values
24
+ def self.extended(base)
25
+ base.reset
26
+ end
27
+
28
+ # Convenience method to allow configuration options to be set in a block
29
+ def configure
30
+ yield self
31
+ self
32
+ end
33
+
34
+ # Create a hash of options and their values
35
+ def options
36
+ options = {}
37
+ VALID_OPTIONS_KEYS.each{|k| options[k] = send(k)}
38
+ options
39
+ end
40
+
41
+ # Reset all configuration options to defaults
42
+ def reset
43
+ self.api_key = DEFAULT_API_KEY
44
+ self.endpoint = DEFAULT_ENDPOINT
45
+ self
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,27 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+
4
+ module Besepa
5
+
6
+ module Utils
7
+
8
+ module Connection
9
+
10
+ # Returns a Faraday::Connection object
11
+ #
12
+ # @param options [Hash] A hash of options
13
+ # @return [Faraday::Connection]
14
+ def connection(options={})
15
+ options = options.merge(Besepa.options)
16
+ @connection ||= Faraday.new ( options[:endpoint] ) do |conn|
17
+ conn.request :json
18
+ conn.response :json, :content_type => /\bjson$/
19
+ conn.authorization( 'Bearer', options[:api_key])
20
+ conn.adapter :net_http
21
+ end
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,60 @@
1
+ module Besepa
2
+
3
+ module Utils
4
+
5
+ # Defines HTTP request methods
6
+ module Request
7
+
8
+ END_POINT_URL_PREFIX = "/api/1"
9
+
10
+ # Perform an HTTP DELETE request
11
+ def delete(path, params={}, options={})
12
+ request(:delete, path, params, options)
13
+ end
14
+
15
+ # Perform an HTTP GET request
16
+ def get(path, params={}, options={})
17
+ request(:get, path, params, options)
18
+ end
19
+
20
+ # Perform an HTTP POST request
21
+ def post(path, params={}, options={})
22
+ request(:post, path, params, options)
23
+ end
24
+
25
+ # Perform an HTTP PUT request
26
+ def put(path, params={}, options={})
27
+ request(:put, path, params, options)
28
+ end
29
+
30
+ protected
31
+
32
+ # Perform an HTTP request
33
+ def request(method, path, params, options)
34
+ response = connection(options).run_request(method, nil, nil, nil) do |request|
35
+ request.options[:raw] = true if options[:raw]
36
+ case method.to_sym
37
+ when :delete, :get
38
+ request.url(END_POINT_URL_PREFIX + path, params)
39
+ when :post, :put
40
+ request.path = END_POINT_URL_PREFIX + path
41
+ request.body = params unless params.empty?
42
+ end
43
+ end
44
+ options[:raw] ? response : handle_response(response)
45
+ end
46
+
47
+ def handle_response(response)
48
+ body = response.body
49
+ if response.status >= 400 || body['error']
50
+ handle_errors(response.status, body)
51
+ else
52
+ body
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -0,0 +1,6 @@
1
+ module Besepa
2
+
3
+ module Utils
4
+ VERSION = '0.2'.freeze
5
+ end
6
+ end
@@ -0,0 +1,16 @@
1
+ module Besepa
2
+
3
+ class Webhook < Besepa::Resource
4
+
5
+ include Besepa::ApiCalls::List
6
+ include Besepa::ApiCalls::Create
7
+ include Besepa::ApiCalls::Destroy
8
+
9
+ FIELDS = [:id, :url, :status, :push_count, :ok_count, :success_rate]
10
+
11
+ FIELDS.each do |f|
12
+ attr_accessor f
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,119 @@
1
+
2
+ require 'helper'
3
+
4
+ describe Besepa::Customer do
5
+
6
+ describe '#all' do
7
+
8
+ before do
9
+ stub_get('/customers').to_return(body: fixture('customers.json'), headers: {content_type: 'application/json; charset=utf-8'})
10
+ end
11
+
12
+ it 'returns a list of customers' do
13
+ customers = Besepa::Customer.all
14
+ expect(customers).to be_an Array
15
+ expect(customers.first).to be_an Besepa::Customer
16
+ expect(customers.size).to eq(1)
17
+ end
18
+
19
+ end
20
+
21
+ describe '#find' do
22
+
23
+ before do
24
+ stub_get('/customers/cus12345').to_return(body: fixture('customer.json'), headers: {content_type: 'application/json; charset=utf-8'})
25
+ end
26
+
27
+ it 'returns a a customer' do
28
+ customer = Besepa::Customer.find('cus12345')
29
+ expect(customer).to be_an Besepa::Customer
30
+ expect(customer.name).to eq("Pancho Villa SLU")
31
+ end
32
+
33
+ end
34
+
35
+ describe '.save' do
36
+
37
+ before do
38
+ stub_get('/customers/cus12345').to_return(body: fixture('customer.json'), headers: {content_type: 'application/json; charset=utf-8'})
39
+ stub_put('/customers/cus12345').to_return(body: fixture('customer.json'), headers: {content_type: 'application/json; charset=utf-8'})
40
+ end
41
+
42
+ it 'returns a a customer' do
43
+ customer = Besepa::Customer.find('cus12345')
44
+ customer.name = customer.name.reverse
45
+ customer = customer.save
46
+ expect(customer).to be_an Besepa::Customer
47
+ end
48
+
49
+ end
50
+
51
+ describe '.destroy' do
52
+
53
+ before do
54
+ stub_get('/customers/cus12345').to_return(body: fixture('customer.json'), headers: {content_type: 'application/json; charset=utf-8'})
55
+ stub_delete('/customers/cus12345').to_return(body: fixture('customer_removed.json'), headers: {content_type: 'application/json; charset=utf-8'})
56
+ end
57
+
58
+ it 'returns a a customer' do
59
+ customer = Besepa::Customer.find('cus12345')
60
+ customer.name = customer.name.reverse
61
+ customer = customer.destroy
62
+ expect(customer).to be_an Besepa::Customer
63
+ expect(customer.status).to eq('REMOVED')
64
+ end
65
+
66
+ end
67
+
68
+
69
+ describe "getting customer debits" do
70
+
71
+ before do
72
+ stub_get('/customers/cus12345/debits').to_return(body: fixture('customer_debits.json'), headers: {content_type: 'application/json; charset=utf-8'})
73
+ end
74
+
75
+ it 'returns a list of debits' do
76
+ debits = Besepa::Customer.new(id: 'cus12345').debits
77
+ expect(debits).to be_an Array
78
+ expect(debits.first).to be_an Besepa::Debit
79
+ expect(debits.size).to eq(1)
80
+ end
81
+
82
+ end
83
+
84
+ describe "creating a debit for a customer" do
85
+
86
+ describe "with valid data" do
87
+
88
+ before do
89
+ stub_post('/customers/cus12345/debits').to_return(body: fixture('customer_add_debit.json'), headers: {content_type: 'application/json; charset=utf-8'})
90
+ end
91
+
92
+ it 'returns the new created debit' do
93
+ debit = Besepa::Customer.new(id: 'cus12345').add_debit("man123", "ref123", "desc123", 1000, '2015-11-23')
94
+
95
+ expect(debit).to be_an Besepa::Debit
96
+ end
97
+
98
+ end
99
+
100
+ end
101
+
102
+
103
+ describe "getting customer bank_accounts" do
104
+
105
+ before do
106
+ stub_get('/customers/cus12345/bank_accounts').to_return(body: fixture('customer_bank_accounts.json'), headers: {content_type: 'application/json; charset=utf-8'})
107
+ end
108
+
109
+
110
+ it 'returns a list of bank accounts' do
111
+ bank_accounts = Besepa::Customer.new(id: 'cus12345').bank_accounts
112
+ expect(bank_accounts).to be_an Array
113
+ expect(bank_accounts.first).to be_an Besepa::BankAccount
114
+ expect(bank_accounts.size).to eq(1)
115
+ end
116
+
117
+ end
118
+
119
+ end
@@ -0,0 +1,17 @@
1
+ {
2
+ "response": {
3
+ "name": "Pancho Villa SLU",
4
+ "taxid": "B98123232",
5
+ "reference": "11234",
6
+ "contact_name": null,
7
+ "contact_email": null,
8
+ "contact_phone": null,
9
+ "address_street": null,
10
+ "address_city": null,
11
+ "address_postalcode": null,
12
+ "address_state": null,
13
+ "address_country": null,
14
+ "status": "ACTIVE",
15
+ "id": "cus12345"
16
+ }
17
+ }
@@ -0,0 +1,54 @@
1
+ {
2
+ "response": {
3
+ "amount": 1000,
4
+ "currency": "EUR",
5
+ "collect_at": "2014-11-15",
6
+ "sent_at": null,
7
+ "status": "READY",
8
+ "description": "desc",
9
+ "id": "deb3482f4dc98245ec092581e4f507a",
10
+ "reference": "REF123",
11
+ "metadata": {
12
+ "shipping": "UPS"
13
+ },
14
+ "customer": {
15
+ "name": "Pancho Villa SLU",
16
+ "taxid": "B98123232",
17
+ "reference": "11232",
18
+ "contact_name": "Pancho Villa",
19
+ "contact_email": "pvilla@panchovilla.com",
20
+ "contact_phone": "123456789",
21
+ "address_street": "Avda. de la Revolución 12",
22
+ "address_city": "Madrid",
23
+ "address_postalcode": "28001",
24
+ "address_state": "Madrid",
25
+ "address_country": "ES",
26
+ "status": "ACTIVE",
27
+ "id": "cusa1654ec35f3745481bb0a984d8f8"
28
+ },
29
+ "mandate": {
30
+ "description": "mandate",
31
+ "status": "SIGNED",
32
+ "signed_at": "2014-11-10T15:59:45.313Z",
33
+ "mandate_type": "RECURRENT",
34
+ "reference": "1415635184",
35
+ "scheme": "CORE",
36
+ "id": "manff3c2d4ea5ca29085c5c871ef2d2",
37
+ "url": "https://test.besepa.com/m/manff3c2d4ea5ca29085c5c871ef2d2"
38
+ },
39
+ "debtor_bank_account": {
40
+ "bank_name": "Banco Santander",
41
+ "bic": "BSCHESMM",
42
+ "iban": "ES7620770024003102575766",
43
+ "status": "ACTIVE",
44
+ "id": "ban9601a13105a897750917b223418c"
45
+ },
46
+ "creditor_bank_account": {
47
+ "bank_name": "Banco Santander",
48
+ "bic": "BSCHESMM",
49
+ "iban": "ES7620770024003102575766",
50
+ "status": "ACTIVE",
51
+ "id": "ban60e4704d70add1851b676aa69fbc"
52
+ }
53
+ }
54
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "response": [
3
+ {
4
+ "id": "banbd5ae7eacf231888edd470ed55144f40",
5
+ "bank_name": "Banco Santander",
6
+ "bic": "BSCHESMM",
7
+ "iban": "ES7620770024003102575766",
8
+ "status": "PENDING_MANDATE",
9
+ "customer_id": "cusf11b647d2cc16e503fe8ba36f88c",
10
+ "mandate": {
11
+ "status": "PENDING_SIGNATURE",
12
+ "signed_at": null,
13
+ "mandate_type": "RECURRENT",
14
+ "reference": "manf08e870d427040854beca9ad6117",
15
+ "scheme": "B2B",
16
+ "id": "manf08d870d327041854beca9ad6117",
17
+ "url": "http://test.besepa.com/m/manf08e870d427040854beca9ad6117"
18
+ }
19
+ }
20
+ ],
21
+ "count": 1
22
+ }
@@ -0,0 +1,71 @@
1
+ {
2
+ "response": [
3
+ {
4
+ "reference": "1421756142",
5
+ "amount": 1000,
6
+ "currency": "EUR",
7
+ "collect_at": "2015-01-30",
8
+ "sent_at": null,
9
+ "status": "READY",
10
+ "description": "Cargo de 1421756142",
11
+ "error_code": null,
12
+ "platform_error_code": null,
13
+ "metadata": null,
14
+ "id": "deb4df034666ef17a312b8bbef0bb5d",
15
+ "customer": {
16
+ "name": "PATODONALD",
17
+ "taxid": "PATODONALD",
18
+ "reference": "PATODONALD",
19
+ "contact_name": null,
20
+ "contact_email": null,
21
+ "contact_phone": null,
22
+ "address_street": "fsfdsfds",
23
+ "address_city": "sfsfss",
24
+ "address_postalcode": "fsf",
25
+ "address_state": "fsf",
26
+ "address_country": "ES",
27
+ "status": "PENDING_MANDATE",
28
+ "id": "cusf0119f36a683c89e0b041462e23b"
29
+ },
30
+ "mandate": {
31
+ "description": "Firmado fuera de BeSEPA.",
32
+ "status": "SIGNED",
33
+ "signed_at": "2015-01-20T12:09:01.000Z",
34
+ "mandate_type": "RECURRENT",
35
+ "reference": "man7ca33df2252a2d640175f40f4312",
36
+ "scheme": "CORE",
37
+ "signature_type": "checkbox",
38
+ "id": "man7ca33df225aa2d640175f40f4312",
39
+ "url": "http://test.besepa.com/m/man7ca33df225aa2d640135f40f4312"
40
+ },
41
+ "debtor_bank_account": {
42
+ "bank_name": "INGDESMMXXX",
43
+ "bic": "INGDESMMXXX",
44
+ "iban": "ES7114452100966029467461",
45
+ "status": "ACTIVE",
46
+ "id": "ban00fb39d4ab493f34aba3077a3c2e",
47
+ "customer_id": "cusf0119fe6a683c89e0b041462e23b",
48
+ "mandate": {
49
+ "description": "Firmado fuera de BeSEPA.",
50
+ "status": "SIGNED",
51
+ "signed_at": "2015-01-20T12:09:01.000Z",
52
+ "mandate_type": "RECURRENT",
53
+ "reference": "man7ca33df225aa2d640175f40f4312",
54
+ "scheme": "CORE",
55
+ "signature_type": "checkbox",
56
+ "id": "man7ca3333df5aard640h75f40f4312",
57
+ "url": "http://test.besepa.com/m/man7ca33df225aa2d640135f40f4312"
58
+ }
59
+ },
60
+ "creditor_bank_account": {
61
+ "bank_name": "Bankinter",
62
+ "bic": "BBVAESMMXXX",
63
+ "iban": "es0820383852396000858559",
64
+ "status": "PENDING_ACTIVATION",
65
+ "id": "ban4d38bb61085e2d1e53bff7c1779a",
66
+ "mandate": null
67
+ }
68
+ }
69
+ ],
70
+ "count": 1
71
+ }