besepa 0.2

Sign up to get free protection for your applications and to get access to all the features.
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
+ }