diff --git a/docs/INDEX.md b/docs/INDEX.md new file mode 100644 index 0000000..d8ac727 --- /dev/null +++ b/docs/INDEX.md @@ -0,0 +1,172 @@ +# Índice da Documentação + +Navegue facilmente por toda a documentação do Asaas SDK. + +## 🚀 Começando + +| Documento | Descrição | +|-----------|-----------| +| [README Principal](README.md) | Visão geral completa do SDK | +| [Guia de Início Rápido](quickstart.md) | Comece em minutos | +| [Configurações Extras](extra.md) | Sandbox, timeout, rate limit | + +## 💰 Pagamentos e Cobranças + +| Documento | Descrição | +|-----------|-----------| +| [Cobranças](payment.md) | Criar, listar, estornar cobranças (PIX, Boleto, Cartão) | +| [Cobranças com Split](payment_split.md) | Dividir pagamentos entre múltiplas contas | +| [Links de Pagamento](paymentlink.md) | Criar páginas de checkout personalizadas | +| [Assinaturas](subscription.md) | Pagamentos recorrentes automáticos | +| [Parcelamentos](installment.md) | Gerenciar cobranças parceladas | + +## 🔷 PIX + +| Documento | Descrição | +|-----------|-----------| +| [PIX - QR Code e Chaves](pix_dict.md) | Criar QR codes, gerenciar chaves PIX | +| [PIX - Transações](pix_transaction.md) | Enviar e receber pagamentos PIX | +| [PIX Automático](pix_automatic.md) | Débito recorrente via PIX | + +## 💸 Transferências + +| Documento | Descrição | +|-----------|-----------| +| [Transferências](transfer.md) | TED, PIX e transferências internas | +| [Pagar Contas](bill.md) | Pagamento de boletos de terceiros | + +## 👥 Gestão de Clientes + +| Documento | Descrição | +|-----------|-----------| +| [Clientes](customeraccount.md) | CRUD completo de clientes | +| [Notificações](notification.md) | Gerenciar notificações de clientes | + +## 🏢 Gestão de Conta + +| Documento | Descrição | +|-----------|-----------| +| [Subcontas](account.md) | Criar e gerenciar subcontas | +| [Saldo](balance.md) | Consultar saldo disponível | +| [Extrato](financial.md) | Visualizar transações financeiras | +| [Dados Comerciais](commercialinfo.md) | Atualizar informações da empresa | +| [Status da Conta](myaccount.md) | Verificar situação da conta | +| [Taxas](accountfee.md) | Consultar taxas aplicadas | +| [Número de Conta](accountnumber.md) | Obter dados bancários | + +## 🔔 Notificações e Integrações + +| Documento | Descrição | +|-----------|-----------| +| [Webhooks](webhook.md) | Configurar notificações automáticas via HTTP | +| [Notas Fiscais](invoice.md) | Emitir e gerenciar NF-e | + +## ⚙️ Configurações e Limites + +| Documento | Descrição | +|-----------|-----------| +| [Configurações Extras](extra.md) | Sandbox, timeout e outras configurações | +| [Rate Limit](ratelimit.md) | Entender limites de requisição | + +## 📊 Por Categoria + +### Para Iniciantes +1. [Guia de Início Rápido](quickstart.md) +2. [Clientes](customeraccount.md) +3. [Cobranças](payment.md) +4. [Webhooks](webhook.md) + +### Pagamentos +1. [Cobranças](payment.md) +2. [PIX - Transações](pix_transaction.md) +3. [Links de Pagamento](paymentlink.md) +4. [Assinaturas](subscription.md) + +### PIX Completo +1. [PIX - QR Code e Chaves](pix_dict.md) +2. [PIX - Transações](pix_transaction.md) +3. [PIX Automático](pix_automatic.md) + +### Gestão Financeira +1. [Saldo](balance.md) +2. [Extrato](financial.md) +3. [Transferências](transfer.md) +4. [Taxas](accountfee.md) + +### Avançado +1. [Cobranças com Split](payment_split.md) +2. [PIX Automático](pix_automatic.md) +3. [Subcontas](account.md) +4. [Notas Fiscais](invoice.md) + +## 🔍 Busca Rápida + +### Quero criar... +- **Uma cobrança PIX** → [Cobranças](payment.md) +- **Um QR Code PIX** → [PIX - QR Code e Chaves](pix_dict.md) +- **Uma assinatura mensal** → [Assinaturas](subscription.md) +- **Um link de pagamento** → [Links de Pagamento](paymentlink.md) +- **Um cliente** → [Clientes](customeraccount.md) +- **Um webhook** → [Webhooks](webhook.md) + +### Quero enviar... +- **Um PIX** → [PIX - Transações](pix_transaction.md) +- **Uma transferência TED** → [Transferências](transfer.md) +- **Dinheiro entre minhas contas** → [Transferências](transfer.md) + +### Quero consultar... +- **Meu saldo** → [Saldo](balance.md) +- **Meu extrato** → [Extrato](financial.md) +- **Minhas taxas** → [Taxas](accountfee.md) +- **Status da minha conta** → [Status da Conta](myaccount.md) + +### Quero gerenciar... +- **Chaves PIX** → [PIX - QR Code e Chaves](pix_dict.md) +- **Clientes** → [Clientes](customeraccount.md) +- **Subcontas** → [Subcontas](account.md) +- **Notificações** → [Notificações](notification.md) + +## 📱 Recursos por Tipo de Negócio + +### E-commerce +- [Cobranças](payment.md) - Receber pagamentos +- [Links de Pagamento](paymentlink.md) - Checkout personalizado +- [Webhooks](webhook.md) - Notificações automáticas +- [Cobranças com Split](payment_split.md) - Marketplace + +### SaaS +- [Assinaturas](subscription.md) - Pagamentos recorrentes +- [Clientes](customeraccount.md) - Gestão de usuários +- [Webhooks](webhook.md) - Integração com sistema +- [Notas Fiscais](invoice.md) - Emissão automática + +### Marketplace +- [Cobranças com Split](payment_split.md) - Dividir pagamentos +- [Subcontas](account.md) - Conta para cada vendedor +- [Transferências](transfer.md) - Repasses automáticos +- [Webhooks](webhook.md) - Notificações em tempo real + +### Serviços Financeiros +- [PIX - Transações](pix_transaction.md) - Enviar e receber PIX +- [Transferências](transfer.md) - TED e transferências +- [Saldo](balance.md) - Consultar saldo +- [Extrato](financial.md) - Movimentações + +## 🆘 Precisa de Ajuda? + +- 📖 [README Principal](README.md) - Visão geral +- 💻 [Exemplos de Código](https://github.com/jpdev01/asaasSdk/blob/master/src/main/java/io/github/jpdev/asaassdk/doc/Examples.java) +- 🌐 [Documentação Oficial Asaas](https://docs.asaas.com) +- 🐛 [Reportar Problemas](https://github.com/jpdev01/asaasSdk/issues) + +## 📝 Convenções da Documentação + +- ✅ Exemplos testados e funcionais +- 💡 Dicas e boas práticas destacadas +- ⚠️ Avisos importantes sobre limitações +- 📊 Tabelas de referência rápida +- 🔗 Links para documentação relacionada + +--- + +**Dica**: Use `Ctrl+F` (ou `Cmd+F` no Mac) para buscar palavras-chave nesta página! diff --git a/docs/NAVIGATION.md b/docs/NAVIGATION.md new file mode 100644 index 0000000..c612afe --- /dev/null +++ b/docs/NAVIGATION.md @@ -0,0 +1,269 @@ +# 🗺️ Mapa de Navegação - Asaas SDK + +Guia visual para encontrar rapidamente o que você precisa na documentação. + +## 🎯 Comece Aqui + +``` +┌─────────────────────────────────────────────────────────────┐ +│ │ +│ 👋 NOVO NO SDK? │ +│ │ +│ 1. Leia o README.md │ +│ 2. Siga o quickstart.md │ +│ 3. Explore os exemplos práticos │ +│ │ +└─────────────────────────────────────────────────────────────┘ +``` + +## 📚 Estrutura da Documentação + +``` +📁 Asaas SDK Documentation +│ +├── 📄 README.md ⭐ COMECE AQUI +│ └── Visão geral completa do SDK +│ +├── 📄 quickstart.md ⚡ INÍCIO RÁPIDO +│ └── Seu primeiro código em minutos +│ +├── 📄 INDEX.md 🗂️ ÍNDICE COMPLETO +│ └── Navegação por categoria +│ +├── 📄 IMPROVEMENTS.md 📝 NOVIDADES +│ └── O que foi melhorado +│ +├── 💰 PAGAMENTOS +│ ├── payment.md ⭐ PRINCIPAL +│ │ ├── Criar cobranças (PIX, Boleto, Cartão) +│ │ ├── Listar e filtrar +│ │ ├── Estornar +│ │ └── Gerenciar status +│ │ +│ ├── subscription.md 🔄 RECORRENTE +│ │ ├── Assinaturas mensais/anuais +│ │ ├── Todos os ciclos +│ │ └── Casos de uso (SaaS, Academia, etc) +│ │ +│ ├── payment_split.md 🔀 MARKETPLACE +│ │ └── Dividir pagamentos +│ │ +│ ├── paymentlink.md 🔗 CHECKOUT +│ │ └── Links de pagamento +│ │ +│ └── installment.md 📊 PARCELAS +│ └── Gerenciar parcelamentos +│ +├── 🔷 PIX +│ ├── pix_dict.md ⭐ QR CODE E CHAVES +│ │ ├── Criar QR Codes +│ │ ├── Gerenciar chaves +│ │ └── Decodificar QR Codes +│ │ +│ ├── pix_transaction.md 💸 TRANSAÇÕES +│ │ ├── Enviar PIX +│ │ ├── Pagar QR Code +│ │ ├── PIX recorrente +│ │ └── Agendamento +│ │ +│ └── pix_automatic.md 🤖 AUTOMÁTICO +│ └── Débito recorrente via PIX +│ +├── 👥 CLIENTES +│ ├── customeraccount.md ⭐ PRINCIPAL +│ │ ├── Criar clientes (PF/PJ) +│ │ ├── Listar e filtrar +│ │ ├── Atualizar dados +│ │ └── Validações +│ │ +│ └── notification.md 🔔 NOTIFICAÇÕES +│ └── Gerenciar notificações +│ +├── 💸 TRANSFERÊNCIAS +│ ├── transfer.md ⭐ PRINCIPAL +│ │ ├── TED +│ │ ├── PIX +│ │ └── Transferências internas +│ │ +│ └── bill.md 📄 PAGAR CONTAS +│ └── Pagamento de boletos +│ +├── 🏢 GESTÃO DE CONTA +│ ├── balance.md 💰 SALDO +│ ├── financial.md 📊 EXTRATO +│ ├── account.md 🏦 SUBCONTAS +│ ├── accountfee.md 💵 TAXAS +│ ├── accountnumber.md 🔢 DADOS BANCÁRIOS +│ ├── myaccount.md ✅ STATUS +│ └── commercialinfo.md 🏢 DADOS COMERCIAIS +│ +├── 🔗 INTEGRAÇÕES +│ ├── webhook.md ⭐ WEBHOOKS +│ │ └── Notificações automáticas +│ │ +│ └── invoice.md 📑 NOTAS FISCAIS +│ └── Emitir NF-e +│ +└── ⚙️ CONFIGURAÇÕES + ├── extra.md 🔧 EXTRAS + │ ├── Sandbox + │ ├── Timeout + │ └── Rate limit + │ + └── ratelimit.md 📈 LIMITES + └── Entender rate limits +``` + +## 🎯 Fluxos Comuns + +### 💳 Receber um Pagamento + +``` +1. customeraccount.md → Criar cliente +2. payment.md → Criar cobrança +3. webhook.md → Configurar notificações +4. payment.md → Verificar status +``` + +### 🔄 Criar Assinatura Recorrente + +``` +1. customeraccount.md → Criar cliente +2. subscription.md → Criar assinatura +3. webhook.md → Configurar notificações +4. payment.md → Monitorar cobranças +``` + +### 💸 Enviar um PIX + +``` +1. pix_dict.md → Criar/verificar chave PIX +2. pix_transaction.md → Enviar PIX +3. balance.md → Verificar saldo +``` + +### 🛒 E-commerce Completo + +``` +1. customeraccount.md → Criar cliente +2. payment.md → Criar cobrança +3. webhook.md → Receber notificações +4. payment.md → Confirmar pagamento +5. invoice.md → Emitir nota fiscal (opcional) +``` + +### 🏪 Marketplace com Split + +``` +1. account.md → Criar subcontas para vendedores +2. customeraccount.md → Criar cliente comprador +3. payment_split.md → Criar cobrança com split +4. webhook.md → Notificar vendedores +5. transfer.md → Gerenciar repasses +``` + +### 💼 SaaS com Assinatura + +``` +1. customeraccount.md → Criar cliente +2. subscription.md → Criar assinatura mensal +3. webhook.md → Monitorar pagamentos +4. payment.md → Tratar inadimplência +5. invoice.md → Emitir NF-e mensal +``` + +## 🔍 Busca Rápida por Palavra-Chave + +| Procurando por... | Vá para... | +|-------------------|------------| +| **Cobrança** | [payment.md](payment.md) | +| **PIX** | [pix_dict.md](pix_dict.md), [pix_transaction.md](pix_transaction.md) | +| **Boleto** | [payment.md](payment.md) | +| **Cartão** | [payment.md](payment.md) | +| **Assinatura** | [subscription.md](subscription.md) | +| **Recorrente** | [subscription.md](subscription.md) | +| **Cliente** | [customeraccount.md](customeraccount.md) | +| **QR Code** | [pix_dict.md](pix_dict.md) | +| **Transferência** | [transfer.md](transfer.md) | +| **TED** | [transfer.md](transfer.md) | +| **Saldo** | [balance.md](balance.md) | +| **Extrato** | [financial.md](financial.md) | +| **Webhook** | [webhook.md](webhook.md) | +| **Notificação** | [notification.md](notification.md), [webhook.md](webhook.md) | +| **Split** | [payment_split.md](payment_split.md) | +| **Marketplace** | [payment_split.md](payment_split.md) | +| **Subconta** | [account.md](account.md) | +| **Nota Fiscal** | [invoice.md](invoice.md) | +| **Sandbox** | [extra.md](extra.md) | +| **Rate Limit** | [ratelimit.md](ratelimit.md) | +| **Link de Pagamento** | [paymentlink.md](paymentlink.md) | +| **Parcelamento** | [installment.md](installment.md) | + +## 📊 Por Nível de Experiência + +### 🌱 Iniciante + +**Comece por aqui:** +1. [README.md](README.md) - Visão geral +2. [quickstart.md](quickstart.md) - Primeiro código +3. [customeraccount.md](customeraccount.md) - Criar clientes +4. [payment.md](payment.md) - Criar cobranças + +**Depois explore:** +- [pix_dict.md](pix_dict.md) - PIX básico +- [webhook.md](webhook.md) - Notificações + +### 🌿 Intermediário + +**Você já sabe o básico, agora:** +1. [subscription.md](subscription.md) - Assinaturas +2. [pix_transaction.md](pix_transaction.md) - Transações PIX +3. [transfer.md](transfer.md) - Transferências +4. [paymentlink.md](paymentlink.md) - Links de pagamento + +**Explore também:** +- [balance.md](balance.md) - Gestão financeira +- [financial.md](financial.md) - Extrato +- [invoice.md](invoice.md) - Notas fiscais + +### 🌳 Avançado + +**Recursos avançados:** +1. [payment_split.md](payment_split.md) - Split de pagamentos +2. [pix_automatic.md](pix_automatic.md) - PIX automático +3. [account.md](account.md) - Subcontas +4. [extra.md](extra.md) - Configurações avançadas + +**Otimização:** +- [ratelimit.md](ratelimit.md) - Gerenciar limites +- Todos os filtros e paginação + +## 🎨 Legenda + +- ⭐ **Documentação principal** - Comece por aqui +- ⚡ **Início rápido** - Para começar rapidamente +- 🔄 **Recorrente** - Pagamentos automáticos +- 🔀 **Split** - Divisão de pagamentos +- 🤖 **Automático** - Processos automatizados +- 💸 **Transações** - Movimentações financeiras +- 🔔 **Notificações** - Alertas e webhooks +- 🔧 **Configurações** - Setup e ajustes + +## 💡 Dicas de Navegação + +1. **Use o INDEX.md** para visão geral por categoria +2. **Use este mapa** para fluxos específicos +3. **Cada documento tem** um índice no topo +4. **Links "Veja Também"** no final de cada documento +5. **Busque por palavra-chave** na tabela acima + +## 🆘 Precisa de Ajuda? + +- 📖 Não encontrou o que procura? Veja o [INDEX.md](INDEX.md) +- 🚀 Primeiro uso? Comece pelo [quickstart.md](quickstart.md) +- 💬 Dúvidas? [Abra uma issue](https://github.com/jpdev01/asaasSdk/issues) +- 📚 Documentação oficial: [docs.asaas.com](https://docs.asaas.com) + +--- + +**Navegação feliz! 🎉** diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..deda35a --- /dev/null +++ b/docs/README.md @@ -0,0 +1,215 @@ +# Asaas SDK para Java + +[![SonarQube](https://sonarcloud.io/api/project_badges/measure?project=jpdev01_asaasSdk&metric=alert_status)](https://sonarcloud.io/summary/overall?id=jpdev01_asaasSdk) +[![Maven Central](https://img.shields.io/maven-central/v/io.github.jpdev01/asaassdk.svg)](https://repo1.maven.org/maven2/io/github/jpdev01/asaassdk/) + +SDK Java oficial para integração com a API do [Asaas](https://asaas.com.br), desenvolvido por [@jpdev01](https://github.com/jpdev01) para facilitar o desenvolvimento de aplicações que utilizam os serviços de pagamento do Asaas. + +## 📋 Índice + +- [Instalação](#-instalação) +- [Início Rápido](#-início-rápido) +- [Configuração](#-configuração) +- [Recursos](#-recursos) +- [Exemplos de Uso](#-exemplos-de-uso) +- [Documentação Completa](#-documentação-completa) +- [Suporte e Contribuição](#-suporte-e-contribuição) + +## 🚀 Começando + +Novo no SDK? Comece pelo [Guia de Início Rápido](quickstart.md) para estar operacional em minutos! + +## 🚀 Instalação + +### Maven + +Adicione a dependência no seu `pom.xml`: + +```xml + + io.github.jpdev01 + asaassdk + 4 + +``` + +### Gradle + +```gradle +implementation 'io.github.jpdev01:asaassdk:1.4' +``` + +## ⚡ Início Rápido + +### 1. Inicialização + +Antes de realizar qualquer requisição, inicialize o SDK com sua chave de API: + +```java +import io.github.jpdev.asaassdk.Asaas; + +public class Main { + public static void main(String[] args) { + // Ambiente de produção + Asaas.init("sua_chave_api"); + + // Ou ambiente sandbox para testes + Asaas.initSandbox("sua_chave_api_sandbox"); + } +} +``` + +Para o guia completo de ínicio rápido veja [Quick Start](./quickstart.md) + +## ⚙️ Configurações adicionais + +[Configurações adicionais](./extra.md) + +## 🎯 Recursos + +O SDK oferece suporte completo para todos os recursos da API Asaas: + +### Pagamentos e Cobranças +- ✅ Cobranças (Boleto, PIX, Cartão de Crédito) +- ✅ Cobranças Parceladas +- ✅ Split de Pagamentos +- ✅ Links de Pagamento +- ✅ Assinaturas Recorrentes +- ✅ Estornos + +### PIX +- ✅ QR Code Estático e Dinâmico +- ✅ Chaves PIX (Criar, Listar, Deletar) +- ✅ Transações PIX +- ✅ PIX Automático (Débito Recorrente) +- ✅ Pagamento via QR Code + +### Transferências +- ✅ TED +- ✅ PIX +- ✅ Transferências Internas (entre contas Asaas) +- ✅ Transferências Recorrentes + +### Gestão de Conta +- ✅ Clientes +- ✅ Subcontas +- ✅ Saldo e Extrato +- ✅ Dados Comerciais +- ✅ Taxas da Conta +- ✅ Status da Conta + +### Outros +- ✅ Webhooks +- ✅ Notificações +- ✅ Notas Fiscais +- ✅ Pagamento de Contas (Boletos) + + +## 📖 Documentação Completa + +### Guias por Funcionalidade + +#### 🚀 Começando +- [Guia de Início Rápido](quickstart.md) - Primeiros passos com o SDK + +#### Pagamentos +- [Cobranças](payment.md) - Criar, listar, estornar cobranças +- [Cobranças com Split](payment_split.md) - Divisão de pagamentos +- [Links de Pagamento](paymentlink.md) - Criar links de checkout +- [Assinaturas](subscription.md) - Pagamentos recorrentes +- [Parcelamentos](installment.md) - Gestão de parcelas + +#### PIX +- [PIX - QR Code e Chaves](pix_dict.md) - Gerenciar chaves e QR codes +- [PIX - Transações](pix_transaction.md) - Enviar e receber PIX +- [PIX Automático](pix_automatic.md) - Débito recorrente via PIX + +#### Transferências e Pagamentos +- [Transferências](transfer.md) - TED, PIX e transferências internas +- [Pagar Contas](bill.md) - Pagamento de boletos + +#### Gestão +- [Clientes](customeraccount.md) - CRUD de clientes +- [Subcontas](account.md) - Gerenciar subcontas +- [Saldo](balance.md) - Consultar saldo +- [Extrato](financial.md) - Transações financeiras +- [Dados Comerciais](commercialinfo.md) - Informações da empresa +- [Status da Conta](myaccount.md) - Situação da conta +- [Taxas](accountfee.md) - Consultar taxas +- [Número de Conta](accountnumber.md) - Dados bancários + +#### Notificações e Integrações +- [Webhooks](webhook.md) - Configurar notificações automáticas +- [Notificações](notification.md) - Gerenciar notificações +- [Notas Fiscais](invoice.md) - Emitir NF-e + +#### Configurações +- [Configurações Extras](extra.md) - Sandbox, timeout, rate limit +- [Rate Limit](ratelimit.md) - Limites de requisição + +### Recursos Adicionais + +- [Exemplos Completos](https://github.com/jpdev01/asaasSdk/blob/master/src/main/java/io/github/jpdev/asaassdk/doc/Examples.java) +- [Documentação Oficial da API Asaas](https://docs.asaas.com/docs/visao-geral) +- [Repositório Maven](https://repo1.maven.org/maven2/io/github/jpdev01/asaassdk/) + +## 🔒 Segurança + +- Nunca exponha suas chaves de API em código público +- Use variáveis de ambiente para armazenar credenciais +- Utilize o ambiente sandbox para testes +- Implemente validação de webhooks para garantir autenticidade + +```java +// Exemplo usando variável de ambiente +String apiKey = System.getenv("ASAAS_API_KEY"); +Asaas.init(apiKey); +``` + +## 🐛 Tratamento de Erros + +```java +try { + Payment payment = Payment.creator() + .setCustomer("cus_invalid") + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("100.00"))) + .create(); +} catch (AsaasException e) { + System.err.println("Erro ao criar cobrança: " + e.getMessage()); + // Trate o erro apropriadamente +} +``` + +## 📊 Análise de Qualidade + +O projeto é continuamente analisado pelo SonarQube. Confira o relatório completo: +- [SonarCloud - Análise de Código](https://sonarcloud.io/summary/overall?id=jpdev01_asaasSdk) + +## 🤝 Suporte e Contribuição + +### Reportar Problemas + +Encontrou um bug ou tem uma sugestão? Abra uma [issue no GitHub](https://github.com/jpdev01/asaasSdk/issues). + +### Contribuir + +Contribuições são bem-vindas! Sinta-se à vontade para abrir Pull Requests com as alterações + +### Comunidade + +- [GitHub](https://github.com/jpdev01/asaasSdk) +- [Documentação Asaas](https://docs.asaas.com) + +## 📝 Licença + +Este projeto está sob a licença MIT. Veja o arquivo LICENSE para mais detalhes. + +## 🙏 Agradecimentos + +Desenvolvido com ❤️ por [@jpdev01](https://github.com/jpdev01) + +--- + +**Nota**: Este SDK não é oficial e não possui vínculo direto com o Asaas. Para suporte oficial da API, consulte a [documentação do Asaas](https://docs.asaas.com). diff --git a/docs/account.md b/docs/account.md index 1b8329f..05988f1 100644 --- a/docs/account.md +++ b/docs/account.md @@ -1,16 +1,277 @@ -## Criar subconta +# Subcontas (Accounts) + +Crie e gerencie subcontas vinculadas à sua conta principal. Ideal para marketplaces, franquias e empresas que precisam segregar operações. + +## 📋 Índice + +- [Criar Subconta](#criar-subconta) +- [Recuperar Subconta](#recuperar-subconta) +- [Listar Subcontas](#listar-subcontas) +- [Atualizar Subconta](#atualizar-subconta) +- [Casos de Uso](#casos-de-uso) + +## Criar Subconta + +### Subconta Pessoa Jurídica + ```java -Account account = Account.creator() - .setName("Teste sub conta") - .setBirthDate(new Date()) - .setCompanyType("LIMITED") - .setEmail("joaoexample2@gmail.com") - .setPostalCode("36572122") - .setCpfCnpj("87.326.705/0001-81") - .create(); +import io.github.jpdev.asaassdk.rest.account.Account; +import java.util.Date; + +Account subconta = Account.creator() + .setName("Loja Parceira LTDA") + .setEmail("contato@lojaparceira.com") + .setCpfCnpj("12.345.678/0001-90") + .setBirthDate(new Date(2020, 0, 1)) // Data de fundação + .setCompanyType("LIMITED") // Tipo de empresa + .setPhone("4733334444") + .setMobilePhone("47999999999") + .setPostalCode("89010-000") + .setAddress("Rua Principal") + .setAddressNumber("100") + .setProvince("Centro") + .create(); + +System.out.println("Subconta criada: " + subconta.getId()); +System.out.println("Wallet ID: " + subconta.getWalletId()); ``` -## Recuperar subconta +### Subconta Pessoa Física + +```java +Account subconta = Account.creator() + .setName("João Silva") + .setEmail("joao@exemplo.com") + .setCpfCnpj("123.456.789-00") + .setBirthDate(new Date(1990, 0, 15)) + .setPhone("47999999999") + .setPostalCode("89010-000") + .setAddress("Rua das Flores") + .setAddressNumber("50") + .setProvince("Centro") + .create(); +``` + +### Subconta com Dados Completos + +```java +Account subconta = Account.creator() + .setName("Empresa XYZ LTDA") + .setEmail("financeiro@empresaxyz.com") + .setCpfCnpj("12345678000190") + .setBirthDate(new Date(2018, 5, 10)) + .setCompanyType("LIMITED") + .setPhone("4733334444") + .setMobilePhone("47988888888") + .setPostalCode("89010-000") + .setAddress("Avenida Brasil") + .setAddressNumber("1000") + .setComplement("Sala 201") + .setProvince("Centro") + .setSite("https://empresaxyz.com") + .setIncomeValue(50000.00) // Faturamento mensal estimado + .create(); + +System.out.println("Subconta criada com sucesso!"); +System.out.println("ID: " + subconta.getId()); +System.out.println("Wallet ID: " + subconta.getWalletId()); +``` + +## Recuperar Subconta + +```java +Account subconta = Account.fetcher("acc_123456789").fetch(); + +System.out.println("Nome: " + subconta.getName()); +System.out.println("Email: " + subconta.getEmail()); +System.out.println("CPF/CNPJ: " + subconta.getCpfCnpj()); +System.out.println("Wallet ID: " + subconta.getWalletId()); +System.out.println("Status: " + subconta.getStatus()); +``` + +## Listar Subcontas + +```java +import io.github.jpdev.asaassdk.rest.account.ResourceSet; + +ResourceSet subcontas = Account.reader().read(); + +for (Account subconta : subcontas.getData()) { + System.out.println("ID: " + subconta.getId()); + System.out.println("Nome: " + subconta.getName()); + System.out.println("Email: " + subconta.getEmail()); + System.out.println("Wallet ID: " + subconta.getWalletId()); + System.out.println("---"); +} +``` + +## Atualizar Subconta + +```java +Account atualizada = Account.updater("acc_123456789") + .setName("Novo Nome da Empresa") + .setEmail("novoemail@empresa.com") + .setPhone("4733335555") + .update(); + +System.out.println("Subconta atualizada: " + atualizada.getName()); +``` + +## Tipos de Empresa + +| Tipo | Descrição | Valor | +|------|-----------|-------| +| MEI | Microempreendedor Individual | `"MEI"` | +| Limitada | Sociedade Limitada | `"LIMITED"` | +| Individual | Empresário Individual | `"INDIVIDUAL"` | +| Associação | Associação | `"ASSOCIATION"` | + +## Casos de Uso + +### Marketplace + ```java -Account.fetcher(account.id).fetch(); -``` \ No newline at end of file +// Criar subconta para cada vendedor +Account vendedor1 = Account.creator() + .setName("Vendedor A LTDA") + .setEmail("vendedora@marketplace.com") + .setCpfCnpj("12345678000190") + .setBirthDate(new Date(2020, 0, 1)) + .setCompanyType("LIMITED") + .setPostalCode("89010-000") + .create(); + +// Usar o walletId para split de pagamentos +String walletId = vendedor1.getWalletId(); +``` + +### Franquia + +```java +// Criar subconta para cada franqueado +Account franquia = Account.creator() + .setName("Franquia Centro") + .setEmail("centro@franquia.com") + .setCpfCnpj("98765432000100") + .setBirthDate(new Date(2021, 0, 1)) + .setCompanyType("LIMITED") + .setPostalCode("89010-000") + .create(); +``` + +### Filiais + +```java +// Criar subconta para cada filial +Account filial = Account.creator() + .setName("Filial Sul") + .setEmail("sul@empresa.com") + .setCpfCnpj("11122233000144") + .setBirthDate(new Date(2019, 0, 1)) + .setCompanyType("LIMITED") + .setPostalCode("89010-000") + .create(); +``` + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.account.Account; +import java.util.Date; + +public class ExemploSubconta { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Criar subconta + Account subconta = Account.creator() + .setName("Parceiro Comercial LTDA") + .setEmail("parceiro@exemplo.com") + .setCpfCnpj("12345678000190") + .setBirthDate(new Date(2020, 0, 1)) + .setCompanyType("LIMITED") + .setPhone("4733334444") + .setPostalCode("89010-000") + .setAddress("Rua Comercial") + .setAddressNumber("500") + .setProvince("Centro") + .create(); + + System.out.println("Subconta criada!"); + System.out.println("ID: " + subconta.getId()); + System.out.println("Wallet ID: " + subconta.getWalletId()); + + // Recuperar subconta + Account recuperada = Account.fetcher(subconta.getId()).fetch(); + System.out.println("Nome: " + recuperada.getName()); + + // Listar todas as subcontas + ResourceSet subcontas = Account.reader().read(); + System.out.println("Total de subcontas: " + subcontas.getTotalCount()); + } +} +``` + +## Boas Práticas + +### 1. Armazene o Wallet ID + +```java +Account subconta = Account.creator() + .setName("Vendedor") + .setCpfCnpj("12345678000190") + .create(); + +// Salvar no banco de dados +String walletId = subconta.getWalletId(); +// Use este ID para splits e transferências +``` + +### 2. Valide Dados Antes de Criar + +```java +String cnpj = "12.345.678/0001-90"; +String cnpjLimpo = cnpj.replaceAll("[^0-9]", ""); + +if (cnpjLimpo.length() == 14) { + Account subconta = Account.creator() + .setCpfCnpj(cnpjLimpo) + .setName("Empresa") + .create(); +} +``` + +### 3. Trate Erros + +```java +try { + Account subconta = Account.creator() + .setName("Empresa") + .setCpfCnpj("12345678000190") + .create(); +} catch (AsaasException e) { + System.err.println("Erro ao criar subconta: " + e.getMessage()); +} +``` + +## Campos Obrigatórios + +| Campo | Tipo | Descrição | +|-------|------|-----------| +| `name` | String | Nome da pessoa/empresa | +| `email` | String | Email de acesso | +| `cpfCnpj` | String | CPF ou CNPJ | +| `birthDate` | Date | Data de nascimento/fundação | +| `postalCode` | String | CEP | + +## Veja Também + +- [Cobranças com Split](payment_split.md) - Dividir pagamentos entre subcontas +- [Transferências](transfer.md) - Transferir entre contas +- [Clientes](customeraccount.md) - Gerenciar clientes + +## Referências + +- [Documentação Oficial - Subcontas](https://docs.asaas.com/reference/criar-subconta) diff --git a/docs/accountfee.md b/docs/accountfee.md index 75445a9..c700c25 100644 --- a/docs/accountfee.md +++ b/docs/accountfee.md @@ -1,5 +1,347 @@ -## Recuperar taxas da conta - +# Taxas da Conta (Account Fees) + +Consulte as taxas aplicadas à sua conta Asaas. Entenda os custos de cada operação. + +## 📋 Índice + +- [Recuperar Taxas](#recuperar-taxas) +- [Tipos de Taxas](#tipos-de-taxas) +- [Exemplos de Cálculo](#exemplos-de-cálculo) + +## Recuperar Taxas + ```java -AccountFee myFees = AccountFee.fetcher().fetch(); -``` \ No newline at end of file +import io.github.jpdev.asaassdk.rest.accountfee.AccountFee; + +AccountFee taxas = AccountFee.fetcher().fetch(); + +System.out.println("=== TAXAS DA CONTA ==="); +System.out.println("\nPix:"); +System.out.println("Taxa Pix: R$ " + taxas.getPixFee()); + +System.out.println("\nBoleto:"); +System.out.println("Taxa Boleto: R$ " + taxas.getBankSlipFee()); + +System.out.println("\nCartão de Crédito:"); +System.out.println("Taxa à vista: " + taxas.getCreditCardFee() + "%"); +System.out.println("Taxa parcelado em 2x: " + taxas.getCreditCardFeeInstallment2() + "%"); +System.out.println("Taxa parcelado em 3x: " + taxas.getCreditCardFeeInstallment3() + "%"); + +System.out.println("\nTransferências:"); +System.out.println("Taxa TED: R$ " + taxas.getTransferFee()); +System.out.println("Taxa Pix: R$ " + taxas.getPixTransferFee()); +``` + +## Tipos de Taxas + +### Recebimento + +#### + +```java +AccountFee taxas = AccountFee.fetcher().fetch(); + +double taxaPix = taxas.getPixFee(); +System.out.println("Taxa para receber via Pix: R$ " + taxaPix); + +// Exemplo: Receber R$ 100,00 via Pix +double valorRecebido = 100.00; +double taxaCobrada = taxaPix; +double valorLiquido = valorRecebido - taxaCobrada; + +System.out.println("Valor bruto: R$ " + valorRecebido); +System.out.println("Taxa: R$ " + taxaCobrada); +System.out.println("Valor líquido: R$ " + valorLiquido); +``` + +#### Boleto + +```java +double taxaBoleto = taxas.getBankSlipFee(); +System.out.println("Taxa para receber via Boleto: R$ " + taxaBoleto); + +// Exemplo: Receber R$ 500,00 via Boleto +double valorRecebido = 500.00; +double taxaCobrada = taxaBoleto; +double valorLiquido = valorRecebido - taxaCobrada; + +System.out.println("Valor bruto: R$ " + valorRecebido); +System.out.println("Taxa: R$ " + taxaCobrada); +System.out.println("Valor líquido: R$ " + valorLiquido); +``` + +#### Cartão de Crédito + +```java +// À vista +double taxaCartaoVista = taxas.getCreditCardFee(); +System.out.println("Taxa cartão à vista: " + taxaCartaoVista + "%"); + +// Parcelado em 2x +double taxaCartao2x = taxas.getCreditCardFeeInstallment2(); +System.out.println("Taxa cartão 2x: " + taxaCartao2x + "%"); + +// Parcelado em 3x +double taxaCartao3x = taxas.getCreditCardFeeInstallment3(); +System.out.println("Taxa cartão 3x: " + taxaCartao3x + "%"); + +// Exemplo: Receber R$ 1.000,00 no cartão à vista +double valorRecebido = 1000.00; +double taxaCobrada = valorRecebido * (taxaCartaoVista / 100); +double valorLiquido = valorRecebido - taxaCobrada; + +System.out.println("\nCartão à vista:"); +System.out.println("Valor bruto: R$ " + valorRecebido); +System.out.println("Taxa (" + taxaCartaoVista + "%): R$ " + taxaCobrada); +System.out.println("Valor líquido: R$ " + valorLiquido); +``` + +### Transferências + +#### TED + +```java +double taxaTed = taxas.getTransferFee(); +System.out.println("Taxa para TED: R$ " + taxaTed); + +// Exemplo: Transferir R$ 1.000,00 via TED +double valorTransferencia = 1000.00; +double taxaCobrada = taxaTed; +double valorDebitado = valorTransferencia + taxaCobrada; + +System.out.println("Valor da transferência: R$ " + valorTransferencia); +System.out.println("Taxa: R$ " + taxaCobrada); +System.out.println("Total debitado: R$ " + valorDebitado); +``` + +#### Pix (Envio) + +```java +double taxaPixEnvio = taxas.getPixTransferFee(); +System.out.println("Taxa para enviar Pix: R$ " + taxaPixEnvio); + +// Exemplo: Enviar R$ 500,00 via Pix +double valorTransferencia = 500.00; +double taxaCobrada = taxaPixEnvio; +double valorDebitado = valorTransferencia + taxaCobrada; + +System.out.println("Valor da transferência: R$ " + valorTransferencia); +System.out.println("Taxa: R$ " + taxaCobrada); +System.out.println("Total debitado: R$ " + valorDebitado); +``` + +## Exemplos de Cálculo + +### Calcular Valor Líquido de uma Venda + +```java +import java.math.BigDecimal; +import java.math.RoundingMode; + +public class CalculadoraTaxas { + + public static void calcularRecebimentoPix(double valorVenda) { + AccountFee taxas = AccountFee.fetcher().fetch(); + + double taxaPix = taxas.getPixFee(); + double valorLiquido = valorVenda - taxaPix; + + System.out.println("=== RECEBIMENTO VIA Pix ==="); + System.out.println("Valor da venda: R$ " + valorVenda); + System.out.println("Taxa Asaas: R$ " + taxaPix); + System.out.println("Você recebe: R$ " + valorLiquido); + } + + public static void calcularRecebimentoCartao(double valorVenda, int parcelas) { + AccountFee taxas = AccountFee.fetcher().fetch(); + + double percentualTaxa = 0; + if (parcelas == 1) { + percentualTaxa = taxas.getCreditCardFee(); + } else if (parcelas == 2) { + percentualTaxa = taxas.getCreditCardFeeInstallment2(); + } else if (parcelas == 3) { + percentualTaxa = taxas.getCreditCardFeeInstallment3(); + } + + double taxaCobrada = valorVenda * (percentualTaxa / 100); + double valorLiquido = valorVenda - taxaCobrada; + + System.out.println("=== RECEBIMENTO VIA CARTÃO ==="); + System.out.println("Valor da venda: R$ " + valorVenda); + System.out.println("Parcelas: " + parcelas + "x"); + System.out.println("Taxa (" + percentualTaxa + "%): R$ " + taxaCobrada); + System.out.println("Você recebe: R$ " + valorLiquido); + } + + public static void main(String[] args) { + calcularRecebimentoPix(100.00); + System.out.println(); + calcularRecebimentoCartao(1000.00, 1); + } +} +``` + +### Comparar Formas de Pagamento + +```java +public class ComparadorTaxas { + + public static void compararTaxas(double valorVenda) { + AccountFee taxas = AccountFee.fetcher().fetch(); + + System.out.println("=== COMPARAÇÃO DE TAXAS ==="); + System.out.println("Valor da venda: R$ " + valorVenda); + System.out.println(); + + // Pix + double liquidoPix = valorVenda - taxas.getPixFee(); + System.out.println("Pix:"); + System.out.println(" Você recebe: R$ " + liquidoPix); + + // Boleto + double liquidoBoleto = valorVenda - taxas.getBankSlipFee(); + System.out.println("Boleto:"); + System.out.println(" Você recebe: R$ " + liquidoBoleto); + + // Cartão à vista + double taxaCartao = valorVenda * (taxas.getCreditCardFee() / 100); + double liquidoCartao = valorVenda - taxaCartao; + System.out.println("Cartão à vista:"); + System.out.println(" Você recebe: R$ " + liquidoCartao); + + // Melhor opção + double melhorValor = Math.max(liquidoPix, Math.max(liquidoBoleto, liquidoCartao)); + String melhorOpcao = ""; + if (melhorValor == liquidoPix) melhorOpcao = "Pix"; + else if (melhorValor == liquidoBoleto) melhorOpcao = "Boleto"; + else melhorOpcao = "Cartão"; + + System.out.println(); + System.out.println("Melhor opção: " + melhorOpcao); + } + + public static void main(String[] args) { + compararTaxas(500.00); + } +} +``` + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.accountfee.AccountFee; + +public class ExemploTaxas { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Recuperar taxas + AccountFee taxas = AccountFee.fetcher().fetch(); + + System.out.println("=== TAXAS DA SUA CONTA ===\n"); + + // Recebimento + System.out.println("RECEBIMENTO:"); + System.out.println("Pix: R$ " + taxas.getPixFee()); + System.out.println("Boleto: R$ " + taxas.getBankSlipFee()); + System.out.println("Cartão à vista: " + taxas.getCreditCardFee() + "%"); + System.out.println("Cartão 2x: " + taxas.getCreditCardFeeInstallment2() + "%"); + System.out.println("Cartão 3x: " + taxas.getCreditCardFeeInstallment3() + "%"); + + System.out.println("\nTRANSFERÊNCIAS:"); + System.out.println("TED: R$ " + taxas.getTransferFee()); + System.out.println("Pix: R$ " + taxas.getPixTransferFee()); + + // Exemplo de cálculo + System.out.println("\n=== EXEMPLO: VENDA DE R$ 100,00 ==="); + double valorVenda = 100.00; + + double liquidoPix = valorVenda - taxas.getPixFee(); + System.out.println("Recebendo via Pix: R$ " + liquidoPix); + + double liquidoBoleto = valorVenda - taxas.getBankSlipFee(); + System.out.println("Recebendo via Boleto: R$ " + liquidoBoleto); + + double taxaCartao = valorVenda * (taxas.getCreditCardFee() / 100); + double liquidoCartao = valorVenda - taxaCartao; + System.out.println("Recebendo via Cartão: R$ " + liquidoCartao); + } +} +``` + +## Taxas Típicas + +**Nota**: As taxas variam conforme o plano contratado. Consulte sempre via API. + +| Operação | Taxa Típica | +|----------|-------------| +| Pix (receber) | R$ 0,99 a R$ 3,49 | +| Boleto | R$ 1,99 a R$ 3,49 | +| Cartão à vista | 2,99% a 4,99% | +| Cartão parcelado | 3,99% a 6,99% | +| TED | R$ 3,50 a R$ 10,00 | +| Pix (enviar) | R$ 0,00 a R$ 3,50 | + +## Boas Práticas + +### 1. Cache as Taxas + +```java +// Evite consultar a cada operação +private static AccountFee taxasCache = null; +private static long ultimaAtualizacao = 0; + +public static AccountFee getTaxas() { + long agora = System.currentTimeMillis(); + + // Atualizar cache a cada 1 hora + if (taxasCache == null || (agora - ultimaAtualizacao) > 3600000) { + taxasCache = AccountFee.fetcher().fetch(); + ultimaAtualizacao = agora; + } + + return taxasCache; +} +``` + +### 2. Mostre ao Cliente + +```java +// Transparência nas taxas +double valorProduto = 100.00; +double taxaPix = taxas.getPixFee(); +double valorTotal = valorProduto + taxaPix; + +System.out.println("Produto: R$ " + valorProduto); +System.out.println("Taxa Pix: R$ " + taxaPix); +System.out.println("Total: R$ " + valorTotal); +``` + +### 3. Repasse as Taxas + +```java +// Adicionar taxa ao valor da venda +double valorProduto = 100.00; +double taxaPix = taxas.getPixFee(); +double valorComTaxa = valorProduto + taxaPix; + +Payment payment = Payment.creator() + .setCustomer(clienteId) + .setBillingType(BillingType.Pix) + .setValue(Money.create(new BigDecimal(valorComTaxa))) + .create(); +``` + +## Veja Também + +- [Saldo](balance.md) - Consultar saldo disponível +- [Extrato](financial.md) - Ver movimentações +- [Cobranças](payment.md) - Criar cobranças + +## Referências + +- [Documentação Oficial - Taxas](https://docs.asaas.com/reference/consultar-taxas) +- [Planos Asaas](https://www.asaas.com/precos) diff --git a/docs/accountnumber.md b/docs/accountnumber.md index 47401e6..23a513b 100644 --- a/docs/accountnumber.md +++ b/docs/accountnumber.md @@ -1,4 +1,348 @@ -## Recuperar número de conta +# Número de Conta (Account Number) + +Consulte os dados bancários da sua conta Asaas. Use para receber transferências TED/DOC de outras instituições. + +## 📋 Índice + +- [Recuperar Dados Bancários](#recuperar-dados-bancários) +- [Informações Disponíveis](#informações-disponíveis) +- [Como Usar](#como-usar) + +## Recuperar Dados Bancários + ```java -AccountNumber accountNumber = AccountNumber.fetcher().fetch(); -``` \ No newline at end of file +import io.github.jpdev.asaassdk.rest.accountnumber.AccountNumber; + +AccountNumber dadosBancarios = AccountNumber.fetcher().fetch(); + +System.out.println("=== DADOS BANCÁRIOS ==="); +System.out.println("Banco: " + dadosBancarios.getBank()); +System.out.println("Agência: " + dadosBancarios.getAgency()); +System.out.println("Agência (com dígito): " + dadosBancarios.getAgencyDigit()); +System.out.println("Conta: " + dadosBancarios.getAccount()); +System.out.println("Conta (com dígito): " + dadosBancarios.getAccountDigit()); +System.out.println("Tipo de conta: " + dadosBancarios.getAccountType()); +``` + +## Informações Disponíveis + +### Dados Completos + +```java +AccountNumber dados = AccountNumber.fetcher().fetch(); + +// Banco +String banco = dados.getBank(); // Ex: "085" (Ailos) +String nomeBanco = dados.getBankName(); // Ex: "Ailos" + +// Agência +String agencia = dados.getAgency(); // Ex: "0001" +String agenciaDigito = dados.getAgencyDigit(); // Ex: "0001-0" + +// Conta +String conta = dados.getAccount(); // Ex: "12345" +String contaDigito = dados.getAccountDigit(); // Ex: "12345-6" + +// Tipo +String tipoConta = dados.getAccountType(); // Ex: "CONTA_CORRENTE" + +System.out.println("Banco: " + nomeBanco + " (" + banco + ")"); +System.out.println("Agência: " + agenciaDigito); +System.out.println("Conta: " + contaDigito); +System.out.println("Tipo: " + tipoConta); +``` + +### Formato para Exibição + +```java +AccountNumber dados = AccountNumber.fetcher().fetch(); + +String dadosFormatados = String.format( + "Banco: %s (%s)\nAgência: %s\nConta: %s\nTipo: %s", + dados.getBankName(), + dados.getBank(), + dados.getAgencyDigit(), + dados.getAccountDigit(), + dados.getAccountType() +); + +System.out.println(dadosFormatados); +``` + +## Como Usar + +### Receber TED/DOC + +```java +AccountNumber dados = AccountNumber.fetcher().fetch(); + +System.out.println("=== PARA RECEBER TED/DOC ==="); +System.out.println("Informe os seguintes dados:"); +System.out.println(); +System.out.println("Banco: " + dados.getBankName() + " (Código: " + dados.getBank() + ")"); +System.out.println("Agência: " + dados.getAgency()); +System.out.println("Conta: " + dados.getAccount() + "-" + dados.getAccountDigit().split("-")[1]); +System.out.println("Tipo: Conta Corrente"); +System.out.println("Titular: [Seu Nome/Razão Social]"); +System.out.println("CPF/CNPJ: [Seu CPF/CNPJ]"); +``` + +### Exibir no Sistema + +```java +public class DadosBancariosView { + + public static void exibirDadosBancarios() { + AccountNumber dados = AccountNumber.fetcher().fetch(); + + System.out.println("╔════════════════════════════════════════╗"); + System.out.println("║ DADOS BANCÁRIOS ASAAS ║"); + System.out.println("╠════════════════════════════════════════╣"); + System.out.println("║ Banco: " + dados.getBankName()); + System.out.println("║ Código: " + dados.getBank()); + System.out.println("║ Agência: " + dados.getAgencyDigit()); + System.out.println("║ Conta: " + dados.getAccountDigit()); + System.out.println("║ Tipo: " + dados.getAccountType()); + System.out.println("╚════════════════════════════════════════╝"); + } + + public static void main(String[] args) { + Asaas.init("sua_api_key"); + exibirDadosBancarios(); + } +} +``` + +### Gerar Comprovante + +```java +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class ComprovanteGerador { + + public static String gerarComprovante() { + AccountNumber dados = AccountNumber.fetcher().fetch(); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"); + String dataHora = LocalDateTime.now().format(formatter); + + StringBuilder comprovante = new StringBuilder(); + comprovante.append("═══════════════════════════════════════\n"); + comprovante.append(" DADOS BANCÁRIOS ASAAS \n"); + comprovante.append("═══════════════════════════════════════\n\n"); + comprovante.append("Banco: ").append(dados.getBankName()).append("\n"); + comprovante.append("Código do Banco: ").append(dados.getBank()).append("\n"); + comprovante.append("Agência: ").append(dados.getAgencyDigit()).append("\n"); + comprovante.append("Conta: ").append(dados.getAccountDigit()).append("\n"); + comprovante.append("Tipo: ").append(dados.getAccountType()).append("\n\n"); + comprovante.append("───────────────────────────────────────\n"); + comprovante.append("Gerado em: ").append(dataHora).append("\n"); + comprovante.append("═══════════════════════════════════════\n"); + + return comprovante.toString(); + } + + public static void main(String[] args) { + Asaas.init("sua_api_key"); + System.out.println(gerarComprovante()); + } +} +``` + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.accountnumber.AccountNumber; + +public class ExemploDadosBancarios { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Recuperar dados bancários + AccountNumber dados = AccountNumber.fetcher().fetch(); + + // Exibir informações + System.out.println("═══════════════════════════════════════"); + System.out.println(" SEUS DADOS BANCÁRIOS ASAAS "); + System.out.println("═══════════════════════════════════════\n"); + + System.out.println("Banco:"); + System.out.println(" Nome: " + dados.getBankName()); + System.out.println(" Código: " + dados.getBank()); + + System.out.println("\nAgência:"); + System.out.println(" Número: " + dados.getAgency()); + System.out.println(" Com dígito: " + dados.getAgencyDigit()); + + System.out.println("\nConta:"); + System.out.println(" Número: " + dados.getAccount()); + System.out.println(" Com dígito: " + dados.getAccountDigit()); + + System.out.println("\nTipo de Conta:"); + System.out.println(" " + dados.getAccountType()); + + System.out.println("\n═══════════════════════════════════════"); + System.out.println("Use estes dados para receber TED/DOC"); + System.out.println("═══════════════════════════════════════"); + } +} +``` + +## Informações Importantes + +### Banco Asaas + +O Asaas opera através do banco **Ailos** (código 085): + +``` +Banco: Ailos +Código: 085 +Tipo de Conta: Conta Corrente +``` + +### Formato dos Dados + +| Campo | Formato | Exemplo | +|-------|---------|---------| +| Banco | 3 dígitos | `085` | +| Agência | 4 dígitos | `0001` | +| Agência com dígito | 4 dígitos + hífen + 1 dígito | `0001-0` | +| Conta | 5-7 dígitos | `12345` | +| Conta com dígito | 5-7 dígitos + hífen + 1 dígito | `12345-6` | + +## Casos de Uso + +### 1. Receber Pagamento de Cliente + +```java +// Cliente quer fazer TED para sua conta +AccountNumber dados = AccountNumber.fetcher().fetch(); + +String mensagem = String.format( + "Para realizar o pagamento via TED, use:\n\n" + + "Banco: %s (%s)\n" + + "Agência: %s\n" + + "Conta: %s\n" + + "Favorecido: [Seu Nome]\n" + + "CPF/CNPJ: [Seu Documento]", + dados.getBankName(), + dados.getBank(), + dados.getAgencyDigit(), + dados.getAccountDigit() +); + +System.out.println(mensagem); +// Enviar por email/SMS para o cliente +``` + +### 2. Integração com Sistema + +```java +public class ContaBancariaService { + + private AccountNumber dadosCache; + + public AccountNumber getDadosBancarios() { + if (dadosCache == null) { + dadosCache = AccountNumber.fetcher().fetch(); + } + return dadosCache; + } + + public String getBanco() { + return getDadosBancarios().getBank(); + } + + public String getAgencia() { + return getDadosBancarios().getAgency(); + } + + public String getConta() { + return getDadosBancarios().getAccount(); + } + + public String getContaCompleta() { + return getDadosBancarios().getAccountDigit(); + } +} +``` + +### 3. Validação de Depósito + +```java +// Verificar se depósito foi para conta correta +public boolean validarDepositoRecebido(String agenciaInformada, String contaInformada) { + AccountNumber dados = AccountNumber.fetcher().fetch(); + + String agenciaCorreta = dados.getAgency(); + String contaCorreta = dados.getAccount(); + + return agenciaInformada.equals(agenciaCorreta) && + contaInformada.equals(contaCorreta); +} +``` + +## Boas Práticas + +### 1. Cache os Dados + +```java +// Dados bancários não mudam frequentemente +private static AccountNumber dadosBancariosCache = null; + +public static AccountNumber getDadosBancarios() { + if (dadosBancariosCache == null) { + dadosBancariosCache = AccountNumber.fetcher().fetch(); + } + return dadosBancariosCache; +} +``` + +### 2. Formate para Exibição + +```java +public static String formatarDadosBancarios() { + AccountNumber dados = getDadosBancarios(); + + return String.format( + "Banco: %s (%s) | Ag: %s | Conta: %s", + dados.getBankName(), + dados.getBank(), + dados.getAgency(), + dados.getAccountDigit() + ); +} +``` + +### 3. Valide Antes de Usar + +```java +AccountNumber dados = AccountNumber.fetcher().fetch(); + +if (dados.getBank() != null && dados.getAccount() != null) { + // Dados válidos, pode usar + System.out.println("Conta: " + dados.getAccountDigit()); +} else { + System.err.println("Erro ao recuperar dados bancários"); +} +``` + +## Limitações + +- Os dados bancários são fixos e definidos pelo Asaas +- Não é possível alterar agência ou conta +- Cada conta Asaas tem dados bancários únicos +- Subcontas possuem dados bancários próprios + +## Veja Também + +- [Saldo](balance.md) - Consultar saldo da conta +- [Extrato](financial.md) - Ver movimentações +- [Transferências](transfer.md) - Enviar transferências + +## Referências + +- [Documentação Oficial - Dados Bancários](https://docs.asaas.com/reference/consultar-dados-bancarios) diff --git a/docs/balance.md b/docs/balance.md index ccd4dd1..67c72a1 100644 --- a/docs/balance.md +++ b/docs/balance.md @@ -1,4 +1,433 @@ -## Recuperar saldo atual +# Saldo (Balance) + +Consulte o saldo disponível e bloqueado da sua conta Asaas em tempo real. + +## 📋 Índice + +- [Recuperar Saldo](#recuperar-saldo) +- [Tipos de Saldo](#tipos-de-saldo) +- [Monitoramento](#monitoramento) +- [Exemplos Práticos](#exemplos-práticos) + +## Recuperar Saldo + ```java -FinanceBalance financeBalance = FinanceBalance.fetcher().fetch(); -``` \ No newline at end of file +import io.github.jpdev.asaassdk.rest.balance.FinanceBalance; + +FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + +System.out.println("=== SALDO DA CONTA ==="); +System.out.println("Saldo disponível: R$ " + saldo.getBalance()); +System.out.println("Saldo bloqueado: R$ " + saldo.getBlockedBalance()); +System.out.println("Saldo total: R$ " + (saldo.getBalance() + saldo.getBlockedBalance())); +``` + +## Tipos de Saldo + +### Saldo Disponível + +Valor que pode ser usado imediatamente para transferências e pagamentos: + +```java +FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + +double saldoDisponivel = saldo.getBalance(); +System.out.println("Você pode transferir: R$ " + saldoDisponivel); + +// Verificar se tem saldo suficiente +double valorTransferencia = 100.00; +if (saldoDisponivel >= valorTransferencia) { + System.out.println("Saldo suficiente para transferência"); +} else { + System.out.println("Saldo insuficiente"); + System.out.println("Faltam: R$ " + (valorTransferencia - saldoDisponivel)); +} +``` + +### Saldo Bloqueado + +Valor retido temporariamente (aguardando compensação, análise, etc): + +```java +FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + +double saldoBloqueado = saldo.getBlockedBalance(); +System.out.println("Saldo bloqueado: R$ " + saldoBloqueado); + +if (saldoBloqueado > 0) { + System.out.println("Você tem valores aguardando liberação"); +} +``` + +### Saldo Total + +Soma do saldo disponível e bloqueado: + +```java +FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + +double saldoTotal = saldo.getBalance() + saldo.getBlockedBalance(); +System.out.println("Saldo total: R$ " + saldoTotal); +``` + +## Monitoramento + +### Verificar Saldo Antes de Transferir + +```java +import io.github.jpdev.asaassdk.rest.transfer.Transfer; +import io.github.jpdev.asaassdk.enums.PixAddressKeyType; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; + +public class TransferenciaSegura { + + public static boolean transferirComVerificacao(String chavePix, double valor) { + // Verificar saldo + FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + + if (saldo.getBalance() < valor) { + System.err.println("Saldo insuficiente!"); + System.err.println("Disponível: R$ " + saldo.getBalance()); + System.err.println("Necessário: R$ " + valor); + return false; + } + + // Realizar transferência + try { + Transfer transfer = Transfer.pixAddressKeyCreator() + .setPixAddressKey(chavePix) + .setPixAddressKeyType(PixAddressKeyType.CPF) + .setValue(Money.create(new BigDecimal(valor))) + .create(); + + System.out.println("Transferência realizada: " + transfer.getId()); + + // Verificar novo saldo + FinanceBalance novoSaldo = FinanceBalance.fetcher().fetch(); + System.out.println("Novo saldo: R$ " + novoSaldo.getBalance()); + + return true; + } catch (Exception e) { + System.err.println("Erro na transferência: " + e.getMessage()); + return false; + } + } + + public static void main(String[] args) { + Asaas.init("sua_api_key"); + transferirComVerificacao("12345678900", 100.00); + } +} +``` + +### Alertas de Saldo Baixo + +```java +public class MonitorSaldo { + + private static final double SALDO_MINIMO = 100.00; + + public static void verificarSaldoMinimo() { + FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + + if (saldo.getBalance() < SALDO_MINIMO) { + System.out.println("⚠️ ALERTA: Saldo baixo!"); + System.out.println("Saldo atual: R$ " + saldo.getBalance()); + System.out.println("Saldo mínimo: R$ " + SALDO_MINIMO); + + // Enviar notificação por email/SMS + enviarAlertaSaldoBaixo(saldo.getBalance()); + } else { + System.out.println("✅ Saldo OK: R$ " + saldo.getBalance()); + } + } + + private static void enviarAlertaSaldoBaixo(double saldoAtual) { + // Implementar envio de email/SMS + System.out.println("Notificação enviada sobre saldo baixo"); + } +} +``` + +### Dashboard de Saldo + +```java +public class DashboardSaldo { + + public static void exibirDashboard() { + FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + + double disponivel = saldo.getBalance(); + double bloqueado = saldo.getBlockedBalance(); + double total = disponivel + bloqueado; + + System.out.println("╔════════════════════════════════════════╗"); + System.out.println("║ DASHBOARD FINANCEIRO ║"); + System.out.println("╠════════════════════════════════════════╣"); + System.out.println("║ ║"); + System.out.println("║ 💰 Saldo Disponível ║"); + System.out.println("║ R$ " + String.format("%-30.2f", disponivel) + "║"); + System.out.println("║ ║"); + System.out.println("║ 🔒 Saldo Bloqueado ║"); + System.out.println("║ R$ " + String.format("%-30.2f", bloqueado) + "║"); + System.out.println("║ ║"); + System.out.println("║ 📊 Saldo Total ║"); + System.out.println("║ R$ " + String.format("%-30.2f", total) + "║"); + System.out.println("║ ║"); + System.out.println("╚════════════════════════════════════════╝"); + + // Percentual bloqueado + if (total > 0) { + double percentualBloqueado = (bloqueado / total) * 100; + System.out.println("\n📈 " + String.format("%.1f%%", percentualBloqueado) + " do saldo está bloqueado"); + } + } + + public static void main(String[] args) { + Asaas.init("sua_api_key"); + exibirDashboard(); + } +} +``` + +## Exemplos Práticos + +### Validar Múltiplas Transferências + +```java +import java.util.List; +import java.util.ArrayList; + +public class ValidadorTransferencias { + + public static class Transferencia { + String destino; + double valor; + + public Transferencia(String destino, double valor) { + this.destino = destino; + this.valor = valor; + } + } + + public static boolean validarLote(List transferencias) { + FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + + double totalNecessario = 0; + for (Transferencia t : transferencias) { + totalNecessario += t.valor; + } + + System.out.println("Saldo disponível: R$ " + saldo.getBalance()); + System.out.println("Total necessário: R$ " + totalNecessario); + + if (saldo.getBalance() >= totalNecessario) { + System.out.println("✅ Saldo suficiente para todas as transferências"); + return true; + } else { + double faltam = totalNecessario - saldo.getBalance(); + System.out.println("❌ Saldo insuficiente. Faltam: R$ " + faltam); + return false; + } + } + + public static void main(String[] args) { + Asaas.init("sua_api_key"); + + List lote = new ArrayList<>(); + lote.add(new Transferencia("12345678900", 100.00)); + lote.add(new Transferencia("98765432100", 200.00)); + lote.add(new Transferencia("11122233344", 150.00)); + + validarLote(lote); + } +} +``` + +### Relatório de Saldo + +```java +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class RelatorioSaldo { + + public static String gerarRelatorio() { + FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"); + String dataHora = LocalDateTime.now().format(formatter); + + StringBuilder relatorio = new StringBuilder(); + relatorio.append("═══════════════════════════════════════\n"); + relatorio.append(" RELATÓRIO DE SALDO \n"); + relatorio.append("═══════════════════════════════════════\n\n"); + relatorio.append("Data/Hora: ").append(dataHora).append("\n\n"); + relatorio.append("Saldo Disponível: R$ ").append(String.format("%.2f", saldo.getBalance())).append("\n"); + relatorio.append("Saldo Bloqueado: R$ ").append(String.format("%.2f", saldo.getBlockedBalance())).append("\n"); + relatorio.append("───────────────────────────────────────\n"); + relatorio.append("Saldo Total: R$ ").append(String.format("%.2f", saldo.getBalance() + saldo.getBlockedBalance())).append("\n\n"); + relatorio.append("═══════════════════════════════════════\n"); + + return relatorio.toString(); + } + + public static void main(String[] args) { + Asaas.init("sua_api_key"); + System.out.println(gerarRelatorio()); + } +} +``` + +### Comparar Saldo ao Longo do Tempo + +```java +import java.util.ArrayList; +import java.util.List; + +public class HistoricoSaldo { + + public static class RegistroSaldo { + LocalDateTime data; + double saldo; + + public RegistroSaldo(LocalDateTime data, double saldo) { + this.data = data; + this.saldo = saldo; + } + } + + private static List historico = new ArrayList<>(); + + public static void registrarSaldo() { + FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + historico.add(new RegistroSaldo(LocalDateTime.now(), saldo.getBalance())); + } + + public static void exibirVariacao() { + if (historico.size() < 2) { + System.out.println("Histórico insuficiente"); + return; + } + + RegistroSaldo primeiro = historico.get(0); + RegistroSaldo ultimo = historico.get(historico.size() - 1); + + double variacao = ultimo.saldo - primeiro.saldo; + double percentual = (variacao / primeiro.saldo) * 100; + + System.out.println("Saldo inicial: R$ " + primeiro.saldo); + System.out.println("Saldo atual: R$ " + ultimo.saldo); + System.out.println("Variação: R$ " + variacao); + System.out.println("Percentual: " + String.format("%.2f%%", percentual)); + } +} +``` + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.balance.FinanceBalance; + +public class ExemploSaldo { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Recuperar saldo + FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + + // Exibir informações + System.out.println("═══════════════════════════════════════"); + System.out.println(" SALDO DA CONTA "); + System.out.println("═══════════════════════════════════════\n"); + + double disponivel = saldo.getBalance(); + double bloqueado = saldo.getBlockedBalance(); + double total = disponivel + bloqueado; + + System.out.println("💰 Saldo Disponível:"); + System.out.println(" R$ " + String.format("%.2f", disponivel)); + System.out.println(); + + System.out.println("🔒 Saldo Bloqueado:"); + System.out.println(" R$ " + String.format("%.2f", bloqueado)); + System.out.println(); + + System.out.println("📊 Saldo Total:"); + System.out.println(" R$ " + String.format("%.2f", total)); + System.out.println(); + + System.out.println("═══════════════════════════════════════"); + + // Análise + if (disponivel < 100) { + System.out.println("⚠️ Saldo baixo! Considere adicionar fundos."); + } else if (disponivel < 500) { + System.out.println("ℹ️ Saldo moderado."); + } else { + System.out.println("✅ Saldo saudável!"); + } + + if (bloqueado > 0) { + double percentual = (bloqueado / total) * 100; + System.out.println("📌 " + String.format("%.1f%%", percentual) + " do saldo está bloqueado"); + } + } +} +``` + +## Boas Práticas + +### 1. Cache com Atualização Periódica + +```java +private static FinanceBalance saldoCache = null; +private static long ultimaAtualizacao = 0; +private static final long INTERVALO_CACHE = 60000; // 1 minuto + +public static FinanceBalance getSaldo() { + long agora = System.currentTimeMillis(); + + if (saldoCache == null || (agora - ultimaAtualizacao) > INTERVALO_CACHE) { + saldoCache = FinanceBalance.fetcher().fetch(); + ultimaAtualizacao = agora; + } + + return saldoCache; +} +``` + +### 2. Sempre Verifique Antes de Transferir + +```java +public static boolean podeTrans ferir(double valor) { + FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + return saldo.getBalance() >= valor; +} +``` + +### 3. Monitore Regularmente + +```java +// Agendar verificação a cada hora +ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); +scheduler.scheduleAtFixedRate(() -> { + FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + if (saldo.getBalance() < 100) { + enviarAlerta("Saldo baixo: R$ " + saldo.getBalance()); + } +}, 0, 1, TimeUnit.HOURS); +``` + +## Veja Também + +- [Extrato](financial.md) - Ver movimentações detalhadas +- [Transferências](transfer.md) - Realizar transferências +- [Taxas](accountfee.md) - Consultar taxas aplicadas + +## Referências + +- [Documentação Oficial - Saldo](https://docs.asaas.com/reference/consultar-saldo) diff --git a/docs/bill.md b/docs/bill.md index 7acc86c..a6d413e 100644 --- a/docs/bill.md +++ b/docs/bill.md @@ -1,6 +1,376 @@ -## Criar um pagamento de conta +# Pagar Contas (Bill Payment) + +Pague boletos de terceiros diretamente pela sua conta Asaas. Simplifique o pagamento de fornecedores, contas de consumo e outros boletos. + +## 📋 Índice + +- [Criar Pagamento](#criar-pagamento) +- [Listar Pagamentos](#listar-pagamentos) +- [Recuperar Pagamento](#recuperar-pagamento) +- [Cancelar Pagamento](#cancelar-pagamento) + +## Criar Pagamento + +### Pagamento por Linha Digitável + ```java -Bill bill = Bill.creator() - .setIdentificationField("25794150099003551916515000211407100000000000000") +import io.github.jpdev.asaassdk.rest.bill.Bill; + +Bill pagamento = Bill.creator() + .setIdentificationField("34191790010104351004791020150008291070026000") + .create(); + +System.out.println("Pagamento criado: " + pagamento.getId()); +System.out.println("Status: " + pagamento.getStatus()); +System.out.println("Valor: R$ " + pagamento.getValue()); +``` + +### Pagamento com Código de Barras + +```java +Bill pagamento = Bill.creator() + .setIdentificationField("34191790010104351004791020150008291070026000") + .setDescription("Pagamento de fornecedor") + .create(); + +System.out.println("Agendado para: " + pagamento.getScheduleDate()); +``` + +### Pagamento Agendado + +```java +import java.util.Calendar; + +Calendar cal = Calendar.getInstance(); +cal.add(Calendar.DAY_OF_MONTH, 5); // Agendar para daqui a 5 dias +Date dataAgendamento = cal.getTime(); + +Bill pagamento = Bill.creator() + .setIdentificationField("34191790010104351004791020150008291070026000") + .setScheduleDate(dataAgendamento) + .create(); + +System.out.println("Pagamento agendado para: " + pagamento.getScheduleDate()); +``` + +### Pagamento com Desconto + +```java +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; + +Bill pagamento = Bill.creator() + .setIdentificationField("34191790010104351004791020150008291070026000") + .setDiscount(Money.create(new BigDecimal("10.00"))) + .setDescription("Pagamento com desconto") + .create(); + +System.out.println("Valor original: R$ " + pagamento.getOriginalValue()); +System.out.println("Desconto: R$ " + pagamento.getDiscount()); +System.out.println("Valor a pagar: R$ " + pagamento.getValue()); +``` + +## Listar Pagamentos + +### Listar Todos + +```java +import io.github.jpdev.asaassdk.rest.bill.ResourceSet; + +ResourceSet pagamentos = Bill.reader().read(); + +for (Bill pagamento : pagamentos.getData()) { + System.out.println("ID: " + pagamento.getId()); + System.out.println("Valor: R$ " + pagamento.getValue()); + System.out.println("Status: " + pagamento.getStatus()); + System.out.println("Data: " + pagamento.getScheduleDate()); + System.out.println("---"); +} +``` + +### Filtrar por Status + +```java +import io.github.jpdev.asaassdk.enums.BillStatus; + +// Apenas pagamentos pendentes +ResourceSet pendentes = Bill.reader() + .setStatus(BillStatus.PENDING) + .read(); + +// Apenas pagamentos confirmados +ResourceSet confirmados = Bill.reader() + .setStatus(BillStatus.CONFIRMED) + .read(); +``` + +### Filtrar por Data + +```java +import java.util.Calendar; + +Calendar cal = Calendar.getInstance(); +cal.set(2024, Calendar.JANUARY, 1); +Date dataInicio = cal.getTime(); + +cal.set(2024, Calendar.DECEMBER, 31); +Date dataFim = cal.getTime(); + +ResourceSet pagamentos = Bill.reader() + .setStartDate(dataInicio) + .setEndDate(dataFim) + .read(); +``` + +### Paginação + +```java +ResourceSet pagamentos = Bill.reader() + .setLimit(50) + .setOffset(0) + .read(); + +System.out.println("Total: " + pagamentos.getTotalCount()); +System.out.println("Tem mais: " + pagamentos.hasMore()); +``` + +## Recuperar Pagamento + +```java +Bill pagamento = Bill.fetcher("bill_123456789").fetch(); + +System.out.println("ID: " + pagamento.getId()); +System.out.println("Valor: R$ " + pagamento.getValue()); +System.out.println("Status: " + pagamento.getStatus()); +System.out.println("Beneficiário: " + pagamento.getRecipient()); +System.out.println("Data de pagamento: " + pagamento.getScheduleDate()); +``` + +## Cancelar Pagamento + +Cancele um pagamento agendado antes da execução: + +```java +import io.github.jpdev.asaassdk.rest.bill.BillCancelled; + +BillCancelled cancelado = Bill.canceller("bill_123456789").cancel(); + +if (cancelado.isCancelled()) { + System.out.println("Pagamento cancelado com sucesso"); +} +``` + +**Nota**: Apenas pagamentos com status `PENDING` ou `SCHEDULED` podem ser cancelados. + +## Status de Pagamentos + +| Status | Descrição | +|--------|-----------| +| `PENDING` | Aguardando processamento | +| `SCHEDULED` | Agendado | +| `CONFIRMED` | Confirmado | +| `CANCELLED` | Cancelado | +| `FAILED` | Falhou | + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.bill.Bill; +import io.github.jpdev.asaassdk.rest.balance.FinanceBalance; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Date; + +public class ExemploPagamentoConta { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Verificar saldo antes de pagar + FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + System.out.println("Saldo disponível: R$ " + saldo.getBalance()); + + // Criar pagamento + String linhaDigitavel = "34191790010104351004791020150008291070026000"; + + Bill pagamento = Bill.creator() + .setIdentificationField(linhaDigitavel) + .setDescription("Pagamento de fornecedor XYZ") + .create(); + + System.out.println("\n=== PAGAMENTO CRIADO ==="); + System.out.println("ID: " + pagamento.getId()); + System.out.println("Beneficiário: " + pagamento.getRecipient()); + System.out.println("Valor: R$ " + pagamento.getValue()); + System.out.println("Status: " + pagamento.getStatus()); + System.out.println("Agendado para: " + pagamento.getScheduleDate()); + + // Verificar novo saldo + FinanceBalance novoSaldo = FinanceBalance.fetcher().fetch(); + System.out.println("\nNovo saldo: R$ " + novoSaldo.getBalance()); + } +} +``` + +## Validação de Linha Digitável + +```java +public class ValidadorBoleto { + + public static boolean validarLinhaDigitavel(String linha) { + // Remover espaços e caracteres especiais + String linhaLimpa = linha.replaceAll("[^0-9]", ""); + + // Linha digitável deve ter 47 dígitos + if (linhaLimpa.length() != 47) { + System.err.println("Linha digitável inválida: deve ter 47 dígitos"); + return false; + } + + return true; + } + + public static void pagarComValidacao(String linhaDigitavel) { + if (!validarLinhaDigitavel(linhaDigitavel)) { + return; + } + + try { + Bill pagamento = Bill.creator() + .setIdentificationField(linhaDigitavel) .create(); -``` \ No newline at end of file + + System.out.println("Pagamento criado: " + pagamento.getId()); + } catch (Exception e) { + System.err.println("Erro ao criar pagamento: " + e.getMessage()); + } + } +} +``` + +## Casos de Uso + +### Pagamento de Fornecedores + +```java +public class PagamentoFornecedor { + + public static void pagarFornecedor(String linhaDigitavel, String nomeFornecedor) { + // Verificar saldo + FinanceBalance saldo = FinanceBalance.fetcher().fetch(); + + Bill pagamento = Bill.creator() + .setIdentificationField(linhaDigitavel) + .setDescription("Pagamento fornecedor: " + nomeFornecedor) + .create(); + + System.out.println("Pagamento para " + nomeFornecedor + " criado"); + System.out.println("Valor: R$ " + pagamento.getValue()); + + // Registrar no sistema + registrarPagamento(pagamento.getId(), nomeFornecedor); + } + + private static void registrarPagamento(String billId, String fornecedor) { + // Salvar no banco de dados + System.out.println("Pagamento registrado no sistema"); + } +} +``` + +### Pagamento em Lote + +```java +import java.util.List; +import java.util.ArrayList; + +public class PagamentoLote { + + public static void pagarLote(List linhasDigitaveis) { + List pagamentosRealizados = new ArrayList<>(); + + for (String linha : linhasDigitaveis) { + try { + Bill pagamento = Bill.creator() + .setIdentificationField(linha) + .create(); + + pagamentosRealizados.add(pagamento); + System.out.println("✅ Pagamento criado: " + pagamento.getId()); + + } catch (Exception e) { + System.err.println("❌ Erro ao pagar: " + linha); + System.err.println(" " + e.getMessage()); + } + } + + System.out.println("\nTotal de pagamentos: " + pagamentosRealizados.size()); + } +} +``` + +## Boas Práticas + +### 1. Valide Antes de Pagar + +```java +String linha = "34191.79001 01043.510047 79102.015000 8 29107002600000"; +String linhaLimpa = linha.replaceAll("[^0-9]", ""); + +if (linhaLimpa.length() == 47) { + Bill pagamento = Bill.creator() + .setIdentificationField(linhaLimpa) + .create(); +} +``` + +### 2. Verifique Saldo + +```java +FinanceBalance saldo = FinanceBalance.fetcher().fetch(); +double valorBoleto = 500.00; + +if (saldo.getBalance() >= valorBoleto) { + Bill pagamento = Bill.creator() + .setIdentificationField(linhaDigitavel) + .create(); +} else { + System.err.println("Saldo insuficiente"); +} +``` + +### 3. Trate Erros + +```java +try { + Bill pagamento = Bill.creator() + .setIdentificationField(linhaDigitavel) + .create(); +} catch (AsaasException e) { + if (e.getMessage().contains("insufficient balance")) { + System.err.println("Saldo insuficiente"); + } else if (e.getMessage().contains("invalid")) { + System.err.println("Linha digitável inválida"); + } else { + System.err.println("Erro: " + e.getMessage()); + } +} +``` + +## Limitações + +- Linha digitável deve ter 47 dígitos +- Pagamento só pode ser cancelado antes da execução +- Verificar saldo antes de criar pagamento +- Alguns boletos podem ter restrições de data + +## Veja Também + +- [Saldo](balance.md) - Verificar saldo disponível +- [Transferências](transfer.md) - Outras formas de pagamento +- [Extrato](financial.md) - Ver histórico de pagamentos + +## Referências + +- [Documentação Oficial - Pagamento de Contas](https://docs.asaas.com/reference/pagar-conta) diff --git a/docs/commercialinfo.md b/docs/commercialinfo.md index f6f7e1f..4c877c7 100644 --- a/docs/commercialinfo.md +++ b/docs/commercialinfo.md @@ -1,11 +1,372 @@ -## Update +# Dados Comerciais (Commercial Info) + +Gerencie as informações comerciais da sua conta Asaas. Mantenha seus dados atualizados para melhor experiência com clientes. + +## 📋 Índice + +- [Recuperar Dados](#recuperar-dados) +- [Atualizar Dados](#atualizar-dados) +- [Campos Disponíveis](#campos-disponíveis) + +## Recuperar Dados + +```java +import io.github.jpdev.asaassdk.rest.commercialinfo.CommercialInfo; + +CommercialInfo dados = CommercialInfo.fetcher().fetch(); + +System.out.println("=== DADOS COMERCIAIS ==="); +System.out.println("Nome: " + dados.getName()); +System.out.println("Site: " + dados.getSite()); +System.out.println("Email: " + dados.getEmail()); +System.out.println("Telefone: " + dados.getPhone()); +System.out.println("Endereço: " + dados.getAddress()); +System.out.println("Cidade: " + dados.getCity()); +System.out.println("Estado: " + dados.getState()); +``` + +## Atualizar Dados + +### Atualizar Site + ```java -CommercialInfo updatedCommercialInfo = CommercialInfo.updater() - .setSite("https://yourSite.com.br") - .update(); +CommercialInfo atualizado = CommercialInfo.updater() + .setSite("https://www.minhaempresa.com.br") + .update(); + +System.out.println("Site atualizado: " + atualizado.getSite()); ``` -## Recuperar informações comerciais +### Atualizar Múltiplos Campos + ```java -CommercialInfo commercialInfo = CommercialInfo.fetcher().fetch(); -``` \ No newline at end of file +CommercialInfo atualizado = CommercialInfo.updater() + .setSite("https://www.minhaempresa.com.br") + .setEmail("contato@minhaempresa.com.br") + .setPhone("4733334444") + .setMobilePhone("47999999999") + .update(); + +System.out.println("Dados atualizados com sucesso!"); +``` + +### Atualizar Endereço + +```java +CommercialInfo atualizado = CommercialInfo.updater() + .setAddress("Rua Principal") + .setAddressNumber("100") + .setComplement("Sala 201") + .setProvince("Centro") + .setPostalCode("89010-000") + .setCity("Blumenau") + .setState("SC") + .update(); + +System.out.println("Endereço atualizado!"); +``` + +### Atualizar Informações de Contato + +```java +CommercialInfo atualizado = CommercialInfo.updater() + .setEmail("contato@empresa.com") + .setPhone("4733334444") + .setMobilePhone("47999999999") + .setWhatsapp("47999999999") + .update(); + +System.out.println("Contatos atualizados!"); +``` + +### Atualizar Redes Sociais + +```java +CommercialInfo atualizado = CommercialInfo.updater() + .setFacebook("https://facebook.com/minhaempresa") + .setInstagram("@minhaempresa") + .setLinkedin("https://linkedin.com/company/minhaempresa") + .update(); + +System.out.println("Redes sociais atualizadas!"); +``` + +## Campos Disponíveis + +### Informações Básicas + +| Campo | Tipo | Descrição | +|-------|------|-----------| +| `name` | String | Nome da empresa | +| `site` | String | Site da empresa | +| `email` | String | Email de contato | +| `phone` | String | Telefone fixo | +| `mobilePhone` | String | Telefone celular | +| `whatsapp` | String | WhatsApp | + +### Endereço + +| Campo | Tipo | Descrição | +|-------|------|-----------| +| `address` | String | Logradouro | +| `addressNumber` | String | Número | +| `complement` | String | Complemento | +| `province` | String | Bairro | +| `postalCode` | String | CEP | +| `city` | String | Cidade | +| `state` | String | Estado (UF) | + +### Redes Sociais + +| Campo | Tipo | Descrição | +|-------|------|-----------| +| `facebook` | String | URL do Facebook | +| `instagram` | String | @ do Instagram | +| `linkedin` | String | URL do LinkedIn | +| `twitter` | String | @ do Twitter | + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.commercialinfo.CommercialInfo; + +public class ExemploDadosComerciais { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Recuperar dados atuais + CommercialInfo dadosAtuais = CommercialInfo.fetcher().fetch(); + + System.out.println("=== DADOS ATUAIS ==="); + System.out.println("Nome: " + dadosAtuais.getName()); + System.out.println("Site: " + dadosAtuais.getSite()); + System.out.println("Email: " + dadosAtuais.getEmail()); + + // Atualizar dados + CommercialInfo dadosAtualizados = CommercialInfo.updater() + .setSite("https://www.novosite.com.br") + .setEmail("contato@novosite.com.br") + .setPhone("4733334444") + .setMobilePhone("47999999999") + .setWhatsapp("47999999999") + .setAddress("Rua Nova") + .setAddressNumber("200") + .setProvince("Centro") + .setPostalCode("89010-000") + .setCity("Blumenau") + .setState("SC") + .setFacebook("https://facebook.com/empresa") + .setInstagram("@empresa") + .update(); + + System.out.println("\n=== DADOS ATUALIZADOS ==="); + System.out.println("Site: " + dadosAtualizados.getSite()); + System.out.println("Email: " + dadosAtualizados.getEmail()); + System.out.println("Telefone: " + dadosAtualizados.getPhone()); + System.out.println("WhatsApp: " + dadosAtualizados.getWhatsapp()); + } +} +``` + +## Casos de Uso + +### Atualização Após Mudança de Endereço + +```java +public class AtualizacaoEndereco { + + public static void mudarEndereco( + String novoEndereco, + String numero, + String bairro, + String cep, + String cidade, + String estado + ) { + CommercialInfo atualizado = CommercialInfo.updater() + .setAddress(novoEndereco) + .setAddressNumber(numero) + .setProvince(bairro) + .setPostalCode(cep) + .setCity(cidade) + .setState(estado) + .update(); + + System.out.println("Endereço atualizado com sucesso!"); + System.out.println("Novo endereço: " + atualizado.getAddress() + ", " + + atualizado.getAddressNumber()); + } +} +``` + +### Configuração Inicial + +```java +public class ConfiguracaoInicial { + + public static void configurarDadosComerciais() { + CommercialInfo dados = CommercialInfo.updater() + .setSite("https://www.minhaempresa.com.br") + .setEmail("contato@minhaempresa.com.br") + .setPhone("4733334444") + .setMobilePhone("47999999999") + .setWhatsapp("47999999999") + .setAddress("Rua Principal") + .setAddressNumber("100") + .setProvince("Centro") + .setPostalCode("89010-000") + .setCity("Blumenau") + .setState("SC") + .setFacebook("https://facebook.com/minhaempresa") + .setInstagram("@minhaempresa") + .update(); + + System.out.println("✅ Dados comerciais configurados!"); + } +} +``` + +### Sincronização com Sistema + +```java +public class SincronizacaoDados { + + public static void sincronizarComSistema() { + // Buscar dados do sistema local + DadosEmpresa dadosLocal = buscarDadosDoSistema(); + + // Atualizar no Asaas + CommercialInfo atualizado = CommercialInfo.updater() + .setSite(dadosLocal.getSite()) + .setEmail(dadosLocal.getEmail()) + .setPhone(dadosLocal.getTelefone()) + .setAddress(dadosLocal.getEndereco()) + .setCity(dadosLocal.getCidade()) + .setState(dadosLocal.getEstado()) + .update(); + + System.out.println("Dados sincronizados com sucesso!"); + } + + private static DadosEmpresa buscarDadosDoSistema() { + // Implementar busca no banco de dados + return new DadosEmpresa(); + } +} +``` + +## Boas Práticas + +### 1. Mantenha Dados Atualizados + +```java +// Atualizar dados regularmente +public static void verificarDados() { + CommercialInfo dados = CommercialInfo.fetcher().fetch(); + + if (dados.getSite() == null || dados.getSite().isEmpty()) { + System.out.println("⚠️ Site não configurado"); + } + + if (dados.getEmail() == null || dados.getEmail().isEmpty()) { + System.out.println("⚠️ Email não configurado"); + } + + if (dados.getPhone() == null || dados.getPhone().isEmpty()) { + System.out.println("⚠️ Telefone não configurado"); + } +} +``` + +### 2. Valide URLs + +```java +public static boolean validarUrl(String url) { + return url != null && + (url.startsWith("http://") || url.startsWith("https://")); +} + +public static void atualizarSite(String novoSite) { + if (validarUrl(novoSite)) { + CommercialInfo.updater() + .setSite(novoSite) + .update(); + } else { + System.err.println("URL inválida"); + } +} +``` + +### 3. Formate Telefones + +```java +public static String formatarTelefone(String telefone) { + // Remover caracteres especiais + return telefone.replaceAll("[^0-9]", ""); +} + +public static void atualizarTelefone(String telefone) { + String telefoneLimpo = formatarTelefone(telefone); + + CommercialInfo.updater() + .setPhone(telefoneLimpo) + .update(); +} +``` + +### 4. Cache de Dados + +```java +private static CommercialInfo dadosCache = null; +private static long ultimaAtualizacao = 0; + +public static CommercialInfo getDadosComerciais() { + long agora = System.currentTimeMillis(); + + // Atualizar cache a cada 1 hora + if (dadosCache == null || (agora - ultimaAtualizacao) > 3600000) { + dadosCache = CommercialInfo.fetcher().fetch(); + ultimaAtualizacao = agora; + } + + return dadosCache; +} +``` + +## Exibição de Dados + +### Formato para Impressão + +```java +public static void imprimirDadosComerciais() { + CommercialInfo dados = CommercialInfo.fetcher().fetch(); + + System.out.println("╔════════════════════════════════════════╗"); + System.out.println("║ DADOS COMERCIAIS ║"); + System.out.println("╠════════════════════════════════════════╣"); + System.out.println("║ Nome: " + dados.getName()); + System.out.println("║ Site: " + dados.getSite()); + System.out.println("║ Email: " + dados.getEmail()); + System.out.println("║ Telefone: " + dados.getPhone()); + System.out.println("║ Celular: " + dados.getMobilePhone()); + System.out.println("║ WhatsApp: " + dados.getWhatsapp()); + System.out.println("║"); + System.out.println("║ Endereço: " + dados.getAddress() + ", " + dados.getAddressNumber()); + System.out.println("║ Bairro: " + dados.getProvince()); + System.out.println("║ CEP: " + dados.getPostalCode()); + System.out.println("║ Cidade: " + dados.getCity() + " - " + dados.getState()); + System.out.println("╚════════════════════════════════════════╝"); +} +``` + +## Veja Também + +- [Status da Conta](myaccount.md) - Verificar situação da conta +- [Dados Bancários](accountnumber.md) - Informações bancárias +- [Subcontas](account.md) - Gerenciar subcontas + +## Referências + +- [Documentação Oficial - Dados Comerciais](https://docs.asaas.com/reference/atualizar-dados-comerciais) diff --git a/docs/customeraccount.md b/docs/customeraccount.md index 572af13..dd09fb3 100644 --- a/docs/customeraccount.md +++ b/docs/customeraccount.md @@ -1,15 +1,411 @@ -## Criar cliente +# Clientes (Customer Accounts) + +Gerencie seus clientes de forma eficiente. Clientes são necessários para criar cobranças, assinaturas e outras operações. + +## 📋 Índice + +- [Criar Cliente](#criar-cliente) +- [Listar Clientes](#listar-clientes) +- [Recuperar Cliente](#recuperar-cliente) +- [Atualizar Cliente](#atualizar-cliente) +- [Deletar Cliente](#deletar-cliente) +- [Restaurar Cliente](#restaurar-cliente) + +## Criar Cliente + +### Cliente Pessoa Física (CPF) + +```java +import io.github.jpdev.asaassdk.rest.customeraccount.CustomerAccount; + +CustomerAccount cliente = CustomerAccount.creator() + .setName("João Silva") + .setCpfCnpj("12345678900") + .setEmail("joao@exemplo.com") + .setPhone("47999999999") + .setMobilePhone("47988888888") + .create(); + +System.out.println("Cliente criado: " + cliente.getId()); +``` + +### Cliente Pessoa Jurídica (CNPJ) + +```java +CustomerAccount empresa = CustomerAccount.creator() + .setName("Empresa XYZ Ltda") + .setCpfCnpj("12345678000190") + .setEmail("contato@empresa.com") + .setPhone("4733334444") + .setCompany("Empresa XYZ Ltda") + .create(); +``` + +### Cliente com Endereço Completo + +```java +CustomerAccount cliente = CustomerAccount.creator() + .setName("Maria Santos") + .setCpfCnpj("98765432100") + .setEmail("maria@exemplo.com") + .setPhone("47999999999") + .setPostalCode("89010-000") + .setAddress("Rua das Flores") + .setAddressNumber("123") + .setComplement("Apto 45") + .setProvince("Centro") + .setCity("Blumenau") + .setState("SC") + .create(); + +System.out.println("Cliente criado com endereço completo"); +``` + +### Cliente com Informações Adicionais + +```java +CustomerAccount cliente = CustomerAccount.creator() + .setName("Pedro Oliveira") + .setCpfCnpj("11122233344") + .setEmail("pedro@exemplo.com") + .setPhone("47999999999") + .setExternalReference("CLI-2024-001") // Referência externa + .setNotificationDisabled(false) // Habilitar notificações + .setAdditionalEmails("financeiro@exemplo.com,cobranca@exemplo.com") + .create(); +``` + +### Cliente Estrangeiro + +```java +CustomerAccount estrangeiro = CustomerAccount.creator() + .setName("John Doe") + .setEmail("john@example.com") + .setPhone("+1234567890") + .setForeignCustomer(true) + .create(); +``` + +## Listar Clientes + +### Listar Todos + +```java +import io.github.jpdev.asaassdk.rest.customeraccount.ResourceSet; + +ResourceSet clientes = CustomerAccount.reader().read(); + +for (CustomerAccount cliente : clientes.getData()) { + System.out.println("ID: " + cliente.getId()); + System.out.println("Nome: " + cliente.getName()); + System.out.println("Email: " + cliente.getEmail()); + System.out.println("CPF/CNPJ: " + cliente.getCpfCnpj()); + System.out.println("---"); +} +``` + +### Filtrar por Nome + +```java +ResourceSet clientes = CustomerAccount.reader() + .setName("João") + .read(); +``` + +### Filtrar por Email + +```java +ResourceSet clientes = CustomerAccount.reader() + .setEmail("joao@exemplo.com") + .read(); +``` + +### Filtrar por CPF/CNPJ + +```java +ResourceSet clientes = CustomerAccount.reader() + .setCpfCnpj("12345678900") + .read(); +``` + +### Filtrar por Referência Externa + +```java +ResourceSet clientes = CustomerAccount.reader() + .setExternalReference("CLI-2024-001") + .read(); +``` + +### Paginação + +```java +ResourceSet clientes = CustomerAccount.reader() + .setLimit(50) // 50 registros por página + .setOffset(0) // Página inicial + .read(); + +System.out.println("Total de clientes: " + clientes.getTotalCount()); +System.out.println("Tem próxima página: " + clientes.hasMore()); + +// Próxima página +if (clientes.hasMore()) { + ResourceSet proximaPagina = CustomerAccount.reader() + .setLimit(50) + .setOffset(50) + .read(); +} +``` + +## Recuperar Cliente + +Busque um cliente específico pelo ID: + +```java +CustomerAccount cliente = CustomerAccount.fetcher("cus_000050606806").fetch(); + +System.out.println("Nome: " + cliente.getName()); +System.out.println("Email: " + cliente.getEmail()); +System.out.println("CPF/CNPJ: " + cliente.getCpfCnpj()); +System.out.println("Telefone: " + cliente.getPhone()); +System.out.println("Endereço: " + cliente.getAddress()); +System.out.println("Cidade: " + cliente.getCity()); +System.out.println("Estado: " + cliente.getState()); +``` + +## Atualizar Cliente + +### Atualizar Dados Básicos + +```java +CustomerAccount clienteAtualizado = CustomerAccount.updater("cus_000050606806") + .setName("João Silva Santos") + .setEmail("joao.novo@exemplo.com") + .setPhone("47988887777") + .update(); + +System.out.println("Cliente atualizado com sucesso"); +``` + +### Atualizar Endereço -Para criar um cliente, utilize CustomerAccount - ```java -CustomerAccount customerAccount = CustomerAccount.creator() - .setName("criado via API") - .setCpfCnpj("10030823005") - .create(); +CustomerAccount clienteAtualizado = CustomerAccount.updater("cus_000050606806") + .setPostalCode("89010-100") + .setAddress("Rua Nova") + .setAddressNumber("456") + .setComplement("Casa") + .setProvince("Bairro Novo") + .setCity("Blumenau") + .setState("SC") + .update(); ``` -## Recuperar cliente +### Atualizar Notificações + +```java +CustomerAccount clienteAtualizado = CustomerAccount.updater("cus_000050606806") + .setNotificationDisabled(true) // Desabilitar notificações + .update(); +``` + +### Atualizar Emails Adicionais + ```java -CustomerAccount customerAccount = CustomerAccount.fetcher("cus_xxxxxxxxxx").fetch(); -``` \ No newline at end of file +CustomerAccount clienteAtualizado = CustomerAccount.updater("cus_000050606806") + .setAdditionalEmails("novo1@exemplo.com,novo2@exemplo.com") + .update(); +``` + +## Deletar Cliente + +Delete um cliente que não possui cobranças ativas: + +```java +import io.github.jpdev.asaassdk.rest.customeraccount.CustomerAccountDeleted; + +CustomerAccountDeleted deleted = CustomerAccount.deleter("cus_000050606806").delete(); + +if (deleted.isDeleted()) { + System.out.println("Cliente deletado com sucesso"); +} +``` + +**Nota**: Apenas clientes sem cobranças pendentes ou ativas podem ser deletados. + +## Restaurar Cliente + +Restaure um cliente que foi deletado: + +```java +CustomerAccount cliente = CustomerAccount.restorer("cus_000050606806").create(); + +System.out.println("Cliente restaurado: " + cliente.getId()); +System.out.println("Nome: " + cliente.getName()); +``` + +## Validações + +### CPF/CNPJ + +O SDK valida automaticamente o formato do CPF/CNPJ: + +- **CPF**: 11 dígitos (com ou sem formatação) + - Exemplos válidos: `12345678900`, `123.456.789-00` +- **CNPJ**: 14 dígitos (com ou sem formatação) + - Exemplos válidos: `12345678000190`, `12.345.678/0001-90` + +### Email + +O email deve estar em formato válido: +- `usuario@dominio.com` +- `usuario.nome@dominio.com.br` + +### Telefone + +Telefones devem incluir DDD: +- Fixo: `4733334444` ou `(47) 3333-4444` +- Celular: `47999999999` ou `(47) 99999-9999` + +### CEP + +CEP deve ter 8 dígitos: +- `89010000` ou `89010-000` + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.customeraccount.CustomerAccount; +import io.github.jpdev.asaassdk.rest.customeraccount.ResourceSet; + +public class ExemploClientes { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Criar cliente + CustomerAccount novoCliente = CustomerAccount.creator() + .setName("Ana Paula Costa") + .setCpfCnpj("12345678900") + .setEmail("ana@exemplo.com") + .setPhone("47999999999") + .setPostalCode("89010-000") + .setAddress("Rua Principal") + .setAddressNumber("100") + .setProvince("Centro") + .setCity("Blumenau") + .setState("SC") + .create(); + + System.out.println("Cliente criado: " + novoCliente.getId()); + + // Buscar cliente + CustomerAccount cliente = CustomerAccount.fetcher(novoCliente.getId()).fetch(); + System.out.println("Cliente encontrado: " + cliente.getName()); + + // Atualizar cliente + CustomerAccount atualizado = CustomerAccount.updater(cliente.getId()) + .setPhone("47988888888") + .update(); + System.out.println("Telefone atualizado: " + atualizado.getPhone()); + + // Listar todos os clientes + ResourceSet clientes = CustomerAccount.reader() + .setLimit(10) + .read(); + + System.out.println("Total de clientes: " + clientes.getTotalCount()); + for (CustomerAccount c : clientes.getData()) { + System.out.println("- " + c.getName() + " (" + c.getEmail() + ")"); + } + } +} +``` + +## Boas Práticas + +### 1. Use Referência Externa + +Mantenha uma referência do seu sistema: + +```java +CustomerAccount cliente = CustomerAccount.creator() + .setName("Cliente Teste") + .setCpfCnpj("12345678900") + .setExternalReference("ID_DO_SEU_SISTEMA_123") + .create(); +``` + +### 2. Valide Dados Antes de Enviar + +```java +String cpf = "123.456.789-00"; +String cpfLimpo = cpf.replaceAll("[^0-9]", ""); // Remove formatação + +if (cpfLimpo.length() == 11) { + CustomerAccount cliente = CustomerAccount.creator() + .setCpfCnpj(cpfLimpo) + // ... outros campos + .create(); +} +``` + +### 3. Trate Erros Adequadamente + +```java +try { + CustomerAccount cliente = CustomerAccount.creator() + .setName("Teste") + .setCpfCnpj("12345678900") + .create(); +} catch (AsaasException e) { + if (e.getMessage().contains("cpfCnpj already exists")) { + System.err.println("Cliente já cadastrado com este CPF/CNPJ"); + } else { + System.err.println("Erro ao criar cliente: " + e.getMessage()); + } +} +``` + +### 4. Mantenha Dados Atualizados + +```java +// Atualizar email quando cliente solicitar +CustomerAccount.updater(clienteId) + .setEmail(novoEmail) + .update(); +``` + +## Campos Disponíveis + +| Campo | Tipo | Obrigatório | Descrição | +|-------|------|-------------|-----------| +| `name` | String | Sim | Nome do cliente | +| `cpfCnpj` | String | Sim* | CPF ou CNPJ | +| `email` | String | Não | Email principal | +| `phone` | String | Não | Telefone fixo | +| `mobilePhone` | String | Não | Telefone celular | +| `address` | String | Não | Endereço | +| `addressNumber` | String | Não | Número | +| `complement` | String | Não | Complemento | +| `province` | String | Não | Bairro | +| `postalCode` | String | Não | CEP | +| `city` | String | Não | Cidade | +| `state` | String | Não | Estado (UF) | +| `externalReference` | String | Não | Referência externa | +| `notificationDisabled` | Boolean | Não | Desabilitar notificações | +| `additionalEmails` | String | Não | Emails adicionais (separados por vírgula) | +| `company` | String | Não | Nome da empresa (PJ) | +| `foreignCustomer` | Boolean | Não | Cliente estrangeiro | + +*Obrigatório exceto para clientes estrangeiros + +## Veja Também + +- [Cobranças](payment.md) - Criar cobranças para clientes +- [Assinaturas](subscription.md) - Criar assinaturas recorrentes +- [Notificações](notification.md) - Gerenciar notificações de clientes + +## Referências + +- [Documentação Oficial - Clientes](https://docs.asaas.com/reference/criar-novo-cliente) diff --git a/docs/extra.md b/docs/extra.md index 3ee95f9..5e8e269 100644 --- a/docs/extra.md +++ b/docs/extra.md @@ -1,28 +1,24 @@ -## Sandbox -You can use the sandbox environment to test your integration. To do this, you need to call the `initSandbox` method before making any requests. -```java -Asaas.initSandbox("your_api_key"); -``` +## ⚙️ Configuração -## Timeout +### Timeout + +Configure o timeout das requisições (padrão: 30000ms): -The default timeout is 30000 milliseconds. You can change it by calling the `setTimeout` method. ```java -Asaas.setTimeout(10000); +Asaas.setTimeout(10000); // 10 segundos ``` -## Rate Limit +### Rate Limit -Possuímos limites de solicitações em certos endpoints onde o abuso pode de certa forma comprometer o desempenho e o uso das APIs do Asaas. Medimos as requisições e podemos restringi-las quando a quantidade permitida é ultrapassada. +Verifique os limites de requisição após cada chamada: -Você pode verificar o status nos cabeçalhos de resposta após uma requisição: ```java Transfer transfer = Transfer.pixAddressKeyCreator() - .setPixAddressKey("PIX_KEY") - .setValue(Money.create(0.01)) - .setDescription("teste") - .setPixAddressKeyType(PixAddressKeyType.CPF) - .create(); + .setPixAddressKey("sua_chave_pix") + .setValue(Money.create(10.00)) + .setPixAddressKeyType(PixAddressKeyType.CPF) + .create(); -transfer.getRateLimit(); // Here you can get the rate limit of the last request -``` \ No newline at end of file +RateLimit rateLimit = transfer.getRateLimit(); +System.out.println("Requisições restantes: " + rateLimit.getRemaining()); +``` diff --git a/docs/financial.md b/docs/financial.md index 094b8b3..50f52ff 100644 --- a/docs/financial.md +++ b/docs/financial.md @@ -1,14 +1,436 @@ -## Recuperar extrato +# Extrato Financeiro (Financial Transactions) + +Consulte todas as movimentações financeiras da sua conta Asaas. Acompanhe entradas, saídas e taxas. + +## 📋 Índice + +- [Listar Transações](#listar-transações) +- [Filtros Disponíveis](#filtros-disponíveis) +- [Tipos de Transação](#tipos-de-transação) +- [Relatórios](#relatórios) + +## Listar Transações + +### Listar Todas + +```java +import io.github.jpdev.asaassdk.rest.financial.FinancialTransaction; +import io.github.jpdev.asaassdk.rest.financial.ResourceSet; + +ResourceSet transacoes = FinancialTransaction.reader().read(); + +for (FinancialTransaction transacao : transacoes.getData()) { + System.out.println("Data: " + transacao.getDate()); + System.out.println("Tipo: " + transacao.getType()); + System.out.println("Valor: R$ " + transacao.getValue()); + System.out.println("Descrição: " + transacao.getDescription()); + System.out.println("Saldo: R$ " + transacao.getBalance()); + System.out.println("---"); +} +``` + +## Filtros Disponíveis + +### Filtrar por Data + +```java +import java.util.Calendar; + +Calendar cal = Calendar.getInstance(); +cal.set(2024, Calendar.JANUARY, 1); +Date dataInicio = cal.getTime(); + +cal.set(2024, Calendar.JANUARY, 31); +Date dataFim = cal.getTime(); + +ResourceSet transacoes = FinancialTransaction.reader() + .setStartDate(dataInicio) + .setEndDate(dataFim) + .read(); + +System.out.println("Transações de Janeiro/2024: " + transacoes.getTotalCount()); +``` + +### Filtrar por Tipo + +```java +import io.github.jpdev.asaassdk.enums.FinancialTransactionType; + +// Apenas recebimentos +ResourceSet recebimentos = FinancialTransaction.reader() + .setType(FinancialTransactionType.PAYMENT_RECEIVED) + .read(); + +// Apenas transferências +ResourceSet transferencias = FinancialTransaction.reader() + .setType(FinancialTransactionType.TRANSFER) + .read(); +``` + +### Filtrar por Cobrança + +```java +ResourceSet transacoes = FinancialTransaction.reader() + .setPaymentId("pay_123456789") + .read(); + +System.out.println("Transações da cobrança: " + transacoes.getTotalCount()); +``` + +### Filtrar por Transferência + +```java +ResourceSet transacoes = FinancialTransaction.reader() + .setTransferId("transfer_123456789") + .read(); +``` + +### Filtrar por Assinatura + +```java +ResourceSet transacoes = FinancialTransaction.reader() + .setSubscriptionId("sub_123456789") + .read(); +``` + +### Paginação + +```java +ResourceSet transacoes = FinancialTransaction.reader() + .setLimit(100) + .setOffset(0) + .read(); + +System.out.println("Total de transações: " + transacoes.getTotalCount()); +System.out.println("Tem mais: " + transacoes.hasMore()); + +// Próxima página +if (transacoes.hasMore()) { + ResourceSet proximaPagina = FinancialTransaction.reader() + .setLimit(100) + .setOffset(100) + .read(); +} +``` + +## Tipos de Transação + +| Tipo | Descrição | +|------|-----------| +| `PAYMENT_RECEIVED` | Pagamento recebido | +| `PAYMENT_FEE` | Taxa de pagamento | +| `TRANSFER` | Transferência enviada | +| `TRANSFER_FEE` | Taxa de transferência | +| `PAYMENT_REFUND` | Estorno de pagamento | +| `CHARGEBACK` | Chargeback | +| `INVOICE_FEE` | Taxa de nota fiscal | +| `ANTICIPATION` | Antecipação | +| `ANTICIPATION_FEE` | Taxa de antecipação | + +## Relatórios + +### Relatório Mensal + +```java +import java.time.LocalDate; +import java.time.ZoneId; + +public class RelatorioMensal { + + public static void gerarRelatorio(int mes, int ano) { + LocalDate inicio = LocalDate.of(ano, mes, 1); + LocalDate fim = inicio.plusMonths(1).minusDays(1); + + Date dataInicio = Date.from(inicio.atStartOfDay(ZoneId.systemDefault()).toInstant()); + Date dataFim = Date.from(fim.atStartOfDay(ZoneId.systemDefault()).toInstant()); + + ResourceSet transacoes = FinancialTransaction.reader() + .setStartDate(dataInicio) + .setEndDate(dataFim) + .read(); + + double totalEntradas = 0; + double totalSaidas = 0; + double totalTaxas = 0; + + for (FinancialTransaction t : transacoes.getData()) { + if (t.getType().equals(FinancialTransactionType.PAYMENT_RECEIVED)) { + totalEntradas += t.getValue(); + } else if (t.getType().contains("FEE")) { + totalTaxas += t.getValue(); + } else if (t.getType().equals(FinancialTransactionType.TRANSFER)) { + totalSaidas += t.getValue(); + } + } + + System.out.println("=== RELATÓRIO " + mes + "/" + ano + " ==="); + System.out.println("Total de transações: " + transacoes.getTotalCount()); + System.out.println("Entradas: R$ " + String.format("%.2f", totalEntradas)); + System.out.println("Saídas: R$ " + String.format("%.2f", totalSaidas)); + System.out.println("Taxas: R$ " + String.format("%.2f", totalTaxas)); + System.out.println("Saldo: R$ " + String.format("%.2f", (totalEntradas - totalSaidas - totalTaxas))); + } + + public static void main(String[] args) { + Asaas.init("sua_api_key"); + gerarRelatorio(1, 2024); // Janeiro de 2024 + } +} +``` + +### Extrato Detalhado + ```java -ResourceSet financialTransactionResourceSet = FinancialTransaction - .reader() - .read(); +public class ExtratoDetalhado { + + public static void gerarExtrato(Date dataInicio, Date dataFim) { + ResourceSet transacoes = FinancialTransaction.reader() + .setStartDate(dataInicio) + .setEndDate(dataFim) + .read(); + + System.out.println("╔════════════════════════════════════════════════════════╗"); + System.out.println("║ EXTRATO FINANCEIRO ║"); + System.out.println("╠════════════════════════════════════════════════════════╣"); + + for (FinancialTransaction t : transacoes.getData()) { + String tipo = formatarTipo(t.getType()); + String valor = String.format("R$ %.2f", t.getValue()); + String saldo = String.format("R$ %.2f", t.getBalance()); + + System.out.println("║ Data: " + t.getDate()); + System.out.println("║ Tipo: " + tipo); + System.out.println("║ Valor: " + valor); + System.out.println("║ Saldo: " + saldo); + System.out.println("║ Descrição: " + t.getDescription()); + System.out.println("╠════════════════════════════════════════════════════════╣"); + } + + System.out.println("╚════════════════════════════════════════════════════════╝"); + } + + private static String formatarTipo(String tipo) { + switch (tipo) { + case "PAYMENT_RECEIVED": return "Pagamento Recebido"; + case "PAYMENT_FEE": return "Taxa de Pagamento"; + case "TRANSFER": return "Transferência"; + case "TRANSFER_FEE": return "Taxa de Transferência"; + default: return tipo; + } + } +} ``` -Filtros também podem ser utilizados: +### Análise de Fluxo de Caixa + +```java +public class FluxoCaixa { + + public static void analisarFluxo(Date dataInicio, Date dataFim) { + ResourceSet transacoes = FinancialTransaction.reader() + .setStartDate(dataInicio) + .setEndDate(dataFim) + .read(); + + Map entradas = new HashMap<>(); + Map saidas = new HashMap<>(); + + for (FinancialTransaction t : transacoes.getData()) { + String tipo = t.getType(); + double valor = t.getValue(); + + if (tipo.equals("PAYMENT_RECEIVED")) { + entradas.put(tipo, entradas.getOrDefault(tipo, 0.0) + valor); + } else { + saidas.put(tipo, saidas.getOrDefault(tipo, 0.0) + valor); + } + } + + System.out.println("=== ANÁLISE DE FLUXO DE CAIXA ===\n"); + + System.out.println("ENTRADAS:"); + entradas.forEach((tipo, valor) -> + System.out.println(" " + tipo + ": R$ " + String.format("%.2f", valor)) + ); + + System.out.println("\nSAÍDAS:"); + saidas.forEach((tipo, valor) -> + System.out.println(" " + tipo + ": R$ " + String.format("%.2f", valor)) + ); + + double totalEntradas = entradas.values().stream().mapToDouble(Double::doubleValue).sum(); + double totalSaidas = saidas.values().stream().mapToDouble(Double::doubleValue).sum(); + + System.out.println("\nRESUMO:"); + System.out.println("Total Entradas: R$ " + String.format("%.2f", totalEntradas)); + System.out.println("Total Saídas: R$ " + String.format("%.2f", totalSaidas)); + System.out.println("Saldo Período: R$ " + String.format("%.2f", (totalEntradas - totalSaidas))); + } +} +``` + +### Exportar para CSV + ```java -ResourceSet financialTransactionResourceSet = FinancialTransaction - .reader() - .setTransferId("transferId") - .read(); -``` \ No newline at end of file +import java.io.FileWriter; +import java.io.IOException; + +public class ExportadorCSV { + + public static void exportarParaCSV(Date dataInicio, Date dataFim, String arquivo) { + ResourceSet transacoes = FinancialTransaction.reader() + .setStartDate(dataInicio) + .setEndDate(dataFim) + .read(); + + try (FileWriter writer = new FileWriter(arquivo)) { + // Cabeçalho + writer.append("Data,Tipo,Valor,Saldo,Descrição\n"); + + // Dados + for (FinancialTransaction t : transacoes.getData()) { + writer.append(t.getDate().toString()).append(","); + writer.append(t.getType()).append(","); + writer.append(String.valueOf(t.getValue())).append(","); + writer.append(String.valueOf(t.getBalance())).append(","); + writer.append(t.getDescription()).append("\n"); + } + + System.out.println("Extrato exportado para: " + arquivo); + + } catch (IOException e) { + System.err.println("Erro ao exportar: " + e.getMessage()); + } + } + + public static void main(String[] args) { + Asaas.init("sua_api_key"); + + Calendar cal = Calendar.getInstance(); + cal.set(2024, Calendar.JANUARY, 1); + Date inicio = cal.getTime(); + + cal.set(2024, Calendar.JANUARY, 31); + Date fim = cal.getTime(); + + exportarParaCSV(inicio, fim, "extrato_janeiro_2024.csv"); + } +} +``` + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.financial.FinancialTransaction; +import io.github.jpdev.asaassdk.rest.financial.ResourceSet; +import java.util.Calendar; +import java.util.Date; + +public class ExemploExtrato { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Definir período (últimos 30 dias) + Calendar cal = Calendar.getInstance(); + Date dataFim = cal.getTime(); + + cal.add(Calendar.DAY_OF_MONTH, -30); + Date dataInicio = cal.getTime(); + + // Buscar transações + ResourceSet transacoes = FinancialTransaction.reader() + .setStartDate(dataInicio) + .setEndDate(dataFim) + .setLimit(100) + .read(); + + System.out.println("=== EXTRATO - ÚLTIMOS 30 DIAS ===\n"); + System.out.println("Total de transações: " + transacoes.getTotalCount()); + System.out.println(); + + // Calcular totais + double totalEntradas = 0; + double totalSaidas = 0; + + for (FinancialTransaction t : transacoes.getData()) { + System.out.println("Data: " + t.getDate()); + System.out.println("Tipo: " + t.getType()); + System.out.println("Valor: R$ " + t.getValue()); + System.out.println("Saldo após: R$ " + t.getBalance()); + System.out.println("---"); + + if (t.getType().equals("PAYMENT_RECEIVED")) { + totalEntradas += t.getValue(); + } else { + totalSaidas += t.getValue(); + } + } + + System.out.println("\n=== RESUMO ==="); + System.out.println("Total Entradas: R$ " + String.format("%.2f", totalEntradas)); + System.out.println("Total Saídas: R$ " + String.format("%.2f", totalSaidas)); + System.out.println("Saldo Período: R$ " + String.format("%.2f", (totalEntradas - totalSaidas))); + } +} +``` + +## Boas Práticas + +### 1. Use Paginação para Grandes Volumes + +```java +int offset = 0; +int limit = 100; +boolean temMais = true; + +while (temMais) { + ResourceSet transacoes = FinancialTransaction.reader() + .setLimit(limit) + .setOffset(offset) + .read(); + + // Processar transações + processarTransacoes(transacoes.getData()); + + temMais = transacoes.hasMore(); + offset += limit; +} +``` + +### 2. Filtre por Período Específico + +```java +// Evite buscar todo o histórico +Calendar cal = Calendar.getInstance(); +cal.add(Calendar.MONTH, -1); // Último mês + +ResourceSet transacoes = FinancialTransaction.reader() + .setStartDate(cal.getTime()) + .setEndDate(new Date()) + .read(); +``` + +### 3. Cache de Relatórios + +```java +private static Map cache = new HashMap<>(); + +public static RelatorioCache getRelatorio(String periodo) { + if (!cache.containsKey(periodo)) { + cache.put(periodo, gerarRelatorio(periodo)); + } + return cache.get(periodo); +} +``` + +## Veja Também + +- [Saldo](balance.md) - Consultar saldo atual +- [Cobranças](payment.md) - Ver cobranças recebidas +- [Transferências](transfer.md) - Ver transferências realizadas + +## Referências + +- [Documentação Oficial - Extrato](https://docs.asaas.com/reference/listar-extrato) diff --git a/docs/installment.md b/docs/installment.md index 93bbe7a..3bd5c71 100644 --- a/docs/installment.md +++ b/docs/installment.md @@ -1,9 +1,390 @@ -## Listar parcelamentos +# Parcelamentos (Installments) + +Gerencie cobranças parceladas. Visualize e controle parcelas de pagamentos divididos. + +## 📋 Índice + +- [Listar Parcelamentos](#listar-parcelamentos) +- [Recuperar Parcelamento](#recuperar-parcelamento) +- [Deletar Parcelamento](#deletar-parcelamento) +- [Gerenciar Parcelas](#gerenciar-parcelas) + +## Listar Parcelamentos + +### Listar Todos + +```java +import io.github.jpdev.asaassdk.rest.installment.Installment; +import io.github.jpdev.asaassdk.rest.installment.ResourceSet; + +ResourceSet parcelamentos = Installment.reader().read(); + +for (Installment parcelamento : parcelamentos.getData()) { + System.out.println("ID: " + parcelamento.getId()); + System.out.println("Cliente: " + parcelamento.getCustomer()); + System.out.println("Valor total: R$ " + parcelamento.getValue()); + System.out.println("Número de parcelas: " + parcelamento.getInstallmentCount()); + System.out.println("Valor da parcela: R$ " + parcelamento.getInstallmentValue()); + System.out.println("Status: " + parcelamento.getStatus()); + System.out.println("---"); +} +``` + +### Filtrar por Cliente + ```java -ResourceSet installmentResourceSet = Installment.reader().read(); +ResourceSet parcelamentos = Installment.reader() + .setCustomer("cus_000050606806") + .read(); + +System.out.println("Parcelamentos do cliente: " + parcelamentos.getTotalCount()); ``` -## Deletar parcelamento +### Filtrar por Status + ```java -DeletedResource installmentDeleted = Installment.deleter("5a2c890b-dd63-4b5a-9169-96c8d7828f4c").delete(); -``` \ No newline at end of file +import io.github.jpdev.asaassdk.enums.InstallmentStatus; + +// Apenas parcelamentos ativos +ResourceSet ativos = Installment.reader() + .setStatus(InstallmentStatus.ACTIVE) + .read(); + +// Apenas parcelamentos concluídos +ResourceSet concluidos = Installment.reader() + .setStatus(InstallmentStatus.COMPLETED) + .read(); +``` + +### Paginação + +```java +ResourceSet parcelamentos = Installment.reader() + .setLimit(50) + .setOffset(0) + .read(); + +System.out.println("Total: " + parcelamentos.getTotalCount()); +System.out.println("Tem mais: " + parcelamentos.hasMore()); +``` + +## Recuperar Parcelamento + +```java +Installment parcelamento = Installment.fetcher("5a2c890b-dd63-4b5a-9169-96c8d7828f4c").fetch(); + +System.out.println("ID: " + parcelamento.getId()); +System.out.println("Cliente: " + parcelamento.getCustomer()); +System.out.println("Valor total: R$ " + parcelamento.getValue()); +System.out.println("Parcelas: " + parcelamento.getInstallmentCount() + "x de R$ " + parcelamento.getInstallmentValue()); +System.out.println("Status: " + parcelamento.getStatus()); +``` + +## Deletar Parcelamento + +Delete um parcelamento e suas parcelas pendentes: + +```java +import io.github.jpdev.asaassdk.rest.installment.DeletedResource; + +DeletedResource deletado = Installment.deleter("5a2c890b-dd63-4b5a-9169-96c8d7828f4c").delete(); + +if (deletado.isDeleted()) { + System.out.println("Parcelamento deletado com sucesso"); +} +``` + +**Nota**: Apenas parcelas pendentes serão deletadas. Parcelas já pagas não são afetadas. + +## Gerenciar Parcelas + +### Listar Parcelas de um Parcelamento + +```java +import io.github.jpdev.asaassdk.rest.payment.Payment; + +Installment parcelamento = Installment.fetcher("installment_id").fetch(); + +// Buscar todas as cobranças do parcelamento +ResourceSet parcelas = Payment.reader() + .setInstallment(parcelamento.getId()) + .read(); + +System.out.println("=== PARCELAS ==="); +int numeroParcela = 1; +for (Payment parcela : parcelas.getData()) { + System.out.println("Parcela " + numeroParcela + ":"); + System.out.println(" ID: " + parcela.getId()); + System.out.println(" Valor: R$ " + parcela.getValue()); + System.out.println(" Vencimento: " + parcela.getDueDate()); + System.out.println(" Status: " + parcela.getStatus()); + System.out.println(); + numeroParcela++; +} +``` + +### Verificar Status das Parcelas + +```java +public class StatusParcelas { + + public static void verificarStatus(String installmentId) { + ResourceSet parcelas = Payment.reader() + .setInstallment(installmentId) + .read(); + + int pagas = 0; + int pendentes = 0; + int vencidas = 0; + + for (Payment parcela : parcelas.getData()) { + switch (parcela.getStatus()) { + case "RECEIVED": + case "CONFIRMED": + pagas++; + break; + case "PENDING": + pendentes++; + break; + case "OVERDUE": + vencidas++; + break; + } + } + + System.out.println("=== STATUS DAS PARCELAS ==="); + System.out.println("Total: " + parcelas.getTotalCount()); + System.out.println("Pagas: " + pagas); + System.out.println("Pendentes: " + pendentes); + System.out.println("Vencidas: " + vencidas); + } +} +``` + +### Calcular Valor Restante + +```java +public class CalculadoraParcelas { + + public static void calcularRestante(String installmentId) { + Installment parcelamento = Installment.fetcher(installmentId).fetch(); + + ResourceSet parcelas = Payment.reader() + .setInstallment(installmentId) + .read(); + + double valorPago = 0; + double valorPendente = 0; + + for (Payment parcela : parcelas.getData()) { + if (parcela.getStatus().equals("RECEIVED") || + parcela.getStatus().equals("CONFIRMED")) { + valorPago += parcela.getValue(); + } else { + valorPendente += parcela.getValue(); + } + } + + System.out.println("=== RESUMO FINANCEIRO ==="); + System.out.println("Valor total: R$ " + parcelamento.getValue()); + System.out.println("Valor pago: R$ " + String.format("%.2f", valorPago)); + System.out.println("Valor pendente: R$ " + String.format("%.2f", valorPendente)); + + double percentualPago = (valorPago / parcelamento.getValue()) * 100; + System.out.println("Percentual pago: " + String.format("%.1f%%", percentualPago)); + } +} +``` + +## Status de Parcelamentos + +| Status | Descrição | +|--------|-----------| +| `ACTIVE` | Parcelamento ativo | +| `COMPLETED` | Todas as parcelas pagas | +| `CANCELLED` | Parcelamento cancelado | + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.installment.Installment; +import io.github.jpdev.asaassdk.rest.installment.ResourceSet; +import io.github.jpdev.asaassdk.rest.payment.Payment; + +public class ExemploParcelamento { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Listar todos os parcelamentos + ResourceSet parcelamentos = Installment.reader().read(); + + System.out.println("=== PARCELAMENTOS ==="); + System.out.println("Total: " + parcelamentos.getTotalCount()); + System.out.println(); + + // Detalhar cada parcelamento + for (Installment p : parcelamentos.getData()) { + System.out.println("ID: " + p.getId()); + System.out.println("Cliente: " + p.getCustomer()); + System.out.println("Valor: " + p.getInstallmentCount() + "x de R$ " + p.getInstallmentValue()); + System.out.println("Total: R$ " + p.getValue()); + System.out.println("Status: " + p.getStatus()); + + // Buscar parcelas + ResourceSet parcelas = Payment.reader() + .setInstallment(p.getId()) + .read(); + + System.out.println("Parcelas:"); + int num = 1; + for (Payment parcela : parcelas.getData()) { + System.out.println(" " + num + "/" + p.getInstallmentCount() + + " - R$ " + parcela.getValue() + + " - " + parcela.getStatus()); + num++; + } + + System.out.println("---\n"); + } + } +} +``` + +## Relatórios + +### Relatório de Inadimplência + +```java +public class RelatorioInadimplencia { + + public static void gerarRelatorio() { + ResourceSet parcelamentos = Installment.reader() + .setStatus(InstallmentStatus.ACTIVE) + .read(); + + System.out.println("=== RELATÓRIO DE INADIMPLÊNCIA ===\n"); + + for (Installment p : parcelamentos.getData()) { + ResourceSet parcelas = Payment.reader() + .setInstallment(p.getId()) + .setStatus(PaymentStatus.OVERDUE) + .read(); + + if (parcelas.getTotalCount() > 0) { + System.out.println("Cliente: " + p.getCustomer()); + System.out.println("Parcelamento: " + p.getId()); + System.out.println("Parcelas vencidas: " + parcelas.getTotalCount()); + + double valorVencido = 0; + for (Payment parcela : parcelas.getData()) { + valorVencido += parcela.getValue(); + } + + System.out.println("Valor vencido: R$ " + String.format("%.2f", valorVencido)); + System.out.println("---"); + } + } + } +} +``` + +### Dashboard de Parcelamentos + +```java +public class DashboardParcelamentos { + + public static void exibirDashboard() { + ResourceSet todos = Installment.reader().read(); + ResourceSet ativos = Installment.reader() + .setStatus(InstallmentStatus.ACTIVE) + .read(); + ResourceSet concluidos = Installment.reader() + .setStatus(InstallmentStatus.COMPLETED) + .read(); + + System.out.println("╔════════════════════════════════════════╗"); + System.out.println("║ DASHBOARD DE PARCELAMENTOS ║"); + System.out.println("╠════════════════════════════════════════╣"); + System.out.println("║ ║"); + System.out.println("║ 📊 Total de Parcelamentos ║"); + System.out.println("║ " + todos.getTotalCount() + " parcelamentos"); + System.out.println("║ ║"); + System.out.println("║ ✅ Ativos ║"); + System.out.println("║ " + ativos.getTotalCount() + " parcelamentos"); + System.out.println("║ ║"); + System.out.println("║ 🎉 Concluídos ║"); + System.out.println("║ " + concluidos.getTotalCount() + " parcelamentos"); + System.out.println("║ ║"); + System.out.println("╚════════════════════════════════════════╝"); + } +} +``` + +## Boas Práticas + +### 1. Monitore Parcelas Vencidas + +```java +public static void monitorarVencidas() { + ResourceSet ativos = Installment.reader() + .setStatus(InstallmentStatus.ACTIVE) + .read(); + + for (Installment p : ativos.getData()) { + ResourceSet vencidas = Payment.reader() + .setInstallment(p.getId()) + .setStatus(PaymentStatus.OVERDUE) + .read(); + + if (vencidas.getTotalCount() > 0) { + // Enviar notificação ao cliente + notificarCliente(p.getCustomer(), vencidas.getTotalCount()); + } + } +} +``` + +### 2. Valide Antes de Deletar + +```java +public static boolean podeDeletar(String installmentId) { + ResourceSet parcelas = Payment.reader() + .setInstallment(installmentId) + .read(); + + for (Payment parcela : parcelas.getData()) { + if (parcela.getStatus().equals("RECEIVED") || + parcela.getStatus().equals("CONFIRMED")) { + System.err.println("Não é possível deletar: existem parcelas pagas"); + return false; + } + } + + return true; +} +``` + +### 3. Cache de Dados + +```java +private static Map cache = new HashMap<>(); + +public static Installment getParcelamento(String id) { + if (!cache.containsKey(id)) { + cache.put(id, Installment.fetcher(id).fetch()); + } + return cache.get(id); +} +``` + +## Veja Também + +- [Cobranças](payment.md) - Criar cobranças parceladas +- [Clientes](customeraccount.md) - Gerenciar clientes +- [Extrato](financial.md) - Ver movimentações + +## Referências + +- [Documentação Oficial - Parcelamentos](https://docs.asaas.com/reference/listar-parcelamentos) diff --git a/docs/invoice.md b/docs/invoice.md index 12e514b..4729f1d 100644 --- a/docs/invoice.md +++ b/docs/invoice.md @@ -1,35 +1,447 @@ -## Scheduling invoice -```java -Invoice invoice = Invoice.creator() - .setServiceDescription("Nota fiscal da Fatura 101940. Descrição dos Serviços: ANÁLISE E DESENVOLVIMENTO DE SISTEMAS") - .setObservations("Mensal referente aos trabalhos de Junho.") - .setValue(Money.create(300)) - .setDeductions(Money.create(2)) - .setEffectiveDate(new Date()) - .setMunicipalServiceName("Análise e Desenvolvimento de Sistemas") - .setTaxes( - new Taxes() - .setRetainIss(true) - .setIss(Money.create(3)) - .setCofins(Money.create(3)) - .setCsll(Money.create(1)) - .setInss(Money.create(3)) - .setIr(Money.create(1.5)) - .setPis(Money.create(0.65)) - ) - .create(); -``` - -## Listar notas fiscais -```java -ResourceSet invoiceResourceSet = Invoice - .reader() - .read(); -``` - -## Recuperar nota fiscal -```java -Invoice invoice = Invoice - .fetcher("inv_000000000232") - .fetch(); -``` \ No newline at end of file +# Notas Fiscais (Invoices) + +Emita notas fiscais de serviço (NF-e) diretamente pela plataforma Asaas. Automatize a emissão de notas para suas cobranças. + +## 📋 Índice + +- [Criar Nota Fiscal](#criar-nota-fiscal) +- [Listar Notas Fiscais](#listar-notas-fiscais) +- [Recuperar Nota Fiscal](#recuperar-nota-fiscal) +- [Cancelar Nota Fiscal](#cancelar-nota-fiscal) +- [Impostos](#impostos) + +## Criar Nota Fiscal + +### Nota Fiscal Básica + +```java +import io.github.jpdev.asaassdk.rest.invoice.Invoice; +import io.github.jpdev.asaassdk.rest.invoice.Taxes; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Date; + +Invoice nota = Invoice.creator() + .setServiceDescription("Desenvolvimento de software") + .setValue(Money.create(new BigDecimal("1000.00"))) + .setEffectiveDate(new Date()) + .setMunicipalServiceName("Análise e Desenvolvimento de Sistemas") + .create(); + +System.out.println("Nota fiscal criada: " + nota.getId()); +System.out.println("Número: " + nota.getNumber()); +System.out.println("Status: " + nota.getStatus()); +``` + +### Nota Fiscal com Impostos + +```java +Taxes impostos = new Taxes() + .setRetainIss(true) + .setIss(Money.create(new BigDecimal("50.00"))) // ISS 5% + .setCofins(Money.create(new BigDecimal("30.00"))) // COFINS 3% + .setCsll(Money.create(new BigDecimal("10.00"))) // CSLL 1% + .setInss(Money.create(new BigDecimal("30.00"))) // INSS 3% + .setIr(Money.create(new BigDecimal("15.00"))) // IR 1.5% + .setPis(Money.create(new BigDecimal("6.50"))); // PIS 0.65% + +Invoice nota = Invoice.creator() + .setServiceDescription("Consultoria em TI") + .setValue(Money.create(new BigDecimal("1000.00"))) + .setEffectiveDate(new Date()) + .setMunicipalServiceName("Consultoria em Tecnologia da Informação") + .setTaxes(impostos) + .create(); + +System.out.println("Nota fiscal com impostos criada"); +System.out.println("Valor bruto: R$ " + nota.getValue()); +System.out.println("Impostos: R$ " + nota.getTaxes().getTotal()); +``` + +### Nota Fiscal com Deduções + +```java +Invoice nota = Invoice.creator() + .setServiceDescription("Desenvolvimento de aplicativo mobile") + .setValue(Money.create(new BigDecimal("5000.00"))) + .setDeductions(Money.create(new BigDecimal("100.00"))) + .setEffectiveDate(new Date()) + .setMunicipalServiceName("Desenvolvimento de Software") + .create(); + +System.out.println("Valor: R$ " + nota.getValue()); +System.out.println("Deduções: R$ " + nota.getDeductions()); +System.out.println("Valor líquido: R$ " + (nota.getValue() - nota.getDeductions())); +``` + +### Nota Fiscal com Observações + +```java +Invoice nota = Invoice.creator() + .setServiceDescription("Manutenção de sistemas") + .setObservations("Referente aos serviços prestados em Janeiro/2024. " + + "Pagamento via PIX. Obrigado pela preferência!") + .setValue(Money.create(new BigDecimal("2000.00"))) + .setEffectiveDate(new Date()) + .setMunicipalServiceName("Manutenção de Software") + .create(); + +System.out.println("Nota fiscal criada com observações"); +``` + +### Nota Fiscal para Cobrança Específica + +```java +Invoice nota = Invoice.creator() + .setPayment("pay_123456789") // ID da cobrança + .setServiceDescription("Serviço de hospedagem") + .setValue(Money.create(new BigDecimal("300.00"))) + .setEffectiveDate(new Date()) + .setMunicipalServiceName("Hospedagem de Sites") + .create(); + +System.out.println("Nota fiscal vinculada à cobrança"); +``` + +## Listar Notas Fiscais + +### Listar Todas + +```java +import io.github.jpdev.asaassdk.rest.invoice.ResourceSet; + +ResourceSet notas = Invoice.reader().read(); + +for (Invoice nota : notas.getData()) { + System.out.println("ID: " + nota.getId()); + System.out.println("Número: " + nota.getNumber()); + System.out.println("Valor: R$ " + nota.getValue()); + System.out.println("Status: " + nota.getStatus()); + System.out.println("Data: " + nota.getEffectiveDate()); + System.out.println("---"); +} +``` + +### Filtrar por Status + +```java +import io.github.jpdev.asaassdk.enums.InvoiceStatus; + +// Apenas notas autorizadas +ResourceSet autorizadas = Invoice.reader() + .setStatus(InvoiceStatus.AUTHORIZED) + .read(); + +// Apenas notas canceladas +ResourceSet canceladas = Invoice.reader() + .setStatus(InvoiceStatus.CANCELLED) + .read(); +``` + +### Filtrar por Cliente + +```java +ResourceSet notas = Invoice.reader() + .setCustomer("cus_000050606806") + .read(); + +System.out.println("Notas do cliente: " + notas.getTotalCount()); +``` + +### Filtrar por Data + +```java +import java.util.Calendar; + +Calendar cal = Calendar.getInstance(); +cal.set(2024, Calendar.JANUARY, 1); +Date dataInicio = cal.getTime(); + +cal.set(2024, Calendar.JANUARY, 31); +Date dataFim = cal.getTime(); + +ResourceSet notas = Invoice.reader() + .setStartDate(dataInicio) + .setEndDate(dataFim) + .read(); +``` + +### Paginação + +```java +ResourceSet notas = Invoice.reader() + .setLimit(50) + .setOffset(0) + .read(); + +System.out.println("Total: " + notas.getTotalCount()); +System.out.println("Tem mais: " + notas.hasMore()); +``` + +## Recuperar Nota Fiscal + +```java +Invoice nota = Invoice.fetcher("inv_000000000232").fetch(); + +System.out.println("=== NOTA FISCAL ==="); +System.out.println("ID: " + nota.getId()); +System.out.println("Número: " + nota.getNumber()); +System.out.println("Valor: R$ " + nota.getValue()); +System.out.println("Status: " + nota.getStatus()); +System.out.println("Descrição: " + nota.getServiceDescription()); +System.out.println("Data de emissão: " + nota.getEffectiveDate()); +System.out.println("PDF: " + nota.getPdfUrl()); +System.out.println("XML: " + nota.getXmlUrl()); +``` + +## Cancelar Nota Fiscal + +```java +import io.github.jpdev.asaassdk.rest.invoice.InvoiceCancelled; + +InvoiceCancelled cancelada = Invoice.canceller("inv_000000000232") + .setReason("Erro na emissão") + .cancel(); + +if (cancelada.isCancelled()) { + System.out.println("Nota fiscal cancelada com sucesso"); +} +``` + +**Nota**: Apenas notas com status `AUTHORIZED` podem ser canceladas. + +## Impostos + +### Tabela de Impostos Comuns + +| Imposto | Descrição | Alíquota Típica | +|---------|-----------|-----------------| +| ISS | Imposto Sobre Serviços | 2% a 5% | +| COFINS | Contribuição para Financiamento da Seguridade Social | 3% | +| CSLL | Contribuição Social sobre o Lucro Líquido | 1% | +| INSS | Instituto Nacional do Seguro Social | 3% | +| IR | Imposto de Renda | 1,5% | +| PIS | Programa de Integração Social | 0,65% | + +### Calcular Impostos + +```java +public class CalculadoraImpostos { + + public static Taxes calcularImpostos(double valorServico) { + double iss = valorServico * 0.05; // 5% + double cofins = valorServico * 0.03; // 3% + double csll = valorServico * 0.01; // 1% + double inss = valorServico * 0.03; // 3% + double ir = valorServico * 0.015; // 1.5% + double pis = valorServico * 0.0065; // 0.65% + + return new Taxes() + .setRetainIss(true) + .setIss(Money.create(new BigDecimal(iss))) + .setCofins(Money.create(new BigDecimal(cofins))) + .setCsll(Money.create(new BigDecimal(csll))) + .setInss(Money.create(new BigDecimal(inss))) + .setIr(Money.create(new BigDecimal(ir))) + .setPis(Money.create(new BigDecimal(pis))); + } + + public static void main(String[] args) { + double valor = 1000.00; + Taxes impostos = calcularImpostos(valor); + + System.out.println("Valor do serviço: R$ " + valor); + System.out.println("Total de impostos: R$ " + impostos.getTotal()); + System.out.println("Valor líquido: R$ " + (valor - impostos.getTotal())); + } +} +``` + +## Status de Notas Fiscais + +| Status | Descrição | +|--------|-----------| +| `SCHEDULED` | Agendada para emissão | +| `AUTHORIZED` | Autorizada pela prefeitura | +| `PROCESSING_CANCELLATION` | Processando cancelamento | +| `CANCELLED` | Cancelada | +| `ERROR` | Erro na emissão | + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.invoice.Invoice; +import io.github.jpdev.asaassdk.rest.invoice.Taxes; +import io.github.jpdev.asaassdk.rest.payment.Payment; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Date; + +public class ExemploNotaFiscal { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Criar cobrança + Payment cobranca = Payment.creator() + .setCustomer("cus_000050606806") + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("1000.00"))) + .setDescription("Desenvolvimento de software") + .create(); + + System.out.println("Cobrança criada: " + cobranca.getId()); + + // Aguardar pagamento... + // Quando pago, emitir nota fiscal + + // Calcular impostos + double valorServico = 1000.00; + Taxes impostos = new Taxes() + .setRetainIss(true) + .setIss(Money.create(new BigDecimal(valorServico * 0.05))) + .setCofins(Money.create(new BigDecimal(valorServico * 0.03))) + .setCsll(Money.create(new BigDecimal(valorServico * 0.01))) + .setInss(Money.create(new BigDecimal(valorServico * 0.03))) + .setIr(Money.create(new BigDecimal(valorServico * 0.015))) + .setPis(Money.create(new BigDecimal(valorServico * 0.0065))); + + // Emitir nota fiscal + Invoice nota = Invoice.creator() + .setPayment(cobranca.getId()) + .setServiceDescription("Desenvolvimento de software sob medida") + .setObservations("Referente ao projeto XYZ. Obrigado!") + .setValue(Money.create(new BigDecimal(valorServico))) + .setEffectiveDate(new Date()) + .setMunicipalServiceName("Análise e Desenvolvimento de Sistemas") + .setTaxes(impostos) + .create(); + + System.out.println("\n=== NOTA FISCAL EMITIDA ==="); + System.out.println("ID: " + nota.getId()); + System.out.println("Número: " + nota.getNumber()); + System.out.println("Valor: R$ " + nota.getValue()); + System.out.println("Status: " + nota.getStatus()); + System.out.println("PDF: " + nota.getPdfUrl()); + System.out.println("XML: " + nota.getXmlUrl()); + } +} +``` + +## Automação + +### Emitir Nota Automaticamente Após Pagamento + +```java +public class EmissaoAutomatica { + + public static void processarPagamento(String paymentId) { + // Verificar se pagamento foi confirmado + Payment payment = Payment.fetcher(paymentId).fetch(); + + if (payment.getStatus().equals("RECEIVED") || + payment.getStatus().equals("CONFIRMED")) { + + // Emitir nota fiscal + emitirNotaFiscal(payment); + } + } + + private static void emitirNotaFiscal(Payment payment) { + Taxes impostos = calcularImpostos(payment.getValue()); + + Invoice nota = Invoice.creator() + .setPayment(payment.getId()) + .setServiceDescription(payment.getDescription()) + .setValue(Money.create(payment.getValue())) + .setEffectiveDate(new Date()) + .setMunicipalServiceName("Serviços de TI") + .setTaxes(impostos) + .create(); + + System.out.println("Nota fiscal emitida: " + nota.getId()); + + // Enviar por email para o cliente + enviarNotaPorEmail(payment.getCustomer(), nota.getPdfUrl()); + } +} +``` + +### Webhook para Emissão Automática + +```java +// Configurar webhook para receber notificação de pagamento +Webhook webhook = Webhook.creator() + .setUrl("https://seusite.com/webhook/pagamento") + .addEvent(Event.PAYMENT_RECEIVED) + .create(); + +// No endpoint do webhook: +public void receberWebhook(WebhookPayload payload) { + if (payload.getEvent().equals("PAYMENT_RECEIVED")) { + String paymentId = payload.getPayment().getId(); + emitirNotaFiscal(paymentId); + } +} +``` + +## Boas Práticas + +### 1. Valide Dados Antes de Emitir + +```java +public static boolean validarDados(String descricao, double valor) { + if (descricao == null || descricao.isEmpty()) { + System.err.println("Descrição obrigatória"); + return false; + } + + if (valor <= 0) { + System.err.println("Valor deve ser maior que zero"); + return false; + } + + return true; +} +``` + +### 2. Trate Erros de Emissão + +```java +try { + Invoice nota = Invoice.creator() + .setServiceDescription("Serviço") + .setValue(Money.create(new BigDecimal("1000.00"))) + .setEffectiveDate(new Date()) + .create(); +} catch (AsaasException e) { + System.err.println("Erro ao emitir nota: " + e.getMessage()); + // Registrar erro e tentar novamente depois +} +``` + +### 3. Armazene URLs de PDF e XML + +```java +Invoice nota = Invoice.creator() + .setServiceDescription("Serviço") + .setValue(Money.create(new BigDecimal("1000.00"))) + .create(); + +// Salvar no banco de dados +String pdfUrl = nota.getPdfUrl(); +String xmlUrl = nota.getXmlUrl(); +salvarNoBanco(nota.getId(), pdfUrl, xmlUrl); +``` + +## Veja Também + +- [Cobranças](payment.md) - Criar cobranças para emitir notas +- [Clientes](customeraccount.md) - Gerenciar clientes +- [Webhooks](webhook.md) - Automatizar emissão + +## Referências + +- [Documentação Oficial - Notas Fiscais](https://docs.asaas.com/reference/emitir-nota-fiscal) diff --git a/docs/payment.md b/docs/payment.md index 1bc91f0..9a92ef4 100644 --- a/docs/payment.md +++ b/docs/payment.md @@ -1,76 +1,346 @@ -## Criar cobrança +# Cobranças (Payments) + +Gerencie cobranças de forma simples e eficiente. O Asaas suporta múltiplas formas de pagamento: PIX, Boleto e Cartão de Crédito. + +## 📋 Índice + +- [Criar Cobrança](#criar-cobrança) +- [Criar Cobrança Parcelada](#criar-cobrança-parcelada) +- [Listar Cobranças](#listar-cobranças) +- [Recuperar Cobrança](#recuperar-cobrança) +- [Verificar Status](#verificar-status) +- [Estornar Cobrança](#estornar-cobrança) +- [Deletar Cobrança](#deletar-cobrança) +- [Restaurar Cobrança](#restaurar-cobrança) + +## Criar Cobrança + +### Cobrança PIX + +```java +import io.github.jpdev.asaassdk.rest.payment.Payment; +import io.github.jpdev.asaassdk.enums.BillingType; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Date; + +Payment payment = Payment.creator() + .setCustomer("cus_000050606806") + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("100.50"))) + .setDescription("Pagamento de serviço") + .create(); + +System.out.println("ID da cobrança: " + payment.getId()); +System.out.println("QR Code PIX: " + payment.getPixQrCode()); +``` + +### Cobrança Boleto + +```java +Payment payment = Payment.creator() + .setCustomer("cus_000050606806") + .setBillingType(BillingType.BOLETO) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("250.00"))) + .setDescription("Mensalidade") + .create(); + +System.out.println("Link do boleto: " + payment.getBankSlipUrl()); +``` + +### Cobrança Cartão de Crédito + ```java Payment payment = Payment.creator() - .setCustomer("cus_000050606806") - .setBillingType(BillingType.PIX) - .setDueDate(new Date()) - .setValue(Money.create(new BigDecimal(10.01))) - .setDescription("Teste") - .create(); + .setCustomer("cus_000050606806") + .setBillingType(BillingType.CREDIT_CARD) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("150.00"))) + .setDescription("Compra de produto") + .create(); ``` -## Criar uma cobrança parcelada +### Cobrança com Desconto + ```java Payment payment = Payment.creator() - .setCustomer("cus_000072683114") - .setBillingType(BillingType.PIX) - .setDueDate(new Date()) - .setInstallmentCount(2) - .setInstallmentValue(Money.create(50)) - .setDescription("Teste") - .create(); + .setCustomer("cus_000050606806") + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("100.00"))) + .setDescription("Pagamento com desconto") + .setDiscount(Money.create(new BigDecimal("10.00"))) + .create(); +``` + +### Cobrança com Juros e Multa + +```java +Payment payment = Payment.creator() + .setCustomer("cus_000050606806") + .setBillingType(BillingType.BOLETO) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("500.00"))) + .setDescription("Mensalidade") + .setInterest(Money.create(new BigDecimal("2.00"))) // Juros por dia + .setFine(Money.create(new BigDecimal("10.00"))) // Multa + .create(); +``` + +## Criar Cobrança Parcelada + +Crie cobranças divididas em múltiplas parcelas: + +```java +Payment payment = Payment.creator() + .setCustomer("cus_000072683114") + .setBillingType(BillingType.CREDIT_CARD) + .setDueDate(new Date()) + .setInstallmentCount(3) // 3 parcelas + .setInstallmentValue(Money.create(new BigDecimal("50.00"))) // R$ 50,00 cada + .setDescription("Compra parcelada") + .create(); + +System.out.println("Total: R$ 150,00 em 3x de R$ 50,00"); +``` + +## Listar Cobranças + +### Listar Todas + +```java +import io.github.jpdev.asaassdk.rest.payment.ResourceSet; + +ResourceSet payments = Payment.reader().read(); + +for (Payment payment : payments.getData()) { + System.out.println("ID: " + payment.getId()); + System.out.println("Valor: " + payment.getValue()); + System.out.println("Status: " + payment.getStatus()); + System.out.println("---"); +} +``` + +### Filtrar por Status + +```java +import io.github.jpdev.asaassdk.enums.PaymentStatus; + +ResourceSet payments = Payment.reader() + .setStatus(PaymentStatus.RECEIVED) + .read(); +``` + +### Filtrar por Data de Vencimento + +```java +import java.util.Calendar; + +Calendar cal = Calendar.getInstance(); +cal.set(2024, Calendar.JANUARY, 1); +Date dataInicio = cal.getTime(); + +cal.set(2024, Calendar.DECEMBER, 31); +Date dataFim = cal.getTime(); + +ResourceSet payments = Payment.reader() + .setStartDueDate(dataInicio) + .setFinishDueDate(dataFim) + .read(); ``` -## Estornar uma cobrança recebida +### Filtrar por Data de Pagamento -Para estornar uma cobrança de forma total: ```java -Payment.refunder(paymentId) - .create(); +ResourceSet payments = Payment.reader() + .setStatus(PaymentStatus.RECEIVED) + .setStartPaymentDate(dataInicio) + .setFinishPaymentDate(dataFim) + .read(); ``` -Para estornar parcialmente, informe o valor a ser estornado: +### Filtrar por Cliente + ```java -Payment.refunder(266093389L).setValue(new BigDecimal("10.0")).create(); +ResourceSet payments = Payment.reader() + .setCustomer("cus_000050606806") + .read(); ``` -## Recuperar cobranças +### Paginação + ```java -ResourceSet paymentResourceSet = Payment.reader().read(); +ResourceSet payments = Payment.reader() + .setLimit(50) // 50 registros por página + .setOffset(0) // Página inicial + .read(); + +System.out.println("Total de cobranças: " + payments.getTotalCount()); +System.out.println("Tem próxima página: " + payments.hasMore()); ``` -Filtros também podem ser utilizados: + +## Recuperar Cobrança + +Busque uma cobrança específica pelo ID: + ```java -ResourceSet paymentResourceSet = Payment.reader() - .setStatus(PaymentStatus.RECEIVED) - .read(); +Payment payment = Payment.fetcher("pay_123456789").fetch(); + +System.out.println("Cliente: " + payment.getCustomer()); +System.out.println("Valor: " + payment.getValue()); +System.out.println("Status: " + payment.getStatus()); +System.out.println("Data de vencimento: " + payment.getDueDate()); ``` -Filtrando pela data de vencimento: + +## Verificar Status + +Consulte apenas o status de uma cobrança: + ```java -ResourceSet paymentResourceSet = Payment.reader() - .setStatus(PaymentStatus.RECEIVED) - .setStartPaymentDate(new Date()) - .setFinishDueDate(new Date()) - .read() +import io.github.jpdev.asaassdk.rest.payment.PaymentStatusData; + +PaymentStatusData status = Payment.statusFetcher("pay_9087711026766517").fetch(); + +System.out.println("Status: " + status.getStatus()); +System.out.println("Pago em: " + status.getPaymentDate()); ``` -## Recuperar status cobrança +## Estornar Cobrança + +### Estorno Total + ```java -Payment.statusFetcher("ID").fetch(); +import io.github.jpdev.asaassdk.rest.payment.PaymentRefund; + +PaymentRefund refund = Payment.refunder("pay_123456789") + .create(); + +System.out.println("Estorno realizado: " + refund.getId()); +System.out.println("Valor estornado: " + refund.getValue()); ``` -Exemplo: + +### Estorno Parcial + ```java -PaymentStatusData paymentStatusData = Payment.statusFetcher("pay_9087711026766517").fetch(); +PaymentRefund refund = Payment.refunder("pay_123456789") + .setValue(new BigDecimal("50.00")) // Estornar apenas R$ 50,00 + .create(); + +System.out.println("Estorno parcial de R$ 50,00 realizado"); ``` -## Remover cobrança +### Estorno com Descrição + ```java -PaymentDeleted paymentDeleted = Payment.deleter(payment.getId()).delete(); +PaymentRefund refund = Payment.refunder("pay_123456789") + .setDescription("Produto com defeito") + .create(); ``` -## Resgatar cobrança deletada +## Deletar Cobrança + +Delete uma cobrança que ainda não foi paga: + +```java +import io.github.jpdev.asaassdk.rest.payment.PaymentDeleted; + +PaymentDeleted deleted = Payment.deleter("pay_123456789").delete(); + +if (deleted.isDeleted()) { + System.out.println("Cobrança deletada com sucesso"); +} +``` + +**Nota**: Apenas cobranças com status `PENDING` podem ser deletadas. + +## Restaurar Cobrança + +Restaure uma cobrança que foi deletada: + ```java -Payment payment = Payment.restorer(payment.getId()).create(); +Payment payment = Payment.restorer("pay_123456789").create(); + +System.out.println("Cobrança restaurada: " + payment.getId()); +System.out.println("Status atual: " + payment.getStatus()); ``` -## Relacionados -- [Cobrança com Split](payment_split.md) \ No newline at end of file +## Status de Cobranças + +| Status | Descrição | +|--------|-----------| +| `PENDING` | Aguardando pagamento | +| `RECEIVED` | Pagamento recebido | +| `CONFIRMED` | Pagamento confirmado | +| `OVERDUE` | Vencida | +| `REFUNDED` | Estornada | +| `RECEIVED_IN_CASH` | Recebida em dinheiro | +| `REFUND_REQUESTED` | Estorno solicitado | +| `CHARGEBACK_REQUESTED` | Chargeback solicitado | +| `CHARGEBACK_DISPUTE` | Disputa de chargeback | +| `AWAITING_CHARGEBACK_REVERSAL` | Aguardando reversão de chargeback | +| `DUNNING_REQUESTED` | Negativação solicitada | +| `DUNNING_RECEIVED` | Negativação confirmada | +| `AWAITING_RISK_ANALYSIS` | Aguardando análise de risco | + +## Tipos de Cobrança + +| Tipo | Descrição | +|------|-----------| +| `BillingType.PIX` | Pagamento via PIX | +| `BillingType.BOLETO` | Boleto bancário | +| `BillingType.CREDIT_CARD` | Cartão de crédito | +| `BillingType.DEBIT_CARD` | Cartão de débito | +| `BillingType.UNDEFINED` | Não definido (cliente escolhe) | + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.payment.Payment; +import io.github.jpdev.asaassdk.rest.customeraccount.CustomerAccount; +import io.github.jpdev.asaassdk.enums.BillingType; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Date; + +public class ExemploCobranca { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Criar cliente + CustomerAccount cliente = CustomerAccount.creator() + .setName("Maria Silva") + .setCpfCnpj("12345678900") + .setEmail("maria@exemplo.com") + .create(); + + // Criar cobrança PIX + Payment cobranca = Payment.creator() + .setCustomer(cliente.getId()) + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("150.00"))) + .setDescription("Pagamento de serviço") + .create(); + + System.out.println("Cobrança criada com sucesso!"); + System.out.println("ID: " + cobranca.getId()); + System.out.println("QR Code: " + cobranca.getPixQrCode()); + System.out.println("Valor: R$ " + cobranca.getValue()); + } +} +``` + +## Veja Também + +- [Cobranças com Split](payment_split.md) - Dividir pagamentos entre múltiplas contas +- [Assinaturas](subscription.md) - Cobranças recorrentes +- [Links de Pagamento](paymentlink.md) - Criar páginas de checkout +- [Clientes](customeraccount.md) - Gerenciar clientes + +## Referências + +- [Documentação Oficial - Cobranças](https://docs.asaas.com/reference/criar-nova-cobranca) diff --git a/docs/payment_split.md b/docs/payment_split.md index 45a7300..a9c858c 100644 --- a/docs/payment_split.md +++ b/docs/payment_split.md @@ -1,33 +1,486 @@ -## Criar cobrança com split +# Cobranças com Split (Payment Split) + +Divida pagamentos entre múltiplas contas automaticamente. Ideal para marketplaces, franquias e plataformas multi-vendedor. + +## 📋 Índice + +- [Criar Cobrança com Split](#criar-cobrança-com-split) +- [Tipos de Split](#tipos-de-split) +- [Listar Splits](#listar-splits) +- [Casos de Uso](#casos-de-uso) + +## Criar Cobrança com Split + +### Split com Valor Fixo + +```java +import io.github.jpdev.asaassdk.rest.payment.Payment; +import io.github.jpdev.asaassdk.rest.payment.SplitSetting; +import io.github.jpdev.asaassdk.enums.BillingType; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Date; + +// Definir split para vendedor +SplitSetting splitVendedor = new SplitSetting() + .setWalletId("635b5330-3931-4ab2-b78c-3c59f136c535") + .setFixedValue(Money.create(new BigDecimal("50.00"))); + +// Criar cobrança com split +Payment payment = Payment.creator() + .setCustomer("cus_000050606806") + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("100.00"))) + .setDescription("Venda no marketplace") + .addSplit(splitVendedor) + .create(); + +System.out.println("Cobrança criada: " + payment.getId()); +System.out.println("Vendedor receberá: R$ 50,00"); +System.out.println("Plataforma receberá: R$ 50,00"); +``` + +### Split com Percentual + ```java +SplitSetting splitVendedor = new SplitSetting() + .setWalletId("635b5330-3931-4ab2-b78c-3c59f136c535") + .setPercentualValue(new BigDecimal("80.00")); // 80% para o vendedor + +Payment payment = Payment.creator() + .setCustomer("cus_000050606806") + .setBillingType(BillingType.CREDIT_CARD) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("100.00"))) + .setDescription("Venda com comissão") + .addSplit(splitVendedor) + .create(); + +System.out.println("Vendedor receberá: R$ 80,00 (80%)"); +System.out.println("Plataforma receberá: R$ 20,00 (20%)"); +``` + +### Split para Múltiplos Vendedores + +```java +// Split para vendedor 1 SplitSetting split1 = new SplitSetting() - .setWalletId("635b5330-3931-4ab2-b78c-3c59f136c535") - .setFixedValue(Money.create(10)); + .setWalletId("wallet-vendedor-1") + .setFixedValue(Money.create(new BigDecimal("40.00"))); + +// Split para vendedor 2 +SplitSetting split2 = new SplitSetting() + .setWalletId("wallet-vendedor-2") + .setFixedValue(Money.create(new BigDecimal("30.00"))); +// Criar cobrança com múltiplos splits Payment payment = Payment.creator() - .setCustomer("cus_000050606806") - .setBillingType(BillingType.PIX) - .setDueDate(new Date()) - .setValue(Money.create(new BigDecimal(10.01))) - .setDescription("Teste") - .addSplit(split1) - .create(); + .setCustomer("cus_000050606806") + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("100.00"))) + .setDescription("Compra com múltiplos vendedores") + .addSplit(split1) + .addSplit(split2) + .create(); + +System.out.println("Vendedor 1: R$ 40,00"); +System.out.println("Vendedor 2: R$ 30,00"); +System.out.println("Plataforma: R$ 30,00"); ``` -É possível adicionar mais splits para carteiras diferentes: +### Split com Taxas Personalizadas + ```java -.addSplit(split1) -.addSplit(split1); +SplitSetting splitVendedor = new SplitSetting() + .setWalletId("wallet-vendedor") + .setFixedValue(Money.create(new BigDecimal("90.00"))) + .setTotalFixedValue(Money.create(new BigDecimal("5.00"))); // Taxa fixa adicional + +Payment payment = Payment.creator() + .setCustomer("cus_000050606806") + .setBillingType(BillingType.BOLETO) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("100.00"))) + .setDescription("Venda com taxa") + .addSplit(splitVendedor) + .create(); ``` -## Listar splits pagos +## Tipos de Split + +### Por Valor Fixo + ```java +SplitSetting split = new SplitSetting() + .setWalletId("wallet-id") + .setFixedValue(Money.create(new BigDecimal("50.00"))); +``` + +### Por Percentual + +```java +SplitSetting split = new SplitSetting() + .setWalletId("wallet-id") + .setPercentualValue(new BigDecimal("75.00")); // 75% +``` + +### Misto (Fixo + Percentual) + +```java +SplitSetting split = new SplitSetting() + .setWalletId("wallet-id") + .setFixedValue(Money.create(new BigDecimal("10.00"))) + .setPercentualValue(new BigDecimal("70.00")); // R$ 10 + 70% do restante +``` + +## Listar Splits + +### Listar Splits Pagos + +```java +import io.github.jpdev.asaassdk.rest.split.Split; +import io.github.jpdev.asaassdk.rest.split.PaymentSplitPaidReader; +import io.github.jpdev.asaassdk.rest.split.ResourceSet; + +PaymentSplitPaidReader reader = Split.paidReader(); +ResourceSet splits = reader.read(); + +for (Object split : splits.getData()) { + System.out.println("Split pago: " + split); +} +``` + +### Listar Splits Recebidos + +```java +import io.github.jpdev.asaassdk.rest.split.PaymentSplitReceivedReader; + +PaymentSplitReceivedReader reader = Split.receivedReader(); +ResourceSet splits = reader.read(); + +for (Object split : splits.getData()) { + System.out.println("Split recebido: " + split); +} +``` + +### Filtrar por Data + +```java +import java.util.Calendar; + +Calendar cal = Calendar.getInstance(); +cal.set(2024, Calendar.JANUARY, 1); +Date dataInicio = cal.getTime(); + +cal.set(2024, Calendar.JANUARY, 31); +Date dataFim = cal.getTime(); + PaymentSplitPaidReader reader = Split.paidReader() -reader.read(); + .setStartDate(dataInicio) + .setEndDate(dataFim); + +ResourceSet splits = reader.read(); +``` + +## Casos de Uso + +### Marketplace + +```java +public class MarketplaceSplit { + + public static Payment criarVendaMarketplace( + String clienteId, + String vendedorWalletId, + double valorProduto, + double comissaoPlataforma + ) { + double valorVendedor = valorProduto - comissaoPlataforma; + + SplitSetting splitVendedor = new SplitSetting() + .setWalletId(vendedorWalletId) + .setFixedValue(Money.create(new BigDecimal(valorVendedor))); + + Payment payment = Payment.creator() + .setCustomer(clienteId) + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal(valorProduto))) + .setDescription("Venda no marketplace") + .addSplit(splitVendedor) + .create(); + + System.out.println("Venda criada:"); + System.out.println("Total: R$ " + valorProduto); + System.out.println("Vendedor: R$ " + valorVendedor); + System.out.println("Comissão: R$ " + comissaoPlataforma); + + return payment; + } + + public static void main(String[] args) { + Asaas.init("sua_api_key"); + criarVendaMarketplace( + "cus_cliente", + "wallet_vendedor", + 100.00, + 15.00 // 15% de comissão + ); + } +} +``` + +### Franquia + +```java +public class FranquiaSplit { + + public static Payment criarVendaFranquia( + String clienteId, + String franqueadoWalletId, + double valorVenda + ) { + // 90% para franqueado, 10% para franqueadora + SplitSetting splitFranqueado = new SplitSetting() + .setWalletId(franqueadoWalletId) + .setPercentualValue(new BigDecimal("90.00")); + + Payment payment = Payment.creator() + .setCustomer(clienteId) + .setBillingType(BillingType.CREDIT_CARD) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal(valorVenda))) + .setDescription("Venda franquia") + .addSplit(splitFranqueado) + .create(); + + System.out.println("Franqueado: R$ " + (valorVenda * 0.9)); + System.out.println("Franqueadora: R$ " + (valorVenda * 0.1)); + + return payment; + } +} +``` + +### Plataforma de Serviços + +```java +public class PlataformaServicos { + + public static Payment criarPagamentoServico( + String clienteId, + String prestadorWalletId, + double valorServico, + double taxaPlataforma + ) { + double valorPrestador = valorServico - taxaPlataforma; + + SplitSetting splitPrestador = new SplitSetting() + .setWalletId(prestadorWalletId) + .setFixedValue(Money.create(new BigDecimal(valorPrestador))); + + Payment payment = Payment.creator() + .setCustomer(clienteId) + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal(valorServico))) + .setDescription("Pagamento de serviço") + .addSplit(splitPrestador) + .create(); + + return payment; + } +} +``` + +### Carrinho com Múltiplos Vendedores + +```java +public class CarrinhoMultiVendedor { + + public static class ItemCarrinho { + String vendedorWalletId; + double valor; + + public ItemCarrinho(String walletId, double valor) { + this.vendedorWalletId = walletId; + this.valor = valor; + } + } + + public static Payment criarPagamentoCarrinho( + String clienteId, + List itens + ) { + double valorTotal = 0; + Payment.Creator paymentCreator = Payment.creator() + .setCustomer(clienteId) + .setBillingType(BillingType.PIX) + .setDueDate(new Date()); + + // Adicionar split para cada vendedor + for (ItemCarrinho item : itens) { + valorTotal += item.valor; + + SplitSetting split = new SplitSetting() + .setWalletId(item.vendedorWalletId) + .setFixedValue(Money.create(new BigDecimal(item.valor))); + + paymentCreator.addSplit(split); + } + + Payment payment = paymentCreator + .setValue(Money.create(new BigDecimal(valorTotal))) + .setDescription("Compra com múltiplos vendedores") + .create(); + + System.out.println("Carrinho criado com " + itens.size() + " vendedores"); + System.out.println("Valor total: R$ " + valorTotal); + + return payment; + } +} +``` + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.payment.Payment; +import io.github.jpdev.asaassdk.rest.payment.SplitSetting; +import io.github.jpdev.asaassdk.rest.account.Account; +import io.github.jpdev.asaassdk.enums.BillingType; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Date; + +public class ExemploSplit { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Criar subconta para vendedor + Account vendedor = Account.creator() + .setName("Vendedor Parceiro") + .setEmail("vendedor@marketplace.com") + .setCpfCnpj("12345678000190") + .setBirthDate(new Date(2020, 0, 1)) + .setCompanyType("LIMITED") + .setPostalCode("89010-000") + .create(); + + System.out.println("Vendedor criado: " + vendedor.getId()); + System.out.println("Wallet ID: " + vendedor.getWalletId()); + + // Criar cobrança com split + double valorTotal = 100.00; + double comissao = 15.00; // 15% + double valorVendedor = valorTotal - comissao; + + SplitSetting split = new SplitSetting() + .setWalletId(vendedor.getWalletId()) + .setFixedValue(Money.create(new BigDecimal(valorVendedor))); + + Payment payment = Payment.creator() + .setCustomer("cus_000050606806") + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal(valorTotal))) + .setDescription("Venda no marketplace") + .addSplit(split) + .create(); + + System.out.println("\n=== COBRANÇA COM SPLIT ==="); + System.out.println("ID: " + payment.getId()); + System.out.println("Valor total: R$ " + valorTotal); + System.out.println("Vendedor recebe: R$ " + valorVendedor); + System.out.println("Plataforma recebe: R$ " + comissao); + } +} ``` -## Listar splits recebidos +## Cálculo de Splits + +### Calculadora de Comissão + ```java -PaymentSplitReceivedReader reader = Split.receivedReader() -reader.read(); -``` \ No newline at end of file +public class CalculadoraSplit { + + public static double calcularComissao(double valorVenda, double percentualComissao) { + return valorVenda * (percentualComissao / 100); + } + + public static double calcularValorVendedor(double valorVenda, double percentualComissao) { + return valorVenda - calcularComissao(valorVenda, percentualComissao); + } + + public static void exibirResumo(double valorVenda, double percentualComissao) { + double comissao = calcularComissao(valorVenda, percentualComissao); + double valorVendedor = calcularValorVendedor(valorVenda, percentualComissao); + + System.out.println("=== RESUMO DO SPLIT ==="); + System.out.println("Valor da venda: R$ " + String.format("%.2f", valorVenda)); + System.out.println("Comissão (" + percentualComissao + "%): R$ " + String.format("%.2f", comissao)); + System.out.println("Vendedor recebe: R$ " + String.format("%.2f", valorVendedor)); + } + + public static void main(String[] args) { + exibirResumo(100.00, 15.00); + } +} +``` + +## Boas Práticas + +### 1. Valide Wallet IDs + +```java +public static boolean validarWalletId(String walletId) { + if (walletId == null || walletId.isEmpty()) { + System.err.println("Wallet ID inválido"); + return false; + } + return true; +} +``` + +### 2. Verifique Valores + +```java +public static boolean validarSplit(double valorTotal, double valorSplit) { + if (valorSplit > valorTotal) { + System.err.println("Valor do split maior que o total"); + return false; + } + return true; +} +``` + +### 3. Registre Splits + +```java +// Salvar informações do split no banco de dados +public static void registrarSplit(String paymentId, String walletId, double valor) { + // Implementar persistência + System.out.println("Split registrado: " + paymentId); +} +``` + +## Limitações + +- Valor mínimo de split: R$ 1,00 +- Soma dos splits não pode exceder o valor total +- Wallet ID deve ser de subconta vinculada +- Splits são processados após confirmação do pagamento + +## Veja Também + +- [Subcontas](account.md) - Criar subcontas para vendedores +- [Cobranças](payment.md) - Criar cobranças +- [Transferências](transfer.md) - Transferir entre contas + +## Referências + +- [Documentação Oficial - Split](https://docs.asaas.com/reference/split-de-pagamento) diff --git a/docs/paymentlink.md b/docs/paymentlink.md index c13cd81..c1a2ac5 100644 --- a/docs/paymentlink.md +++ b/docs/paymentlink.md @@ -1,42 +1,536 @@ -## Criar um link de pagamento +# Links de Pagamento (Payment Links) + +Crie páginas de checkout personalizadas sem programação. Compartilhe links para receber pagamentos de forma simples. + +## 📋 Índice + +- [Criar Link](#criar-link) +- [Listar Links](#listar-links) +- [Atualizar Link](#atualizar-link) +- [Deletar Link](#deletar-link) +- [Tipos de Cobrança](#tipos-de-cobrança) + +## Criar Link + +### Link Básico + +```java +import io.github.jpdev.asaassdk.rest.paymentlink.PaymentLink; +import io.github.jpdev.asaassdk.enums.BillingType; +import io.github.jpdev.asaassdk.enums.PaymentLinkChargeType; + +PaymentLink link = PaymentLink.creator() + .setName("Produto Digital") + .setBillingType(BillingType.PIX) + .setChargeType(PaymentLinkChargeType.DETACHED) + .create(); + +System.out.println("Link criado: " + link.getId()); +System.out.println("URL: " + link.getUrl()); +``` + +### Link com Valor Fixo + +```java +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; + +PaymentLink link = PaymentLink.creator() + .setName("Curso Online") + .setDescription("Curso completo de programação") + .setBillingType(BillingType.CREDIT_CARD) + .setChargeType(PaymentLinkChargeType.DETACHED) + .setValue(Money.create(new BigDecimal("297.00"))) + .create(); + +System.out.println("Link: " + link.getUrl()); +System.out.println("Valor: R$ 297,00"); +``` + +### Link com Parcelamento + +```java +PaymentLink link = PaymentLink.creator() + .setName("Notebook") + .setDescription("Notebook Dell Inspiron") + .setBillingType(BillingType.CREDIT_CARD) + .setChargeType(PaymentLinkChargeType.INSTALLMENT) + .setValue(Money.create(new BigDecimal("3000.00"))) + .setMaxInstallmentCount(12) // Até 12x + .create(); + +System.out.println("Link criado com parcelamento em até 12x"); +``` + +### Link com Data de Expiração + +```java +import java.util.Calendar; + +Calendar cal = Calendar.getInstance(); +cal.add(Calendar.DAY_OF_MONTH, 30); // Expira em 30 dias +Date dataExpiracao = cal.getTime(); + +PaymentLink link = PaymentLink.creator() + .setName("Promoção Limitada") + .setBillingType(BillingType.PIX) + .setChargeType(PaymentLinkChargeType.DETACHED) + .setValue(Money.create(new BigDecimal("99.00"))) + .setEndDate(dataExpiracao) + .create(); + +System.out.println("Link expira em: " + link.getEndDate()); +``` + +### Link com Limite de Vencimento + +```java +PaymentLink link = PaymentLink.creator() + .setName("Mensalidade") + .setBillingType(BillingType.BOLETO) + .setChargeType(PaymentLinkChargeType.DETACHED) + .setValue(Money.create(new BigDecimal("150.00"))) + .setDueDateLimitDays(5) // Cliente tem 5 dias para pagar + .create(); + +System.out.println("Prazo de pagamento: 5 dias"); +``` + +### Link com Múltiplas Formas de Pagamento + +```java +PaymentLink link = PaymentLink.creator() + .setName("Produto Versátil") + .setBillingType(BillingType.UNDEFINED) // Cliente escolhe + .setChargeType(PaymentLinkChargeType.DETACHED) + .setValue(Money.create(new BigDecimal("500.00"))) + .create(); + +System.out.println("Cliente pode escolher: PIX, Boleto ou Cartão"); +``` + +### Link com Assinatura + +```java +import io.github.jpdev.asaassdk.enums.SubscriptionCycle; + +PaymentLink link = PaymentLink.creator() + .setName("Plano Premium") + .setDescription("Acesso completo à plataforma") + .setBillingType(BillingType.CREDIT_CARD) + .setChargeType(PaymentLinkChargeType.RECURRENT) + .setValue(Money.create(new BigDecimal("49.90"))) + .setSubscriptionCycle(SubscriptionCycle.MONTHLY) + .create(); + +System.out.println("Link de assinatura mensal criado"); +``` + +## Listar Links + +### Listar Todos + +```java +import io.github.jpdev.asaassdk.rest.paymentlink.ResourceSet; + +ResourceSet links = PaymentLink.reader().read(); + +for (PaymentLink link : links.getData()) { + System.out.println("Nome: " + link.getName()); + System.out.println("URL: " + link.getUrl()); + System.out.println("Valor: R$ " + link.getValue()); + System.out.println("Status: " + link.getActive()); + System.out.println("---"); +} +``` + +### Filtrar por Status + ```java -PaymentLink paymentLink = PaymentLink.creator() - .setName("name") - .setBillingType(BillingType.PIX) - .setChargeType(PaymentLinkChargeType.INSTALLMENT) - .setEndDate(new Date()) - .setDueDateLimitDays(10) - .setMaxInstallmentCount(2) - .create(); +// Apenas links ativos +ResourceSet ativos = PaymentLink.reader() + .setActive(true) + .read(); + +// Apenas links inativos +ResourceSet inativos = PaymentLink.reader() + .setActive(false) + .read(); ``` -## Atualizar Link de pagamento +### Paginação + ```java -PaymentLink updated = PaymentLink.updater(paymentLink.getId()) - .setName("name") - .setBillingType(BillingType.PIX) - .setChargeType(PaymentLinkChargeType.INSTALLMENT) - .setEndDate(new Date()) - .setDueDateLimitDays(10) - .setMaxInstallmentCount(2) - .update(); +ResourceSet links = PaymentLink.reader() + .setLimit(50) + .setOffset(0) + .read(); + +System.out.println("Total: " + links.getTotalCount()); +System.out.println("Tem mais: " + links.hasMore()); ``` -## Deletar um link de pagamento +## Atualizar Link + +### Atualizar Valor + ```java -DeletedResource deletedPaymentLink = PaymentLink - .deleter("725104409743") - .delete(); +PaymentLink atualizado = PaymentLink.updater("725104409743") + .setValue(Money.create(new BigDecimal("399.00"))) + .update(); + +System.out.println("Novo valor: R$ " + atualizado.getValue()); +``` + +### Atualizar Nome e Descrição + +```java +PaymentLink atualizado = PaymentLink.updater("725104409743") + .setName("Novo Nome do Produto") + .setDescription("Nova descrição detalhada") + .update(); +``` + +### Atualizar Data de Expiração + +```java +Calendar cal = Calendar.getInstance(); +cal.add(Calendar.MONTH, 1); +Date novaData = cal.getTime(); + +PaymentLink atualizado = PaymentLink.updater("725104409743") + .setEndDate(novaData) + .update(); + +System.out.println("Nova data de expiração: " + atualizado.getEndDate()); ``` -## Listar links de pagamento +### Desativar Link + ```java -ResourceSet paymentLinkResourceSet = PaymentLink - .reader() - .read(); +PaymentLink atualizado = PaymentLink.updater("725104409743") + .setActive(false) + .update(); + +System.out.println("Link desativado"); ``` -## Recuperar um link de pagamento +## Recuperar Link + ```java PaymentLink link = PaymentLink.fetcher("725104409743").fetch(); -``` \ No newline at end of file + +System.out.println("=== DETALHES DO LINK ==="); +System.out.println("ID: " + link.getId()); +System.out.println("Nome: " + link.getName()); +System.out.println("URL: " + link.getUrl()); +System.out.println("Valor: R$ " + link.getValue()); +System.out.println("Tipo: " + link.getChargeType()); +System.out.println("Forma de pagamento: " + link.getBillingType()); +System.out.println("Ativo: " + link.getActive()); +System.out.println("Data de criação: " + link.getDateCreated()); +``` + +## Deletar Link + +```java +import io.github.jpdev.asaassdk.rest.paymentlink.DeletedResource; + +DeletedResource deletado = PaymentLink.deleter("725104409743").delete(); + +if (deletado.isDeleted()) { + System.out.println("Link deletado com sucesso"); +} +``` + +## Tipos de Cobrança + +| Tipo | Descrição | Uso | +|------|-----------|-----| +| `DETACHED` | Cobrança avulsa | Venda única | +| `INSTALLMENT` | Parcelamento | Venda parcelada | +| `RECURRENT` | Recorrente | Assinatura | + +## Casos de Uso + +### E-commerce + +```java +public class LinkEcommerce { + + public static PaymentLink criarLinkProduto( + String nomeProduto, + String descricao, + double preco, + int maxParcelas + ) { + PaymentLink link = PaymentLink.creator() + .setName(nomeProduto) + .setDescription(descricao) + .setBillingType(BillingType.CREDIT_CARD) + .setChargeType(PaymentLinkChargeType.INSTALLMENT) + .setValue(Money.create(new BigDecimal(preco))) + .setMaxInstallmentCount(maxParcelas) + .create(); + + System.out.println("Link do produto criado:"); + System.out.println("URL: " + link.getUrl()); + System.out.println("Parcelamento: até " + maxParcelas + "x"); + + return link; + } + + public static void main(String[] args) { + Asaas.init("sua_api_key"); + criarLinkProduto("Smartphone XYZ", "Smartphone top de linha", 2500.00, 10); + } +} +``` + +### Serviços Digitais + +```java +public class LinkServicosDigitais { + + public static PaymentLink criarLinkCurso( + String nomeCurso, + double preco + ) { + PaymentLink link = PaymentLink.creator() + .setName(nomeCurso) + .setDescription("Acesso vitalício ao curso") + .setBillingType(BillingType.PIX) + .setChargeType(PaymentLinkChargeType.DETACHED) + .setValue(Money.create(new BigDecimal(preco))) + .create(); + + System.out.println("Link do curso: " + link.getUrl()); + return link; + } +} +``` + +### Assinaturas + +```java +public class LinkAssinatura { + + public static PaymentLink criarPlano( + String nomePlano, + double valorMensal, + SubscriptionCycle ciclo + ) { + PaymentLink link = PaymentLink.creator() + .setName(nomePlano) + .setDescription("Assinatura " + ciclo.toString().toLowerCase()) + .setBillingType(BillingType.CREDIT_CARD) + .setChargeType(PaymentLinkChargeType.RECURRENT) + .setValue(Money.create(new BigDecimal(valorMensal))) + .setSubscriptionCycle(ciclo) + .create(); + + System.out.println("Plano criado: " + link.getUrl()); + return link; + } + + public static void main(String[] args) { + Asaas.init("sua_api_key"); + + // Plano mensal + criarPlano("Plano Básico", 29.90, SubscriptionCycle.MONTHLY); + + // Plano anual + criarPlano("Plano Anual", 299.00, SubscriptionCycle.YEARLY); + } +} +``` + +### Doações + +```java +public class LinkDoacao { + + public static PaymentLink criarLinkDoacao(String causa) { + PaymentLink link = PaymentLink.creator() + .setName("Doação - " + causa) + .setDescription("Contribua com qualquer valor") + .setBillingType(BillingType.PIX) + .setChargeType(PaymentLinkChargeType.DETACHED) + // Sem valor fixo - cliente define + .create(); + + System.out.println("Link de doação: " + link.getUrl()); + return link; + } +} +``` + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.paymentlink.PaymentLink; +import io.github.jpdev.asaassdk.enums.*; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Calendar; +import java.util.Date; + +public class ExemploPaymentLink { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Criar link de pagamento + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.DAY_OF_MONTH, 30); + Date dataExpiracao = cal.getTime(); + + PaymentLink link = PaymentLink.creator() + .setName("Curso de Java Avançado") + .setDescription("Curso completo com certificado") + .setBillingType(BillingType.CREDIT_CARD) + .setChargeType(PaymentLinkChargeType.INSTALLMENT) + .setValue(Money.create(new BigDecimal("497.00"))) + .setMaxInstallmentCount(6) + .setEndDate(dataExpiracao) + .setDueDateLimitDays(7) + .create(); + + System.out.println("=== LINK DE PAGAMENTO CRIADO ==="); + System.out.println("ID: " + link.getId()); + System.out.println("Nome: " + link.getName()); + System.out.println("URL: " + link.getUrl()); + System.out.println("Valor: R$ " + link.getValue()); + System.out.println("Parcelamento: até 6x"); + System.out.println("Expira em: " + link.getEndDate()); + + // Compartilhar URL + System.out.println("\nCompartilhe este link:"); + System.out.println(link.getUrl()); + + // Atualizar link + PaymentLink atualizado = PaymentLink.updater(link.getId()) + .setDescription("Curso completo com certificado + bônus") + .update(); + + System.out.println("\nDescrição atualizada!"); + + // Listar todos os links + ResourceSet links = PaymentLink.reader().read(); + System.out.println("\nTotal de links: " + links.getTotalCount()); + } +} +``` + +## Gerenciamento de Links + +### Dashboard de Links + +```java +public class DashboardLinks { + + public static void exibirDashboard() { + ResourceSet todos = PaymentLink.reader().read(); + ResourceSet ativos = PaymentLink.reader() + .setActive(true) + .read(); + + System.out.println("╔════════════════════════════════════════╗"); + System.out.println("║ DASHBOARD DE LINKS ║"); + System.out.println("╠════════════════════════════════════════╣"); + System.out.println("║ Total de links: " + todos.getTotalCount()); + System.out.println("║ Links ativos: " + ativos.getTotalCount()); + System.out.println("║ Links inativos: " + (todos.getTotalCount() - ativos.getTotalCount())); + System.out.println("╚════════════════════════════════════════╝"); + } +} +``` + +### Relatório de Vendas por Link + +```java +public class RelatorioVendas { + + public static void gerarRelatorio(String linkId) { + PaymentLink link = PaymentLink.fetcher(linkId).fetch(); + + // Buscar pagamentos do link + ResourceSet pagamentos = Payment.reader() + .setPaymentLink(linkId) + .read(); + + double totalVendas = 0; + int totalPagamentos = 0; + + for (Payment p : pagamentos.getData()) { + if (p.getStatus().equals("RECEIVED") || + p.getStatus().equals("CONFIRMED")) { + totalVendas += p.getValue(); + totalPagamentos++; + } + } + + System.out.println("=== RELATÓRIO DE VENDAS ==="); + System.out.println("Link: " + link.getName()); + System.out.println("Total de pagamentos: " + totalPagamentos); + System.out.println("Total vendido: R$ " + String.format("%.2f", totalVendas)); + } +} +``` + +## Boas Práticas + +### 1. Use Nomes Descritivos + +```java +PaymentLink link = PaymentLink.creator() + .setName("Curso Java - Turma Janeiro 2024") + .setDescription("Descrição completa do produto") + .create(); +``` + +### 2. Defina Data de Expiração + +```java +Calendar cal = Calendar.getInstance(); +cal.add(Calendar.MONTH, 3); // Expira em 3 meses + +PaymentLink link = PaymentLink.creator() + .setName("Promoção") + .setEndDate(cal.getTime()) + .create(); +``` + +### 3. Configure Parcelamento Adequado + +```java +// Para produtos de alto valor +PaymentLink link = PaymentLink.creator() + .setName("Produto Premium") + .setValue(Money.create(new BigDecimal("5000.00"))) + .setMaxInstallmentCount(12) + .create(); +``` + +### 4. Monitore Links Ativos + +```java +ResourceSet ativos = PaymentLink.reader() + .setActive(true) + .read(); + +if (ativos.getTotalCount() > 100) { + System.out.println("⚠️ Muitos links ativos. Considere desativar os não utilizados."); +} +``` + +## Veja Também + +- [Cobranças](payment.md) - Criar cobranças diretas +- [Assinaturas](subscription.md) - Pagamentos recorrentes +- [Clientes](customeraccount.md) - Gerenciar clientes + +## Referências + +- [Documentação Oficial - Links de Pagamento](https://docs.asaas.com/reference/criar-link-de-pagamento) diff --git a/docs/pix_automatic.md b/docs/pix_automatic.md index 6472185..f7edeb6 100644 --- a/docs/pix_automatic.md +++ b/docs/pix_automatic.md @@ -1,100 +1,459 @@ -# Pix Automático +# PIX Automático (Débito Recorrente) + +Configure débitos recorrentes via PIX. Ideal para assinaturas, mensalidades e pagamentos automáticos. + +## 📋 Índice + +- [Autorizações](#autorizações) +- [Instruções de Pagamento](#instruções-de-pagamento) +- [Gerenciar Autorizações](#gerenciar-autorizações) +- [Casos de Uso](#casos-de-uso) ## Autorizações -### Criar autorização Pix Automático +### Criar Autorização ```java -/* - any date - */ +import io.github.jpdev.asaassdk.rest.pixautomatic.authorization.PixAutomaticAuthorization; +import io.github.jpdev.asaassdk.rest.pixautomatic.authorization.ImmediateQrCodeCreator; +import io.github.jpdev.asaassdk.enums.PixAutomaticAuthorizationFrequency; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Calendar; +import java.util.Date; + +// Data de início Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_MONTH, 1); Date startDate = calendar.getTime(); -ImmediateQrCodeCreator immediateQrCodeCreator = new ImmediateQrCodeCreator() - .setDescription("teste") - .setExpirationSeconds(3600) - .setOriginalValue(Money.create(10)); +// QR Code para autorização +ImmediateQrCodeCreator qrCode = new ImmediateQrCodeCreator() + .setDescription("Autorização PIX Automático") + .setExpirationSeconds(3600) // 1 hora + .setOriginalValue(Money.create(new BigDecimal("0.01"))); // Valor simbólico +// Criar autorização PixAutomaticAuthorization authorization = PixAutomaticAuthorization.creator() - .setCustomerId("cus_000007258649") // your customer_id + .setCustomerId("cus_000007258649") .setStartDate(startDate) .setFrequency(PixAutomaticAuthorizationFrequency.MONTHLY) - .setValue(Money.create(100)) - .setContractId("CONTRACT_ID_123") - .setImmediateQrCode(immediateQrCodeCreator) + .setValue(Money.create(new BigDecimal("99.90"))) + .setContractId("CONTRATO_123") + .setImmediateQrCode(qrCode) + .create(); + +System.out.println("Autorização criada: " + authorization.getId()); +System.out.println("QR Code: " + authorization.getQrCode()); +System.out.println("Status: " + authorization.getStatus()); +``` + +### Autorização Mensal + +```java +Calendar cal = Calendar.getInstance(); +cal.add(Calendar.DAY_OF_MONTH, 1); + +ImmediateQrCodeCreator qrCode = new ImmediateQrCodeCreator() + .setDescription("Mensalidade") + .setExpirationSeconds(3600) + .setOriginalValue(Money.create(new BigDecimal("0.01"))); + +PixAutomaticAuthorization auth = PixAutomaticAuthorization.creator() + .setCustomerId("cus_000007258649") + .setStartDate(cal.getTime()) + .setFrequency(PixAutomaticAuthorizationFrequency.MONTHLY) + .setValue(Money.create(new BigDecimal("150.00"))) + .setContractId("MENSALIDADE_2024") + .setImmediateQrCode(qrCode) .create(); + +System.out.println("Débito mensal de R$ 150,00 autorizado"); ``` -### Listar autorizações Pix Automático +### Autorização Semanal ```java -ResourceSet authorizationResourceSet = PixAutomaticAuthorization.reader().read(); +Calendar cal = Calendar.getInstance(); +cal.add(Calendar.DAY_OF_MONTH, 1); + +ImmediateQrCodeCreator qrCode = new ImmediateQrCodeCreator() + .setDescription("Pagamento semanal") + .setExpirationSeconds(3600) + .setOriginalValue(Money.create(new BigDecimal("0.01"))); + +PixAutomaticAuthorization auth = PixAutomaticAuthorization.creator() + .setCustomerId("cus_000007258649") + .setStartDate(cal.getTime()) + .setFrequency(PixAutomaticAuthorizationFrequency.WEEKLY) + .setValue(Money.create(new BigDecimal("50.00"))) + .setContractId("SEMANAL_123") + .setImmediateQrCode(qrCode) + .create(); + +System.out.println("Débito semanal de R$ 50,00 autorizado"); +``` -for (PixAutomaticAuthorization authorization : authorizationResourceSet.getData()) { - System.out.println(authorization.getContractId()); +## Listar Autorizações + +### Listar Todas + +```java +import io.github.jpdev.asaassdk.rest.pixautomatic.authorization.ResourceSet; + +ResourceSet autorizacoes = PixAutomaticAuthorization.reader().read(); + +for (PixAutomaticAuthorization auth : autorizacoes.getData()) { + System.out.println("ID: " + auth.getId()); + System.out.println("Cliente: " + auth.getCustomerId()); + System.out.println("Valor: R$ " + auth.getValue()); + System.out.println("Frequência: " + auth.getFrequency()); + System.out.println("Status: " + auth.getStatus()); + System.out.println("Contrato: " + auth.getContractId()); + System.out.println("---"); } ``` -### Recuperar uma autorização do Pix Automático +## Recuperar Autorização ```java -import io.github.jpdev.asaassdk.rest.pixautomatic.authorization.PixAutomaticAuthorization; +String authId = "uuid-da-autorizacao"; + +PixAutomaticAuthorization auth = PixAutomaticAuthorization.fetcher(authId).fetch(); -String id = "uuidv4"; -PixAutomaticAuthorization authorization = PixAutomaticAuthorization.fetcher(id).fetch(); +System.out.println("=== AUTORIZAÇÃO ==="); +System.out.println("ID: " + auth.getId()); +System.out.println("Cliente: " + auth.getCustomerId()); +System.out.println("Valor: R$ " + auth.getValue()); +System.out.println("Frequência: " + auth.getFrequency()); +System.out.println("Data início: " + auth.getStartDate()); +System.out.println("Status: " + auth.getStatus()); +System.out.println("Contrato: " + auth.getContractId()); ``` -### Cancelar autorização +## Cancelar Autorização ```java -String id = "uuidv4"; +String authId = "uuid-da-autorizacao"; -PixAutomaticAuthorization cancelledAuthorization = PixAutomaticAuthorization - .deleter("AUTHORIZATION_ID") - .delete(); +PixAutomaticAuthorization cancelada = PixAutomaticAuthorization.deleter(authId).delete(); + +if (cancelada.getStatus().equals("CANCELLED")) { + System.out.println("Autorização cancelada com sucesso"); +} ``` ## Instruções de Pagamento -### Criar instrução de pagamento +### Criar Instrução ```java -Calendar calendar = Calendar.getInstance(); -calendar.add(Calendar.DAY_OF_MONTH, 3); // any date +import io.github.jpdev.asaassdk.rest.payment.Payment; +import io.github.jpdev.asaassdk.enums.BillingType; + +Calendar cal = Calendar.getInstance(); +cal.add(Calendar.DAY_OF_MONTH, 3); -String activeAuthorizationId = "uuidv4"; +String authorizationId = "uuid-autorizacao-ativa"; Payment payment = Payment.creator() - .setCustomer("cus_000007258649") // your customer_id + .setCustomer("cus_000007258649") .setBillingType(BillingType.PIX) - .setDueDate(calendar.getTime()) - .setValue(Money.create(100)) - .setDescription("Test") - .setPixAutomaticAuthorizationId(activeAuthorizationId) + .setDueDate(cal.getTime()) + .setValue(Money.create(new BigDecimal("99.90"))) + .setDescription("Mensalidade") + .setPixAutomaticAuthorizationId(authorizationId) .create(); + +System.out.println("Instrução de pagamento criada: " + payment.getId()); +System.out.println("Será debitado automaticamente em: " + payment.getDueDate()); ``` -### Listar instruções de pagamento +### Listar Instruções ```java -ResourceSet paymentInstructionResourceSet = PixAutomaticPaymentInstruction - .reader() - .read(); +import io.github.jpdev.asaassdk.rest.pixautomatic.paymentinstruction.PixAutomaticPaymentInstruction; +import io.github.jpdev.asaassdk.rest.pixautomatic.paymentinstruction.ResourceSet; + +ResourceSet instrucoes = PixAutomaticPaymentInstruction.reader().read(); + +for (PixAutomaticPaymentInstruction inst : instrucoes.getData()) { + System.out.println("ID: " + inst.getId()); + System.out.println("Valor: R$ " + inst.getValue()); + System.out.println("Data: " + inst.getDueDate()); + System.out.println("Status: " + inst.getStatus()); + System.out.println("---"); +} +``` + +### Recuperar Instrução + +```java +String instructionId = "uuid-instrucao"; + +PixAutomaticPaymentInstruction inst = PixAutomaticPaymentInstruction.fetcher(instructionId).fetch(); + +System.out.println("Instrução: " + inst.getId()); +System.out.println("Valor: R$ " + inst.getValue()); +System.out.println("Data de débito: " + inst.getDueDate()); +System.out.println("Status: " + inst.getStatus()); +``` + +## Casos de Uso + +### Assinatura Mensal + +```java +public class AssinaturaPixAutomatico { + + public static PixAutomaticAuthorization criarAssinatura( + String clienteId, + double valorMensal, + String contratoId + ) { + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.DAY_OF_MONTH, 1); + + ImmediateQrCodeCreator qrCode = new ImmediateQrCodeCreator() + .setDescription("Autorização de assinatura") + .setExpirationSeconds(3600) + .setOriginalValue(Money.create(new BigDecimal("0.01"))); + + PixAutomaticAuthorization auth = PixAutomaticAuthorization.creator() + .setCustomerId(clienteId) + .setStartDate(cal.getTime()) + .setFrequency(PixAutomaticAuthorizationFrequency.MONTHLY) + .setValue(Money.create(new BigDecimal(valorMensal))) + .setContractId(contratoId) + .setImmediateQrCode(qrCode) + .create(); -for (PixAutomaticPaymentInstruction instruction : paymentInstructionResourceSet.getData()) { - System.out.println(instruction.getId()); - System.out.println(instruction.getDueDate()); + System.out.println("Assinatura criada:"); + System.out.println("Valor mensal: R$ " + valorMensal); + System.out.println("QR Code para autorização: " + auth.getQrCode()); + + return auth; + } + + public static void main(String[] args) { + Asaas.init("sua_api_key"); + criarAssinatura("cus_cliente", 49.90, "PLANO_PREMIUM_2024"); + } } ``` -### Recuperar instrução de pagamento específica +### Academia/Escola ```java -String id = "uuidv4"; +public class MensalidadeAutomatica { + + public static void configurarMensalidade( + String alunoId, + double valorMensalidade + ) { + // Criar autorização + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.DAY_OF_MONTH, 1); + + ImmediateQrCodeCreator qrCode = new ImmediateQrCodeCreator() + .setDescription("Autorização mensalidade") + .setExpirationSeconds(3600) + .setOriginalValue(Money.create(new BigDecimal("0.01"))); -PixAutomaticPaymentInstruction paymentInstruction = PixAutomaticPaymentInstruction - .fetcher(id) - .fetch(); + PixAutomaticAuthorization auth = PixAutomaticAuthorization.creator() + .setCustomerId(alunoId) + .setStartDate(cal.getTime()) + .setFrequency(PixAutomaticAuthorizationFrequency.MONTHLY) + .setValue(Money.create(new BigDecimal(valorMensalidade))) + .setContractId("MENSALIDADE_" + alunoId) + .setImmediateQrCode(qrCode) + .create(); + + System.out.println("Mensalidade configurada:"); + System.out.println("Aluno: " + alunoId); + System.out.println("Valor: R$ " + valorMensalidade); + System.out.println("Cliente deve escanear: " + auth.getQrCode()); + } +} ``` + +### Serviço de Streaming + +```java +public class StreamingPixAutomatico { + + public static void criarPlano( + String usuarioId, + String nomePlano, + double valorMensal + ) { + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.DAY_OF_MONTH, 1); + + ImmediateQrCodeCreator qrCode = new ImmediateQrCodeCreator() + .setDescription("Plano " + nomePlano) + .setExpirationSeconds(3600) + .setOriginalValue(Money.create(new BigDecimal("0.01"))); + + PixAutomaticAuthorization auth = PixAutomaticAuthorization.creator() + .setCustomerId(usuarioId) + .setStartDate(cal.getTime()) + .setFrequency(PixAutomaticAuthorizationFrequency.MONTHLY) + .setValue(Money.create(new BigDecimal(valorMensal))) + .setContractId("STREAMING_" + nomePlano + "_" + usuarioId) + .setImmediateQrCode(qrCode) + .create(); + + System.out.println("Plano " + nomePlano + " configurado"); + System.out.println("Débito mensal: R$ " + valorMensal); + } +} +``` + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.pixautomatic.authorization.*; +import io.github.jpdev.asaassdk.rest.payment.Payment; +import io.github.jpdev.asaassdk.enums.*; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Calendar; + +public class ExemploPixAutomatico { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + String clienteId = "cus_000007258649"; + + // 1. Criar autorização + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.DAY_OF_MONTH, 1); + + ImmediateQrCodeCreator qrCode = new ImmediateQrCodeCreator() + .setDescription("Autorização PIX Automático") + .setExpirationSeconds(3600) + .setOriginalValue(Money.create(new BigDecimal("0.01"))); + + PixAutomaticAuthorization auth = PixAutomaticAuthorization.creator() + .setCustomerId(clienteId) + .setStartDate(cal.getTime()) + .setFrequency(PixAutomaticAuthorizationFrequency.MONTHLY) + .setValue(Money.create(new BigDecimal("99.90"))) + .setContractId("CONTRATO_2024_001") + .setImmediateQrCode(qrCode) + .create(); + + System.out.println("=== AUTORIZAÇÃO CRIADA ==="); + System.out.println("ID: " + auth.getId()); + System.out.println("Status: " + auth.getStatus()); + System.out.println("QR Code: " + auth.getQrCode()); + System.out.println("\nCliente deve escanear o QR Code para autorizar"); + + // Aguardar autorização do cliente... + // Quando status = ACTIVE, criar instruções de pagamento + + // 2. Criar instrução de pagamento + cal.add(Calendar.DAY_OF_MONTH, 2); + + Payment payment = Payment.creator() + .setCustomer(clienteId) + .setBillingType(BillingType.PIX) + .setDueDate(cal.getTime()) + .setValue(Money.create(new BigDecimal("99.90"))) + .setDescription("Mensalidade") + .setPixAutomaticAuthorizationId(auth.getId()) + .create(); + + System.out.println("\n=== INSTRUÇÃO DE PAGAMENTO ==="); + System.out.println("ID: " + payment.getId()); + System.out.println("Valor: R$ " + payment.getValue()); + System.out.println("Data de débito: " + payment.getDueDate()); + + // 3. Listar autorizações + ResourceSet autorizacoes = PixAutomaticAuthorization.reader() + .setCustomerId(clienteId) + .read(); + + System.out.println("\nTotal de autorizações: " + autorizacoes.getTotalCount()); + } +} +``` + +## Fluxo de Autorização + +``` +1. Criar autorização → Gera QR Code +2. Cliente escaneia QR Code → Autoriza no app do banco +3. Status muda para ACTIVE +4. Criar instruções de pagamento +5. Débitos automáticos conforme frequência +``` + +## Boas Práticas + +### 1. Valide Status Antes de Criar Instrução + +```java +PixAutomaticAuthorization auth = PixAutomaticAuthorization.fetcher(authId).fetch(); + +if (auth.getStatus().equals("ACTIVE")) { + // Criar instrução de pagamento + Payment payment = Payment.creator() + .setPixAutomaticAuthorizationId(authId) + .create(); +} else { + System.err.println("Autorização não está ativa"); +} +``` + +### 2. Configure Tempo de Expiração Adequado + +```java +ImmediateQrCodeCreator qrCode = new ImmediateQrCodeCreator() + .setDescription("Autorização") + .setExpirationSeconds(7200) // 2 horas + .setOriginalValue(Money.create(new BigDecimal("0.01"))); +``` + +### 3. Use IDs de Contrato Únicos + +```java +String contratoId = "CONTRATO_" + clienteId + "_" + System.currentTimeMillis(); + +PixAutomaticAuthorization auth = PixAutomaticAuthorization.creator() + .setContractId(contratoId) + .create(); +``` + +### 4. Monitore Autorizações Expiradas + +```java +ResourceSet expiradas = PixAutomaticAuthorization.reader() + .setStatus(PixAutomaticAuthorizationStatus.EXPIRED) + .read(); + +if (expiradas.getTotalCount() > 0) { + System.out.println("⚠️ " + expiradas.getTotalCount() + " autorizações expiradas"); +} +``` + +## Limitações + +- Cliente precisa autorizar via QR Code no app do banco +- Valor máximo por transação: conforme limite do banco +- Frequência mínima: diária +- Autorização pode ser cancelada pelo cliente a qualquer momento + +## Veja Também + +- [PIX - Transações](pix_transaction.md) - Transações PIX manuais +- [Assinaturas](subscription.md) - Assinaturas via cartão +- [Cobranças](payment.md) - Criar cobranças + +## Referências + +- [Documentação Oficial - PIX Automático](https://docs.asaas.com/reference/pix-automatico) +- [Banco Central - PIX Automático](https://www.bcb.gov.br/estabilidadefinanceira/pix) diff --git a/docs/pix_dict.md b/docs/pix_dict.md index 2e0d741..d357bee 100644 --- a/docs/pix_dict.md +++ b/docs/pix_dict.md @@ -1,32 +1,397 @@ -## Criar um QR Code Pix estático +# PIX - QR Code e Chaves + +Gerencie chaves PIX, crie QR Codes estáticos e dinâmicos, e decodifique QR Codes de terceiros. + +## 📋 Índice + +- [QR Code PIX](#qr-code-pix) +- [Chaves PIX](#chaves-pix) +- [Decodificar QR Code](#decodificar-qr-code) + +## QR Code PIX + +### Criar QR Code Estático + +QR Code estático permite receber pagamentos com valor fixo: + +```java +import io.github.jpdev.asaassdk.rest.pix.PixQrCode; +import java.math.BigDecimal; + +PixQrCode qrCode = PixQrCode.creator() + .setAddressKey("sua_chave_pix@email.com") + .setDescription("Pagamento de produto") + .setValue(new BigDecimal("50.00")) + .create(); + +System.out.println("Payload: " + qrCode.getPayload()); +System.out.println("Imagem Base64: " + qrCode.getEncodedImage()); +``` + +### QR Code com Diferentes Chaves + +#### Email + +```java +PixQrCode qrCode = PixQrCode.creator() + .setAddressKey("pagamento@empresa.com") + .setDescription("Pagamento") + .setValue(new BigDecimal("100.00")) + .create(); +``` + +#### CPF/CNPJ + +```java +PixQrCode qrCode = PixQrCode.creator() + .setAddressKey("12345678900") + .setDescription("Pagamento") + .setValue(new BigDecimal("75.50")) + .create(); +``` + +#### Telefone + +```java +PixQrCode qrCode = PixQrCode.creator() + .setAddressKey("+5547999999999") + .setDescription("Pagamento") + .setValue(new BigDecimal("25.00")) + .create(); +``` + +#### Chave Aleatória (EVP) + +```java +PixQrCode qrCode = PixQrCode.creator() + .setAddressKey("123e4567-e89b-12d3-a456-426614174000") + .setDescription("Pagamento") + .setValue(new BigDecimal("150.00")) + .create(); +``` + +### QR Code Dinâmico (via Cobrança) + +Para criar um QR Code dinâmico, crie uma cobrança PIX: + +```java +import io.github.jpdev.asaassdk.rest.payment.Payment; +import io.github.jpdev.asaassdk.enums.BillingType; +import io.github.jpdev.asaassdk.util.Money; +import java.util.Date; + +Payment payment = Payment.creator() + .setCustomer("cus_000050606806") + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("100.00"))) + .setDescription("Pagamento de serviço") + .create(); + +// QR Code disponível na cobrança +String qrCodePayload = payment.getPixQrCode(); +String qrCodeImage = payment.getPixQrCodeImage(); + +System.out.println("QR Code Payload: " + qrCodePayload); +``` + +### Exibir QR Code + +O campo `encodedImage` retorna a imagem em Base64: + +```java +PixQrCode qrCode = PixQrCode.creator() + .setAddressKey("sua_chave@email.com") + .setValue(new BigDecimal("50.00")) + .create(); + +// Imagem em Base64 (pode ser usada diretamente em HTML) +String imagemBase64 = qrCode.getEncodedImage(); + +// Exemplo de uso em HTML: +// +``` + +## Chaves PIX + +### Criar Chave Aleatória (EVP) + +Crie uma chave PIX aleatória vinculada à sua conta: + +```java +import io.github.jpdev.asaassdk.rest.pix.PixAddressKey; +import io.github.jpdev.asaassdk.enums.PixAddressKeyType; + +PixAddressKey chave = PixAddressKey.creator() + .setType(PixAddressKeyType.EVP) + .create(); + +System.out.println("Chave criada: " + chave.getKey()); +System.out.println("ID: " + chave.getId()); +System.out.println("Status: " + chave.getStatus()); +``` + +### Listar Chaves PIX + +#### Listar Todas + +```java +import io.github.jpdev.asaassdk.rest.pix.ResourceSet; + +ResourceSet chaves = PixAddressKey.reader().read(); + +for (PixAddressKey chave : chaves.getData()) { + System.out.println("Chave: " + chave.getKey()); + System.out.println("Tipo: " + chave.getType()); + System.out.println("Status: " + chave.getStatus()); + System.out.println("---"); +} +``` + +#### Filtrar por Status + ```java -PixQrCode qrCode = PixQrCode - .creator() - .setAddressKey("SUA_CHAVE_PIX") - .setDescription("teste") - .setValue(new BigDecimal("0.01")).create(); +import io.github.jpdev.asaassdk.enums.PixAddressKeyStatus; + +// Apenas chaves ativas +ResourceSet chavesAtivas = PixAddressKey.reader() + .setStatus(PixAddressKeyStatus.ACTIVE) + .read(); + +// Apenas chaves aguardando ativação +ResourceSet chavesAguardando = PixAddressKey.reader() + .setStatus(PixAddressKeyStatus.AWAITING_ACTIVATION) + .read(); ``` -## Decodificar um QR Code Pix +#### Filtrar por Tipo + ```java -PixDecodedQrCode decodedQrCode = PixDecodedQrCode.decoder() - .setPayload("payload") - .create(); +// Apenas chaves EVP (aleatórias) +ResourceSet chavesEVP = PixAddressKey.reader() + .setType(PixAddressKeyType.EVP) + .read(); + +// Apenas chaves de email +ResourceSet chavesEmail = PixAddressKey.reader() + .setType(PixAddressKeyType.EMAIL) + .read(); ``` -## Criar uma chave Pix aleatória +### Recuperar Chave Específica + ```java -PixAddressKey.creator().setType(PixAddressKeyType.EVP).create(); +PixAddressKey chave = PixAddressKey.fetcher("chave_id").fetch(); + +System.out.println("Chave: " + chave.getKey()); +System.out.println("Tipo: " + chave.getType()); +System.out.println("Status: " + chave.getStatus()); +System.out.println("Data de criação: " + chave.getDateCreated()); ``` -## Recuperar chaves Pix ativas +### Deletar Chave PIX + ```java -ResourceSet pixAddressKeyList = PixAddressKey.reader() - .setStatus(PixAddressKeyStatus.ACTIVE) - .read(); +import io.github.jpdev.asaassdk.rest.pix.PixAddressKeyDeleted; + +PixAddressKeyDeleted deleted = PixAddressKey.deleter("chave_id").delete(); + +if (deleted.isDeleted()) { + System.out.println("Chave deletada com sucesso"); +} ``` -## Cancelar uma transação Pix +**Nota**: A exclusão de chaves PIX pode levar até 7 dias para ser processada pelo Banco Central. + +## Decodificar QR Code + +Decodifique um QR Code PIX para visualizar as informações antes de pagar: + ```java -PixTransaction cancelledPixTransaction = PixTransaction.canceller("35363f6e-93e2-11ec-b9d9-96f4053b1bd4").create(); -``` \ No newline at end of file +import io.github.jpdev.asaassdk.rest.pix.PixDecodedQrCode; + +String payload = "00020101021226770014br.gov.bcb.pix..."; + +PixDecodedQrCode decoded = PixDecodedQrCode.decoder() + .setPayload(payload) + .create(); + +System.out.println("Valor: " + decoded.getValue()); +System.out.println("Beneficiário: " + decoded.getName()); +System.out.println("Cidade: " + decoded.getCity()); +System.out.println("Chave: " + decoded.getAddressKey()); +System.out.println("Descrição: " + decoded.getDescription()); +``` + +### Validar QR Code Antes de Pagar + +```java +try { + PixDecodedQrCode decoded = PixDecodedQrCode.decoder() + .setPayload(qrCodePayload) + .create(); + + // Validar informações + if (decoded.getValue().compareTo(new BigDecimal("1000.00")) > 0) { + System.out.println("ATENÇÃO: Valor alto - R$ " + decoded.getValue()); + } + + System.out.println("Você está pagando para: " + decoded.getName()); + System.out.println("Valor: R$ " + decoded.getValue()); + + // Confirmar antes de pagar + // ... lógica de confirmação + +} catch (AsaasException e) { + System.err.println("QR Code inválido: " + e.getMessage()); +} +``` + +## Tipos de Chave PIX + +| Tipo | Descrição | Exemplo | +|------|-----------|---------| +| `EVP` | Chave aleatória | `123e4567-e89b-12d3-a456-426614174000` | +| `CPF` | CPF | `12345678900` | +| `CNPJ` | CNPJ | `12345678000190` | +| `EMAIL` | Email | `pagamento@empresa.com` | +| `PHONE` | Telefone | `+5547999999999` | + +## Status de Chaves PIX + +| Status | Descrição | +|--------|-----------| +| `ACTIVE` | Chave ativa e funcional | +| `AWAITING_ACTIVATION` | Aguardando ativação | +| `AWAITING_ACCOUNT_ACTIVATION` | Aguardando ativação da conta | +| `ERROR` | Erro no processamento | +| `DELETED` | Chave deletada | + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.pix.*; +import io.github.jpdev.asaassdk.enums.*; +import java.math.BigDecimal; + +public class ExemploPix { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // 1. Criar chave PIX aleatória + PixAddressKey minhaChave = PixAddressKey.creator() + .setType(PixAddressKeyType.EVP) + .create(); + + System.out.println("Chave PIX criada: " + minhaChave.getKey()); + + // 2. Criar QR Code estático + PixQrCode qrCode = PixQrCode.creator() + .setAddressKey(minhaChave.getKey()) + .setDescription("Pagamento de produto") + .setValue(new BigDecimal("50.00")) + .create(); + + System.out.println("QR Code gerado!"); + System.out.println("Payload: " + qrCode.getPayload()); + + // 3. Listar todas as chaves ativas + ResourceSet chaves = PixAddressKey.reader() + .setStatus(PixAddressKeyStatus.ACTIVE) + .read(); + + System.out.println("\nChaves PIX ativas:"); + for (PixAddressKey chave : chaves.getData()) { + System.out.println("- " + chave.getKey() + " (" + chave.getType() + ")"); + } + + // 4. Decodificar um QR Code + String qrCodeExterno = "00020101021226770014br.gov.bcb.pix..."; + + try { + PixDecodedQrCode decoded = PixDecodedQrCode.decoder() + .setPayload(qrCodeExterno) + .create(); + + System.out.println("\nQR Code decodificado:"); + System.out.println("Beneficiário: " + decoded.getName()); + System.out.println("Valor: R$ " + decoded.getValue()); + } catch (Exception e) { + System.err.println("Erro ao decodificar: " + e.getMessage()); + } + } +} +``` + +## Boas Práticas + +### 1. Use Chaves EVP para Maior Segurança + +```java +// Chaves aleatórias são mais seguras +PixAddressKey chave = PixAddressKey.creator() + .setType(PixAddressKeyType.EVP) + .create(); +``` + +### 2. Valide QR Codes Antes de Processar + +```java +try { + PixDecodedQrCode decoded = PixDecodedQrCode.decoder() + .setPayload(payload) + .create(); + + // Validar antes de prosseguir + if (decoded.getValue() != null && decoded.getName() != null) { + // QR Code válido + } +} catch (AsaasException e) { + // QR Code inválido +} +``` + +### 3. Armazene o ID da Chave + +```java +PixAddressKey chave = PixAddressKey.creator() + .setType(PixAddressKeyType.EVP) + .create(); + +// Salvar no banco de dados +String chaveId = chave.getId(); +String chaveValor = chave.getKey(); +``` + +### 4. Monitore o Status das Chaves + +```java +PixAddressKey chave = PixAddressKey.fetcher(chaveId).fetch(); + +if (chave.getStatus() == PixAddressKeyStatus.ACTIVE) { + // Chave pronta para uso +} else if (chave.getStatus() == PixAddressKeyStatus.AWAITING_ACTIVATION) { + // Aguardar ativação +} +``` + +## Limitações + +- Cada conta pode ter até 20 chaves PIX +- Chaves EVP são geradas automaticamente pelo sistema +- A exclusão de chaves pode levar até 7 dias +- QR Codes estáticos não expiram +- QR Codes dinâmicos (via cobrança) expiram conforme a data de vencimento + +## Veja Também + +- [PIX - Transações](pix_transaction.md) - Enviar e receber pagamentos PIX +- [PIX Automático](pix_automatic.md) - Débito recorrente via PIX +- [Cobranças](payment.md) - Criar cobranças com PIX + +## Referências + +- [Documentação Oficial - PIX](https://docs.asaas.com/reference/pix) +- [Banco Central - PIX](https://www.bcb.gov.br/estabilidadefinanceira/pix) diff --git a/docs/pix_transaction.md b/docs/pix_transaction.md index 9d1eb8b..2a96ba1 100644 --- a/docs/pix_transaction.md +++ b/docs/pix_transaction.md @@ -1,88 +1,535 @@ -## Recuperar informações de uma transação Pix +# PIX - Transações + +Envie e receba pagamentos PIX de forma rápida e segura. Realize transferências via chave PIX, dados bancários ou QR Code. + +## 📋 Índice + +- [Criar Transação PIX](#criar-transação-pix) +- [Pagar QR Code](#pagar-qr-code) +- [Listar Transações](#listar-transações) +- [Recuperar Transação](#recuperar-transação) +- [Cancelar Transação](#cancelar-transação) +- [PIX Recorrente](#pix-recorrente) + +## Criar Transação PIX + +### Via Chave PIX - CPF + ```java -PixTransaction pixTransaction = PixTransaction.fetcher("PIX_TRANSACTION_ID").fetch(); +import io.github.jpdev.asaassdk.rest.transfer.Transfer; +import io.github.jpdev.asaassdk.enums.PixAddressKeyType; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; + +Transfer transfer = Transfer.pixAddressKeyCreator() + .setPixAddressKey("12345678900") + .setPixAddressKeyType(PixAddressKeyType.CPF) + .setValue(Money.create(new BigDecimal("100.00"))) + .setDescription("Pagamento fornecedor") + .create(); + +System.out.println("Transferência realizada: " + transfer.getId()); +System.out.println("Status: " + transfer.getStatus()); ``` -Exemplo utilizando Identificador fim a fim: + +### Via Chave PIX - Email + ```java -PixTransaction pixTransaction = PixTransaction.fetcher("E18236120202302141342s15536c561e").fetch(); +Transfer transfer = Transfer.pixAddressKeyCreator() + .setPixAddressKey("destinatario@email.com") + .setPixAddressKeyType(PixAddressKeyType.EMAIL) + .setValue(Money.create(new BigDecimal("50.00"))) + .setDescription("Pagamento de serviço") + .create(); ``` -Exemplo utilizando Identificador ID: + +### Via Chave PIX - Telefone + ```java -PixTransaction pixTransaction = PixTransaction.fetcher("bc515f74-d5c7-4bc2-93e5-3bafc0a9b15d").fetch(); +Transfer transfer = Transfer.pixAddressKeyCreator() + .setPixAddressKey("+5547999999999") + .setPixAddressKeyType(PixAddressKeyType.PHONE) + .setValue(Money.create(new BigDecimal("75.50"))) + .setDescription("Transferência") + .create(); ``` -## Criar uma transação Pix -### Via chave +### Via Chave PIX - CNPJ + ```java Transfer transfer = Transfer.pixAddressKeyCreator() - .setPixAddressKey("CHAVE") - .setValue(Money.create(new BigDecimal(0.01))) - .setDescription("teste") - .setPixAddressKeyType(PixAddressKeyType.CPF) - .create(); + .setPixAddressKey("12345678000190") + .setPixAddressKeyType(PixAddressKeyType.CNPJ) + .setValue(Money.create(new BigDecimal("1000.00"))) + .setDescription("Pagamento de nota fiscal") + .create(); ``` -### Via dados bancários -```java -BankAccountSetting bankAccountSetting = new BankAccountSetting() - .setBank(new BankSetting().setCode("085")) - .setAccountName("Paulo") - .setOwnerName("Paulo") - .setOwnerBirthDate(new Date()) - .setCpfCnpj("06928316000124") - .setAgency("0108") - .setAccount("10895") - .setAccountDigit("5") - .setBankAccountType(BankAccountType.CONTA_CORRENTE); + +### Via Chave PIX - Aleatória (EVP) + +```java +Transfer transfer = Transfer.pixAddressKeyCreator() + .setPixAddressKey("123e4567-e89b-12d3-a456-426614174000") + .setPixAddressKeyType(PixAddressKeyType.EVP) + .setValue(Money.create(new BigDecimal("250.00"))) + .setDescription("Pagamento") + .create(); +``` + +### Via Dados Bancários + +Quando o destinatário não possui chave PIX: + +```java +import io.github.jpdev.asaassdk.rest.transfer.BankAccountSetting; +import io.github.jpdev.asaassdk.rest.transfer.BankSetting; +import io.github.jpdev.asaassdk.enums.BankAccountType; +import java.util.Date; + +BankAccountSetting bankAccount = new BankAccountSetting() + .setBank(new BankSetting().setCode("085")) // Código do banco + .setAccountName("João Silva") + .setOwnerName("João Silva") + .setOwnerBirthDate(new Date(1990, 0, 1)) + .setCpfCnpj("12345678900") + .setAgency("0001") + .setAccount("12345") + .setAccountDigit("6") + .setBankAccountType(BankAccountType.CONTA_CORRENTE); + Transfer transfer = Transfer.pixManualCreator() - .setBankAccount(bankAccountSetting) - .setValue(Money.create(new BigDecimal(1.01))) - .create(); + .setBankAccount(bankAccount) + .setValue(Money.create(new BigDecimal("150.00"))) + .setDescription("Pagamento via dados bancários") + .create(); + +System.out.println("PIX enviado: " + transfer.getId()); ``` -### Pix Recorrente +### Com Agendamento + +Agende uma transferência PIX para data futura: + ```java - PixRecurring recurring = new PixRecurring() - .setFrequency(PixRecurringFrequency.MONTHLY) - .setQuantity(2); +import java.util.Calendar; + +Calendar cal = Calendar.getInstance(); +cal.add(Calendar.DAY_OF_MONTH, 3); // Daqui a 3 dias +Date dataAgendamento = cal.getTime(); Transfer transfer = Transfer.pixAddressKeyCreator() - .setPixAddressKey("+5547999999999") - .setValue(Money.create(0.01)) - .setDescription("teste") - .setPixAddressKeyType(PixAddressKeyType.PHONE) - .setRecurring(recurring) - .create(); + .setPixAddressKey("12345678900") + .setPixAddressKeyType(PixAddressKeyType.CPF) + .setValue(Money.create(new BigDecimal("200.00"))) + .setDescription("Pagamento agendado") + .setScheduleDate(dataAgendamento) + .create(); + +System.out.println("PIX agendado para: " + transfer.getScheduleDate()); ``` -## Pagar um QR Code Pix +## Pagar QR Code + +### QR Code Estático + ```java -final String examplePayload = "00020101021226730014br.gov.bcb.pix2551pix-h.asaas.com/pixqrcode/cobv/pay_76575613967995145204000053039865802BR5905ASAAS6009Joinville61088922827162070503***63045E7A"; -PixTransaction pixTransactionQrCodeCreator = PixTransaction - .qrCodeCreator() - .setPayload(examplePayload) - .setValue(Money.create(new BigDecimal(10.0))) - .create(); +import io.github.jpdev.asaassdk.rest.pix.PixTransaction; + +String payload = "00020101021226730014br.gov.bcb.pix2551pix-h.asaas.com..."; + +PixTransaction transaction = PixTransaction.qrCodeCreator() + .setPayload(payload) + .setValue(Money.create(new BigDecimal("50.00"))) + .setDescription("Pagamento via QR Code") + .create(); + +System.out.println("Pagamento realizado: " + transaction.getId()); +System.out.println("Status: " + transaction.getStatus()); +``` + +### QR Code Dinâmico + +QR Codes dinâmicos já possuem o valor embutido: + +```java +String payloadDinamico = "00020101021226770014br.gov.bcb.pix..."; + +PixTransaction transaction = PixTransaction.qrCodeCreator() + .setPayload(payloadDinamico) + .create(); + +System.out.println("Pagamento de R$ " + transaction.getValue() + " realizado"); +``` + +### Validar QR Code Antes de Pagar + +```java +import io.github.jpdev.asaassdk.rest.pix.PixDecodedQrCode; + +// Primeiro, decodificar o QR Code +PixDecodedQrCode decoded = PixDecodedQrCode.decoder() + .setPayload(payload) + .create(); + +System.out.println("Beneficiário: " + decoded.getName()); +System.out.println("Valor: R$ " + decoded.getValue()); +System.out.println("Descrição: " + decoded.getDescription()); + +// Confirmar e pagar +PixTransaction transaction = PixTransaction.qrCodeCreator() + .setPayload(payload) + .create(); +``` + +## Listar Transações + +### Listar Todas + +```java +import io.github.jpdev.asaassdk.rest.pix.ResourceSet; + +ResourceSet transactions = PixTransaction.reader().read(); + +for (PixTransaction tx : transactions.getData()) { + System.out.println("ID: " + tx.getId()); + System.out.println("Tipo: " + tx.getType()); + System.out.println("Valor: R$ " + tx.getValue()); + System.out.println("Status: " + tx.getStatus()); + System.out.println("Data: " + tx.getDateCreated()); + System.out.println("---"); +} +``` + +### Filtrar por Tipo + +```java +import io.github.jpdev.asaassdk.enums.PixTransactionType; + +// Apenas débitos (enviados) +ResourceSet debitos = PixTransaction.reader() + .setType(PixTransactionType.DEBIT) + .read(); + +// Apenas créditos (recebidos) +ResourceSet creditos = PixTransaction.reader() + .setType(PixTransactionType.CREDIT) + .read(); +``` + +### Filtrar por Status + +```java +import io.github.jpdev.asaassdk.enums.PixTransactionStatus; + +// Apenas concluídas +ResourceSet concluidas = PixTransaction.reader() + .setStatus(PixTransactionStatus.DONE) + .read(); + +// Apenas pendentes +ResourceSet pendentes = PixTransaction.reader() + .setStatus(PixTransactionStatus.PENDING) + .read(); +``` + +### Filtrar por Data + +```java +import java.util.Calendar; + +Calendar cal = Calendar.getInstance(); +cal.set(2024, Calendar.JANUARY, 1); +Date dataInicio = cal.getTime(); + +cal.set(2024, Calendar.JANUARY, 31); +Date dataFim = cal.getTime(); + +ResourceSet transactions = PixTransaction.reader() + .setStartDate(dataInicio) + .setEndDate(dataFim) + .read(); ``` -## Listar transações Pix +### Filtrar por Chave PIX + ```java -ResourceSet pixTransactionResourceSet = PixTransaction.reader().read(); +ResourceSet transactions = PixTransaction.reader() + .setPixAddressKey("12345678900") + .read(); ``` -Também é possível utilizar filtros +### Paginação ```java -ResourceSet pixTransactionResourceSet = PixTransaction.reader() - .setType(PixTransactionType.DEBIT) - .read(); +ResourceSet transactions = PixTransaction.reader() + .setLimit(50) + .setOffset(0) + .read(); + +System.out.println("Total: " + transactions.getTotalCount()); +System.out.println("Tem mais: " + transactions.hasMore()); ``` -## Cancelar uma transação Pix +## Recuperar Transação -Para cancelar uma transação Pix, você deve informar o id da transação Pix que deseja cancelar. +### Por ID ```java -PixTransaction cancelledPixTransaction = PixTransaction - .canceller("35363f6e-93e2-11ec-b9d9-96f4053b1bd4") - .create(); +PixTransaction transaction = PixTransaction.fetcher("bc515f74-d5c7-4bc2-93e5-3bafc0a9b15d").fetch(); + +System.out.println("Valor: R$ " + transaction.getValue()); +System.out.println("Status: " + transaction.getStatus()); +System.out.println("Tipo: " + transaction.getType()); +System.out.println("Chave PIX: " + transaction.getPixAddressKey()); ``` + +### Por Identificador Fim a Fim (End to End ID) + +```java +PixTransaction transaction = PixTransaction.fetcher("E18236120202302141342s15536c561e").fetch(); + +System.out.println("Transação encontrada: " + transaction.getId()); +``` + +## Cancelar Transação + +Cancele uma transação PIX agendada ou pendente: + +```java +PixTransaction cancelled = PixTransaction.canceller("35363f6e-93e2-11ec-b9d9-96f4053b1bd4").create(); + +if (cancelled.getStatus() == PixTransactionStatus.CANCELLED) { + System.out.println("Transação cancelada com sucesso"); +} +``` + +**Nota**: Apenas transações com status `PENDING` ou `SCHEDULED` podem ser canceladas. + +## PIX Recorrente + +Configure transferências PIX automáticas: + +### Mensal + +```java +import io.github.jpdev.asaassdk.rest.transfer.PixRecurring; +import io.github.jpdev.asaassdk.enums.PixRecurringFrequency; + +PixRecurring recurring = new PixRecurring() + .setFrequency(PixRecurringFrequency.MONTHLY) + .setQuantity(12); // 12 meses + +Transfer transfer = Transfer.pixAddressKeyCreator() + .setPixAddressKey("12345678900") + .setPixAddressKeyType(PixAddressKeyType.CPF) + .setValue(Money.create(new BigDecimal("500.00"))) + .setDescription("Aluguel mensal") + .setRecurring(recurring) + .create(); + +System.out.println("PIX recorrente configurado por 12 meses"); +``` + +### Semanal + +```java +PixRecurring recurring = new PixRecurring() + .setFrequency(PixRecurringFrequency.WEEKLY) + .setQuantity(4); // 4 semanas + +Transfer transfer = Transfer.pixAddressKeyCreator() + .setPixAddressKey("fornecedor@email.com") + .setPixAddressKeyType(PixAddressKeyType.EMAIL) + .setValue(Money.create(new BigDecimal("100.00"))) + .setDescription("Pagamento semanal") + .setRecurring(recurring) + .create(); +``` + +### Diário + +```java +PixRecurring recurring = new PixRecurring() + .setFrequency(PixRecurringFrequency.DAILY) + .setQuantity(30); // 30 dias + +Transfer transfer = Transfer.pixAddressKeyCreator() + .setPixAddressKey("+5547999999999") + .setPixAddressKeyType(PixAddressKeyType.PHONE) + .setValue(Money.create(new BigDecimal("50.00"))) + .setDescription("Pagamento diário") + .setRecurring(recurring) + .create(); +``` + +## Status de Transações + +| Status | Descrição | +|--------|-----------| +| `PENDING` | Aguardando processamento | +| `SCHEDULED` | Agendada | +| `DONE` | Concluída | +| `CANCELLED` | Cancelada | +| `FAILED` | Falhou | +| `AWAITING_RISK_ANALYSIS` | Aguardando análise de risco | + +## Tipos de Transação + +| Tipo | Descrição | +|------|-----------| +| `DEBIT` | Débito (enviado) | +| `CREDIT` | Crédito (recebido) | + +## Códigos de Banco + +Principais bancos para transferência via dados bancários: + +| Código | Banco | +|--------|-------| +| `001` | Banco do Brasil | +| `033` | Santander | +| `104` | Caixa Econômica | +| `237` | Bradesco | +| `341` | Itaú | +| `077` | Banco Inter | +| `260` | Nubank | +| `290` | PagSeguro | +| `323` | Mercado Pago | +| `085` | Ailos | + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.transfer.Transfer; +import io.github.jpdev.asaassdk.rest.pix.*; +import io.github.jpdev.asaassdk.enums.*; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; + +public class ExemploPixTransacao { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // 1. Enviar PIX via chave + Transfer transfer = Transfer.pixAddressKeyCreator() + .setPixAddressKey("12345678900") + .setPixAddressKeyType(PixAddressKeyType.CPF) + .setValue(Money.create(new BigDecimal("100.00"))) + .setDescription("Pagamento fornecedor") + .create(); + + System.out.println("PIX enviado: " + transfer.getId()); + + // 2. Pagar QR Code + String qrCodePayload = "00020101021226730014br.gov.bcb.pix..."; + + // Decodificar primeiro + PixDecodedQrCode decoded = PixDecodedQrCode.decoder() + .setPayload(qrCodePayload) + .create(); + + System.out.println("Pagando para: " + decoded.getName()); + System.out.println("Valor: R$ " + decoded.getValue()); + + // Confirmar pagamento + PixTransaction payment = PixTransaction.qrCodeCreator() + .setPayload(qrCodePayload) + .create(); + + System.out.println("Pagamento realizado: " + payment.getId()); + + // 3. Listar transações do dia + ResourceSet transactions = PixTransaction.reader() + .setStartDate(new Date()) + .read(); + + System.out.println("\nTransações de hoje:"); + for (PixTransaction tx : transactions.getData()) { + String tipo = tx.getType() == PixTransactionType.DEBIT ? "Enviado" : "Recebido"; + System.out.println(tipo + ": R$ " + tx.getValue()); + } + } +} +``` + +## Boas Práticas + +### 1. Valide Dados Antes de Enviar + +```java +String cpf = "123.456.789-00"; +String cpfLimpo = cpf.replaceAll("[^0-9]", ""); + +if (cpfLimpo.length() == 11) { + Transfer transfer = Transfer.pixAddressKeyCreator() + .setPixAddressKey(cpfLimpo) + .setPixAddressKeyType(PixAddressKeyType.CPF) + .setValue(Money.create(valor)) + .create(); +} +``` + +### 2. Trate Erros Adequadamente + +```java +try { + Transfer transfer = Transfer.pixAddressKeyCreator() + .setPixAddressKey("chave_invalida") + .setPixAddressKeyType(PixAddressKeyType.CPF) + .setValue(Money.create(new BigDecimal("100.00"))) + .create(); +} catch (AsaasException e) { + if (e.getMessage().contains("insufficient balance")) { + System.err.println("Saldo insuficiente"); + } else if (e.getMessage().contains("invalid key")) { + System.err.println("Chave PIX inválida"); + } else { + System.err.println("Erro: " + e.getMessage()); + } +} +``` + +### 3. Confirme Valores Altos + +```java +BigDecimal valor = new BigDecimal("5000.00"); + +if (valor.compareTo(new BigDecimal("1000.00")) > 0) { + System.out.println("ATENÇÃO: Transferência de valor alto - R$ " + valor); + // Solicitar confirmação adicional +} +``` + +### 4. Monitore Rate Limit + +```java +Transfer transfer = Transfer.pixAddressKeyCreator() + .setPixAddressKey("12345678900") + .setPixAddressKeyType(PixAddressKeyType.CPF) + .setValue(Money.create(new BigDecimal("100.00"))) + .create(); + +RateLimit rateLimit = transfer.getRateLimit(); +System.out.println("Requisições restantes: " + rateLimit.getRemaining()); +``` + +## Limitações + +- Valor mínimo: R$ 0,01 +- Valor máximo: Depende do limite da sua conta +- Horário: 24/7 (PIX funciona todos os dias) +- Tempo de processamento: Instantâneo (até 10 segundos) +- Cancelamento: Apenas para transações pendentes ou agendadas + +## Veja Também + +- [PIX - QR Code e Chaves](pix_dict.md) - Gerenciar chaves e QR codes +- [PIX Automático](pix_automatic.md) - Débito recorrente via PIX +- [Transferências](transfer.md) - TED e transferências internas + +## Referências + +- [Documentação Oficial - PIX](https://docs.asaas.com/reference/pix) +- [Banco Central - PIX](https://www.bcb.gov.br/estabilidadefinanceira/pix) diff --git a/docs/quickstart.md b/docs/quickstart.md new file mode 100644 index 0000000..ded6c6d --- /dev/null +++ b/docs/quickstart.md @@ -0,0 +1,338 @@ +# Guia de Início Rápido + +Comece a usar o Asaas SDK em minutos! Este guia mostra os passos essenciais para integrar pagamentos na sua aplicação. + +## 📦 Instalação + +### Maven + +Adicione ao seu `pom.xml`: + +```xml + + io.github.jpdev01 + asaassdk + 1.4 + +``` + +### Gradle + +Adicione ao seu `build.gradle`: + +```gradle +implementation 'io.github.jpdev01:asaassdk:1.4' +``` + +## 🔑 Obter Chave de API + +1. Acesse [Asaas](https://www.asaas.com) +2. Faça login na sua conta +3. Vá em **Configurações** → **Integrações** → **API** +4. Copie sua chave de API + +**Importante**: Use a chave de produção apenas em ambiente de produção! + +## ⚡ Primeiro Código + +### 1. Inicializar o SDK + +```java +import io.github.jpdev.asaassdk.Asaas; + +public class Main { + public static void main(String[] args) { + // Ambiente de produção + Asaas.init("sua_chave_api_producao"); + + // OU ambiente sandbox (para testes) + // Asaas.initSandbox("sua_chave_api_sandbox"); + } +} +``` + +### 2. Criar um Cliente + +```java +import io.github.jpdev.asaassdk.rest.customeraccount.CustomerAccount; + +CustomerAccount cliente = CustomerAccount.creator() + .setName("João Silva") + .setCpfCnpj("12345678900") + .setEmail("joao@exemplo.com") + .setPhone("47999999999") + .create(); + +System.out.println("✅ Cliente criado: " + cliente.getId()); +``` + +### 3. Criar uma Cobrança PIX + +```java +import io.github.jpdev.asaassdk.rest.payment.Payment; +import io.github.jpdev.asaassdk.enums.BillingType; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Date; + +Payment cobranca = Payment.creator() + .setCustomer(cliente.getId()) + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("100.00"))) + .setDescription("Pagamento de serviço") + .create(); + +System.out.println("✅ Cobrança criada: " + cobranca.getId()); +System.out.println("📱 QR Code PIX: " + cobranca.getPixQrCode()); +``` + +## 🎯 Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.customeraccount.CustomerAccount; +import io.github.jpdev.asaassdk.rest.payment.Payment; +import io.github.jpdev.asaassdk.enums.BillingType; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Date; + +public class ExemploCompleto { + public static void main(String[] args) { + try { + // 1. Inicializar SDK + Asaas.init("sua_chave_api"); + System.out.println("✅ SDK inicializado"); + + // 2. Criar cliente + CustomerAccount cliente = CustomerAccount.creator() + .setName("Maria Santos") + .setCpfCnpj("12345678900") + .setEmail("maria@exemplo.com") + .setPhone("47999999999") + .create(); + + System.out.println("✅ Cliente criado: " + cliente.getId()); + + // 3. Criar cobrança PIX + Payment cobranca = Payment.creator() + .setCustomer(cliente.getId()) + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("150.00"))) + .setDescription("Pagamento de produto") + .create(); + + System.out.println("✅ Cobrança criada: " + cobranca.getId()); + System.out.println("💰 Valor: R$ " + cobranca.getValue()); + System.out.println("📱 QR Code: " + cobranca.getPixQrCode()); + + // 4. Verificar status + System.out.println("📊 Status: " + cobranca.getStatus()); + + } catch (Exception e) { + System.err.println("❌ Erro: " + e.getMessage()); + e.printStackTrace(); + } + } +} +``` + +## 🚀 Casos de Uso Comuns + +### Cobrança com Boleto + +```java +Payment boleto = Payment.creator() + .setCustomer(cliente.getId()) + .setBillingType(BillingType.BOLETO) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("250.00"))) + .setDescription("Mensalidade") + .create(); + +System.out.println("Link do boleto: " + boleto.getBankSlipUrl()); +``` + +### Assinatura Mensal + +```java +import io.github.jpdev.asaassdk.rest.subscription.Subscription; +import io.github.jpdev.asaassdk.enums.SubscriptionCycle; + +Subscription assinatura = Subscription.creator() + .setCustomer(cliente.getId()) + .setBillingType(BillingType.CREDIT_CARD) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("99.90"))) + .setCycle(SubscriptionCycle.MONTHLY) + .setDescription("Plano Premium") + .create(); + +System.out.println("Assinatura criada: " + assinatura.getId()); +``` + +### Transferência PIX + +```java +import io.github.jpdev.asaassdk.rest.transfer.Transfer; +import io.github.jpdev.asaassdk.enums.PixAddressKeyType; + +Transfer transfer = Transfer.pixAddressKeyCreator() + .setPixAddressKey("12345678900") + .setPixAddressKeyType(PixAddressKeyType.CPF) + .setValue(Money.create(new BigDecimal("100.00"))) + .setDescription("Pagamento fornecedor") + .create(); + +System.out.println("PIX enviado: " + transfer.getId()); +``` + +### Webhook para Notificações + +```java +import io.github.jpdev.asaassdk.rest.webhook.Webhook; +import io.github.jpdev.asaassdk.enums.Event; +import io.github.jpdev.asaassdk.enums.SendType; + +Webhook webhook = Webhook.creator() + .setName("Notificações de Pagamento") + .setUrl("https://seusite.com/webhook/asaas") + .setEmail("notificacoes@seusite.com") + .setSendType(SendType.SEQUENTIALLY) + .addEvent(Event.PAYMENT_RECEIVED) + .addEvent(Event.PAYMENT_CONFIRMED) + .create(); + +System.out.println("Webhook configurado: " + webhook.getId()); +``` + +## 🔧 Configurações Úteis + +### Ambiente Sandbox + +Para testes, use o ambiente sandbox: + +```java +Asaas.initSandbox("sua_chave_api_sandbox"); +``` + +### Timeout Personalizado + +Ajuste o timeout das requisições (padrão: 30 segundos): + +```java +Asaas.setTimeout(10000); // 10 segundos +``` + +### Verificar Rate Limit + +```java +Payment payment = Payment.creator() + .setCustomer(cliente.getId()) + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("100.00"))) + .create(); + +RateLimit rateLimit = payment.getRateLimit(); +System.out.println("Requisições restantes: " + rateLimit.getRemaining()); +System.out.println("Limite total: " + rateLimit.getLimit()); +System.out.println("Reseta em: " + rateLimit.getReset()); +``` + +## 🛡️ Boas Práticas + +### 1. Use Variáveis de Ambiente + +Nunca exponha suas chaves de API no código: + +```java +String apiKey = System.getenv("ASAAS_API_KEY"); +Asaas.init(apiKey); +``` + +### 2. Trate Erros Adequadamente + +```java +try { + Payment payment = Payment.creator() + .setCustomer("cus_invalid") + .setBillingType(BillingType.PIX) + .setDueDate(new Date()) + .setValue(Money.create(new BigDecimal("100.00"))) + .create(); +} catch (AsaasException e) { + System.err.println("Erro ao criar cobrança: " + e.getMessage()); + // Registrar erro, notificar equipe, etc. +} +``` + +### 3. Valide Dados de Entrada + +```java +String cpf = "123.456.789-00"; +String cpfLimpo = cpf.replaceAll("[^0-9]", ""); + +if (cpfLimpo.length() == 11) { + CustomerAccount cliente = CustomerAccount.creator() + .setCpfCnpj(cpfLimpo) + .setName("Cliente") + .create(); +} +``` + +### 4. Use Referências Externas + +Mantenha sincronização com seu sistema: + +```java +CustomerAccount cliente = CustomerAccount.creator() + .setName("João Silva") + .setCpfCnpj("12345678900") + .setExternalReference("CLIENTE_ID_123") // ID do seu sistema + .create(); +``` + +## 📚 Próximos Passos + +Agora que você já sabe o básico, explore mais recursos: + +### Pagamentos +- [Cobranças Detalhadas](payment.md) +- [Cobranças com Split](payment_split.md) +- [Links de Pagamento](paymentlink.md) +- [Assinaturas](subscription.md) + +### PIX +- [PIX - QR Code e Chaves](pix_dict.md) +- [PIX - Transações](pix_transaction.md) +- [PIX Automático](pix_automatic.md) + +### Gestão +- [Clientes](customeraccount.md) +- [Saldo e Extrato](balance.md) +- [Transferências](transfer.md) + +### Integrações +- [Webhooks](webhook.md) +- [Notificações](notification.md) + +## 🆘 Precisa de Ajuda? + +- 📖 [Documentação Completa](README.md) +- 💻 [Exemplos de Código](https://github.com/jpdev01/asaasSdk/blob/master/src/main/java/io/github/jpdev/asaassdk/doc/Examples.java) +- 🌐 [Documentação Oficial Asaas](https://docs.asaas.com) +- 🐛 [Reportar Problemas](https://github.com/jpdev01/asaasSdk/issues) + +## ⚠️ Importante + +- **Sandbox**: Use para testes, não processa pagamentos reais +- **Produção**: Use apenas com chave de produção válida +- **Segurança**: Nunca exponha suas chaves de API +- **Validação**: Sempre valide dados antes de enviar + +--- + +**Pronto!** Você já está apto para integrar pagamentos com Asaas! 🎉 diff --git a/docs/subscription.md b/docs/subscription.md index 4e78c49..b4e30bb 100644 --- a/docs/subscription.md +++ b/docs/subscription.md @@ -1,33 +1,521 @@ -## Criar uma assinatura +# Assinaturas (Subscriptions) -Ao criar a assinatura a primeira mensalidade será gerada vencendo na data enviada no parâmetro nextDueDate. +Crie e gerencie cobranças recorrentes automáticas. Ideal para SaaS, academias, escolas e qualquer negócio com pagamentos mensais. + +## 📋 Índice + +- [Criar Assinatura](#criar-assinatura) +- [Listar Assinaturas](#listar-assinaturas) +- [Recuperar Assinatura](#recuperar-assinatura) +- [Atualizar Assinatura](#atualizar-assinatura) +- [Cancelar Assinatura](#cancelar-assinatura) +- [Ciclos de Cobrança](#ciclos-de-cobrança) + +## Criar Assinatura + +### Assinatura Mensal + +```java +import io.github.jpdev.asaassdk.rest.subscription.Subscription; +import io.github.jpdev.asaassdk.enums.BillingType; +import io.github.jpdev.asaassdk.enums.SubscriptionCycle; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Date; + +Subscription assinatura = Subscription.creator() + .setCustomer("cus_000072683044") + .setBillingType(BillingType.CREDIT_CARD) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("99.90"))) + .setCycle(SubscriptionCycle.MONTHLY) + .setDescription("Plano Premium") + .create(); + +System.out.println("Assinatura criada: " + assinatura.getId()); +System.out.println("Próximo vencimento: " + assinatura.getNextDueDate()); +``` + +### Assinatura Anual ```java -Subscription subscription = Subscription.creator() - .setCustomer("cus_000072683044") - .setBillingType(BillingType.BOLETO) - .setNextDueDate(new Date()) - .setValue(Money.create(50)) - .setCycle(SubscriptionCycle.MONTHLY) - .setDescription("Assinatura Plano Pró") - .create(); +Subscription assinatura = Subscription.creator() + .setCustomer("cus_000072683044") + .setBillingType(BillingType.BOLETO) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("999.00"))) + .setCycle(SubscriptionCycle.YEARLY) + .setDescription("Plano Anual") + .create(); ``` -## Listar assinaturas - +### Assinatura Semanal + +```java +Subscription assinatura = Subscription.creator() + .setCustomer("cus_000072683044") + .setBillingType(BillingType.PIX) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("29.90"))) + .setCycle(SubscriptionCycle.WEEKLY) + .setDescription("Plano Semanal") + .create(); +``` + +### Assinatura Trimestral + +```java +Subscription assinatura = Subscription.creator() + .setCustomer("cus_000072683044") + .setBillingType(BillingType.CREDIT_CARD) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("249.90"))) + .setCycle(SubscriptionCycle.QUARTERLY) + .setDescription("Plano Trimestral") + .create(); +``` + +### Assinatura Semestral + +```java +Subscription assinatura = Subscription.creator() + .setCustomer("cus_000072683044") + .setBillingType(BillingType.CREDIT_CARD) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("499.90"))) + .setCycle(SubscriptionCycle.SEMIANNUALLY) + .setDescription("Plano Semestral") + .create(); +``` + +### Assinatura com Desconto + +```java +Subscription assinatura = Subscription.creator() + .setCustomer("cus_000072683044") + .setBillingType(BillingType.CREDIT_CARD) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("99.90"))) + .setCycle(SubscriptionCycle.MONTHLY) + .setDescription("Plano Premium com desconto") + .setDiscount(Money.create(new BigDecimal("10.00"))) // R$ 10 de desconto + .create(); + +System.out.println("Valor com desconto: R$ 89,90"); +``` + +### Assinatura com Juros e Multa + +```java +Subscription assinatura = Subscription.creator() + .setCustomer("cus_000072683044") + .setBillingType(BillingType.BOLETO) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("150.00"))) + .setCycle(SubscriptionCycle.MONTHLY) + .setDescription("Mensalidade") + .setInterest(Money.create(new BigDecimal("2.00"))) // R$ 2,00 por dia de atraso + .setFine(Money.create(new BigDecimal("10.00"))) // R$ 10,00 de multa + .create(); +``` + +### Assinatura com Data de Término + +```java +import java.util.Calendar; + +Calendar cal = Calendar.getInstance(); +cal.add(Calendar.MONTH, 12); // 12 meses a partir de hoje +Date dataTermino = cal.getTime(); + +Subscription assinatura = Subscription.creator() + .setCustomer("cus_000072683044") + .setBillingType(BillingType.CREDIT_CARD) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("99.90"))) + .setCycle(SubscriptionCycle.MONTHLY) + .setDescription("Plano com término definido") + .setEndDate(dataTermino) + .create(); + +System.out.println("Assinatura válida até: " + assinatura.getEndDate()); +``` + +### Assinatura com Número Máximo de Cobranças + ```java -ResourceSet subscriptionResourceSet = Subscription.reader().read(); +Subscription assinatura = Subscription.creator() + .setCustomer("cus_000072683044") + .setBillingType(BillingType.CREDIT_CARD) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("99.90"))) + .setCycle(SubscriptionCycle.MONTHLY) + .setDescription("Plano de 6 meses") + .setMaxPayments(6) // Apenas 6 cobranças + .create(); ``` -Também é possível utilizar filtros +## Listar Assinaturas + +### Listar Todas + +```java +import io.github.jpdev.asaassdk.rest.subscription.ResourceSet; + +ResourceSet assinaturas = Subscription.reader().read(); + +for (Subscription assinatura : assinaturas.getData()) { + System.out.println("ID: " + assinatura.getId()); + System.out.println("Cliente: " + assinatura.getCustomer()); + System.out.println("Valor: R$ " + assinatura.getValue()); + System.out.println("Status: " + assinatura.getStatus()); + System.out.println("Ciclo: " + assinatura.getCycle()); + System.out.println("Próximo vencimento: " + assinatura.getNextDueDate()); + System.out.println("---"); +} +``` + +### Filtrar por Status + +```java +import io.github.jpdev.asaassdk.enums.SubscriptionStatus; + +// Apenas assinaturas ativas +ResourceSet ativas = Subscription.reader() + .setStatus(SubscriptionStatus.ACTIVE) + .read(); + +// Apenas assinaturas expiradas +ResourceSet expiradas = Subscription.reader() + .setStatus(SubscriptionStatus.EXPIRED) + .read(); +``` + +### Filtrar por Cliente + +```java +ResourceSet assinaturas = Subscription.reader() + .setCustomer("cus_000072683044") + .read(); + +System.out.println("Cliente possui " + assinaturas.getTotalCount() + " assinatura(s)"); +``` + +### Filtrar por Cliente e Status + +```java +ResourceSet assinaturasAtivas = Subscription.reader() + .setCustomer("cus_000072683044") + .setStatus(SubscriptionStatus.ACTIVE) + .read(); +``` + +### Filtrar por Tipo de Cobrança + +```java +// Assinaturas com cartão de crédito +ResourceSet cartao = Subscription.reader() + .setBillingType(BillingType.CREDIT_CARD) + .read(); + +// Assinaturas com PIX +ResourceSet pix = Subscription.reader() + .setBillingType(BillingType.PIX) + .read(); +``` + +### Paginação + +```java +ResourceSet assinaturas = Subscription.reader() + .setLimit(50) + .setOffset(0) + .read(); + +System.out.println("Total: " + assinaturas.getTotalCount()); +System.out.println("Tem mais: " + assinaturas.hasMore()); +``` + +## Recuperar Assinatura + +```java +Subscription assinatura = Subscription.fetcher("sub_123456789").fetch(); + +System.out.println("ID: " + assinatura.getId()); +System.out.println("Cliente: " + assinatura.getCustomer()); +System.out.println("Valor: R$ " + assinatura.getValue()); +System.out.println("Status: " + assinatura.getStatus()); +System.out.println("Ciclo: " + assinatura.getCycle()); +System.out.println("Próximo vencimento: " + assinatura.getNextDueDate()); +System.out.println("Data de criação: " + assinatura.getDateCreated()); +``` + +## Atualizar Assinatura + +### Atualizar Valor ```java -ResourceSet subscriptionResourceSet = Subscription.reader() - .setStatus(SubscriptionStatus.ACTIVE) - .read(); +Subscription atualizada = Subscription.updater("sub_123456789") + .setValue(Money.create(new BigDecimal("149.90"))) + .update(); + +System.out.println("Novo valor: R$ " + atualizada.getValue()); +``` + +### Atualizar Forma de Pagamento + +```java +Subscription atualizada = Subscription.updater("sub_123456789") + .setBillingType(BillingType.PIX) + .update(); + +System.out.println("Nova forma de pagamento: PIX"); +``` + +### Atualizar Próximo Vencimento + +```java +import java.util.Calendar; + +Calendar cal = Calendar.getInstance(); +cal.add(Calendar.DAY_OF_MONTH, 15); +Date novoVencimento = cal.getTime(); + +Subscription atualizada = Subscription.updater("sub_123456789") + .setNextDueDate(novoVencimento) + .update(); + +System.out.println("Próximo vencimento: " + atualizada.getNextDueDate()); +``` + +### Atualizar Descrição + +```java +Subscription atualizada = Subscription.updater("sub_123456789") + .setDescription("Plano Premium Plus") + .update(); +``` + +### Atualizar Múltiplos Campos + +```java +Subscription atualizada = Subscription.updater("sub_123456789") + .setValue(Money.create(new BigDecimal("199.90"))) + .setDescription("Plano Enterprise") + .setBillingType(BillingType.CREDIT_CARD) + .update(); +``` + +## Cancelar Assinatura + +```java +import io.github.jpdev.asaassdk.rest.subscription.SubscriptionDeleted; + +SubscriptionDeleted cancelada = Subscription.deleter("sub_123456789").delete(); + +if (cancelada.isDeleted()) { + System.out.println("Assinatura cancelada com sucesso"); +} +``` + +**Nota**: Ao cancelar uma assinatura, as cobranças futuras não serão mais geradas. + +## Ciclos de Cobrança + +| Ciclo | Descrição | Enum | +|-------|-----------|------| +| Semanal | A cada 7 dias | `SubscriptionCycle.WEEKLY` | +| Quinzenal | A cada 15 dias | `SubscriptionCycle.BIWEEKLY` | +| Mensal | A cada mês | `SubscriptionCycle.MONTHLY` | +| Bimestral | A cada 2 meses | `SubscriptionCycle.BIMONTHLY` | +| Trimestral | A cada 3 meses | `SubscriptionCycle.QUARTERLY` | +| Semestral | A cada 6 meses | `SubscriptionCycle.SEMIANNUALLY` | +| Anual | A cada ano | `SubscriptionCycle.YEARLY` | + +## Status de Assinaturas + +| Status | Descrição | +|--------|-----------| +| `ACTIVE` | Assinatura ativa | +| `EXPIRED` | Assinatura expirada | +| `INACTIVE` | Assinatura inativa | + +## Exemplo Completo + +```java +import io.github.jpdev.asaassdk.Asaas; +import io.github.jpdev.asaassdk.rest.customeraccount.CustomerAccount; +import io.github.jpdev.asaassdk.rest.subscription.Subscription; +import io.github.jpdev.asaassdk.enums.*; +import io.github.jpdev.asaassdk.util.Money; +import java.math.BigDecimal; +import java.util.Date; + +public class ExemploAssinatura { + public static void main(String[] args) { + // Inicializar SDK + Asaas.init("sua_api_key"); + + // Criar cliente + CustomerAccount cliente = CustomerAccount.creator() + .setName("João Silva") + .setCpfCnpj("12345678900") + .setEmail("joao@exemplo.com") + .create(); + + System.out.println("Cliente criado: " + cliente.getId()); + + // Criar assinatura mensal + Subscription assinatura = Subscription.creator() + .setCustomer(cliente.getId()) + .setBillingType(BillingType.CREDIT_CARD) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("99.90"))) + .setCycle(SubscriptionCycle.MONTHLY) + .setDescription("Plano Premium") + .create(); + + System.out.println("Assinatura criada: " + assinatura.getId()); + System.out.println("Valor: R$ " + assinatura.getValue()); + System.out.println("Próximo vencimento: " + assinatura.getNextDueDate()); + + // Listar assinaturas ativas do cliente + ResourceSet assinaturas = Subscription.reader() + .setCustomer(cliente.getId()) + .setStatus(SubscriptionStatus.ACTIVE) + .read(); + + System.out.println("\nAssinaturas ativas: " + assinaturas.getTotalCount()); + + // Atualizar valor da assinatura + Subscription atualizada = Subscription.updater(assinatura.getId()) + .setValue(Money.create(new BigDecimal("149.90"))) + .update(); + + System.out.println("Valor atualizado para: R$ " + atualizada.getValue()); + } +} +``` + +## Boas Práticas + +### 1. Notifique o Cliente + +```java +// Criar assinatura e enviar email de confirmação +Subscription assinatura = Subscription.creator() + .setCustomer(clienteId) + .setBillingType(BillingType.CREDIT_CARD) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("99.90"))) + .setCycle(SubscriptionCycle.MONTHLY) + .create(); + +// Enviar email personalizado ao cliente +enviarEmailConfirmacao(cliente.getEmail(), assinatura); +``` + +### 2. Configure Webhooks + +```java +import io.github.jpdev.asaassdk.rest.webhook.Webhook; +import io.github.jpdev.asaassdk.enums.Event; + +Webhook webhook = Webhook.creator() + .setUrl("https://seusite.com/webhook/asaas") + .addEvent(Event.PAYMENT_RECEIVED) + .addEvent(Event.PAYMENT_OVERDUE) + .create(); +``` + +### 3. Trate Erros de Pagamento + +```java +// Monitorar cobranças da assinatura +ResourceSet cobrancas = Payment.reader() + .setSubscription(assinaturaId) + .setStatus(PaymentStatus.OVERDUE) + .read(); + +if (cobrancas.getTotalCount() > 0) { + // Notificar cliente sobre pagamento em atraso + // Suspender acesso ao serviço +} +``` + +### 4. Ofereça Período de Teste + +```java +import java.util.Calendar; + +// Primeira cobrança daqui a 7 dias (trial de 7 dias) +Calendar cal = Calendar.getInstance(); +cal.add(Calendar.DAY_OF_MONTH, 7); + +Subscription assinatura = Subscription.creator() + .setCustomer(clienteId) + .setBillingType(BillingType.CREDIT_CARD) + .setNextDueDate(cal.getTime()) + .setValue(Money.create(new BigDecimal("99.90"))) + .setCycle(SubscriptionCycle.MONTHLY) + .setDescription("Plano Premium - Trial 7 dias") + .create(); +``` + +## Casos de Uso + +### SaaS + +```java +// Plano mensal de software +Subscription saas = Subscription.creator() + .setCustomer(clienteId) + .setBillingType(BillingType.CREDIT_CARD) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("49.90"))) + .setCycle(SubscriptionCycle.MONTHLY) + .setDescription("Plano Básico") + .create(); +``` + +### Academia + +```java +// Mensalidade de academia +Subscription academia = Subscription.creator() + .setCustomer(clienteId) + .setBillingType(BillingType.BOLETO) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("120.00"))) + .setCycle(SubscriptionCycle.MONTHLY) + .setDescription("Mensalidade Academia") + .setFine(Money.create(new BigDecimal("10.00"))) + .setInterest(Money.create(new BigDecimal("1.00"))) + .create(); +``` + +### Escola + +```java +// Mensalidade escolar +Subscription escola = Subscription.creator() + .setCustomer(clienteId) + .setBillingType(BillingType.BOLETO) + .setNextDueDate(new Date()) + .setValue(Money.create(new BigDecimal("800.00"))) + .setCycle(SubscriptionCycle.MONTHLY) + .setDescription("Mensalidade Escolar") + .setMaxPayments(12) // 12 meses letivos + .create(); +``` + +## Veja Também + +- [Cobranças](payment.md) - Gerenciar cobranças individuais +- [Clientes](customeraccount.md) - Gerenciar clientes +- [Webhooks](webhook.md) - Notificações automáticas +- [Parcelamentos](installment.md) - Cobranças parceladas + +## Referências -ResourceSet subscriptionResourceSet = Subscription.reader() - .setCustomer("cus_000072683044") - .setStatus(SubscriptionStatus.ACTIVE) - .read(); -``` \ No newline at end of file +- [Documentação Oficial - Assinaturas](https://docs.asaas.com/reference/assinaturas)