@lina-openx/react-native-lina-pay-sdk 1.0.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.
- package/LinaPaySdk.podspec +20 -0
- package/README.md +522 -0
- package/android/build.gradle +77 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/linapaysdk/LinaPaySdkModule.kt +18 -0
- package/android/src/main/java/com/linapaysdk/LinaPaySdkPackage.kt +17 -0
- package/ios/LinaPaySdk.h +5 -0
- package/ios/LinaPaySdk.mm +16 -0
- package/lib/module/config/environment.js +61 -0
- package/lib/module/config/environment.js.map +1 -0
- package/lib/module/index.js +142 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/services/auth.service.js +73 -0
- package/lib/module/services/auth.service.js.map +1 -0
- package/lib/module/services/consent.service.js +49 -0
- package/lib/module/services/consent.service.js.map +1 -0
- package/lib/module/services/participants.service.js +71 -0
- package/lib/module/services/participants.service.js.map +1 -0
- package/lib/module/services/payment.service.js +39 -0
- package/lib/module/services/payment.service.js.map +1 -0
- package/lib/module/types/auth.types.js +2 -0
- package/lib/module/types/auth.types.js.map +1 -0
- package/lib/module/types/consent.types.js +2 -0
- package/lib/module/types/consent.types.js.map +1 -0
- package/lib/module/types/index.js +2 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/types/participants.types.js +2 -0
- package/lib/module/types/participants.types.js.map +1 -0
- package/lib/module/types/payment.types.js +2 -0
- package/lib/module/types/payment.types.js.map +1 -0
- package/lib/module/utils/consent.utils.js +168 -0
- package/lib/module/utils/consent.utils.js.map +1 -0
- package/lib/module/utils/http.utils.js +58 -0
- package/lib/module/utils/http.utils.js.map +1 -0
- package/lib/module/utils/payment.utils.js +27 -0
- package/lib/module/utils/payment.utils.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/config/environment.d.ts +38 -0
- package/lib/typescript/src/config/environment.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +108 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/services/auth.service.d.ts +13 -0
- package/lib/typescript/src/services/auth.service.d.ts.map +1 -0
- package/lib/typescript/src/services/consent.service.d.ts +9 -0
- package/lib/typescript/src/services/consent.service.d.ts.map +1 -0
- package/lib/typescript/src/services/participants.service.d.ts +9 -0
- package/lib/typescript/src/services/participants.service.d.ts.map +1 -0
- package/lib/typescript/src/services/payment.service.d.ts +9 -0
- package/lib/typescript/src/services/payment.service.d.ts.map +1 -0
- package/lib/typescript/src/types/auth.types.d.ts +23 -0
- package/lib/typescript/src/types/auth.types.d.ts.map +1 -0
- package/lib/typescript/src/types/consent.types.d.ts +129 -0
- package/lib/typescript/src/types/consent.types.d.ts.map +1 -0
- package/lib/typescript/src/types/index.d.ts +9 -0
- package/lib/typescript/src/types/index.d.ts.map +1 -0
- package/lib/typescript/src/types/participants.types.d.ts +50 -0
- package/lib/typescript/src/types/participants.types.d.ts.map +1 -0
- package/lib/typescript/src/types/payment.types.d.ts +107 -0
- package/lib/typescript/src/types/payment.types.d.ts.map +1 -0
- package/lib/typescript/src/utils/consent.utils.d.ts +10 -0
- package/lib/typescript/src/utils/consent.utils.d.ts.map +1 -0
- package/lib/typescript/src/utils/http.utils.d.ts +21 -0
- package/lib/typescript/src/utils/http.utils.d.ts.map +1 -0
- package/lib/typescript/src/utils/payment.utils.d.ts +10 -0
- package/lib/typescript/src/utils/payment.utils.d.ts.map +1 -0
- package/package.json +169 -0
- package/src/config/environment.ts +58 -0
- package/src/index.tsx +178 -0
- package/src/services/auth.service.ts +88 -0
- package/src/services/consent.service.ts +63 -0
- package/src/services/participants.service.ts +89 -0
- package/src/services/payment.service.ts +49 -0
- package/src/types/auth.types.ts +24 -0
- package/src/types/consent.types.ts +152 -0
- package/src/types/index.ts +34 -0
- package/src/types/participants.types.ts +53 -0
- package/src/types/payment.types.ts +141 -0
- package/src/utils/consent.utils.ts +225 -0
- package/src/utils/http.utils.ts +80 -0
- package/src/utils/payment.utils.ts +32 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "LinaPaySdk"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"]
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
|
|
13
|
+
s.platforms = { :ios => min_ios_version_supported }
|
|
14
|
+
s.source = { :git => "https://gitlab.com/lina-infratech/ob-data-pull/react-native-lina-pay-sdk.git", :tag => "#{s.version}" }
|
|
15
|
+
|
|
16
|
+
s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
|
|
17
|
+
s.private_header_files = "ios/**/*.h"
|
|
18
|
+
|
|
19
|
+
install_modules_dependencies(s)
|
|
20
|
+
end
|
package/README.md
ADDED
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
# react-native-lina-pay-sdk
|
|
2
|
+
|
|
3
|
+
SDK React Native para integração com Lina Open Finance - Facilitando a criação de pagamentos através do Open Finance.
|
|
4
|
+
|
|
5
|
+
## 📖 Documentação
|
|
6
|
+
|
|
7
|
+
- **[Guia do Usuário Completo](./docs/USER_GUIDE.md)** - Documentação detalhada para implementação
|
|
8
|
+
- **[Diagramas de Fluxo](./docs/FLOW_DIAGRAM.md)** - Diagramas visuais do fluxo de pagamento
|
|
9
|
+
|
|
10
|
+
## 🚀 Instalação
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
npm install react-native-lina-pay-sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
ou
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
yarn add react-native-lina-pay-sdk
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## 📋 Requisitos
|
|
23
|
+
|
|
24
|
+
- React Native >= 0.83.0
|
|
25
|
+
- Node >= 20
|
|
26
|
+
|
|
27
|
+
## 🔧 Uso
|
|
28
|
+
|
|
29
|
+
### Configuração Inicial
|
|
30
|
+
|
|
31
|
+
Por padrão, o SDK está configurado para usar o ambiente de homologação (HML). Para produção ou outros ambientes, configure as URLs base:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import LinaPaySdk from 'react-native-lina-pay-sdk';
|
|
35
|
+
|
|
36
|
+
// Configurar para produção
|
|
37
|
+
LinaPaySdk.configure({
|
|
38
|
+
iamBaseUrl: 'https://iam.prod.linaob.com.br',
|
|
39
|
+
apiBaseUrl: 'https://embedded-payment-manager.prod.linaob.com.br'
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Listagem de Participantes
|
|
44
|
+
|
|
45
|
+
Obtenha a lista de instituições financeiras participantes do Open Finance:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { getParticipants, type Participant, LinaPayError } from 'react-native-lina-pay-sdk';
|
|
49
|
+
|
|
50
|
+
async function fetchParticipants() {
|
|
51
|
+
try {
|
|
52
|
+
const participants = await getParticipants({
|
|
53
|
+
subtenantId: 'seu-subtenant-id',
|
|
54
|
+
subtenantSecret: 'seu-subtenant-secret'
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
console.log(`${participants.length} participantes encontrados`);
|
|
58
|
+
|
|
59
|
+
participants.forEach(participant => {
|
|
60
|
+
console.log(`${participant.customerFriendlyName} - ${participant.registrationNumber}`);
|
|
61
|
+
});
|
|
62
|
+
} catch (error) {
|
|
63
|
+
if (error instanceof LinaPayError) {
|
|
64
|
+
console.error('Erro Lina Pay:', error.message, error.statusCode);
|
|
65
|
+
} else {
|
|
66
|
+
console.error('Erro desconhecido:', error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Criação de Consentimento de Pagamento
|
|
73
|
+
|
|
74
|
+
Crie um consentimento para iniciar um pagamento via Open Finance:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { createConsent, type CreateConsentRequest, LinaPayError } from 'react-native-lina-pay-sdk';
|
|
78
|
+
|
|
79
|
+
async function createPaymentConsent() {
|
|
80
|
+
try {
|
|
81
|
+
const payload: CreateConsentRequest = {
|
|
82
|
+
organisationId: 'c8f0bf49-4744-4933-8960-7add6e590841',
|
|
83
|
+
authorisationServerId: 'c8f0bf49-4744-4933-8960-7add6e590841',
|
|
84
|
+
payment: {
|
|
85
|
+
redirectUri: 'http://example.com/redirect',
|
|
86
|
+
value: 1500.50,
|
|
87
|
+
creditor: {
|
|
88
|
+
name: 'John Doe',
|
|
89
|
+
personType: 'PESSOA_NATURAL',
|
|
90
|
+
cpfCnpj: '12345678901234',
|
|
91
|
+
accountNumber: '1234567890',
|
|
92
|
+
accountIssuer: '0001',
|
|
93
|
+
accountPixKey: 'email@example.com',
|
|
94
|
+
accountIspb: '12345678',
|
|
95
|
+
accountType: 'CACC'
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
platform: 'APP'
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const consent = await createConsent(
|
|
102
|
+
{
|
|
103
|
+
subtenantId: 'seu-subtenant-id',
|
|
104
|
+
subtenantSecret: 'seu-subtenant-secret'
|
|
105
|
+
},
|
|
106
|
+
payload
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
console.log('Consentimento criado:', consent.consentId);
|
|
110
|
+
console.log('Status:', consent.status);
|
|
111
|
+
console.log('URL de redirecionamento:', consent.redirectUrl);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
if (error instanceof LinaPayError) {
|
|
114
|
+
console.error('Erro ao criar consentimento:', error.message);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Criação de Pagamento
|
|
121
|
+
|
|
122
|
+
Após o usuário autorizar o consentimento, crie o pagamento usando os parâmetros retornados:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { createPayment, type CreatePaymentRequest, LinaPayError } from 'react-native-lina-pay-sdk';
|
|
126
|
+
|
|
127
|
+
async function processPayment() {
|
|
128
|
+
try {
|
|
129
|
+
// state, code e idToken são retornados após autorização do consentimento
|
|
130
|
+
const payment = await createPayment(
|
|
131
|
+
{
|
|
132
|
+
subtenantId: 'seu-subtenant-id',
|
|
133
|
+
subtenantSecret: 'seu-subtenant-secret'
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
state: 'rumUP',
|
|
137
|
+
code: '1RDYVFQnPn721',
|
|
138
|
+
idToken: 'eyJhbGciOiJQUz',
|
|
139
|
+
tenantId: 'tenantId'
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
console.log('Pagamento criado:', payment.id);
|
|
144
|
+
console.log('Status:', payment.status);
|
|
145
|
+
console.log('Valor:', payment.value);
|
|
146
|
+
console.log('Itens de pagamento:', payment.payments.length);
|
|
147
|
+
} catch (error) {
|
|
148
|
+
if (error instanceof LinaPayError) {
|
|
149
|
+
console.error('Erro ao criar pagamento:', error.message);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Exemplo Completo com React
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
import React, { useState } from 'react';
|
|
159
|
+
import { View, Button, FlatList, Text } from 'react-native';
|
|
160
|
+
import { getParticipants, type Participant } from 'react-native-lina-pay-sdk';
|
|
161
|
+
|
|
162
|
+
export default function ParticipantsList() {
|
|
163
|
+
const [participants, setParticipants] = useState<Participant[]>([]);
|
|
164
|
+
const [loading, setLoading] = useState(false);
|
|
165
|
+
|
|
166
|
+
const loadParticipants = async () => {
|
|
167
|
+
setLoading(true);
|
|
168
|
+
try {
|
|
169
|
+
const result = await getParticipants({
|
|
170
|
+
subtenantId: process.env.SUBTENANT_ID!,
|
|
171
|
+
subtenantSecret: process.env.SUBTENANT_SECRET!
|
|
172
|
+
});
|
|
173
|
+
setParticipants(result);
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.error(error);
|
|
176
|
+
} finally {
|
|
177
|
+
setLoading(false);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
return (
|
|
182
|
+
<View>
|
|
183
|
+
<Button
|
|
184
|
+
title="Carregar Participantes"
|
|
185
|
+
onPress={loadParticipants}
|
|
186
|
+
disabled={loading}
|
|
187
|
+
/>
|
|
188
|
+
<FlatList
|
|
189
|
+
data={participants}
|
|
190
|
+
keyExtractor={(item) => `${item.organisationId}-${item.authorisationServerId}`}
|
|
191
|
+
renderItem={({ item }) => (
|
|
192
|
+
<View>
|
|
193
|
+
<Text>{item.customerFriendlyName}</Text>
|
|
194
|
+
<Text>{item.legalEntityName}</Text>
|
|
195
|
+
<Text>CNPJ: {item.registrationNumber}</Text>
|
|
196
|
+
</View>
|
|
197
|
+
)}
|
|
198
|
+
/>
|
|
199
|
+
</View>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## 📚 API Reference
|
|
205
|
+
|
|
206
|
+
### `createConsent(credentials, payload)`
|
|
207
|
+
|
|
208
|
+
Cria um consentimento de pagamento via Open Finance.
|
|
209
|
+
|
|
210
|
+
**Parâmetros:**
|
|
211
|
+
- `credentials` (objeto, obrigatório):
|
|
212
|
+
- `subtenantId` (string): ID do subtenant fornecido pela Lina
|
|
213
|
+
- `subtenantSecret` (string): Secret do subtenant fornecido pela Lina
|
|
214
|
+
- `payload` (objeto, obrigatório):
|
|
215
|
+
- `organisationId` (string, obrigatório): UUID da organização participante
|
|
216
|
+
- `authorisationServerId` (string, obrigatório): UUID do servidor de autorização
|
|
217
|
+
- `payment` (objeto, obrigatório):
|
|
218
|
+
- `redirectUri` (string, obrigatório): URL de redirecionamento após autorização
|
|
219
|
+
- `value` (number, obrigatório): Valor do pagamento (deve ser positivo)
|
|
220
|
+
- `creditor` (objeto, obrigatório):
|
|
221
|
+
- `name` (string, obrigatório): Nome do beneficiário
|
|
222
|
+
- `personType` (string, obrigatório): Tipo de pessoa ('PESSOA_NATURAL' | 'PESSOA_JURIDICA')
|
|
223
|
+
- `cpfCnpj` (string, obrigatório): CPF (11 dígitos) ou CNPJ (14 dígitos)
|
|
224
|
+
- `accountNumber` (string, obrigatório): Número da conta
|
|
225
|
+
- `accountIssuer` (string, obrigatório): Agência
|
|
226
|
+
- `accountPixKey` (string, obrigatório): Chave PIX
|
|
227
|
+
- `accountIspb` (string, obrigatório): Código ISPB
|
|
228
|
+
- `accountType` (string, obrigatório): Tipo de conta ('CACC' | 'SLRY' | 'SVGS' | 'TRAN')
|
|
229
|
+
- `details` (string, opcional): Detalhes do pagamento
|
|
230
|
+
- `externalId` (string, opcional): ID externo
|
|
231
|
+
- `cpfCnpj` (string, opcional): CPF/CNPJ do pagador
|
|
232
|
+
- `debitor` (objeto, opcional): Informações do pagador
|
|
233
|
+
- `schedule` (objeto, opcional): Agendamento do pagamento
|
|
234
|
+
- `txId` (string | string[], opcional): ID(s) da transação
|
|
235
|
+
- `redirectUri` (string, opcional): URL de redirecionamento alternativa
|
|
236
|
+
- `platform` (string, opcional): Plataforma ('APP' | 'WEB')
|
|
237
|
+
|
|
238
|
+
**Retorna:** `Promise<CreateConsentResponse>`
|
|
239
|
+
|
|
240
|
+
**Estrutura do CreateConsentResponse:**
|
|
241
|
+
```typescript
|
|
242
|
+
interface CreateConsentResponse {
|
|
243
|
+
consentId: string; // URN do consentimento criado
|
|
244
|
+
redirectUrl: string; // URL para autorização do usuário
|
|
245
|
+
id: string; // UUID interno do consentimento
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**Exemplo de resposta:**
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"consentId": "urn:nubank:796a30aa-0a3c-3f60-acb1-d6097864267e",
|
|
253
|
+
"redirectUrl": "https://nuapp.nubank.com.br/open-banking/authorize?request_uri=...",
|
|
254
|
+
"id": "60735a9c-0036-4b1a-9247-2fd8ef651c7b"
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**Exemplo com Agendamento:**
|
|
259
|
+
```typescript
|
|
260
|
+
const consentWithSchedule = await createConsent(credentials, {
|
|
261
|
+
organisationId: 'org-uuid',
|
|
262
|
+
authorisationServerId: 'auth-uuid',
|
|
263
|
+
payment: {
|
|
264
|
+
redirectUri: 'http://example.com/redirect',
|
|
265
|
+
value: 1500.50,
|
|
266
|
+
creditor: { /* ... */ },
|
|
267
|
+
schedule: {
|
|
268
|
+
single: {
|
|
269
|
+
date: '2024-09-01' // Pagamento único em data específica
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
**Tipos de Agendamento Disponíveis:**
|
|
277
|
+
- `single`: Pagamento único em data específica
|
|
278
|
+
- `daily`: Pagamentos diários recorrentes
|
|
279
|
+
- `weekly`: Pagamentos semanais recorrentes
|
|
280
|
+
- `monthly`: Pagamentos mensais recorrentes
|
|
281
|
+
- `custom`: Datas customizadas
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
### `createPayment(credentials, payload)`
|
|
286
|
+
|
|
287
|
+
Cria um pagamento após validação do consentimento via Open Finance.
|
|
288
|
+
|
|
289
|
+
**Parâmetros:**
|
|
290
|
+
- `credentials` (objeto, obrigatório):
|
|
291
|
+
- `subtenantId` (string): ID do subtenant fornecido pela Lina
|
|
292
|
+
- `subtenantSecret` (string): Secret do subtenant fornecido pela Lina
|
|
293
|
+
- `payload` (objeto, obrigatório):
|
|
294
|
+
- `state` (string, obrigatório): Estado retornado após autorização do consentimento
|
|
295
|
+
- `code` (string, obrigatório): Código retornado após autorização do consentimento
|
|
296
|
+
- `idToken` (string, obrigatório): Token ID retornado após autorização do consentimento
|
|
297
|
+
- `tenantId` (string, obrigatório): ID do tenant
|
|
298
|
+
|
|
299
|
+
**Retorna:** `Promise<CreatePaymentResponse>`
|
|
300
|
+
|
|
301
|
+
**Estrutura do CreatePaymentResponse:**
|
|
302
|
+
```typescript
|
|
303
|
+
interface CreatePaymentResponse {
|
|
304
|
+
id: string; // UUID do pagamento
|
|
305
|
+
type: PaymentType; // Tipo do pagamento (ex: 'NOW')
|
|
306
|
+
createDateTime: string; // Data/hora de criação (ISO 8601)
|
|
307
|
+
externalId?: string; // ID externo
|
|
308
|
+
externalComment?: string; // Comentário externo
|
|
309
|
+
lastChangedDateTime: string; // Data/hora da última alteração (ISO 8601)
|
|
310
|
+
status: PaymentStatus; // Status do pagamento (ex: 'CONSUMIDO', 'PAGO')
|
|
311
|
+
tenantId: string; // ID do tenant
|
|
312
|
+
cpfCnpj: string; // CPF/CNPJ do pagador
|
|
313
|
+
redirectUri: string; // URL de redirecionamento
|
|
314
|
+
value: string; // Valor do pagamento (como string)
|
|
315
|
+
consentId: string; // URN do consentimento associado
|
|
316
|
+
creditor: PaymentCreditor; // Informações do beneficiário
|
|
317
|
+
debitor?: PaymentDebitor; // Informações do pagador
|
|
318
|
+
payments: PaymentItem[]; // Array de itens de pagamento
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
interface PaymentItem {
|
|
322
|
+
endToEndId: string; // ID end-to-end da transação
|
|
323
|
+
id: string; // UUID do item de pagamento
|
|
324
|
+
dueDate: string; // Data de vencimento (ISO 8601)
|
|
325
|
+
externalComment?: string; // Comentário externo
|
|
326
|
+
txId: string | null; // ID da transação (pode ser null)
|
|
327
|
+
status: PaymentItemStatus; // Status do item (ex: 'PAGO')
|
|
328
|
+
externalPaymentId: string; // ID externo do pagamento
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
**Exemplo de uso:**
|
|
333
|
+
```typescript
|
|
334
|
+
import { createPayment, type CreatePaymentRequest } from 'react-native-lina-pay-sdk';
|
|
335
|
+
|
|
336
|
+
const payment = await createPayment(
|
|
337
|
+
{
|
|
338
|
+
subtenantId: 'your-subtenant-id',
|
|
339
|
+
subtenantSecret: 'your-subtenant-secret'
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
state: 'rumUP',
|
|
343
|
+
code: '1RDYVFQnPn721',
|
|
344
|
+
idToken: 'eyJhbGciOiJQUz',
|
|
345
|
+
tenantId: 'tenantId'
|
|
346
|
+
}
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
console.log('Payment ID:', payment.id);
|
|
350
|
+
console.log('Status:', payment.status);
|
|
351
|
+
console.log('Value:', payment.value);
|
|
352
|
+
console.log('Payments count:', payment.payments.length);
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**Observações:**
|
|
356
|
+
- Este método deve ser chamado após o usuário autorizar o consentimento
|
|
357
|
+
- Os parâmetros `state`, `code` e `idToken` são retornados após a autorização do consentimento
|
|
358
|
+
- O valor do pagamento é retornado como string pela API
|
|
359
|
+
- O array `payments` contém os detalhes de cada pagamento individual processado
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
### `getParticipants(credentials)`
|
|
364
|
+
|
|
365
|
+
Obtém a lista de participantes registrados no Open Finance.
|
|
366
|
+
|
|
367
|
+
**Parâmetros:**
|
|
368
|
+
- `credentials` (objeto, obrigatório):
|
|
369
|
+
- `subtenantId` (string): ID do subtenant fornecido pela Lina
|
|
370
|
+
- `subtenantSecret` (string): Secret do subtenant fornecido pela Lina
|
|
371
|
+
|
|
372
|
+
**Retorna:** `Promise<Participant[]>`
|
|
373
|
+
|
|
374
|
+
**Estrutura do Participant:**
|
|
375
|
+
```typescript
|
|
376
|
+
interface Participant {
|
|
377
|
+
organisationId: string; // UUID da organização
|
|
378
|
+
organisationName: string; // Nome da organização
|
|
379
|
+
legalEntityName: string; // Razão social
|
|
380
|
+
registrationNumber: string; // CNPJ
|
|
381
|
+
authorisationServerId: string; // UUID do servidor de autorização
|
|
382
|
+
customerFriendlyName: string; // Nome amigável
|
|
383
|
+
customerFriendlyLogoUri: string; // URL do logotipo
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
**Observações:**
|
|
388
|
+
- Participantes com múltiplos servidores de autorização resultam em múltiplas entradas na lista
|
|
389
|
+
- Participantes sem servidores de autorização são automaticamente filtrados
|
|
390
|
+
- O token de autenticação é gerenciado automaticamente pelo SDK (com cache)
|
|
391
|
+
|
|
392
|
+
### `configure(config)`
|
|
393
|
+
|
|
394
|
+
Configura as URLs base do SDK para diferentes ambientes.
|
|
395
|
+
|
|
396
|
+
**Parâmetros:**
|
|
397
|
+
- `config` (objeto):
|
|
398
|
+
- `iamBaseUrl` (string, opcional): URL base do serviço de autenticação IAM
|
|
399
|
+
- `apiBaseUrl` (string, opcional): URL base da API do Embedded Payment Manager
|
|
400
|
+
|
|
401
|
+
**Valores padrão (Homologação):**
|
|
402
|
+
```typescript
|
|
403
|
+
{
|
|
404
|
+
iamBaseUrl: 'https://iam.hml.linaob.com.br',
|
|
405
|
+
apiBaseUrl: 'https://embedded-payment-manager.hml.linaob.com.br'
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### `LinaPayError`
|
|
410
|
+
|
|
411
|
+
Classe de erro customizada para tratamento de erros do SDK.
|
|
412
|
+
|
|
413
|
+
**Propriedades:**
|
|
414
|
+
- `message` (string): Mensagem de erro
|
|
415
|
+
- `statusCode` (número, opcional): Código HTTP do erro (se aplicável)
|
|
416
|
+
- `originalError` (unknown, opcional): Erro original que causou o LinaPayError
|
|
417
|
+
|
|
418
|
+
## 🔐 Autenticação
|
|
419
|
+
|
|
420
|
+
O SDK gerencia automaticamente a autenticação OAuth2 com o servidor IAM:
|
|
421
|
+
- Token de acesso é obtido usando as credenciais fornecidas
|
|
422
|
+
- Token é cacheado e reutilizado enquanto válido
|
|
423
|
+
- Renovação automática do token quando expira (5 minutos antes da expiração real)
|
|
424
|
+
|
|
425
|
+
## ⚠️ Tratamento de Erros
|
|
426
|
+
|
|
427
|
+
Todos os métodos podem lançar `LinaPayError` nas seguintes situações:
|
|
428
|
+
|
|
429
|
+
- **Credenciais inválidas**: `statusCode: 401` ou `403`
|
|
430
|
+
- **Erro de rede**: Timeout ou sem conexão
|
|
431
|
+
- **Erro do servidor**: `statusCode: 500+`
|
|
432
|
+
- **Validação de payload**: Campos obrigatórios ausentes ou inválidos
|
|
433
|
+
- **Validação de formato**: CPF/CNPJ, URLs, datas ou valores numéricos inválidos
|
|
434
|
+
|
|
435
|
+
Exemplo de tratamento:
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
import { LinaPayError } from 'react-native-lina-pay-sdk';
|
|
439
|
+
|
|
440
|
+
try {
|
|
441
|
+
const consent = await createConsent(credentials, payload);
|
|
442
|
+
} catch (error) {
|
|
443
|
+
if (error instanceof LinaPayError) {
|
|
444
|
+
// Erros de validação (sem statusCode)
|
|
445
|
+
if (!error.statusCode) {
|
|
446
|
+
console.error('Erro de validação:', error.message);
|
|
447
|
+
// Ex: "payment.value must be greater than zero"
|
|
448
|
+
// Ex: "payment.creditor.cpfCnpj must be a valid CPF or CNPJ"
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// Erros HTTP
|
|
453
|
+
switch (error.statusCode) {
|
|
454
|
+
case 400:
|
|
455
|
+
console.error('Payload inválido:', error.message);
|
|
456
|
+
break;
|
|
457
|
+
case 401:
|
|
458
|
+
case 403:
|
|
459
|
+
console.error('Credenciais inválidas');
|
|
460
|
+
break;
|
|
461
|
+
case 500:
|
|
462
|
+
console.error('Erro no servidor');
|
|
463
|
+
break;
|
|
464
|
+
default:
|
|
465
|
+
console.error('Erro:', error.message);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
## 🧪 Desenvolvimento
|
|
472
|
+
|
|
473
|
+
### Rodando o Exemplo
|
|
474
|
+
|
|
475
|
+
O projeto inclui um app de exemplo que demonstra o uso do SDK:
|
|
476
|
+
|
|
477
|
+
```sh
|
|
478
|
+
# Instalar dependências
|
|
479
|
+
yarn
|
|
480
|
+
|
|
481
|
+
# Buildar o SDK
|
|
482
|
+
yarn prepare
|
|
483
|
+
|
|
484
|
+
# Rodar o exemplo no Android
|
|
485
|
+
yarn example android
|
|
486
|
+
|
|
487
|
+
# Rodar o exemplo no iOS
|
|
488
|
+
yarn example ios
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### Testes
|
|
492
|
+
|
|
493
|
+
```sh
|
|
494
|
+
# Rodar testes unitários
|
|
495
|
+
yarn test
|
|
496
|
+
|
|
497
|
+
# Verificar tipos TypeScript
|
|
498
|
+
yarn typecheck
|
|
499
|
+
|
|
500
|
+
# Lint
|
|
501
|
+
yarn lint
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### Estrutura do Projeto
|
|
505
|
+
|
|
506
|
+
```
|
|
507
|
+
src/
|
|
508
|
+
├── config/
|
|
509
|
+
│ └── environment.ts # Configuração de URLs
|
|
510
|
+
├── services/
|
|
511
|
+
│ ├── auth.service.ts # Autenticação OAuth2
|
|
512
|
+
│ └── participants.service.ts # API de participantes
|
|
513
|
+
├── types/
|
|
514
|
+
│ ├── auth.types.ts # Tipos de autenticação
|
|
515
|
+
│ ├── participants.types.ts # Tipos de participantes
|
|
516
|
+
│ └── index.ts # Re-exports
|
|
517
|
+
├── utils/
|
|
518
|
+
│ └── http.utils.ts # Utilidades HTTP
|
|
519
|
+
└── index.tsx # API pública do SDK
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
Desenvolvido por [Lina OpenX](https://www.linaopenx.com.br/) com ❤️
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
ext.getExtOrDefault = {name ->
|
|
3
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['LinaPaySdk_' + name]
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
repositories {
|
|
7
|
+
google()
|
|
8
|
+
mavenCentral()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
dependencies {
|
|
12
|
+
classpath "com.android.tools.build:gradle:8.7.2"
|
|
13
|
+
// noinspection DifferentKotlinGradleVersion
|
|
14
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
apply plugin: "com.android.library"
|
|
20
|
+
apply plugin: "kotlin-android"
|
|
21
|
+
|
|
22
|
+
apply plugin: "com.facebook.react"
|
|
23
|
+
|
|
24
|
+
def getExtOrIntegerDefault(name) {
|
|
25
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["LinaPaySdk_" + name]).toInteger()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
android {
|
|
29
|
+
namespace "com.linapaysdk"
|
|
30
|
+
|
|
31
|
+
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
|
|
32
|
+
|
|
33
|
+
defaultConfig {
|
|
34
|
+
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
|
|
35
|
+
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
buildFeatures {
|
|
39
|
+
buildConfig true
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
buildTypes {
|
|
43
|
+
release {
|
|
44
|
+
minifyEnabled false
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
lintOptions {
|
|
49
|
+
disable "GradleCompatible"
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
compileOptions {
|
|
53
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
54
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
sourceSets {
|
|
58
|
+
main {
|
|
59
|
+
java.srcDirs += [
|
|
60
|
+
"generated/java",
|
|
61
|
+
"generated/jni"
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
repositories {
|
|
68
|
+
mavenCentral()
|
|
69
|
+
google()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
def kotlin_version = getExtOrDefault("kotlinVersion")
|
|
73
|
+
|
|
74
|
+
dependencies {
|
|
75
|
+
implementation "com.facebook.react:react-android"
|
|
76
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
77
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
package com.linapaysdk
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
5
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
6
|
+
|
|
7
|
+
@ReactModule(name = LinaPaySdkModule.NAME)
|
|
8
|
+
class LinaPaySdkModule(reactContext: ReactApplicationContext) :
|
|
9
|
+
ReactContextBaseJavaModule(reactContext) {
|
|
10
|
+
|
|
11
|
+
override fun getName(): String {
|
|
12
|
+
return NAME
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
companion object {
|
|
16
|
+
const val NAME = "LinaPaySdk"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package com.linapaysdk
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
|
|
8
|
+
class LinaPaySdkPackage : ReactPackage {
|
|
9
|
+
@Deprecated("Use createNativeModules(ReactApplicationContext) instead.")
|
|
10
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
11
|
+
return listOf(LinaPaySdkModule(reactContext))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
15
|
+
return emptyList()
|
|
16
|
+
}
|
|
17
|
+
}
|
package/ios/LinaPaySdk.h
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#import "LinaPaySdk.h"
|
|
2
|
+
|
|
3
|
+
@implementation LinaPaySdk
|
|
4
|
+
|
|
5
|
+
RCT_EXPORT_MODULE()
|
|
6
|
+
|
|
7
|
+
// Don't compile this code when we build for the old architecture.
|
|
8
|
+
#ifdef RCT_NEW_ARCH_ENABLED
|
|
9
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
10
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
11
|
+
{
|
|
12
|
+
return nullptr;
|
|
13
|
+
}
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
@end
|