vindi-rails 0.2.0
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.
- checksums.yaml +7 -0
- data/.agents/rules/code-style-ruby.md +100 -0
- data/CHANGELOG.md +21 -0
- data/CHANGELOG.pt-BR.md +21 -0
- data/README.md +74 -0
- data/README.pt-BR.md +74 -0
- data/WIKI.md +246 -0
- data/WIKI.pt-BR.md +246 -0
- data/lib/generators/vindi/install_generator.rb +17 -0
- data/lib/generators/vindi/templates/vindi.rb +11 -0
- data/lib/vindi/api_operations/create.rb +14 -0
- data/lib/vindi/api_operations/delete.rb +15 -0
- data/lib/vindi/api_operations/list.rb +14 -0
- data/lib/vindi/api_operations/update.rb +14 -0
- data/lib/vindi/client.rb +69 -0
- data/lib/vindi/configuration.rb +14 -0
- data/lib/vindi/errors.rb +22 -0
- data/lib/vindi/railtie.rb +7 -0
- data/lib/vindi/resource.rb +31 -0
- data/lib/vindi/resources/affiliate.rb +11 -0
- data/lib/vindi/resources/bill.rb +14 -0
- data/lib/vindi/resources/bill_item.rb +11 -0
- data/lib/vindi/resources/charge.rb +13 -0
- data/lib/vindi/resources/customer.rb +14 -0
- data/lib/vindi/resources/discount.rb +13 -0
- data/lib/vindi/resources/export_batch.rb +12 -0
- data/lib/vindi/resources/import_batch.rb +12 -0
- data/lib/vindi/resources/invoice.rb +11 -0
- data/lib/vindi/resources/issue.rb +12 -0
- data/lib/vindi/resources/merchant.rb +11 -0
- data/lib/vindi/resources/merchant_user.rb +11 -0
- data/lib/vindi/resources/message.rb +11 -0
- data/lib/vindi/resources/movement.rb +11 -0
- data/lib/vindi/resources/notification.rb +11 -0
- data/lib/vindi/resources/partner.rb +11 -0
- data/lib/vindi/resources/payment_method.rb +11 -0
- data/lib/vindi/resources/payment_profile.rb +13 -0
- data/lib/vindi/resources/period.rb +11 -0
- data/lib/vindi/resources/plan.rb +14 -0
- data/lib/vindi/resources/product.rb +14 -0
- data/lib/vindi/resources/product_item.rb +14 -0
- data/lib/vindi/resources/public.rb +9 -0
- data/lib/vindi/resources/role.rb +11 -0
- data/lib/vindi/resources/subscription.rb +14 -0
- data/lib/vindi/resources/transaction.rb +12 -0
- data/lib/vindi/resources/usage.rb +13 -0
- data/lib/vindi/resources/user.rb +11 -0
- data/lib/vindi/version.rb +5 -0
- data/lib/vindi.rb +59 -0
- data/vindi-rails.gemspec +33 -0
- metadata +109 -0
data/WIKI.pt-BR.md
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Wiki do SDK Vindi
|
|
2
|
+
|
|
3
|
+
[Read in English (WIKI.md)](./WIKI.md)
|
|
4
|
+
|
|
5
|
+
Bem-vindo à Wiki do SDK `vindi-rails`. Este documento detalha todos os recursos mapeados, operações suportadas e guias de uso.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Design & Arquitetura do SDK
|
|
10
|
+
|
|
11
|
+
O SDK utiliza o `RestClient` internamente para se comunicar com a API da Vindi.
|
|
12
|
+
Os recursos são representados como objetos Ruby que herdam de `Vindi::Resource`. Os atributos retornados pela API são acessíveis através de métodos getter dinâmicos nas instâncias.
|
|
13
|
+
|
|
14
|
+
### Tratamento de Erros
|
|
15
|
+
|
|
16
|
+
O SDK lança exceções específicas de acordo com os códigos de status HTTP retornados. Todos os erros herdam de `Vindi::Error`:
|
|
17
|
+
|
|
18
|
+
- `Vindi::UnauthorizedError` (401)
|
|
19
|
+
- `Vindi::ForbiddenError` (403)
|
|
20
|
+
- `Vindi::NotFoundError` (404)
|
|
21
|
+
- `Vindi::UnprocessableEntityError` (422)
|
|
22
|
+
- `Vindi::RateLimitError` (429)
|
|
23
|
+
- `Vindi::InternalServerError` (500+)
|
|
24
|
+
- `Vindi::APIError` (Tratamento genérico para outros códigos HTTP)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 2. Mapeamento de Recursos e Operações CRUD
|
|
29
|
+
|
|
30
|
+
A tabela abaixo lista todos os recursos mapeados e suas operações disponíveis:
|
|
31
|
+
|
|
32
|
+
| Classe do Recurso | Endpoint | Operações CRUD Habilitadas |
|
|
33
|
+
| :--- | :--- | :--- |
|
|
34
|
+
| `Vindi::Customer` | `customers` | `list`, `create`, `update`, `delete` |
|
|
35
|
+
| `Vindi::PaymentProfile` | `payment_profiles` | `list`, `create`, `delete` |
|
|
36
|
+
| `Vindi::Subscription` | `subscriptions` | `list`, `create`, `update`, `delete` |
|
|
37
|
+
| `Vindi::Charge` | `charges` | `list`, `create`, `update` |
|
|
38
|
+
| `Vindi::Plan` | `plans` | `list`, `create`, `update`, `delete` |
|
|
39
|
+
| `Vindi::Product` | `products` | `list`, `create`, `update`, `delete` |
|
|
40
|
+
| `Vindi::ProductItem` | `product_items` | `list`, `create`, `update`, `delete` |
|
|
41
|
+
| `Vindi::Discount` | `discounts` | `list`, `create`, `delete` |
|
|
42
|
+
| `Vindi::Bill` | `bills` | `list`, `create`, `update`, `delete` |
|
|
43
|
+
| `Vindi::BillItem` | `bill_items` | `list` |
|
|
44
|
+
| `Vindi::Period` | `periods` | `list` |
|
|
45
|
+
| `Vindi::Transaction` | `transactions` | `list`, `create` |
|
|
46
|
+
| `Vindi::Usage` | `usages` | `list`, `create`, `delete` |
|
|
47
|
+
| `Vindi::Invoice` | `invoices` | `list` |
|
|
48
|
+
| `Vindi::Movement` | `movements` | `list` |
|
|
49
|
+
| `Vindi::Message` | `messages` | `list` |
|
|
50
|
+
| `Vindi::ExportBatch` | `export_batches` | `list`, `create` |
|
|
51
|
+
| `Vindi::ImportBatch` | `import_batches` | `list`, `create` |
|
|
52
|
+
| `Vindi::Issue` | `issues` | `list`, `update` |
|
|
53
|
+
| `Vindi::Notification` | `notifications` | `list` |
|
|
54
|
+
| `Vindi::Merchant` | `merchants` | `list` |
|
|
55
|
+
| `Vindi::MerchantUser` | `merchant_users` | `list` |
|
|
56
|
+
| `Vindi::Role` | `roles` | `list` |
|
|
57
|
+
| `Vindi::User` | `users` | `list` |
|
|
58
|
+
| `Vindi::Public` | `public` | Nenhuma (Configuração Estática) |
|
|
59
|
+
| `Vindi::Affiliate` | `affiliates` | `list` |
|
|
60
|
+
| `Vindi::Partner` | `partner` | `list` |
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 3. Exemplos de Uso
|
|
65
|
+
|
|
66
|
+
### Clientes (`Vindi::Customer`)
|
|
67
|
+
|
|
68
|
+
```ruby
|
|
69
|
+
# Criar um cliente
|
|
70
|
+
cliente = Vindi::Customer.create(
|
|
71
|
+
name: "João Silva",
|
|
72
|
+
email: "joao@exemplo.com"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Acessar atributos do retorno
|
|
76
|
+
puts cliente.id
|
|
77
|
+
puts cliente.name
|
|
78
|
+
|
|
79
|
+
# Atualizar cliente
|
|
80
|
+
atualizado = Vindi::Customer.update(cliente.id, email: "joao.novo@exemplo.com")
|
|
81
|
+
|
|
82
|
+
# Excluir cliente
|
|
83
|
+
Vindi::Customer.delete(cliente.id)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Perfis de Pagamento (`Vindi::PaymentProfile`)
|
|
87
|
+
|
|
88
|
+
```ruby
|
|
89
|
+
# Criar perfil de pagamento com cartão
|
|
90
|
+
perfil = Vindi::PaymentProfile.create(
|
|
91
|
+
customer_id: 12345,
|
|
92
|
+
payment_company_code: "visa",
|
|
93
|
+
holder_name: "JOAO SILVA",
|
|
94
|
+
card_number: "4111111111111111",
|
|
95
|
+
card_expiration_date: "12/2030",
|
|
96
|
+
card_cvv: "123"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# Excluir perfil de pagamento
|
|
100
|
+
Vindi::PaymentProfile.delete(perfil.id)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Assinaturas (`Vindi::Subscription`)
|
|
104
|
+
|
|
105
|
+
```ruby
|
|
106
|
+
# Criar assinatura
|
|
107
|
+
assinatura = Vindi::Subscription.create(
|
|
108
|
+
customer_id: cliente.id,
|
|
109
|
+
plan_id: plano.id,
|
|
110
|
+
payment_method_code: "credit_card"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Cancelar/Excluir assinatura
|
|
114
|
+
Vindi::Subscription.delete(assinatura.id)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Cobranças (`Vindi::Charge`)
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
# Listar cobranças pendentes
|
|
121
|
+
cobrancas = Vindi::Charge.list(status: "pending")
|
|
122
|
+
|
|
123
|
+
# Obter valor da primeira cobrança
|
|
124
|
+
puts cobrancas.first.amount
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Planos (`Vindi::Plan`)
|
|
128
|
+
|
|
129
|
+
```ruby
|
|
130
|
+
# Criar um plano
|
|
131
|
+
plano = Vindi::Plan.create(
|
|
132
|
+
name: "Plano Ouro Premium",
|
|
133
|
+
code: "gold_premium",
|
|
134
|
+
interval: "months",
|
|
135
|
+
interval_count: 1
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# Listar planos
|
|
139
|
+
planos = Vindi::Plan.list
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Produtos & Itens de Produto (`Vindi::Product` & `Vindi::ProductItem`)
|
|
143
|
+
|
|
144
|
+
```ruby
|
|
145
|
+
# Criar um produto
|
|
146
|
+
produto = Vindi::Product.create(
|
|
147
|
+
name: "Serviço de Hospedagem",
|
|
148
|
+
code: "hosting"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# Associar um produto a um plano/assinatura
|
|
152
|
+
item_produto = Vindi::ProductItem.create(
|
|
153
|
+
product_id: produto.id,
|
|
154
|
+
plan_id: plano.id
|
|
155
|
+
)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Descontos (`Vindi::Discount`)
|
|
159
|
+
|
|
160
|
+
```ruby
|
|
161
|
+
# Criar/aplicar um desconto
|
|
162
|
+
desconto = Vindi::Discount.create(
|
|
163
|
+
amount: 15.00,
|
|
164
|
+
discount_type: "percentage",
|
|
165
|
+
percentage: 10
|
|
166
|
+
)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Faturas & Itens de Fatura (`Vindi::Bill` & `Vindi::BillItem`)
|
|
170
|
+
|
|
171
|
+
```ruby
|
|
172
|
+
# Criar uma fatura manualmente
|
|
173
|
+
fatura = Vindi::Bill.create(
|
|
174
|
+
customer_id: cliente.id,
|
|
175
|
+
payment_method_code: "credit_card",
|
|
176
|
+
bill_items: [
|
|
177
|
+
{ product_id: produto.id, amount: 99.90 }
|
|
178
|
+
]
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
# Listar itens de uma fatura
|
|
182
|
+
itens = Vindi::BillItem.list(bill_id: fatura.id)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Períodos (`Vindi::Period`)
|
|
186
|
+
|
|
187
|
+
```ruby
|
|
188
|
+
# Listar períodos de uma assinatura
|
|
189
|
+
periodos = Vindi::Period.list(subscription_id: assinatura.id)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Transações (`Vindi::Transaction`)
|
|
193
|
+
|
|
194
|
+
```ruby
|
|
195
|
+
# Criar uma transação manual (captura de cobrança)
|
|
196
|
+
transacao = Vindi::Transaction.create(
|
|
197
|
+
charge_id: cobranca.id,
|
|
198
|
+
amount: 99.90
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
# Listar transações
|
|
202
|
+
transacoes = Vindi::Transaction.list
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Consumos/Usos (`Vindi::Usage`)
|
|
206
|
+
|
|
207
|
+
```ruby
|
|
208
|
+
# Informar consumo de uso de uma assinatura
|
|
209
|
+
uso = Vindi::Usage.create(
|
|
210
|
+
subscription_id: assinatura.id,
|
|
211
|
+
quantity: 50,
|
|
212
|
+
description: "Chamadas de API consumidas"
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
# Listar consumos informados
|
|
216
|
+
usos = Vindi::Usage.list(subscription_id: assinatura.id)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Notas Fiscais (`Vindi::Invoice`)
|
|
220
|
+
|
|
221
|
+
```ruby
|
|
222
|
+
# Listar notas fiscais emitidas
|
|
223
|
+
notas_fiscais = Vindi::Invoice.list(status: "issued")
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Problemas/Pendências (`Vindi::Issue`)
|
|
227
|
+
|
|
228
|
+
```ruby
|
|
229
|
+
# Atualizar status de uma pendência (ex: marcar como resolvida)
|
|
230
|
+
pendencia = Vindi::Issue.update(issue_id, status: "resolved")
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Lotes de Importação/Exportação (`Vindi::ImportBatch` & `Vindi::ExportBatch`)
|
|
234
|
+
|
|
235
|
+
```ruby
|
|
236
|
+
# Iniciar lote para importação de clientes/assinaturas
|
|
237
|
+
lote_importacao = Vindi::ImportBatch.create(
|
|
238
|
+
batch_type: "customer",
|
|
239
|
+
file_url: "https://exemplo.com/importacao.csv"
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
# Solicitar lote de exportação de dados
|
|
243
|
+
lote_exportacao = Vindi::ExportBatch.create(
|
|
244
|
+
batch_type: "bill"
|
|
245
|
+
)
|
|
246
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
|
|
5
|
+
module Vindi
|
|
6
|
+
module Generators
|
|
7
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
|
9
|
+
|
|
10
|
+
desc "Creates a Vindi initializer to configure your API credentials."
|
|
11
|
+
|
|
12
|
+
def copy_initializer
|
|
13
|
+
template "vindi.rb", "config/initializers/vindi.rb"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Vindi.configure do |config|
|
|
4
|
+
# Set your Vindi private API key.
|
|
5
|
+
# We recommend using Rails credentials or environment variables.
|
|
6
|
+
config.api_key = ENV["VINDI_API_KEY"]
|
|
7
|
+
|
|
8
|
+
# Set the base URL for the API (default is sandbox).
|
|
9
|
+
# For production, use: "https://gp.vindi.com.br/api/v1"
|
|
10
|
+
# config.api_url = "https://sandbox-gp.vindi.com.br/api/v1"
|
|
11
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vindi
|
|
4
|
+
module APIOperations
|
|
5
|
+
module Create
|
|
6
|
+
def create(params = {})
|
|
7
|
+
response = Client.request(:post, endpoint, params)
|
|
8
|
+
singular_key = endpoint.end_with?("batches") ? endpoint.sub(/es$/, "").to_sym : endpoint.chomp("s").to_sym
|
|
9
|
+
resource_attrs = response.key?(singular_key) ? response[singular_key] : response
|
|
10
|
+
new(resource_attrs)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vindi
|
|
4
|
+
module APIOperations
|
|
5
|
+
module Delete
|
|
6
|
+
def delete(id)
|
|
7
|
+
response = Client.request(:delete, "#{endpoint}/#{id}")
|
|
8
|
+
singular_key = endpoint.end_with?("batches") ? endpoint.sub(/es$/, "").to_sym : endpoint.chomp("s").to_sym
|
|
9
|
+
resource_attrs = response.key?(singular_key) ? response[singular_key] : response
|
|
10
|
+
new(resource_attrs)
|
|
11
|
+
end
|
|
12
|
+
alias destroy delete
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vindi
|
|
4
|
+
module APIOperations
|
|
5
|
+
module List
|
|
6
|
+
def list(params = {})
|
|
7
|
+
response = Client.request(:get, endpoint, params)
|
|
8
|
+
key = endpoint.to_sym
|
|
9
|
+
items = response[key] || response[:results] || []
|
|
10
|
+
items.map { |item_attrs| new(item_attrs) }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vindi
|
|
4
|
+
module APIOperations
|
|
5
|
+
module Update
|
|
6
|
+
def update(id, params = {})
|
|
7
|
+
response = Client.request(:put, "#{endpoint}/#{id}", params)
|
|
8
|
+
singular_key = endpoint.end_with?("batches") ? endpoint.sub(/es$/, "").to_sym : endpoint.chomp("s").to_sym
|
|
9
|
+
resource_attrs = response.key?(singular_key) ? response[singular_key] : response
|
|
10
|
+
new(resource_attrs)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/vindi/client.rb
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "base64"
|
|
4
|
+
|
|
5
|
+
module Vindi
|
|
6
|
+
class Client
|
|
7
|
+
class << self
|
|
8
|
+
def request(method, path, params = {}, headers = {})
|
|
9
|
+
api_key = Vindi.configuration.api_key
|
|
10
|
+
raise UnauthorizedError.new("API key is not configured.", status: 401) unless api_key
|
|
11
|
+
|
|
12
|
+
url = build_url(path)
|
|
13
|
+
payload = build_payload(method, params)
|
|
14
|
+
req_headers = build_headers(api_key, headers)
|
|
15
|
+
|
|
16
|
+
execute_request(method, url, payload, req_headers)
|
|
17
|
+
rescue RestClient::Exception => e
|
|
18
|
+
handle_rest_client_error(e)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def build_url(path)
|
|
24
|
+
"#{Vindi.configuration.api_url}/#{path.sub(%r{^/}, '')}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def build_payload(method, params)
|
|
28
|
+
return nil if %i[get delete].include?(method.to_sym.downcase)
|
|
29
|
+
params.to_json
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def build_headers(api_key, custom_headers)
|
|
33
|
+
auth = Base64.strict_encode64("#{api_key}:")
|
|
34
|
+
{
|
|
35
|
+
"Authorization" => "Basic #{auth}",
|
|
36
|
+
"Content-Type" => "application/json",
|
|
37
|
+
"Accept" => "application/json"
|
|
38
|
+
}.merge(custom_headers)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def execute_request(method, url, payload, headers)
|
|
42
|
+
options = { method: method.to_sym, url: url, headers: headers }
|
|
43
|
+
options[:payload] = payload if payload
|
|
44
|
+
response = RestClient::Request.execute(options)
|
|
45
|
+
JSON.parse(response.body, symbolize_names: true)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def handle_rest_client_error(error)
|
|
49
|
+
status = error.response&.code
|
|
50
|
+
body = error.response&.body
|
|
51
|
+
message = "HTTP request failed: #{error.message}. Response: #{body}"
|
|
52
|
+
|
|
53
|
+
raise_specific_error(message, status, body)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def raise_specific_error(msg, status, body)
|
|
57
|
+
case status
|
|
58
|
+
when 401 then raise UnauthorizedError.new(msg, status: status, response_body: body)
|
|
59
|
+
when 403 then raise ForbiddenError.new(msg, status: status, response_body: body)
|
|
60
|
+
when 404 then raise NotFoundError.new(msg, status: status, response_body: body)
|
|
61
|
+
when 422 then raise UnprocessableEntityError.new(msg, status: status, response_body: body)
|
|
62
|
+
when 429 then raise RateLimitError.new(msg, status: status, response_body: body)
|
|
63
|
+
when 500..599 then raise InternalServerError.new(msg, status: status, response_body: body)
|
|
64
|
+
else raise APIError.new(msg, status: status, response_body: body)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vindi
|
|
4
|
+
class Configuration
|
|
5
|
+
attr_accessor :api_key, :api_url
|
|
6
|
+
|
|
7
|
+
DEFAULT_API_URL = "https://sandbox-gp.vindi.com.br/api/v1"
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@api_key = nil
|
|
11
|
+
@api_url = DEFAULT_API_URL
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/vindi/errors.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vindi
|
|
4
|
+
class Error < StandardError; end
|
|
5
|
+
|
|
6
|
+
class APIError < Error
|
|
7
|
+
attr_reader :status, :response_body
|
|
8
|
+
|
|
9
|
+
def initialize(message, status: nil, response_body: nil)
|
|
10
|
+
super(message)
|
|
11
|
+
@status = status
|
|
12
|
+
@response_body = response_body
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class UnauthorizedError < APIError; end
|
|
17
|
+
class ForbiddenError < APIError; end
|
|
18
|
+
class NotFoundError < APIError; end
|
|
19
|
+
class UnprocessableEntityError < APIError; end
|
|
20
|
+
class RateLimitError < APIError; end
|
|
21
|
+
class InternalServerError < APIError; end
|
|
22
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vindi
|
|
4
|
+
class Resource
|
|
5
|
+
attr_reader :attributes
|
|
6
|
+
|
|
7
|
+
def initialize(attributes = {})
|
|
8
|
+
@attributes = attributes || {}
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def inspect
|
|
12
|
+
"#<#{self.class} #{attributes.inspect}>"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def method_missing(method_name, *args, &block)
|
|
16
|
+
if attributes.key?(method_name)
|
|
17
|
+
attributes[method_name]
|
|
18
|
+
else
|
|
19
|
+
super
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
24
|
+
attributes.key?(method_name) || super
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.endpoint
|
|
28
|
+
raise NotImplementedError, "Subclasses must implement .endpoint"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vindi
|
|
4
|
+
class Customer < Resource
|
|
5
|
+
extend APIOperations::List
|
|
6
|
+
extend APIOperations::Create
|
|
7
|
+
extend APIOperations::Update
|
|
8
|
+
extend APIOperations::Delete
|
|
9
|
+
|
|
10
|
+
def self.endpoint
|
|
11
|
+
"customers"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|