vindi-rails 0.2.0 → 0.3.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 +4 -4
- data/CHANGELOG.md +11 -0
- data/CHANGELOG.pt-BR.md +11 -0
- data/README.md +96 -74
- data/README.pt-BR.md +97 -74
- data/WIKI.md +479 -246
- data/WIKI.pt-BR.md +479 -246
- data/lib/vindi/api_operations/create.rb +18 -14
- data/lib/vindi/api_operations/update.rb +18 -14
- data/lib/vindi/resource.rb +36 -31
- data/lib/vindi/version.rb +1 -1
- metadata +2 -2
data/WIKI.pt-BR.md
CHANGED
|
@@ -1,246 +1,479 @@
|
|
|
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
|
-
#
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
#
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
#
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
#
|
|
243
|
-
|
|
244
|
-
batch_type: "
|
|
245
|
-
|
|
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
|
+
# Criar um cliente com uma chave de idempotência (evita duplicados)
|
|
76
|
+
cliente = Vindi::Customer.create(
|
|
77
|
+
{ name: "João Silva", email: "joao@exemplo.com" },
|
|
78
|
+
idempotency_key: "chave-unica-aqui"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Acessar atributos do retorno
|
|
82
|
+
puts cliente.id
|
|
83
|
+
puts cliente.name
|
|
84
|
+
|
|
85
|
+
# Atualizar cliente
|
|
86
|
+
atualizado = Vindi::Customer.update(cliente.id, email: "joao.novo@exemplo.com")
|
|
87
|
+
|
|
88
|
+
# Excluir cliente
|
|
89
|
+
Vindi::Customer.delete(cliente.id)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Perfis de Pagamento (`Vindi::PaymentProfile`)
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
# Criar perfil de pagamento com cartão
|
|
96
|
+
perfil = Vindi::PaymentProfile.create(
|
|
97
|
+
customer_id: 12345,
|
|
98
|
+
payment_company_code: "visa",
|
|
99
|
+
holder_name: "JOAO SILVA",
|
|
100
|
+
card_number: "4111111111111111",
|
|
101
|
+
card_expiration_date: "12/2030",
|
|
102
|
+
card_cvv: "123"
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
# Excluir perfil de pagamento
|
|
106
|
+
Vindi::PaymentProfile.delete(perfil.id)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Assinaturas (`Vindi::Subscription`)
|
|
110
|
+
|
|
111
|
+
```ruby
|
|
112
|
+
# Criar assinatura
|
|
113
|
+
assinatura = Vindi::Subscription.create(
|
|
114
|
+
customer_id: cliente.id,
|
|
115
|
+
plan_id: plano.id,
|
|
116
|
+
payment_method_code: "credit_card"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
# Cancelar/Excluir assinatura
|
|
120
|
+
Vindi::Subscription.delete(assinatura.id)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Cobranças (`Vindi::Charge`)
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
# Listar cobranças pendentes
|
|
127
|
+
cobrancas = Vindi::Charge.list(status: "pending")
|
|
128
|
+
|
|
129
|
+
# Obter valor da primeira cobrança
|
|
130
|
+
puts cobrancas.first.amount
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Planos (`Vindi::Plan`)
|
|
134
|
+
|
|
135
|
+
```ruby
|
|
136
|
+
# Criar um plano
|
|
137
|
+
plano = Vindi::Plan.create(
|
|
138
|
+
name: "Plano Ouro Premium",
|
|
139
|
+
code: "gold_premium",
|
|
140
|
+
interval: "months",
|
|
141
|
+
interval_count: 1
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
# Listar planos
|
|
145
|
+
planos = Vindi::Plan.list
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Produtos & Itens de Produto (`Vindi::Product` & `Vindi::ProductItem`)
|
|
149
|
+
|
|
150
|
+
```ruby
|
|
151
|
+
# Criar um produto
|
|
152
|
+
produto = Vindi::Product.create(
|
|
153
|
+
name: "Serviço de Hospedagem",
|
|
154
|
+
code: "hosting"
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
# Associar um produto a um plano/assinatura
|
|
158
|
+
item_produto = Vindi::ProductItem.create(
|
|
159
|
+
product_id: produto.id,
|
|
160
|
+
plan_id: plano.id
|
|
161
|
+
)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Descontos (`Vindi::Discount`)
|
|
165
|
+
|
|
166
|
+
```ruby
|
|
167
|
+
# Criar/aplicar um desconto
|
|
168
|
+
desconto = Vindi::Discount.create(
|
|
169
|
+
amount: 15.00,
|
|
170
|
+
discount_type: "percentage",
|
|
171
|
+
percentage: 10
|
|
172
|
+
)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Faturas & Itens de Fatura (`Vindi::Bill` & `Vindi::BillItem`)
|
|
176
|
+
|
|
177
|
+
```ruby
|
|
178
|
+
# Criar uma fatura manualmente
|
|
179
|
+
fatura = Vindi::Bill.create(
|
|
180
|
+
customer_id: cliente.id,
|
|
181
|
+
payment_method_code: "credit_card",
|
|
182
|
+
bill_items: [
|
|
183
|
+
{ product_id: produto.id, amount: 99.90 }
|
|
184
|
+
]
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
# Listar itens de uma fatura
|
|
188
|
+
itens = Vindi::BillItem.list(bill_id: fatura.id)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Períodos (`Vindi::Period`)
|
|
192
|
+
|
|
193
|
+
```ruby
|
|
194
|
+
# Listar períodos de uma assinatura
|
|
195
|
+
periodos = Vindi::Period.list(subscription_id: assinatura.id)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Transações (`Vindi::Transaction`)
|
|
199
|
+
|
|
200
|
+
```ruby
|
|
201
|
+
# Criar uma transação manual (captura de cobrança)
|
|
202
|
+
transacao = Vindi::Transaction.create(
|
|
203
|
+
charge_id: cobranca.id,
|
|
204
|
+
amount: 99.90
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
# Listar transações
|
|
208
|
+
transacoes = Vindi::Transaction.list
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Consumos/Usos (`Vindi::Usage`)
|
|
212
|
+
|
|
213
|
+
```ruby
|
|
214
|
+
# Informar consumo de uso de uma assinatura
|
|
215
|
+
uso = Vindi::Usage.create(
|
|
216
|
+
subscription_id: assinatura.id,
|
|
217
|
+
quantity: 50,
|
|
218
|
+
description: "Chamadas de API consumidas"
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
# Listar consumos informados
|
|
222
|
+
usos = Vindi::Usage.list(subscription_id: assinatura.id)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Notas Fiscais (`Vindi::Invoice`)
|
|
226
|
+
|
|
227
|
+
```ruby
|
|
228
|
+
# Listar notas fiscais emitidas
|
|
229
|
+
notas_fiscais = Vindi::Invoice.list(status: "issued")
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Problemas/Pendências (`Vindi::Issue`)
|
|
233
|
+
|
|
234
|
+
```ruby
|
|
235
|
+
# Atualizar status de uma pendência (ex: marcar como resolvida)
|
|
236
|
+
pendencia = Vindi::Issue.update(issue_id, status: "resolved")
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Lotes de Importação/Exportação (`Vindi::ImportBatch` & `Vindi::ExportBatch`)
|
|
240
|
+
|
|
241
|
+
```ruby
|
|
242
|
+
# Iniciar lote para importação de clientes/assinaturas
|
|
243
|
+
lote_importacao = Vindi::ImportBatch.create(
|
|
244
|
+
batch_type: "customer",
|
|
245
|
+
file_url: "https://exemplo.com/importacao.csv"
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
# Solicitar lote de exportação de dados
|
|
249
|
+
lote_exportacao = Vindi::ExportBatch.create(
|
|
250
|
+
batch_type: "bill"
|
|
251
|
+
)
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## 4. Gems de Extensão Adicionais
|
|
257
|
+
|
|
258
|
+
Para manter a biblioteca core leve e livre de dependências acopladas, as features específicas do Rails são distribuídas por meio de gems complementares.
|
|
259
|
+
|
|
260
|
+
### 4.1 Integrações de Backend ([`vindi-rails-integrations`](https://github.com/wesleyskap/vindi-rails-integrations))
|
|
261
|
+
|
|
262
|
+
Fornece sincronização automática de modelos do ActiveRecord, endpoints de webhook, jobs de processamento assíncrono e tarefas administrativas via Rake.
|
|
263
|
+
|
|
264
|
+
#### Instalação
|
|
265
|
+
Adicione a gem ao seu Gemfile:
|
|
266
|
+
```ruby
|
|
267
|
+
gem 'vindi-rails-integrations'
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
#### Configuração de Webhooks
|
|
271
|
+
Gere o controller de webhook e o manipulador correspondente na sua aplicação Rails:
|
|
272
|
+
```bash
|
|
273
|
+
bundle exec rails generate vindi:webhook
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
##### 1. Webhooks Controller (`app/controllers/vindi/webhooks_controller.rb`)
|
|
277
|
+
Valida as notificações via POST enviadas pela Vindi comparando um token de segurança recebido via parâmetros.
|
|
278
|
+
- **Endpoint**: `POST /vindi/webhooks?token=SEU_TOKEN_SEGURO`
|
|
279
|
+
- **Resposta do Controller**: Retorna `{ "status": "received" }` com status `200 OK` em caso de sucesso, ou `{ "error": "Unauthorized access token" }` (`401 Unauthorized`) / `{ "error": "Invalid payload" }` (`400 Bad Request`).
|
|
280
|
+
|
|
281
|
+
##### 2. Processamento Assíncrono (`app/jobs/vindi/webhook_job.rb`)
|
|
282
|
+
Processa os eventos em background. Inclui regras de segurança recomendadas, como a validação de idempotência.
|
|
283
|
+
|
|
284
|
+
##### 3. Handlers Modulares de Webhooks
|
|
285
|
+
Para arquiteturas mais limpas, separe o processamento de cada tipo de evento em arquivos de serviço dedicados:
|
|
286
|
+
```bash
|
|
287
|
+
bundle exec rails generate vindi:webhook_handler subscription_canceled
|
|
288
|
+
```
|
|
289
|
+
Isso gera `app/services/vindi/webhooks/base_handler.rb` (classe base) e `app/services/vindi/webhooks/subscription_canceled_handler.rb`. O `WebhookJob` gerado descobrirá e despachará automaticamente para essas classes modulares de forma dinâmica.
|
|
290
|
+
|
|
291
|
+
###### Exemplo de Payload de Webhook Vindi (Evento)
|
|
292
|
+
```json
|
|
293
|
+
{
|
|
294
|
+
"event": {
|
|
295
|
+
"id": 1928374,
|
|
296
|
+
"type": "bill_paid",
|
|
297
|
+
"created_at": "2026-06-10T15:00:00.000-03:00",
|
|
298
|
+
"data": {
|
|
299
|
+
"bill": {
|
|
300
|
+
"id": 887766,
|
|
301
|
+
"amount": "150.00",
|
|
302
|
+
"status": "paid",
|
|
303
|
+
"customer": {
|
|
304
|
+
"id": 112233,
|
|
305
|
+
"name": "Jane Doe",
|
|
306
|
+
"email": "jane.doe@example.com",
|
|
307
|
+
"code": "user_42"
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### Sincronização de ActiveRecord
|
|
316
|
+
Associe qualquer modelo ActiveRecord (ex: `User`, `Account`) para ser sincronizado automaticamente com os Clientes da Vindi.
|
|
317
|
+
|
|
318
|
+
##### 1. Configuração do Gerador
|
|
319
|
+
Execute o gerador de sincronização para o seu modelo:
|
|
320
|
+
```bash
|
|
321
|
+
bundle exec rails generate vindi:sync User
|
|
322
|
+
```
|
|
323
|
+
Isso criará uma migração para adicionar a coluna `vindi_customer_id` (String) à tabela correspondente e incluirá o módulo `Vindi::Synchronizable`.
|
|
324
|
+
|
|
325
|
+
##### 2. Uso & Sobrescrita de Atributos
|
|
326
|
+
Inclua o Concern `Vindi::Synchronizable` e customize o mapeamento de atributos se necessário:
|
|
327
|
+
```ruby
|
|
328
|
+
class User < ApplicationRecord
|
|
329
|
+
include Vindi::Synchronizable
|
|
330
|
+
|
|
331
|
+
# Opcional: Personalizar os atributos enviados à Vindi
|
|
332
|
+
def vindi_customer_attributes
|
|
333
|
+
{
|
|
334
|
+
name: "#{first_name} #{last_name}",
|
|
335
|
+
email: email,
|
|
336
|
+
registry_code: cpf_ou_cnpj, # Se aplicável
|
|
337
|
+
code: "user_#{id}"
|
|
338
|
+
}
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Quando um registro do modelo for salvo, os seguintes gatilhos serão acionados:
|
|
344
|
+
- **Ao Criar**: Chama `Vindi::Customer.create` e salva o `vindi_customer_id` retornado diretamente no seu banco local.
|
|
345
|
+
- **Ao Atualizar**: Verifica se `name` ou `email` mudaram e chama `Vindi::Customer.update` para sincronizar os dados na Vindi.
|
|
346
|
+
|
|
347
|
+
##### 3. Fila Outbox Transacional Resiliente (Opcional)
|
|
348
|
+
Para evitar requisições HTTP síncronas de rede dentro das suas transações de banco de dados locais e garantir maior resiliência:
|
|
349
|
+
|
|
350
|
+
1. Gere a migração do outbox:
|
|
351
|
+
```bash
|
|
352
|
+
bundle exec rails generate vindi:outbox
|
|
353
|
+
bundle exec rails db:migrate
|
|
354
|
+
```
|
|
355
|
+
2. Habilite-o no initializer de configuração:
|
|
356
|
+
```ruby
|
|
357
|
+
Vindi.configure do |config|
|
|
358
|
+
config.use_outbox = true
|
|
359
|
+
end
|
|
360
|
+
```
|
|
361
|
+
3. Ao cadastrar/atualizar um registro local, as pendências são salvas na tabela `vindi_pending_syncs` na mesma transação local, e o job `Vindi::ProcessPendingSyncsJob` é disparado assincronamente após o commit para fazer a sincronização final.
|
|
362
|
+
|
|
363
|
+
#### Tarefas Rake (Rake Tasks)
|
|
364
|
+
A gem disponibiliza ferramentas para auditoria e teste de integração local:
|
|
365
|
+
|
|
366
|
+
##### 1. Auditoria de Sincronização (`vindi:audit`)
|
|
367
|
+
Compara a base local do seu modelo com o cadastro de clientes da API da Vindi:
|
|
368
|
+
```bash
|
|
369
|
+
bundle exec rake vindi:audit model=User
|
|
370
|
+
```
|
|
371
|
+
**Exemplo de log de saída da auditoria:**
|
|
372
|
+
```text
|
|
373
|
+
Analyzing User database...
|
|
374
|
+
[Audit] Checking User ID: 42 (Vindi ID: 112233) - Match found.
|
|
375
|
+
[Audit] Checking User ID: 43 (Vindi ID: nil) - Missing in Vindi!
|
|
376
|
+
[Audit Warning] User ID 43 created in Vindi with customer ID 112234.
|
|
377
|
+
Reconciliation complete. 1 missing records synchronized.
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
##### 2. Simulador de Webhook (`vindi:test_webhook`)
|
|
381
|
+
Envia uma requisição POST de teste simulando um evento da Vindi diretamente para o seu endpoint local:
|
|
382
|
+
```bash
|
|
383
|
+
bundle exec rake vindi:test_webhook event=bill_paid url=http://localhost:3000/vindi/webhooks token=SEU_TOKEN_SEGURO
|
|
384
|
+
```
|
|
385
|
+
**Exemplo de requisição enviada:**
|
|
386
|
+
```text
|
|
387
|
+
Sending POST to http://localhost:3000/vindi/webhooks?token=SEU_TOKEN_SEGURO...
|
|
388
|
+
Payload: {"event":{"id":9999,"type":"bill_paid","data":{...}}}
|
|
389
|
+
Response Code: 200 OK
|
|
390
|
+
Response Body: {"status":"received"}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
##### 3. Diagnóstico e Conectividade (`vindi:status`)
|
|
394
|
+
Verifica as credenciais configuradas na API, ambiente ativo e executa testes rápidos de conectividade em tempo real com mascaramento seguro:
|
|
395
|
+
```bash
|
|
396
|
+
bundle exec rake vindi:status
|
|
397
|
+
```
|
|
398
|
+
**Exemplo de log de status:**
|
|
399
|
+
```text
|
|
400
|
+
=== Vindi Integration Status ===
|
|
401
|
+
Environment: Sandbox
|
|
402
|
+
API URL: https://sandbox-gp.vindi.com.br/api/v1
|
|
403
|
+
API Key: *****2345
|
|
404
|
+
Webhook: *****_999
|
|
405
|
+
--------------------------------
|
|
406
|
+
Connectivity: SUCCESS
|
|
407
|
+
================================
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
### 4.2 Componentes Front-End ([`vindi-rails-engines`](https://github.com/wesleyskap/vindi-rails-engines))
|
|
413
|
+
|
|
414
|
+
Assets e templates prontos para captura de dados de pagamento seguros no navegador em conformidade com as regras PCI.
|
|
415
|
+
|
|
416
|
+
#### Instalação
|
|
417
|
+
Adicione a gem ao seu Gemfile:
|
|
418
|
+
```ruby
|
|
419
|
+
gem 'vindi-rails-engines'
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
#### Configuração do Checkout
|
|
423
|
+
Inicialize os templates HTML e controladores Stimulus JS:
|
|
424
|
+
```bash
|
|
425
|
+
bundle exec rails generate vindi:checkout
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
##### 1. Controlador Stimulus JS (`app/javascript/controllers/vindi_checkout_controller.js`)
|
|
429
|
+
Intercepta a submissão do formulário, serializa os dados do cartão, comunica-se com o tokenizador JS da Vindi e injeta o token gerado em um campo oculto antes de enviar os dados ao Rails:
|
|
430
|
+
```javascript
|
|
431
|
+
// Connects to data-controller="vindi-checkout"
|
|
432
|
+
import { Controller } from "@hotwired/stimulus"
|
|
433
|
+
|
|
434
|
+
export default class extends Controller {
|
|
435
|
+
static targets = [ "publicKey", "holderName", "cardNumber", "expiry", "cvv", "tokenInput" ]
|
|
436
|
+
|
|
437
|
+
tokenizeCard(event) {
|
|
438
|
+
event.preventDefault()
|
|
439
|
+
const vindi = new Vindi(this.publicKeyTarget.value)
|
|
440
|
+
|
|
441
|
+
vindi.createToken({
|
|
442
|
+
holder_name: this.holderNameTarget.value,
|
|
443
|
+
card_number: this.cardNumberTarget.value.replace(/\s+/g, ''),
|
|
444
|
+
card_expiration: this.expiryTarget.value,
|
|
445
|
+
card_cvv: this.cvvTarget.value
|
|
446
|
+
}).then((response) => {
|
|
447
|
+
// response: { token: "tok_abc123XYZ", created_at: "2026-06-10..." }
|
|
448
|
+
this.tokenInputTarget.value = response.token
|
|
449
|
+
this.element.submit()
|
|
450
|
+
}).catch((error) => {
|
|
451
|
+
alert("Erro de Tokenização: " + error.message)
|
|
452
|
+
})
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
##### 2. Exemplo de Resposta de Chave Pública da Vindi
|
|
458
|
+
Ao chamar `vindi.createToken(...)` com os dados do cartão, o SDK Javascript da Vindi retorna o token de perfil de pagamento:
|
|
459
|
+
```json
|
|
460
|
+
{
|
|
461
|
+
"token": "tok_3278918239abc",
|
|
462
|
+
"created_at": "2026-06-10T16:50:00.000-03:00"
|
|
463
|
+
}
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Utilize este token (`payment_profile_token`) no seu controller Rails no backend para criar assinaturas ou transações com segurança:
|
|
467
|
+
```ruby
|
|
468
|
+
# Exemplo de Controller processando o token do checkout
|
|
469
|
+
def charge
|
|
470
|
+
Vindi::Charge.create(
|
|
471
|
+
payment_method_code: "credit_card",
|
|
472
|
+
payment_profile: {
|
|
473
|
+
token: params[:payment_profile_token]
|
|
474
|
+
},
|
|
475
|
+
amount: "150.00",
|
|
476
|
+
customer_id: current_user.vindi_customer_id
|
|
477
|
+
)
|
|
478
|
+
end
|
|
479
|
+
```
|