├── .github └── workflows │ └── dotnet.yml ├── .gitignore ├── LICENSE ├── PIX-Sicoob.sln ├── README.md ├── Sicoob.Cobranca ├── DataAnotation │ └── CustomDateTimeWithZoneConverter.cs ├── Helpers.cs ├── Models │ ├── Shared │ │ ├── Beneficiariofinal.cs │ │ ├── DadosPagador.cs │ │ ├── Enum.cs │ │ ├── Listahistorico.cs │ │ ├── Movimentacoes.cs │ │ ├── Rateiocredito.cs │ │ ├── RetornoArquivoMovimentacao.cs │ │ ├── RetornoConsultaMovimentacoes.cs │ │ └── RetornoSolicitacaoMovimentacoesCarteira.cs │ ├── v2 │ │ ├── AlterarDataVencimento.cs │ │ ├── BaixarBoleto.cs │ │ ├── BoletoBase.cs │ │ ├── ConsultaBoleto.cs │ │ ├── IncluirBoletos.cs │ │ ├── ProtestarBoleto.cs │ │ └── ResultadoInfo.cs │ └── v3 │ │ ├── AlterarBoletoRequest.cs │ │ ├── BaixarBoletoRequest.cs │ │ ├── ConsultaBoletoRequest.cs │ │ ├── IncluirBoleto.cs │ │ ├── MovimentacaoRequest.cs │ │ └── ProtestoRequest.cs ├── Sicoob.Cobranca.csproj ├── SicoobCobrancaV2.cs └── SicoobCobrancaV3.cs ├── Sicoob.Conta ├── Models │ ├── ExtratoResponse.cs │ ├── ResultadoResponse.cs │ └── SaldoResponse.cs ├── Sicoob.Conta.csproj ├── SicoobContaCorrente.cs └── SicoobContaPoupanca.cs ├── Sicoob.PIX.UnitTest └── Sicoob.PIX.UnitTest.csproj ├── Sicoob.PIX ├── Sicoob.PIX.csproj ├── SicoobConsultaPayload.cs └── SicoobPIX.cs ├── Sicoob.Shared.UnitTest ├── ExtensionsTests │ └── ToKvpTests.cs ├── ModelsTests │ └── ConfiguracaoTests │ │ └── ScopeTests.cs └── Sicoob.Shared.UnitTest.csproj ├── Sicoob.Shared ├── Extensions │ ├── ClassToKVP.cs │ └── ToRFC.cs ├── Models │ ├── Acesso │ │ └── TokenResponse.cs │ ├── AuthorizationScope.cs │ ├── Configuracao.cs │ └── Geral │ │ ├── RequestParametros.cs │ │ ├── ResponseErro.cs │ │ └── ResponseParametros.cs ├── Sicoob.Shared.csproj └── Sicoob.cs └── Sicoob.Testes ├── Program.cs ├── Sicoob.Testes.csproj ├── TestesApiCobranca.cs ├── TestesApiConta.cs └── TestesApiPIX.cs /.github/workflows/dotnet.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a .NET project 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net 3 | 4 | name: .NET 5 | 6 | on: 7 | push: 8 | branches: [ "main" ] 9 | pull_request: 10 | branches: [ "main" ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | - name: Setup .NET 20 | uses: actions/setup-dotnet@v3 21 | with: 22 | dotnet-version: 6.0.x 23 | - name: Restore dependencies 24 | run: dotnet restore 25 | - name: Build 26 | run: dotnet build --no-restore 27 | - name: Test 28 | run: dotnet test --no-build --verbosity normal 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | 352 | .idea/ 353 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 SHARP Sistemas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PIX-Sicoob.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.4.33205.214 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sicoob.Testes", "Sicoob.Testes\Sicoob.Testes.csproj", "{F4E1E8D3-9690-48C0-BDAB-8E89C6486BA1}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sicoob.PIX", "Sicoob.PIX\Sicoob.PIX.csproj", "{31571823-D5E5-4F24-8A33-33006862268F}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sicoob.Shared.UnitTest", "Sicoob.Shared.UnitTest\Sicoob.Shared.UnitTest.csproj", "{C796024A-477D-460A-B511-D6188415FFA2}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sicoob.Shared", "Sicoob.Shared\Sicoob.Shared.csproj", "{0466318D-33CF-46ED-8466-3809F01A97C3}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sicoob.PIX.UnitTest", "Sicoob.PIX.UnitTest\Sicoob.PIX.UnitTest.csproj", "{4C140134-CF64-4104-82CA-5A09AD0E2AF5}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sicoob.Cobranca", "Sicoob.Cobranca\Sicoob.Cobranca.csproj", "{05DD23BA-333E-4024-95A7-A9A1A8719925}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sicoob.Conta", "Sicoob.Conta\Sicoob.Conta.csproj", "{CB15FFEA-0F15-4928-AB43-19E61BADD1FE}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Release|Any CPU = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {F4E1E8D3-9690-48C0-BDAB-8E89C6486BA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {F4E1E8D3-9690-48C0-BDAB-8E89C6486BA1}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {F4E1E8D3-9690-48C0-BDAB-8E89C6486BA1}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {F4E1E8D3-9690-48C0-BDAB-8E89C6486BA1}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {31571823-D5E5-4F24-8A33-33006862268F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {31571823-D5E5-4F24-8A33-33006862268F}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {31571823-D5E5-4F24-8A33-33006862268F}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {31571823-D5E5-4F24-8A33-33006862268F}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {C796024A-477D-460A-B511-D6188415FFA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {C796024A-477D-460A-B511-D6188415FFA2}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {C796024A-477D-460A-B511-D6188415FFA2}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {C796024A-477D-460A-B511-D6188415FFA2}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {0466318D-33CF-46ED-8466-3809F01A97C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {0466318D-33CF-46ED-8466-3809F01A97C3}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {0466318D-33CF-46ED-8466-3809F01A97C3}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {0466318D-33CF-46ED-8466-3809F01A97C3}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {4C140134-CF64-4104-82CA-5A09AD0E2AF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {4C140134-CF64-4104-82CA-5A09AD0E2AF5}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {4C140134-CF64-4104-82CA-5A09AD0E2AF5}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {4C140134-CF64-4104-82CA-5A09AD0E2AF5}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {05DD23BA-333E-4024-95A7-A9A1A8719925}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {05DD23BA-333E-4024-95A7-A9A1A8719925}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {05DD23BA-333E-4024-95A7-A9A1A8719925}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {05DD23BA-333E-4024-95A7-A9A1A8719925}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {CB15FFEA-0F15-4928-AB43-19E61BADD1FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {CB15FFEA-0F15-4928-AB43-19E61BADD1FE}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {CB15FFEA-0F15-4928-AB43-19E61BADD1FE}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {CB15FFEA-0F15-4928-AB43-19E61BADD1FE}.Release|Any CPU.Build.0 = Release|Any CPU 54 | EndGlobalSection 55 | GlobalSection(SolutionProperties) = preSolution 56 | HideSolutionNode = FALSE 57 | EndGlobalSection 58 | GlobalSection(ExtensibilityGlobals) = postSolution 59 | SolutionGuid = {C17C26FE-7CDA-4B64-8800-D67A134E6C45} 60 | EndGlobalSection 61 | EndGlobal 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [![.NET](https://github.com/SharpSistemas/SicoobAPI/actions/workflows/dotnet.yml/badge.svg)](https://github.com/SharpSistemas/SicoobAPI) APIs Sicoob 2 | 3 | - [ APIs Sicoob](#-apis-sicoob) 4 | - [Sicoob.PIX](#sicoobpix) 5 | - [Exemplos de uso](#exemplos-de-uso) 6 | - [Permissões](#permissões) 7 | - [Webhook](#webhook) 8 | - [Sicoob.Conta](#sicoobconta) 9 | - [Exemplos de uso](#exemplos-de-uso-1) 10 | - [Consulta de Saldo](#consulta-de-saldo) 11 | - [Consulta de Extrato](#consulta-de-extrato) 12 | - [Permissões](#permissões-1) 13 | 14 | 15 | O objetivo deste repositório para comunicação via API com o banco Sicoob. 16 | 17 | Para comunicação com o Sicoob é necessário um "Cadastro de Aplicativo" em developers.sicoob.com.br. 18 | Para isso é necessário ter os dados bancarios da conta a ser automatizada e de seu respectivo certificado ICP-Brasil em arquivo. 19 | 20 | Cada conta bancária a ser automatizada deve ter um cadastro como Aplicativo, entre em contato com sua agência e solicite auxílio. 21 | 22 | É necessário ter o certificado em dois formatos: 23 | * *.PFX (padrão quando um certificado A1 é adiquirido) com a senha e - para comunicação; 24 | * *.CER (apenas a chave pública em formato Base-64) - para o cadastro 25 | 26 | Durante o cadastro será informado os dados da conta bancária sendo automatizada e o certificado no formato PEM. Será gerado um `ClientId`. 27 | 28 | O Sicoob possui APIs para: 29 | * PIX 30 | * Cobrança Bancária (Boleto) 31 | * Conta Corrente 32 | * Conta Poupança 33 | 34 | 35 | API PIX: 36 | [![NuGet](https://buildstats.info/nuget/Sicoob.PIX)](https://www.nuget.org/packages/Sicoob.PIX) 37 | 38 | API Cobrança: 39 | [![NuGet](https://buildstats.info/nuget/Sicoob.Cobranca)](https://www.nuget.org/packages/Sicoob.Cobranca) 40 | 41 | API Conta Corrente e Poupança: 42 | [![NuGet](https://buildstats.info/nuget/Sicoob.Conta)](https://www.nuget.org/packages/Sicoob.Conta) 43 | 44 | A documentação do Sicoob é falha, incompleta e em alguns tópicos é completamente ausente. 45 | O Gerente não tem acesso à documentação, o WhatsApp das APIs manda solicitar via e-mail, e o e-mails não são respondidos. 46 | Farei o póssível para documentar aqui as funções não documentadas lá, porém sob o risco de errar alguma funcionalidade 47 | 48 | 49 | Link da documentação oficial: https://developers.sicoob.com.br 50 | 51 | O Sicoob parece respeitar bem as definições Públicas Padrão do PIX, então usarei de base o repositório https://github.com/SharpSistemas/PIX-BCB 52 | 53 | # Sicoob.PIX 54 | 55 | APIs do Sicoob para funções PIX 56 | 57 | Funcionalidades da API: 58 | * Consultar e Devolver PIX recebidos no período (com e sem txId) 59 | * Criar, Consultar e revisar Pix-Cobrança imediato 60 | * Criar, Consultar e revisar Pix-Cobrança com vencimento 61 | * Criar, Consultar e revisar lotes de Pix-Cobrança com vencimento 62 | * Criar, Consultar e revisar PayloadLocation de Pix (cria um acesso público para dados de uma cobrança) 63 | * Criar, consultar e cancelar Webhook 64 | 65 | ## Exemplos de uso 66 | 67 | Criação do objeto API 68 | 69 | ~~~C# 70 | // Cria configuração 71 | var cfg = new ConfiguracaoAPI() 72 | { 73 | ClientId = "00000000-0000-0000-0000-000000000000", // Obtém no "Aplicativo" no developers.sicoob.com.br 74 | Scope = AuthorizationScope.PIX_SomenteLeitura(), 75 | CertificadoSenha = "SenhaCertificado", 76 | UrlCertificadoPFX = "caminho/do/pfx/com/chave/privada.pfx" 77 | }; 78 | 79 | // cria o objeto de comunicação com as APIs de PIX 80 | var sicoob = new SicoobPIX(cfg); 81 | // Inicializa o acesso das APIs 82 | await sicoob.SetupAsync(); 83 | 84 | // A autenticação dura 300 segundos (5min) e é auto renovado pela biblioteca 85 | // Cada chamada verifica e, se necessário, atualiza o token 86 | // Chame AtualizarCredenciaisAsync() para renovar manualmente 87 | // É possível consultar dados da vigência do Token nas propriedades: 88 | // * sicoob.ExpiresIn 89 | // * sicoob.ExpiresAtUTC 90 | // * sicoob.Expired 91 | ~~~ 92 | **Atenção:** Por segurança, o construtor da classe Sicoob (e todas suas derivações, como o SicoobPIX) apaga a propriedade `CertificadoSenha` do objeto de configuração 93 | 94 | Nota: É possível inicializar a classe passando o certificado x509 diretamente no construtor ao invés de utilizar a configuração. 95 | 96 | Funções Cobrança para PIX-Imediato 97 | ~~~C# 98 | // Listar todas as cobranças num período 99 | var cobs = await sicoob.ListarCobrancasAsync(new ConsultarCobrancaImediata 100 | { 101 | inicio = DateTime.UtcNow.Date.AddDays(-1), 102 | fim = DateTime.UtcNow.AddDays(1).Date, 103 | }); 104 | 105 | // Criar uma Cobrança para a chave: "12.345.678/0001-00", no valor de R$ 19,90, com limite de 1h para pagamento 106 | var transactionId = gerarNovaTxId(); // Controle interno (string), pode ser um guid (pattern: ^[a-zA-Z0-9]{26,35}$) 107 | var dadosCobranca = PIX.Models.Cobranca.CriarCobrancaRequest.Padrao(chave: "12345678000100", valor: 19.90M, expiracaoSegundos: 3600)); 108 | var nova = await sicoob.CriarCobrancaAsync(transactionId, dadosCobranca); 109 | // Baixar QR Code 110 | var pngBytes = await sicoob.ConsultarImagemCobrancaAsync(transactionId); 111 | 112 | // Consultar cobrança 113 | var consulta = await sicoob.ConsultarCobrancaAsync(transactionId); 114 | 115 | // Função interna da empresa para gerar Ids de Transação 116 | string gerarNovaTxId() 117 | => Guid.NewGuid().ToString(); 118 | ~~~ 119 | 120 | Funções de consulta de PIX Recebidos 121 | ~~~C# 122 | /* PIX */ 123 | var pixPeriodo = await sicoob.ListarPIXAsync(new ConsultarPix() 124 | { 125 | inicio = DateTime.UtcNow.Date.AddDays(-1), 126 | fim = DateTime.UtcNow.AddDays(1).Date, 127 | }); 128 | ~~~ 129 | 130 | ## Permissões 131 | 132 | A autenticação para o endpoint PIX do sicoob separa as diversas funções em diferentes escopos, cada um com a variante Read e Write: 133 | 134 | * cob: permissões para endpoints de cobrança imediata 135 | * cobv: permissões para endpoints de cobrança com vencimento 136 | * lotecobv: permissões para endpoints de lotes cobrança com vencimento 137 | * pix: permissões para consulta e alteração de transações PIX (com ou sem cobrança) 138 | * webhook: permissões para endpoints de webhook 139 | * payloadlocation: permissões para endpoints de payloads 140 | 141 | Confira aqui a classe para configuração dos Scopes [AuthorizationScope](https://github.com/SharpSistemas/SicoobAPI/blob/main/Sicoob.Shared/Models/AuthorizationScope.cs) 142 | 143 | Veja detalhes em https://developers.sicoob.com.br/#!/documentacao?section=apis&item=pix 144 | 145 | ## Webhook 146 | 147 | A documentação do Webhook é um dos casos aonde só há informações parciais 148 | 149 | Existe a documentação dos endpoints para criar e gerenciar o cadastro de Webhooks, porém não há nenhuma documentação da requisição que será feita pelo Sicoob no endpoint. 150 | 151 | Ao consultar o suporte do sicoob no setor de APIs, fomos informados que não há documentação e devemos trabalhar por tentativa e erro (veja abaixo), portanto a documentação pode estar incompleta ou errada. 152 | 153 | 154 | Após registrar o Webhook, todo PIX recebido que tenha TransactionId será notificado através de uma chamada Webhook, 155 | aonde os servidores do Sicoob farão uma chamada REST na aplicação com informações sobre o PIX. 156 | 157 | Exemplo: 158 | 159 | É registrado um Webhook para a chave: "12.345.678/0001-00": 160 | ~~~ C# 161 | await sicoob.CriarWebHook("12345678000100", "https://meu.site.com.br/api/"); 162 | ~~~ 163 | 164 | O Sicoob vai fazer um POST para `ttps://meu.site.com.br/api/pix`, repare que é feito um POST para o endereço registrado adicionado de `/pix` no final. 165 | 166 | Caso seja registrado como `https://meu.site.com.br/api/pix`, será feito um POST para `https://meu.site.com.br/api/pix/pix` (repare o duplo `pix`). 167 | 168 | O POST não tem nenhum header especial, e contém um array de dados do PIX no payload conforme model: `Sicoob.PIX.Models.Webhook.WebhookPostRequest` 169 | 170 | ~~~C# 171 | // Exemplo de um Endpoint em ASP 172 | [HttpPost] 173 | [Route("cuidado com sua rota aqui/pix")] // não esquecer do /pix 174 | public IActionResult Webhook_Pix([FromBody] Sicoob.PIX.Models.Webhook.WebhookPostRequest payload){ 175 | // Processa o payload 176 | return Ok(); 177 | } 178 | ~~~ 179 | 180 | Dump de uma requisição do sicoob capturada 181 | ~~~ JSON 182 | { 183 | "method": "POST", 184 | "uri": "/api/pix", 185 | "headers": { 186 | "Via": "1.1 wsap501.sicoob.com.br:80 (Cisco-WSA/12.0.3-007)", 187 | "X-Imforwards": "20", 188 | "Content-Length": "164", 189 | "User-Agent": "axios/0.21.4", 190 | "Content-Type": "application/json", 191 | "Accept": "application/json, text/plain, */*", 192 | "Connection": "close" 193 | }, 194 | "body": "{\"pix\":[{\"endToEndId\":\"xxxxxxxxxxx\",\"txid\":\"xxxxxxxxxxx\",\"valor\":\"xxx.xx\",\"horario\":\"2020-01-01T00:00:00.000Z\",\"devolucoes\":[]}]}", 195 | } 196 | ~~~ 197 | 198 | 199 | Segue o Contato com a equipe do suporte ao desenvolvedor do Sicoob em JAN/2023: 200 | ~~~ 201 | Nós: 202 | Eu estou lendo a documentação sobre o registro, consulta e edição de WebHook 203 | Mas não achei o protocolo da chamada que o Sicoob vai fazer 204 | Não achei COMO o sicoob vai bater no meu endpoint 205 | Qual método? (POST/GET?), não tem se vai mandar parâmetros, headers, qual o payload .... 206 | Como eu faço para saber o que vou receber? 207 | 208 | Sicoob ([NOME REMOVIDO]): 209 | Você será notificado na URL cadastrada do Webhook e poderá identificar pelos IPs do Webhook PIX do Sicoob. 210 | 211 | Infelizmente não temos exemplos disponíveis, será necessário testar sua aplicação. 212 | ~~~ 213 | Protocolo do Atendimento: [REMOVIDO] 214 | 215 | 216 | # Sicoob.Conta 217 | 218 | APIs do Sicoob para funções de Conta Bancária 219 | 220 | Funcionalidades da API: 221 | * Consultar Saldo e Extrato para Conta Corrente 222 | * Consultar Saldo e Extrato para Conta Poupança 223 | 224 | ## Exemplos de uso 225 | 226 | Criação do objeto API 227 | 228 | ~~~C# 229 | // Cria configuração 230 | var cfg = new ConfiguracaoAPI() 231 | { 232 | ClientId = "00000000-0000-0000-0000-000000000000", // Obtém no "Aplicativo" no developers.sicoob.com.br 233 | Scope = AuthorizationScope.TodosContaCorrente(), 234 | CertificadoSenha = "SenhaCertificado", 235 | UrlCertificadoPFX = "caminho/do/pfx/com/chave/privada.pfx" 236 | }; 237 | 238 | // cria o objeto de comunicação com as APIs de PIX 239 | var sicoob = new SicoobContaCorrente(cfg); 240 | // Inicializa o acesso das APIs 241 | await sicoob.SetupAsync(); 242 | 243 | // A autenticação dura 300 segundos (5min) e é auto renovado pela biblioteca 244 | // Cada chamada verifica e, se necessário, atualiza o token 245 | // Chame AtualizarCredenciaisAsync() para renovar manualmente 246 | // É possível consultar dados da vigência do Token nas propriedades: 247 | // * sicoob.ExpiresIn 248 | // * sicoob.ExpiresAtUTC 249 | // * sicoob.Expired 250 | ~~~ 251 | 252 | Repare que a única diferença na inicialização entre PIX e Conta é no Scope e no nome da classe 253 | 254 | ### Consulta de Saldo 255 | ~~~C# 256 | var saldo = await sicoob.ObterSaldoAsync(); 257 | ~~~ 258 | 259 | ### Consulta de Extrato 260 | ~~~C# 261 | var extrato = await sicoob.ObterExtratoAsync(12, 2022); 262 | ~~~ 263 | O sicoob limita extrato aos últimos 3 meses 264 | 265 | 266 | ## Permissões 267 | 268 | A autenticação para o endpoint de Conta do sicoob é diferente do PIX, seguem os escopos: 269 | 270 | * Conta Corrente: 271 | * openid: Obrigatório 272 | * cco_extrato: Permite consultar extrato 273 | * cco_saldo: Permite consultar saldo 274 | * Poupança: 275 | * poupanca_contas: Permite listar as contas 276 | * poupanca_extrato: Permite consultar extrato 277 | * poupanca_saldo: Permite consultar saldo 278 | 279 | Confira aqui a classe para configuração dos Scopes [AuthorizationScope](https://github.com/SharpSistemas/SicoobAPI/blob/main/Sicoob.Shared/Models/AuthorizationScope.cs) 280 | 281 | Veja detalhes em https://developers.sicoob.com.br/ navegue para: 282 | * APIs -> Conta-Corrente 283 | * APIs -> Poupança 284 | 285 | 286 | -------------------------------------------------------------------------------- /Sicoob.Cobranca/DataAnotation/CustomDateTimeWithZoneConverter.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Converters; 2 | 3 | public class CustomDateTimeWithZoneConverter : IsoDateTimeConverter 4 | { 5 | public CustomDateTimeWithZoneConverter() 6 | { 7 | DateTimeFormat = "yyyy-MM-ddTHH:mm:sszzz"; 8 | } 9 | } 10 | 11 | public class CustomDateTimeConverter : IsoDateTimeConverter 12 | { 13 | public CustomDateTimeConverter() 14 | { 15 | DateTimeFormat = "yyyy-MM-dd"; 16 | } 17 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Helpers.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Cobranca; 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO.Compression; 6 | using System.IO; 7 | using Sicoob.Cobranca.Models.Shared; 8 | 9 | public static class Helpers 10 | { 11 | public static IEnumerable ProcessarArquivoMovimentacao(string zipBase64) 12 | { 13 | var bytes = Convert.FromBase64String(zipBase64); 14 | return ProcessarArquivoMovimentacao(bytes); 15 | } 16 | public static IEnumerable ProcessarArquivoMovimentacao(byte[] bytesZip) 17 | { 18 | Stream data = new MemoryStream(bytesZip); 19 | 20 | ZipArchive archive = new ZipArchive(data); 21 | foreach (ZipArchiveEntry entry in archive.Entries) 22 | { 23 | using var sr = new StreamReader(entry.Open()); 24 | var registros = Newtonsoft.Json.JsonConvert.DeserializeObject(sr.ReadToEnd()); 25 | if (registros == null) continue; 26 | foreach (var r in registros) yield return r; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/Shared/Beneficiariofinal.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Cobranca.Models.Shared; 2 | 3 | public class Beneficiariofinal 4 | { 5 | public string? numeroCpfCnpj { get; set; } 6 | public string? nome { get; set; } 7 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/Shared/DadosPagador.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Cobranca.Models.Shared; 2 | 3 | public class DadosPagador 4 | { 5 | public string numeroCpfCnpj { get; set; } 6 | public string nome { get; set; } 7 | public string endereco { get; set; } 8 | public string bairro { get; set; } 9 | public string cidade { get; set; } 10 | public string cep { get; set; } 11 | public string uf { get; set; } 12 | public string[] email { get; set; } 13 | } 14 | -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/Shared/Enum.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Cobranca.Models.Shared; 2 | 3 | 4 | public enum IdentificacaoEmissaoBoleto: int 5 | { 6 | BancoEmite = 1, 7 | ClienteEmite = 2 8 | } 9 | 10 | public enum IdentificacaoDistribuicaoBoleto : int 11 | { 12 | BancoDistribui = 1, 13 | ClienteDistribui = 2 14 | } 15 | 16 | public enum TipoDesconto : int 17 | { 18 | SemDesconto = 0, 19 | ValorFixoAteDataInformada = 1, 20 | PercentualAteDataInformada = 2, 21 | ValorPorAntecipacaoDiaCorrido = 3, 22 | ValorPorAntecipacaoDiaUtil = 4, 23 | PercentualPorAntecipacaoDiaCorrido = 5, 24 | PercentualPorAntecipacaoDiaUtil = 6 25 | } 26 | 27 | public enum TipoJurosMora : int 28 | { 29 | ValorPorDia = 1, 30 | TaxaMensal = 2, 31 | Isento = 3 32 | } 33 | 34 | public enum TipoMulta : int 35 | { 36 | Isento = 0, 37 | ValorFixo = 1, 38 | Percentual = 2 39 | } 40 | 41 | public enum CodigoNegativacao : int 42 | { 43 | NegativarDiasUteis = 2, 44 | NaoNegativar = 3 45 | } 46 | 47 | public enum CodigoProtesto : int 48 | { 49 | ProtestarDiasCorridos = 1, 50 | ProtestarDiasUteis = 2, 51 | NaoProtestar = 3, 52 | } 53 | 54 | public enum CodigoCadastrarPIX : int 55 | { 56 | Padrao = 0, 57 | ComPIX = 1, 58 | SemPIX = 1 59 | } 60 | 61 | public enum Modalidade : int 62 | { 63 | SimplesComRegistro = 1, 64 | CarneDePagamentos = 5, 65 | Indexada = 6, 66 | CartaoDeCredito = 14 67 | } 68 | public struct SituacaoBoleto 69 | { 70 | public const string Liquidado = "Liquidado"; 71 | public const string EmAberto = "Em Aberto"; 72 | public const string Baixado = "Baixado"; 73 | } 74 | 75 | public enum TipoHistorico : int 76 | { 77 | Entrada = 1, 78 | Alteracao = 2, 79 | Prorrogacao = 3, 80 | Terifas = 4, 81 | Protesto = 5, 82 | LiquidacaoBaixa = 6 83 | } 84 | 85 | public enum Tipo 86 | { 87 | Entrada = 1, 88 | Prorrogacao = 2, 89 | A_Vencer = 3, 90 | Vencido = 4, 91 | Liquidacao = 5, 92 | Baixa = 6, 93 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/Shared/Listahistorico.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Sicoob.Cobranca.Models.Shared; 4 | 5 | public class Listahistorico 6 | { 7 | public DateTime? dataHistorico { get; set; } 8 | public int? tipoHistorico { get; set; } 9 | public string? descricaoHistorico { get; set; } 10 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/Shared/Movimentacoes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Sicoob.Cobranca.Models.Shared; 4 | 5 | public class SolicitacaoMovimentacoesCarteira 6 | { 7 | public int numeroContrato { get; set; } 8 | /// 9 | /// 1. Entrada 2. Prorrogação 3. A Vencer 4. Vencido 5. Liquidação 6. Baixa 10 | /// 11 | public int tipoMovimento { get; set; } 12 | public DateTime dataInicial { get; set; } 13 | public DateTime dataFinal { get; set; } 14 | } 15 | 16 | public class ResponseMovimentacao 17 | { 18 | public T resultado { get; set; } 19 | } 20 | 21 | public class MovimentacoesArquivos 22 | { 23 | public int codigoSolicitacao { get; set; } 24 | public int idArquivo { get; set; } 25 | public string nomeArquivo { get; set; } 26 | public MovimentacoesArquivo[]? Movimentacoes { get; set; } 27 | } 28 | 29 | public class MovimentacoesArquivo 30 | { 31 | public string siglaMovimento { get; set; } 32 | public DateTime dataInicioMovimento { get; set; } 33 | public DateTime dataFimMovimento { get; set; } 34 | public int numeroCliente { get; set; } 35 | public int numeroContrato { get; set; } 36 | public int modalidade { get; set; } 37 | public int numeroTitulo { get; set; } 38 | public string seuNumero { get; set; } 39 | public DateTime dataVencimentoTitulo { get; set; } 40 | public decimal valorTitulo { get; set; } 41 | public string codigoBarras { get; set; } 42 | public int numeroContaCorrente { get; set; } 43 | public decimal valorTarifaMovimento { get; set; } 44 | public decimal valorAbatimento { get; set; } 45 | public DateTime dataMovimentoLiquidacao { get; set; } 46 | public DateTime dataLiquidacao { get; set; } 47 | public DateTime dataPrevisaoCredito { get; set; } 48 | public int numeroBancoRecebedor { get; set; } 49 | public int numeroAgenciaRecebedora { get; set; } 50 | public int idTipoOpFinanceira { get; set; } 51 | public string tipoOpFinanceira { get; set; } 52 | public decimal valorDesconto { get; set; } 53 | public decimal valorMora { get; set; } 54 | public decimal valorLiquido { get; set; } 55 | } 56 | -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/Shared/Rateiocredito.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Cobranca.Models.Shared; 2 | 3 | public class Rateiocredito 4 | { 5 | public int numeroBanco { get; set; } 6 | public int numeroAgencia { get; set; } 7 | public int numeroContaCorrente { get; set; } 8 | public bool contaPrincipal { get; set; } 9 | public int codigoTipoValorRateio { get; set; } 10 | public decimal valorRateio { get; set; } 11 | public int codigoTipoCalculoRateio { get; set; } 12 | public string? numeroCpfCnpjTitular { get; set; } 13 | public string? nomeTitular { get; set; } 14 | public int codigoFinalidadeTed { get; set; } 15 | public string? codigoTipoContaDestinoTed { get; set; } 16 | public int quantidadeDiasFloat { get; set; } 17 | public string? dataFloatCredito { get; set; } 18 | } 19 | -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/Shared/RetornoArquivoMovimentacao.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Cobranca.Models.Shared; 2 | 3 | public class RetornoArquivoMovimentacao 4 | { 5 | public string arquivo { get; set; } 6 | public string nomeArquivo { get; set; } 7 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/Shared/RetornoConsultaMovimentacoes.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Cobranca.Models.Shared; 2 | 3 | public class RetornoConsultaMovimentacoes 4 | { 5 | public string quantidadeTotalRegistros { get; set; } 6 | public int quantidadeRegistrosArquivo { get; set; } 7 | public int quantidadeArquivo { get; set; } 8 | public int[] idArquivos { get; set; } 9 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/Shared/RetornoSolicitacaoMovimentacoesCarteira.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Cobranca.Models.Shared; 2 | 3 | public class RetornoSolicitacaoMovimentacoesCarteira 4 | { 5 | public string mensagem { get; set; } 6 | public int codigoSolicitacao { get; set; } 7 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/v2/AlterarDataVencimento.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace Sicoob.Cobranca.Models.v2; 5 | 6 | public class AlterarDataVencimentoRequest : BoletoBase 7 | { 8 | [JsonConverter(typeof(CustomDateTimeWithZoneConverter))] 9 | public DateTime dataVencimento { get; set; } 10 | } 11 | 12 | public class AlterarDataVencimentoResponse 13 | { 14 | public DadosDataVencimento[]? resultado { get; set; } 15 | public ResultadoInfo?[] mensagens { get; set; } 16 | } 17 | public class DadosDataVencimento 18 | { 19 | public ResultadoInfo? status { get; set; } 20 | public AlterarDataVencimentoRequest? boleto { get; set; } 21 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/v2/BaixarBoleto.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Cobranca.Models.v2; 2 | 3 | public class BaixarBoletoRequest : BoletoBase 4 | { 5 | public string seuNumero { get; set; } 6 | } 7 | 8 | public class BaixarBoletoResponse 9 | { 10 | public DadosBaixa[]? resultado { get; set; } 11 | public ResultadoInfo? mensagens { get; set; } 12 | } 13 | public class DadosBaixa 14 | { 15 | public ResultadoInfo? status { get; set; } 16 | public BaixarBoletoRequest? boleto { get; set; } 17 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/v2/BoletoBase.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Sicoob.Cobranca.Models.v2; 4 | 5 | public abstract class BoletoBase 6 | { 7 | public int numeroContrato { get; set; } 8 | public int modalidade { get; set; } = 1; // Simples com Registro 9 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 10 | public int? nossoNumero { get; set; } 11 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/v2/ConsultaBoleto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Sicoob.Cobranca.Models.Shared; 3 | 4 | namespace Sicoob.Cobranca.Models.v2; 5 | 6 | public class ConsultaBoletoRequest 7 | { 8 | public int numeroContrato { get; set; } 9 | public int modalidade { get; set; } = 1; // Só tem a opção de `1` 10 | public int? nossoNumero { get; set; } 11 | public string? linhaDigitavel { get; set; } 12 | public string? codigoBarras { get; set; } 13 | public bool? gerarPdf { get; set; } 14 | } 15 | public class ConsultaBoletosPagadorRequest 16 | { 17 | public int numeroContrato { get; set; } 18 | /// 19 | /// 1: Em Aberto 20 | /// 2: Baixado 21 | /// 3: Liquidado 22 | /// 23 | public int? codigoSituacao { get; set; } 24 | 25 | public string? dataInicio { get; set; } 26 | public string? dataFim { get; set; } 27 | } 28 | 29 | public class ConsultaBoletoResponse 30 | { 31 | public DadosBoleto? resultado { get; set; } 32 | } 33 | public class ConsultaBoletosPagadorResponse 34 | { 35 | public DadosBoleto[]? resultado { get; set; } 36 | } 37 | public class DadosBoleto 38 | { 39 | public int numeroContrato { get; set; } 40 | public int modalidade { get; set; } 41 | public int numeroContaCorrente { get; set; } 42 | public string? especieDocumento { get; set; } 43 | public DateTime dataEmissao { get; set; } 44 | public int nossoNumero { get; set; } 45 | public string? seuNumero { get; set; } 46 | public string? identificacaoBoletoEmpresa { get; set; } 47 | public string? codigoBarras { get; set; } 48 | public string? linhaDigitavel { get; set; } 49 | public int identificacaoEmissaoBoleto { get; set; } 50 | public int identificacaoDistribuicaoBoleto { get; set; } 51 | public decimal valor { get; set; } 52 | public DateTime dataVencimento { get; set; } 53 | public DateTime dataLimitePagamento { get; set; } 54 | public decimal valorAbatimento { get; set; } 55 | public string tipoDesconto { get; set; } 56 | public DateTime dataPrimeiroDesconto { get; set; } 57 | public decimal valorPrimeiroDesconto { get; set; } 58 | public DateTime dataSegundoDesconto { get; set; } 59 | public decimal valorSegundoDesconto { get; set; } 60 | public DateTime dataTerceiroDesconto { get; set; } 61 | public decimal valorTerceiroDesconto { get; set; } 62 | public int tipoMulta { get; set; } 63 | public DateTime dataMulta { get; set; } 64 | public decimal valorMulta { get; set; } 65 | public int tipoJurosMora { get; set; } 66 | public DateTime dataJurosMora { get; set; } 67 | public decimal valorJurosMora { get; set; } 68 | public int numeroParcela { get; set; } 69 | public bool aceite { get; set; } 70 | public int codigoNegativacao { get; set; } 71 | public int numeroDiasNegativacao { get; set; } 72 | public int codigoProtesto { get; set; } 73 | public int numeroDiasProtesto { get; set; } 74 | public int quantidadeDiasFloat { get; set; } 75 | public DadosPagador? pagador { get; set; } 76 | public Beneficiariofinal? beneficiarioFinal { get; set; } 77 | public Mensagensinstrucao? mensagensInstrucao { get; set; } 78 | public Listahistorico[]? listaHistorico { get; set; } 79 | public string? situacaoBoleto { get; set; } 80 | public Rateiocredito[]? rateioCreditos { get; set; } 81 | public string? pdfBoleto { get; set; } 82 | public string? qrCode { get; set; } 83 | } 84 | 85 | public class Mensagensinstrucao 86 | { 87 | public int tipoInstrucao { get; set; } 88 | public string[] mensagens { get; set; } 89 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/v2/IncluirBoletos.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | using Sicoob.Cobranca.Models.Shared; 4 | 5 | namespace Sicoob.Cobranca.Models.v2; 6 | 7 | public class IncluirBoletosRequest : BoletoBase 8 | { 9 | public int numeroContaCorrente { get; set; } 10 | public string especieDocumento { get; set; } = "DM"; // Duplicata Mercantil, ver lista 11 | 12 | [JsonConverter(typeof(CustomDateTimeWithZoneConverter))] 13 | public DateTime dataEmissao { get; set; } 14 | public string seuNumero { get; set; } 15 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 16 | public string identificacaoBoletoEmpresa { get; set; } 17 | public int identificacaoEmissaoBoleto { get; set; } 18 | public int identificacaoDistribuicaoBoleto { get; set; } 19 | public decimal valor { get; set; } 20 | [JsonConverter(typeof(CustomDateTimeWithZoneConverter))] 21 | public DateTime dataVencimento { get; set; } 22 | [JsonConverter(typeof(CustomDateTimeWithZoneConverter))] 23 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 24 | public DateTime? dataLimitePagamento { get; set; } 25 | public int valorAbatimento { get; set; } 26 | public int tipoDesconto { get; set; } 27 | [JsonConverter(typeof(CustomDateTimeWithZoneConverter))] 28 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 29 | public DateTime? dataPrimeiroDesconto { get; set; } 30 | public decimal valorPrimeiroDesconto { get; set; } 31 | [JsonConverter(typeof(CustomDateTimeWithZoneConverter))] 32 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 33 | public DateTime? dataSegundoDesconto { get; set; } 34 | public decimal valorSegundoDesconto { get; set; } 35 | [JsonConverter(typeof(CustomDateTimeWithZoneConverter))] 36 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 37 | public DateTime? dataTerceiroDesconto { get; set; } 38 | public decimal valorTerceiroDesconto { get; set; } 39 | public int tipoMulta { get; set; } 40 | [JsonConverter(typeof(CustomDateTimeWithZoneConverter))] 41 | public DateTime dataMulta { get; set; } 42 | public decimal valorMulta { get; set; } 43 | public int tipoJurosMora { get; set; } 44 | [JsonConverter(typeof(CustomDateTimeWithZoneConverter))] 45 | public DateTime dataJurosMora { get; set; } 46 | public decimal valorJurosMora { get; set; } 47 | public int numeroParcela { get; set; } 48 | public bool aceite { get; set; } 49 | public int codigoNegativacao { get; set; } 50 | public int numeroDiasNegativacao { get; set; } 51 | public int codigoProtesto { get; set; } 52 | public int numeroDiasProtesto { get; set; } 53 | public DadosPagador pagador { get; set; } 54 | public Beneficiariofinal beneficiarioFinal { get; set; } 55 | public Mensagensinstrucao mensagensInstrucao { get; set; } 56 | public bool gerarPdf { get; set; } 57 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 58 | public Rateiocredito?[] rateioCreditos { get; set; } 59 | /// 60 | /// 0: Padrão, 1: Com PIX, 2: Sem PIX 61 | /// 62 | public int codigoCadastrarPIX { get; set; } 63 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 64 | public int? numeroContratoCobranca { get; set; } 65 | } 66 | 67 | public class IncluirBoletosResponse 68 | { 69 | public DadosInclusao[]? resultado { get; set; } 70 | } 71 | public class DadosInclusao 72 | { 73 | public ResultadoInfo? status { get; set; } 74 | public DadosBoleto? boleto { get; set; } 75 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/v2/ProtestarBoleto.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace Sicoob.Cobranca.Models.v2; 4 | 5 | public class ProtestarBoletoRequest: BoletoBase 6 | { 7 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 8 | public int? numeroContratoCobranca { get; set; } 9 | } 10 | 11 | public class ProtestarBoletoResponse 12 | { 13 | public DadosProtestar[]? resultado { get; set; } 14 | public ResultadoInfo[]? mensagens { get; set; } 15 | } 16 | public class DadosProtestar 17 | { 18 | public ResultadoInfo? status { get; set; } 19 | public ProtestarBoletoRequest? boleto { get; set; } 20 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/v2/ResultadoInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Cobranca.Models.v2; 2 | 3 | public class ResultadoInfo 4 | { 5 | public int codigo { get; set; } 6 | public string mensagem { get; set; } = string.Empty; 7 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/v3/AlterarBoletoRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | 5 | namespace Sicoob.Cobranca.Models.v3; 6 | 7 | public class AlterarBoletoRequest 8 | { 9 | public long numeroCliente { get; set; } 10 | public int codigoModalidade { get; set; } 11 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 12 | public EspecieDocumento? especieDocumento { get; set; } 13 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 14 | public SeuNumero? seuNumero { get; set; } 15 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 16 | public Desconto? desconto { get; set; } 17 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 18 | public Abatimento? abatimento { get; set; } 19 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 20 | public Multa? multa { get; set; } 21 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 22 | public JurosMora? jurosMora { get; set; } 23 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 24 | public RateioCredito? rateioCredito { get; set; } 25 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 26 | public Pix? pix { get; set; } 27 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 28 | public ProrrogacaoVencimento? prorrogacaoVencimento { get; set; } 29 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 30 | public ProrrogacaoLimitePagamento? prorrogacaoLimitePagamento { get; set; } 31 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 32 | public ValorNominal? valorNominal { get; set; } 33 | } 34 | 35 | public class EspecieDocumento 36 | { 37 | public string codigoEspecieDocumento { get; set; } 38 | } 39 | 40 | public class SeuNumero 41 | { 42 | public string seuNumero { get; set; } 43 | public string identificacaoBoletoEmpresa { get; set; } 44 | } 45 | 46 | public class Desconto 47 | { 48 | public int tipoDesconto { get; set; } 49 | public DateTime dataPrimeiroDesconto { get; set; } 50 | public decimal valorPrimeiroDesconto { get; set; } 51 | public DateTime? dataSegundoDesconto { get; set; } 52 | public decimal? valorSegundoDesconto { get; set; } 53 | public DateTime? dataTerceiroDesconto { get; set; } 54 | public decimal? valorTerceiroDesconto { get; set; } 55 | } 56 | 57 | public class Abatimento 58 | { 59 | public decimal valorAbatimento { get; set; } 60 | } 61 | 62 | public class Multa 63 | { 64 | public int tipoMulta { get; set; } 65 | public DateTime dataMulta { get; set; } 66 | public decimal valorMulta { get; set; } 67 | } 68 | 69 | public class JurosMora 70 | { 71 | public int tipoJurosMora { get; set; } 72 | public DateTime dataJurosMora { get; set; } 73 | public decimal valorJurosMora { get; set; } 74 | } 75 | 76 | public class RateioCredito 77 | { 78 | public int tipoOperacao { get; set; } 79 | public List rateioCreditos { get; set; } 80 | } 81 | 82 | public class RateioCreditoDetalhe 83 | { 84 | public int numeroBanco { get; set; } 85 | public int numeroAgencia { get; set; } 86 | public int numeroContaCorrente { get; set; } 87 | public bool contaPrincipal { get; set; } 88 | public int codigoTipoValorRateio { get; set; } 89 | public decimal valorRateio { get; set; } 90 | public int codigoTipoCalculoRateio { get; set; } 91 | public string numeroCpfCnpjTitular { get; set; } 92 | public string nomeTitular { get; set; } 93 | public int codigoFinalidadeTed { get; set; } 94 | public string codigoTipoContaDestinoTed { get; set; } 95 | public int quantidadeDiasFloat { get; set; } 96 | public DateTime dataFloatCredito { get; set; } 97 | } 98 | 99 | public class Pix 100 | { 101 | public bool utilizarPix { get; set; } 102 | } 103 | 104 | public class ProrrogacaoVencimento 105 | { 106 | public DateTime dataVencimento { get; set; } 107 | } 108 | 109 | public class ProrrogacaoLimitePagamento 110 | { 111 | public DateTime dataLimitePagamento { get; set; } 112 | } 113 | 114 | public class ValorNominal 115 | { 116 | public decimal valor { get; set; } 117 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/v3/BaixarBoletoRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Cobranca.Models.v3; 2 | 3 | public class BaixarBoletoRequest 4 | { 5 | public long numeroCliente { get; set; } 6 | public int codigoModalidade { get; set; } 7 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/v3/ConsultaBoletoRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Cobranca.Models.v3; 2 | 3 | using System; 4 | using Sicoob.Cobranca.Models.Shared; 5 | using Sicoob.Cobranca.Models.v2; 6 | 7 | public class ConsultaBoletoRequest 8 | { 9 | public int numeroCliente { get; set; } 10 | public int codigoModalidade { get; set; } = 1; // Só tem a opção de `1` 11 | public int? nossoNumero { get; set; } 12 | public string? linhaDigitavel { get; set; } 13 | public string? codigoBarras { get; set; } 14 | public bool? gerarPdf { get; set; } 15 | } 16 | 17 | public class ConsultaBoletoPagadorRequest 18 | { 19 | public int numeroCliente { get; set; } 20 | /// 21 | /// 1: Em Aberto 22 | /// 2: Baixado 23 | /// 3: Liquidado 24 | /// 25 | public int? codigoSituação { get; set; } 26 | 27 | public string? dataInicio { get; set; } 28 | public string? dataFim { get; set; } 29 | } 30 | 31 | public class IncluirBoletosResponse 32 | { 33 | public DadosBoleto? resultado { get; set; } 34 | } 35 | 36 | public class ConsultaBoletoResponse 37 | { 38 | public DadosBoleto? resultado { get; set; } 39 | } 40 | 41 | public class ConsultaBoletosPagadorResponse 42 | { 43 | public DadosBoleto[]? resultado { get; set; } 44 | } 45 | 46 | public class DadosBoleto 47 | { 48 | public int numeroCliente { get; set; } 49 | public int codigoModalidade { get; set; } 50 | public int numeroContaCorrente { get; set; } 51 | public string? especieDocumento { get; set; } 52 | public DateTime dataEmissao { get; set; } 53 | public int nossoNumero { get; set; } 54 | public string? seuNumero { get; set; } 55 | public string? identificacaoBoletoEmpresa { get; set; } 56 | public string? codigoBarras { get; set; } 57 | public string? linhaDigitavel { get; set; } 58 | public decimal valor { get; set; } 59 | public DateTime dataVencimento { get; set; } 60 | public DateTime dataLimitePagamento { get; set; } 61 | public decimal valorAbatimento { get; set; } 62 | public int tipoDesconto { get; set; } 63 | public DateTime dataPrimeiroDesconto { get; set; } 64 | public decimal valorPrimeiroDesconto { get; set; } 65 | public DateTime dataSegundoDesconto { get; set; } 66 | public decimal valorSegundoDesconto { get; set; } 67 | public DateTime dataTerceiroDesconto { get; set; } 68 | public decimal valorTerceiroDesconto { get; set; } 69 | public int tipoMulta { get; set; } 70 | public DateTime dataMulta { get; set; } 71 | public decimal valorMulta { get; set; } 72 | public int tipoJurosMora { get; set; } 73 | public DateTime dataJurosMora { get; set; } 74 | public decimal valorJurosMora { get; set; } 75 | public int numeroParcela { get; set; } 76 | public bool aceite { get; set; } 77 | public int codigoNegativacao { get; set; } 78 | public int codigoProtesto { get; set; } 79 | public int numeroDiasProtesto { get; set; } 80 | public int quantidadeDiasFloat { get; set; } 81 | public DadosPagador? pagador { get; set; } 82 | public Beneficiariofinal? beneficiarioFinal { get; set; } 83 | public string[]? mensagensInstrucao { get; set; } 84 | public Listahistorico[]? listaHistorico { get; set; } 85 | public string? situacaoBoleto { get; set; } 86 | public Rateiocredito[]? rateioCreditos { get; set; } 87 | public string? pdfBoleto { get; set; } 88 | public string? qrCode { get; set; } 89 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/v3/IncluirBoleto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | using Sicoob.Cobranca.Models.Shared; 5 | 6 | namespace Sicoob.Cobranca.Models.v3; 7 | 8 | public class IncluirBoletoRequest 9 | { 10 | public long numeroCliente { get; set; } 11 | public int codigoModalidade { get; set; } 12 | public int numeroContaCorrente { get; set; } 13 | public string codigoEspecieDocumento { get; set; } = "DM"; // Duplicata Mercantil, ver lista 14 | [JsonConverter(typeof(CustomDateTimeConverter))] 15 | public DateTime? dataEmissao { get; set; } 16 | public long nossoNumero { get; set; } 17 | public string seuNumero { get; set; } 18 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 19 | public string? identificacaoBoletoEmpresa { get; set; } 20 | public int identificacaoEmissaoBoleto { get; set; } 21 | public int identificacaoDistribuicaoBoleto { get; set; } 22 | public decimal valor { get; set; } 23 | [JsonConverter(typeof(CustomDateTimeConverter))] 24 | public DateTime dataVencimento { get; set; } 25 | [JsonConverter(typeof(CustomDateTimeConverter))] 26 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 27 | public DateTime? dataLimitePagamento { get; set; } 28 | public decimal valorAbatimento { get; set; } 29 | public int tipoDesconto { get; set; } 30 | [JsonConverter(typeof(CustomDateTimeConverter))] 31 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 32 | public DateTime dataPrimeiroDesconto { get; set; } 33 | public decimal valorPrimeiroDesconto { get; set; } 34 | [JsonConverter(typeof(CustomDateTimeConverter))] 35 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 36 | public DateTime dataSegundoDesconto { get; set; } 37 | public decimal valorSegundoDesconto { get; set; } 38 | [JsonConverter(typeof(CustomDateTimeConverter))] 39 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 40 | public DateTime dataTerceiroDesconto { get; set; } 41 | public decimal valorTerceiroDesconto { get; set; } 42 | public int tipoMulta { get; set; } 43 | [JsonConverter(typeof(CustomDateTimeConverter))] 44 | public DateTime dataMulta { get; set; } 45 | public decimal valorMulta { get; set; } 46 | public int tipoJurosMora { get; set; } 47 | [JsonConverter(typeof(CustomDateTimeConverter))] 48 | public DateTime dataJurosMora { get; set; } 49 | public decimal valorJurosMora { get; set; } 50 | public int numeroParcela { get; set; } 51 | public bool aceite { get; set; } 52 | public int codigoNegativacao { get; set; } 53 | public int numeroDiasNegativacao { get; set; } 54 | public int codigoProtesto { get; set; } 55 | public int numeroDiasProtesto { get; set; } 56 | public DadosPagador pagador { get; set; } 57 | public Beneficiariofinal beneficiarioFinal { get; set; } 58 | public string[] mensagensInstrucao { get; set; } 59 | public bool gerarPdf { get; set; } 60 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 61 | public Rateiocredito[] rateioCreditos { get; set; } 62 | /// 63 | /// 0: Padrão, 1: Com PIX, 2: Sem PIX 64 | /// 65 | public int codigoCadastrarPIX { get; set; } 66 | [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 67 | public int? numeroContratoCobranca { get; set; } 68 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/v3/MovimentacaoRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Sicoob.Cobranca.Models.v3; 4 | 5 | public class MovimentacaoRequest 6 | { 7 | public int numeroCliente { get; set; } 8 | /// 9 | /// 1. Entrada 2. Prorrogação 3. A Vencer 4. Vencido 5. Liquidação 6. Baixa 10 | /// 11 | public int tipoMovimento { get; set; } 12 | public DateTime dataInicial { get; set; } 13 | public DateTime dataFinal { get; set; } 14 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Models/v3/ProtestoRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Cobranca.Models.v3; 2 | 3 | public class ProtestoRequest 4 | { 5 | public long numeroCliente { get; set; } 6 | public int codigoModalidade { get; set; } 7 | } -------------------------------------------------------------------------------- /Sicoob.Cobranca/Sicoob.Cobranca.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 12.0 6 | enable 7 | disable 8 | 1.0.0 9 | RafaelEstevam.Net 10 | SHARP SISTEMAS LTDA 11 | Sicoob Cobrança for C# 12 | C# implementation for Billing with SICOOB 13 | MIT 14 | https://github.com/SharpSistemas/SicoobAPI 15 | https://github.com/SharpSistemas/SicoobAPI 16 | git 17 | Simple API client 18 | 19 | See examples and documentation on the GitHub page 20 | https://github.com/SharpSistemas/SicoobAPI 21 | 22 | README.md 23 | 24 | 25 | 26 | 27 | True 28 | \ 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Sicoob.Cobranca/SicoobCobrancaV2.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Cobranca; 7 | 8 | using Sicoob.Cobranca.Models.Shared; 9 | using Sicoob.Cobranca.Models.v2; 10 | using Sicoob.Shared.Models.Acesso; 11 | using Sicoob.Shared.Models.Geral; 12 | using Simple.API; 13 | using System; 14 | using System.Collections.Generic; 15 | using System.IO; 16 | using System.Linq; 17 | using System.Net.Http; 18 | using System.Threading.Tasks; 19 | 20 | /// 21 | /// Classe para comunicação com as APIs de Cobrança do Sicoob 22 | /// 23 | public sealed class SicoobCobrancaV2 : Shared.Sicoob 24 | { 25 | // Documentações 26 | // > APIs tipo "Swagger": 27 | // https://developers.sicoob.com.br/#!/apis 28 | // > Link que o Suporte do Sicoob enviou 29 | // https://documenter.getpostman.com/view/20565799/Uzs6yNhe#6447c293-f67b-44ba-b7be-41f5c3de978d 30 | 31 | private readonly int numeroContrato; 32 | private ClientInfo clientApi; 33 | public Shared.Models.ConfiguracaoAPI ConfigApi { get; } 34 | public string? PastaCopiaMovimentacoes { get; set; } 35 | public delegate void UpdateToken(Shared.Models.ConfiguracaoToken token); 36 | public event UpdateToken UpdateTokenEvent; 37 | 38 | public SicoobCobrancaV2(Shared.Models.ConfiguracaoAPI configApi, int NumeroContrato, System.Security.Cryptography.X509Certificates.X509Certificate2? certificado = null) 39 | : base(configApi, certificado) 40 | { 41 | numeroContrato = NumeroContrato; 42 | ConfigApi = configApi; 43 | clientApi = new ClientInfo(ConfigApi.UrlApi); 44 | } 45 | 46 | protected override void setupClients(HttpClientHandler handler) 47 | { 48 | clientApi = new ClientInfo(ConfigApi.UrlApi, handler); 49 | clientApi.SetHeader("client_id", ConfigApi.ClientId); 50 | 51 | if (ConfigApi.Token is not null) 52 | clientApi.SetAuthorizationBearer(ConfigApi.Token.Token); 53 | } 54 | protected override void atualizaClients(TokenResponse token) 55 | { 56 | ConfigApi.Token = new Shared.Models.ConfiguracaoToken() 57 | { 58 | ExpiresAtUTC = DateTime.UtcNow.AddSeconds(token.expires_in), 59 | Token = token.access_token 60 | }; 61 | //Notificar quando o token foi atualizado 62 | if (UpdateTokenEvent is not null) 63 | UpdateTokenEvent(ConfigApi.Token); 64 | 65 | clientApi.SetAuthorizationBearer(token.access_token); 66 | } 67 | 68 | /* Boletos */ 69 | 70 | /// 71 | /// Consulta boleto utilizando um dos três métodos de busca 72 | /// 73 | /// 74 | /// Número identificador do boleto no Sisbr. Caso seja infomado, não é necessário infomar a linha digitável ou código de barras 75 | /// Número da linha digitável do boleto com 47 posições. Caso seja informado, não é necessário informar o nosso número ou código de barras 76 | /// Número de código de barras do boleto com 44 posições.Caso seja informado, não é necessário informar o nosso número ou linha digitável 77 | /// Boleto buscado 78 | public async Task ConsultarBoleto(int? nossoNumero = null, string? linhaDigitavel = null, string? codigoBarras = null, int modalidade = (int)Modalidade.SimplesComRegistro) 79 | { 80 | var consulta = new ConsultaBoletoRequest() 81 | { 82 | modalidade = modalidade, 83 | numeroContrato = numeroContrato, 84 | nossoNumero = nossoNumero, 85 | linhaDigitavel = linhaDigitavel, 86 | codigoBarras = codigoBarras 87 | }; 88 | return await ExecutaChamadaAsync(() => clientApi.GetAsync(ConfigApi.UrlApi + "cobranca-bancaria/v2/boletos", consulta)); 89 | } 90 | 91 | /// 92 | /// Consulta boletos de um Pagador 93 | /// 94 | /// CPF/CNPJ do Pagador 95 | /// Número que identifica o contrato do beneficiário no Sisbr 96 | /// Código da Situação do Boleto. 1: Em aberto, 2: Baixado, 3: Liquidado 97 | /// Data de Vencimento Inicial 98 | /// Data de Vencimento Final 99 | /// Boletos do Pagador 100 | public async Task ConsultarBoletosPagador(string numeroCpfCnpj, int? codigoSituacao = null, DateTime? dataVencimentoInicio = null, DateTime? dataVencimentoFim = null) 101 | { 102 | var consulta = new ConsultaBoletosPagadorRequest() 103 | { 104 | numeroContrato = numeroContrato, 105 | codigoSituacao = codigoSituacao, 106 | dataInicio = dataVencimentoInicio?.ToString("yyyy-MM-dd"), 107 | dataFim = dataVencimentoFim?.ToString("yyyy-MM-dd") 108 | }; 109 | return await ExecutaChamadaAsync(() => clientApi.GetAsync(ConfigApi.UrlApi + "cobranca-bancaria/v2/boletos/pagadores/" + numeroCpfCnpj, consulta)); 110 | } 111 | 112 | public async Task ConsultarSegundaViaBoleto(int modalidade, int? nossoNumero = null, string? linhaDigitavel = null, string? codigoBarras = null, bool gerarPdf = false) 113 | { 114 | var consulta = new ConsultaBoletoRequest() 115 | { 116 | modalidade = modalidade, 117 | numeroContrato = numeroContrato, 118 | nossoNumero = nossoNumero, 119 | linhaDigitavel = linhaDigitavel, 120 | codigoBarras = codigoBarras, 121 | gerarPdf = gerarPdf 122 | }; 123 | return await ExecutaChamadaAsync(() => clientApi.GetAsync(ConfigApi.UrlApi + "cobranca-bancaria/v2/boletos/segunda-via", consulta)); 124 | } 125 | 126 | public async Task IncluirBoletos(IncluirBoletosRequest[] boletos) 127 | { 128 | return await ExecutaChamadaAsync(() => clientApi.PostAsync(ConfigApi.UrlApi + "cobranca-bancaria/v2/boletos", boletos)); 129 | } 130 | 131 | public async Task BaixarBoletos(BaixarBoletoRequest[] boletos) 132 | { 133 | return await ExecutaChamadaAsync(() => clientApi.PatchAsync(ConfigApi.UrlApi + "cobranca-bancaria/v2/boletos/baixa", boletos)); 134 | } 135 | 136 | public async Task ProtestarBoletos(ProtestarBoletoRequest[] boletos) 137 | { 138 | return await ExecutaChamadaAsync(() => clientApi.PostAsync(ConfigApi.UrlApi + "cobranca-bancaria/v2/boletos/protestos", boletos)); 139 | } 140 | 141 | public async Task AlterarDataVencimento(AlterarDataVencimentoRequest[] boletos) 142 | { 143 | return await ExecutaChamadaAsync(() => clientApi.PatchAsync(ConfigApi.UrlApi + "cobranca-bancaria/v2/boletos/prorrogacoes/data-vencimento", boletos)); 144 | } 145 | 146 | /* Movimentação */ 147 | public async Task SolicitarMovimentacao(Tipo tipoMovimento, DateTime data) 148 | { 149 | var di = data.Date; 150 | var df = data.Date.AddDays(1).AddSeconds(-1); 151 | return await SolicitarMovimentacao(tipoMovimento, di, df); 152 | } 153 | public async Task SolicitarMovimentacao(Tipo tipoMovimento, DateTime dataInicial, DateTime dataFinal) 154 | => await SolicitarMovimentacao(new SolicitacaoMovimentacoesCarteira() { numeroContrato = numeroContrato, tipoMovimento = (int)tipoMovimento, dataInicial = dataInicial, dataFinal = dataFinal }); 155 | private async Task SolicitarMovimentacao(SolicitacaoMovimentacoesCarteira solicitacao) 156 | { 157 | var retorno = await ExecutaChamadaAsync(() => clientApi.PostAsync>(ConfigApi.UrlApi + "cobranca-bancaria/v2/boletos/solicitacoes/movimentacao", solicitacao)); 158 | return retorno.resultado; 159 | } 160 | public async Task ConsultarSituacaoSolicitacao(int codigoSolicitacao) 161 | { 162 | await VerificaAtualizaCredenciaisAsync(); 163 | var result = await clientApi.GetAsync>( ConfigApi.UrlApi + "cobranca-bancaria/v2/boletos/solicitacoes/movimentacao", new { numeroContrato, codigoSolicitacao }); 164 | 165 | if (result.IsSuccessStatusCode) return result.Data.resultado; 166 | 167 | // "{\"mensagens\":[{\"mensagem\":\"Solicitação ainda em processamento.\",\"codigo\":\"5004\"}]}" 168 | if (result.TryParseErrorResponseData(out ErroRequisicao err)) 169 | { 170 | if (err.mensagens == null) { } 171 | 172 | if (err.mensagens.Any(o => o.codigo == 5004)) return null; 173 | 174 | throw new ErroRequisicaoException(err); 175 | } 176 | result.EnsureSuccessStatusCode(); // Erro comum 177 | return null; // a linha de cima vai arremessar o erro padrão 178 | } 179 | internal async Task DownloadArquivoMovimentacao(int codigoSolicitacao, int idArquivo) 180 | { 181 | var retorno = await ExecutaChamadaAsync(() => clientApi.GetAsync>(ConfigApi.UrlApi + "/cobranca-bancaria/v2/boletos/movimentacao-download", new { numeroContrato, codigoSolicitacao, idArquivo })); 182 | return retorno.resultado; 183 | } 184 | public async Task BaixarMovimentacoes(int codigoSolicitacao, int[] arquivos) 185 | { 186 | var lst = new List(); 187 | foreach (var idArquivo in arquivos) 188 | { 189 | var retorno = await DownloadArquivoMovimentacao(codigoSolicitacao, idArquivo); 190 | 191 | var bytesZip = Convert.FromBase64String(retorno.arquivo); 192 | salvarCopiaMovimentacao(bytesZip, retorno.nomeArquivo); 193 | 194 | var registros = Helpers.ProcessarArquivoMovimentacao(bytesZip); 195 | lst.Add(new MovimentacoesArquivos 196 | { 197 | codigoSolicitacao = codigoSolicitacao, 198 | idArquivo = idArquivo, 199 | nomeArquivo = retorno.nomeArquivo, 200 | Movimentacoes = registros.ToArray(), 201 | }); 202 | } 203 | return lst.ToArray(); 204 | } 205 | 206 | private void salvarCopiaMovimentacao(byte[] bytesZip, string nomeArquivo) 207 | { 208 | if (PastaCopiaMovimentacoes == null) return; 209 | if (!Directory.Exists(PastaCopiaMovimentacoes)) Directory.CreateDirectory(PastaCopiaMovimentacoes); 210 | 211 | var path = Path.Combine(PastaCopiaMovimentacoes, nomeArquivo); 212 | if (File.Exists(path)) return; 213 | 214 | File.WriteAllBytes(path, bytesZip); 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /Sicoob.Cobranca/SicoobCobrancaV3.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Cobranca; 7 | 8 | using Sicoob.Cobranca.Models.Shared; 9 | using Sicoob.Cobranca.Models.v3; 10 | using Sicoob.Shared.Models; 11 | using Sicoob.Shared.Models.Acesso; 12 | using Sicoob.Shared.Models.Geral; 13 | using Simple.API; 14 | using System; 15 | using System.Collections.Generic; 16 | using System.IO; 17 | using System.Linq; 18 | using System.Net.Http; 19 | using System.Threading.Tasks; 20 | 21 | /// 22 | /// Classe para comunicação com as APIs de Cobrança do Sicoob 23 | /// 24 | public sealed class SicoobCobrancaV3 : Shared.Sicoob 25 | { 26 | // Documentações 27 | // > APIs tipo "Swagger": 28 | // https://developers.sicoob.com.br/#!/apis 29 | // > Link que o Suporte do Sicoob enviou 30 | // https://documenter.getpostman.com/view/20565799/Uzs6yNhe#6447c293-f67b-44ba-b7be-41f5c3de978d 31 | 32 | private readonly int numeroContrato; 33 | private ClientInfo clientApi; 34 | private ConfiguracaoAPI ConfigApi { get; } 35 | public string? PastaCopiaMovimentacoes { get; set; } 36 | public delegate void UpdateToken(ConfiguracaoToken token); 37 | public event UpdateToken? UpdateTokenEvent; 38 | 39 | public SicoobCobrancaV3(ConfiguracaoAPI configApi, int nroContrato, System.Security.Cryptography.X509Certificates.X509Certificate2? certificado = null) 40 | : base(configApi, certificado) 41 | { 42 | numeroContrato = nroContrato; 43 | ConfigApi = configApi; 44 | clientApi = new ClientInfo(ConfigApi.UrlApi); 45 | } 46 | 47 | protected override void setupClients(HttpClientHandler handler) 48 | { 49 | clientApi = new ClientInfo(ConfigApi.UrlApi, handler); 50 | clientApi.SetHeader("client_id", ConfigApi.ClientId); 51 | 52 | if (ConfigApi.Token is not null) 53 | clientApi.SetAuthorizationBearer(ConfigApi.Token.Token); 54 | } 55 | protected override void atualizaClients(TokenResponse token) 56 | { 57 | ConfigApi.Token = new ConfiguracaoToken() 58 | { 59 | ExpiresAtUTC = DateTime.UtcNow.AddSeconds(token.expires_in), 60 | Token = token.access_token 61 | }; 62 | //Notificar quando o token foi atualizado 63 | if (UpdateTokenEvent is not null) 64 | UpdateTokenEvent(ConfigApi.Token); 65 | 66 | clientApi.SetAuthorizationBearer(token.access_token); 67 | } 68 | 69 | /* Boletos */ 70 | 71 | /// 72 | /// Consulta boleto utilizando um dos três métodos de busca 73 | /// 74 | /// 75 | /// Número identificador do boleto no Sisbr. Caso seja infomado, não é necessário infomar a linha digitável ou código de barras 76 | /// Número da linha digitável do boleto com 47 posições. Caso seja informado, não é necessário informar o nosso número ou código de barras 77 | /// Número de código de barras do boleto com 44 posições.Caso seja informado, não é necessário informar o nosso número ou linha digitável 78 | /// Boleto buscado 79 | public async Task ConsultarBoleto(int? nossoNumero = null, string? linhaDigitavel = null, string? codigoBarras = null, int modalidade = (int)Modalidade.SimplesComRegistro) 80 | { 81 | var consulta = new ConsultaBoletoRequest() 82 | { 83 | codigoModalidade = modalidade, 84 | numeroCliente = numeroContrato, 85 | nossoNumero = nossoNumero, 86 | linhaDigitavel = linhaDigitavel, 87 | codigoBarras = codigoBarras 88 | }; 89 | return await ExecutaChamadaAsync(() => clientApi.GetAsync(ConfigApi.UrlApi + "cobranca-bancaria/v3/boletos", consulta)); 90 | } 91 | 92 | /// 93 | /// Consulta boletos de um Pagador 94 | /// 95 | /// CPF/CNPJ do Pagador 96 | /// Código da Situação do Boleto. 1: Em aberto, 2: Baixado, 3: Liquidado 97 | /// Data de Vencimento Inicial 98 | /// Data de Vencimento Final 99 | /// Boletos do Pagador 100 | public async Task ConsultarBoletosPagador(string numeroCpfCnpj, int? codigoSituacao = null, DateTime? dataVencimentoInicio = null, DateTime? dataVencimentoFim = null) 101 | { 102 | var consulta = new ConsultaBoletoPagadorRequest() 103 | { 104 | numeroCliente = numeroContrato, 105 | codigoSituação = codigoSituacao, 106 | dataInicio = dataVencimentoInicio?.ToString("yyyy-MM-dd"), 107 | dataFim = dataVencimentoFim?.ToString("yyyy-MM-dd") 108 | }; 109 | return await ExecutaChamadaAsync(() => clientApi.GetAsync(ConfigApi.UrlApi + "cobranca-bancaria/v3/boletos/pagadores/" + numeroCpfCnpj, consulta)); 110 | } 111 | 112 | public async Task ConsultarSegundaViaBoleto(int modalidade, int? nossoNumero = null, string? linhaDigitavel = null, string? codigoBarras = null, bool gerarPdf = false) 113 | { 114 | var consulta = new ConsultaBoletoRequest() 115 | { 116 | codigoModalidade = modalidade, 117 | numeroCliente = numeroContrato, 118 | nossoNumero = nossoNumero, 119 | linhaDigitavel = linhaDigitavel, 120 | codigoBarras = codigoBarras, 121 | gerarPdf = gerarPdf 122 | }; 123 | return await ExecutaChamadaAsync(() => clientApi.GetAsync(ConfigApi.UrlApi + "cobranca-bancaria/v3/boletos/segunda-via", consulta)); 124 | } 125 | 126 | public async Task IncluirBoletos(IncluirBoletoRequest boleto) 127 | { 128 | return await ExecutaChamadaAsync(() => clientApi.PostAsync(ConfigApi.UrlApi + "cobranca-bancaria/v3/boletos", boleto)); 129 | } 130 | 131 | public async Task BaixarBoletos(int nossoNumero, int codigoModalidade) 132 | { 133 | var baixa = new BaixarBoletoRequest 134 | { 135 | numeroCliente = numeroContrato, 136 | codigoModalidade = codigoModalidade 137 | }; 138 | await ExecutaChamadaAsync(() => clientApi.PatchAsync(ConfigApi.UrlApi + $"cobranca-bancaria/v3/boletos/{nossoNumero}/baixar", baixa)); 139 | } 140 | 141 | public async Task ProtestarBoletos(int nossoNumero, int codigoModalidade) 142 | { 143 | var protesto = new ProtestoRequest 144 | { 145 | numeroCliente = numeroContrato, 146 | codigoModalidade = codigoModalidade, 147 | }; 148 | await ExecutaChamadaAsync(() => clientApi.PostAsync(ConfigApi.UrlApi + $"cobranca-bancaria/v3/boletos/{nossoNumero}/protestos", protesto)); 149 | } 150 | 151 | public async Task AlterarBoleto(int nossoNumero, AlterarBoletoRequest boletos) 152 | { 153 | await ExecutaChamadaAsync(() => clientApi.PatchAsync(ConfigApi.UrlApi + "cobranca-bancaria/v3/boletos/" + nossoNumero, boletos)); 154 | } 155 | 156 | /* Movimentação */ 157 | public async Task SolicitarMovimentacao(Tipo tipoMovimento, DateTime data) 158 | { 159 | var di = data.Date; 160 | var df = data.Date.AddDays(1).AddSeconds(-1); 161 | return await SolicitarMovimentacao(tipoMovimento, di, df); 162 | } 163 | public async Task SolicitarMovimentacao(Tipo tipoMovimento, DateTime dataInicial, DateTime dataFinal) 164 | => await SolicitarMovimentacao(new MovimentacaoRequest() { numeroCliente = numeroContrato, tipoMovimento = (int)tipoMovimento, dataInicial = dataInicial, dataFinal = dataFinal }); 165 | private async Task SolicitarMovimentacao(MovimentacaoRequest movimentacao) 166 | { 167 | var retorno = await ExecutaChamadaAsync(() => clientApi.PostAsync>(ConfigApi.UrlApi + "cobranca-bancaria/v3/boletos/movimentacoes", movimentacao)); 168 | return retorno.resultado; 169 | } 170 | public async Task ConsultarSituacaoSolicitacao(int codigoSolicitacao) 171 | { 172 | await VerificaAtualizaCredenciaisAsync(); 173 | var result = await clientApi.GetAsync>( ConfigApi.UrlApi + "cobranca-bancaria/v3/boletos/solicitacoes/movimentacao", new { numeroCliente = numeroContrato, codigoSolicitacao }); 174 | 175 | if (result.IsSuccessStatusCode) return result.Data.resultado; 176 | 177 | // "{\"mensagens\":[{\"mensagem\":\"Solicitação ainda em processamento.\",\"codigo\":\"5004\"}]}" 178 | if (result.TryParseErrorResponseData(out ErroRequisicao err)) 179 | { 180 | if (err.mensagens == null) { } 181 | 182 | if (err.mensagens.Any(o => o.codigo == 5004)) return null; 183 | 184 | throw new ErroRequisicaoException(err); 185 | } 186 | result.EnsureSuccessStatusCode(); // Erro comum 187 | return null; // a linha de cima vai arremessar o erro padrão 188 | } 189 | 190 | private async Task DownloadArquivoMovimentacao(int codigoSolicitacao, int idArquivo) 191 | { 192 | var retorno = await ExecutaChamadaAsync(() => clientApi.GetAsync>(ConfigApi.UrlApi + "/cobranca-bancaria/v3/boletos/movimentacoes/download", new { numeroCliente = numeroContrato, codigoSolicitacao, idArquivo })); 193 | return retorno.resultado; 194 | } 195 | public async Task BaixarMovimentacoes(int codigoSolicitacao, int[] arquivos) 196 | { 197 | var lst = new List(); 198 | foreach (var idArquivo in arquivos) 199 | { 200 | var retorno = await DownloadArquivoMovimentacao(codigoSolicitacao, idArquivo); 201 | 202 | var bytesZip = Convert.FromBase64String(retorno.arquivo); 203 | SalvarCopiaMovimentacao(bytesZip, retorno.nomeArquivo); 204 | 205 | var registros = Helpers.ProcessarArquivoMovimentacao(bytesZip); 206 | lst.Add(new MovimentacoesArquivos 207 | { 208 | codigoSolicitacao = codigoSolicitacao, 209 | idArquivo = idArquivo, 210 | nomeArquivo = retorno.nomeArquivo, 211 | Movimentacoes = registros.ToArray(), 212 | }); 213 | } 214 | return lst.ToArray(); 215 | } 216 | 217 | private void SalvarCopiaMovimentacao(byte[] bytesZip, string nomeArquivo) 218 | { 219 | if (PastaCopiaMovimentacoes == null) return; 220 | if (!Directory.Exists(PastaCopiaMovimentacoes)) Directory.CreateDirectory(PastaCopiaMovimentacoes); 221 | 222 | var path = Path.Combine(PastaCopiaMovimentacoes, nomeArquivo); 223 | if (File.Exists(path)) return; 224 | 225 | File.WriteAllBytes(path, bytesZip); 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /Sicoob.Conta/Models/ExtratoResponse.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Conta.Models; 7 | 8 | using System; 9 | 10 | public class ExtratoResponse 11 | { 12 | public decimal Saldo { get; set; } 13 | public Transacao[] Transacoes { get; set; } 14 | 15 | } 16 | public class Transacao 17 | { 18 | public string Tipo { get; set; } 19 | public decimal Valor { get; set; } 20 | public DateTime Data { get; set; } 21 | public DateTime DataLote { get; set; } 22 | public string Descricao { get; set; } 23 | public string NumeroDocumento { get; set; } 24 | public string CpfCnpj { get; set; } 25 | public string DescInfComplementar { get; set; } 26 | 27 | public override string ToString() => $"{Data:d} {Valor:C2} {Descricao}"; 28 | } 29 | -------------------------------------------------------------------------------- /Sicoob.Conta/Models/ResultadoResponse.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Conta.Models; 7 | 8 | public class ResultadoResponse 9 | { 10 | public Mensagem[] Mensagens { get; set; } 11 | public T resultado { get; set; } 12 | } 13 | public class Mensagem 14 | { 15 | public string codigo { get; set; } 16 | public string mensagem { get; set;} 17 | } 18 | -------------------------------------------------------------------------------- /Sicoob.Conta/Models/SaldoResponse.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Conta.Models; 7 | 8 | public class SaldoResponse 9 | { 10 | public decimal Saldo { get; set; } 11 | public decimal SaldoLimite { get; set; } 12 | } 13 | -------------------------------------------------------------------------------- /Sicoob.Conta/Sicoob.Conta.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 12.0 6 | warnings 7 | disable 8 | 0.9.3 9 | RafaelEstevam.Net 10 | SHARP SISTEMAS LTDA 11 | Sicoob Conta for C# 12 | C# implementation for Bank Account with SICOOB 13 | MIT 14 | https://github.com/SharpSistemas/SicoobAPI 15 | https://github.com/SharpSistemas/SicoobAPI 16 | git 17 | Simple API client 18 | https://github.com/SharpSistemas/SicoobAPI 19 | README.md 20 | true 21 | $(NoWarn);1591 22 | 23 | 24 | 25 | 26 | True 27 | \ 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Sicoob.Conta/SicoobContaCorrente.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Conta; 7 | 8 | using Sicoob.Conta.Models; 9 | using Sicoob.Shared.Models.Acesso; 10 | using Simple.API; 11 | using System.Net.Http; 12 | using System.Threading.Tasks; 13 | 14 | public sealed class SicoobContaCorrente : Shared.Sicoob 15 | { 16 | // Documentações 17 | // > APIs tipo "Swagger": 18 | // https://developers.sicoob.com.br/#!/apis 19 | 20 | private readonly int numeroContaCorrente; 21 | private ClientInfo clientApi; 22 | 23 | public Shared.Models.ConfiguracaoAPI ConfigApi { get; } 24 | 25 | public SicoobContaCorrente(Shared.Models.ConfiguracaoAPI configApi, int NumeroContaCorrente, System.Security.Cryptography.X509Certificates.X509Certificate2? certificado = null) 26 | : base(configApi, certificado) 27 | { 28 | ConfigApi = configApi; 29 | numeroContaCorrente = NumeroContaCorrente; 30 | } 31 | 32 | protected override void setupClients(HttpClientHandler handler) 33 | { 34 | clientApi = new ClientInfo(ConfigApi.UrlApi, handler); 35 | clientApi.SetHeader("x-sicoob-clientid", ConfigApi.ClientId); 36 | 37 | #if DEBUG 38 | enableDebug(clientApi); 39 | #endif 40 | } 41 | protected override void atualizaClients(TokenResponse token) 42 | { 43 | clientApi.SetAuthorizationBearer(token.access_token); // Deveria ser o id_token, mas dá erro de falta de scope 44 | } 45 | 46 | /// 47 | /// O recurso de Saldo retorna o valor disponível atual e o limite de crédito (cheque especial) de uma conta corrente. 48 | /// 49 | public async Task> ObterSaldoAsync() 50 | => await ExecutaChamadaAsync(() => clientApi.GetAsync>("/conta-corrente/v2/saldo", new { numeroContaCorrente })); 51 | 52 | 53 | /// 54 | /// O recurso de Extrato retorna todas as transações ocorridas em uma conta corrente no devido mês e ano. 55 | /// Há um limite de 3 meses 56 | /// 57 | public async Task> ObterExtratoAsync(int mes, int ano) 58 | => await ExecutaChamadaAsync(() => clientApi.GetAsync>($"/conta-corrente/v2/extrato/{mes}/{ano}", new { numeroContaCorrente })); 59 | 60 | } 61 | -------------------------------------------------------------------------------- /Sicoob.Conta/SicoobContaPoupanca.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Conta; 7 | 8 | using Sicoob.Shared.Models.Acesso; 9 | using Simple.API; 10 | using System.Net.Http; 11 | using System.Threading.Tasks; 12 | 13 | public sealed class SicoobContaPoupanca : Shared.Sicoob 14 | { 15 | // Documentações 16 | // > APIs tipo "Swagger": 17 | // https://developers.sicoob.com.br/#!/apis 18 | 19 | private ClientInfo clientApi; 20 | public Shared.Models.ConfiguracaoAPI ConfigApi { get; } 21 | 22 | public SicoobContaPoupanca(Shared.Models.ConfiguracaoAPI configApi, System.Security.Cryptography.X509Certificates.X509Certificate2? certificado = null) 23 | : base(configApi, certificado) 24 | { 25 | ConfigApi = configApi; 26 | } 27 | 28 | protected override void setupClients(HttpClientHandler handler) 29 | { 30 | clientApi = new ClientInfo(ConfigApi.UrlApi, handler); 31 | clientApi.SetHeader("x-sicoob-clientid", ConfigApi.ClientId); 32 | } 33 | protected override void atualizaClients(TokenResponse token) 34 | { 35 | clientApi.SetAuthorizationBearer(token.access_token); 36 | } 37 | 38 | /// 39 | /// Pesquisa as contas de poupança que pertencem a um CPF ou CNPJ. 40 | /// 41 | public async Task ListarContasAsync() 42 | => await ExecutaChamadaAsync(() => clientApi.GetAsync($"/poupanca/v1/contas")); 43 | /// 44 | /// Consulta o extrato de um mês e ano de uma conta poupança. 45 | /// 46 | public async Task ObterSaldoAsync(string contaPoupanca) 47 | => await ExecutaChamadaAsync(() => clientApi.GetAsync($"/poupanca/v1/contas/{contaPoupanca}/saldo")); 48 | /// 49 | /// Consulta o saldo atual de uma conta poupança. 50 | /// 51 | public async Task ObterExtratoAsync(int mes, int ano, string contaPoupanca) 52 | => await ExecutaChamadaAsync(() => clientApi.GetAsync($"/poupanca/v1/contas/{contaPoupanca}/extrato/{mes}/{ano}")); 53 | 54 | } 55 | -------------------------------------------------------------------------------- /Sicoob.PIX.UnitTest/Sicoob.PIX.UnitTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0 5 | disable 6 | enable 7 | 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | runtime; build; native; contentfiles; analyzers; buildtransitive 16 | all 17 | 18 | 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | all 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Sicoob.PIX/Sicoob.PIX.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 12.0 6 | warnings 7 | disable 8 | 0.9.8 9 | RafaelEstevam.Net 10 | SHARP SISTEMAS LTDA 11 | Sicoob PIX for C# 12 | C# implementation for PIX with SICOOB 13 | MIT 14 | https://github.com/SharpSistemas/SicoobAPI 15 | https://github.com/SharpSistemas/SicoobAPI 16 | git 17 | SICOOB PIX 18 | 19 | See examples and documentation on the GitHub page 20 | https://github.com/SharpSistemas/SicoobAPI 21 | 22 | README.md 23 | true 24 | $(NoWarn);1591 25 | 26 | 27 | 28 | 29 | True 30 | \ 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Sicoob.PIX/SicoobConsultaPayload.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.PIX; 7 | 8 | using Simple.API; 9 | using System.Threading.Tasks; 10 | 11 | /// 12 | /// Consulta os endpoints abertos (Sem autenticação) 13 | /// 14 | public class SicoobConsultaPayload 15 | { 16 | private readonly ClientInfo clientApi; 17 | private readonly ClientInfo clientPix; 18 | public SicoobConsultaPayload() 19 | { 20 | clientApi = new ClientInfo("https://api.sicoob.com.br/pix/api/v2/"); 21 | clientPix = new ClientInfo("https://pix.sicoob.com.br"); 22 | } 23 | /// 24 | /// Consulta um Location 25 | /// 26 | /// JWT contendo os dados do PIX 27 | public async Task ConsultaCobPayloadAsync(string urlAcessToken) 28 | { 29 | var response = await clientApi.GetAsync(urlAcessToken); 30 | response.EnsureSuccessStatusCode(); 31 | return response.Data; 32 | } 33 | /// 34 | /// Consulta campo payloadURL do PIX 35 | /// 36 | /// JWT contendo os dados do PIX 37 | public async Task ConsultaPixPayloadUrlAsync(string url) 38 | { 39 | url = url.Substring(url.IndexOf("/") + 1); 40 | var response = await clientPix.GetAsync(url); 41 | response.EnsureSuccessStatusCode(); 42 | return response.Data; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /Sicoob.PIX/SicoobPIX.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.PIX; 7 | 8 | using CS.BCB.PIX.Contratos; 9 | using CS.BCB.PIX.Models; 10 | using Sicoob.Shared; 11 | using Sicoob.Shared.Models.Acesso; 12 | using Simple.API; 13 | using System; 14 | using System.Globalization; 15 | using System.Threading.Tasks; 16 | 17 | /// 18 | /// Classe para comunicação com as APIs de PIX do Sicoob 19 | /// 20 | public sealed class SicoobPIX : Sicoob, IApiPix 21 | { 22 | // Documentações 23 | // > APIs tipo "Swagger": 24 | // https://developers.sicoob.com.br/#!/apis 25 | // > APIs no POSTMAN: 26 | // https://documenter.getpostman.com/view/20565799/UzBnrmod#239d9f68-d646-4209-994a-cd564b6d6d1a 27 | // Auxiliares 28 | // > Parseia BR Code para debugar: 29 | // https://openpix.com.br/qrcode/scanner/ 30 | // > Gera QR para teste: 31 | // https://webqr.com/create.html 32 | 33 | private ClientInfo clientApi; 34 | public Shared.Models.ConfiguracaoAPI ConfigApi { get; } 35 | 36 | public SicoobPIX(Shared.Models.ConfiguracaoAPI configApi, System.Security.Cryptography.X509Certificates.X509Certificate2? certificado = null) 37 | : base(configApi, certificado) 38 | { 39 | ConfigApi = configApi; 40 | } 41 | 42 | protected override void setupClients(System.Net.Http.HttpClientHandler handler) 43 | { 44 | clientApi = new ClientInfo(ConfigApi.UrlApi, handler); 45 | clientApi.SetHeader("x-sicoob-clientid", ConfigApi.ClientId); 46 | 47 | #if DEBUG 48 | enableDebug(clientApi); 49 | #endif 50 | 51 | } 52 | protected override void atualizaClients(TokenResponse token) 53 | { 54 | clientApi.SetAuthorizationBearer(token.access_token); 55 | } 56 | 57 | /* COB */ 58 | /// 59 | /// Endpoint que cria uma cobrança imediata (QRCode Pix). 60 | /// 61 | /// String, deve ter de 27 a 36 caracteres. Identificador único da cobrança Pix 62 | /// Dados para geração da cobrança imediata. 63 | /// Cobrança imediata criada 64 | public async Task CriarCobrancaAsync(string transactionId, NovaCobrancaImediata cobranca) 65 | { 66 | validaTxID(transactionId); 67 | return await ExecutaChamadaAsyncPIX(() => clientApi.PutAsync($"/pix/api/v2/cob/{transactionId}", cobranca)); 68 | } 69 | /// 70 | /// Endpoint para criar uma cobrança imediata, neste caso, o txid deve ser definido pelo PSP. 71 | /// 72 | /// Dados para geração da cobrança imediata. 73 | /// Cobrança imediata criada 74 | public async Task CriarCobrancaAsync(NovaCobrancaImediata cobranca) 75 | => await ExecutaChamadaAsyncPIX(() => clientApi.PostAsync($"/pix/api/v2/cob", cobranca)); 76 | /// 77 | /// Endpoint para revisar uma cobrança através de um determinado txid. 78 | /// 79 | /// String, deve ter de 27 a 36 caracteres. Identificador único da cobrança Pix. 80 | /// Dados para geração da cobrança 81 | /// Cobrança imediata revisada. A revisão deve ser incrementada em 1. 82 | public async Task RevisarCobrancaAsync(string transactionId, RevisarCobrancaImediata cobranca) 83 | { 84 | validaTxID(transactionId); 85 | return await ExecutaChamadaAsyncPIX(() => clientApi.PatchAsync($"/pix/api/v2/cob/{transactionId}", cobranca)); 86 | } 87 | 88 | /// 89 | /// Endpoint para consultar uma cobrança através de um determinado txid. 90 | /// 91 | /// String, deve ter de 27 a 36 caracteres. Identificador único da cobrança Pix. 92 | /// Revisao a ser consultada 93 | /// Dados da cobrança imediata 94 | public async Task ConsultarCobrancaAsync(string transactionId, int? revisao = null) 95 | { 96 | validaTxID(transactionId); 97 | 98 | string url = $"/pix/api/v2/cob/{transactionId}"; 99 | if (revisao.HasValue) url += $"?revisao={revisao.Value}"; 100 | 101 | return await ExecutaChamadaAsyncPIX(() => clientApi.GetAsync(url)); 102 | } 103 | /// 104 | /// Endpoint para consultar cobranças imediatas através de parâmetros como início, fim, cpf, cnpj e status. 105 | /// 106 | /// Dados da consulta 107 | /// Lista de cobranças imediatas. 108 | public async Task ListarCobrancasAsync(ConsultarCobrancaImediata consulta) 109 | => await ExecutaChamadaAsyncPIX(() => clientApi.GetAsync("/pix/api/v2/cob", consulta.ToKVP())); 110 | 111 | /// 112 | /// Endpoint para gerar a imagem qrcode de uma cobrança através de um determinado txid. 113 | /// 114 | /// String, deve ter de 27 a 36 caracteres. Identificador único da cobrança Pix. 115 | /// Revisao a ser consultada 116 | /// Largura da imagem a ser exibida 117 | /// Bytes da imagem codificada em PNG 118 | [Obsolete("Sicoob removeu o endpoint", true)] 119 | public async Task ConsultarImagemCobrancaAsync(string transactionId, int? revisao = null, int? largura = null) 120 | { 121 | validaTxID(transactionId); 122 | string url = $"/pix/api/v2/cob/{transactionId}/imagem"; 123 | 124 | return await ExecutaChamadaAsyncPIX(() => clientApi.GetAsync(url, new { revisao, largura }.ToKVP())); 125 | } 126 | 127 | /* COBV */ 128 | 129 | /* COBV-Lote */ 130 | 131 | /* PayloadLocation */ 132 | 133 | /* PIX */ 134 | /// 135 | /// Endpoint para consultar Pix recebidos 136 | /// 137 | /// Dados da consulta 138 | /// Lista dos Pix recebidos de acordo com o critério de busca. 139 | public async Task ListarPIXAsync(ConsultarPix consulta) 140 | => await ExecutaChamadaAsyncPIX(() => clientApi.GetAsync("/pix/api/v2/pix", consulta.ToKVP())); 141 | /// 142 | /// Endpoint para consultar um Pix através de um e2eid. 143 | /// 144 | /// Id fim a fim da transação. Deve ter 32 caracteres. 145 | /// Dados do Pix efetuado. 146 | public async Task ConsultarPIXAsync(string endToEndId) 147 | => await ExecutaChamadaAsyncPIX(() => clientApi.GetAsync($"/pix/api/v2/pix/{endToEndId}")); 148 | 149 | /// 150 | /// Endpoint para solicitar uma devolução através de um e2eid do Pix e do ID da devolução. 151 | /// O motivo que será atribuído à PACS.004 será "Devolução solicitada pelo usuário recebedor do pagamento original" 152 | /// cuja sigla é "MD06" de acordo com a aba RTReason da PACS.004 que consta no Catálogo de Mensagens do Pix. 153 | /// 154 | /// Id fim a fim da transação. 155 | /// Id gerado pelo cliente para representar unicamente uma devolução. 156 | /// Valor a ser devolvido 157 | /// Dados da devolução 158 | public async Task SolicitarDevlucaoPixAsync(string endToEndId, string idDevolucao, decimal valor) 159 | { 160 | validaIDDevolucao(idDevolucao); 161 | string url = $"/pix/api/v2/pix/{endToEndId}/devolucao/{idDevolucao}"; 162 | return await ExecutaChamadaAsyncPIX(() => clientApi.PutAsync(url, new { valor = valor.ToString("N2", CultureInfo.InvariantCulture) })); 163 | } 164 | /// 165 | /// Endpoint para consultar uma devolução através de um EndToEndID do Pix e do ID da devolução 166 | /// 167 | /// Id fim a fim da transação. 168 | /// Id gerado pelo cliente para representar unicamente uma devolução. 169 | /// Dados da devolução 170 | public async Task ConsultarDevlucaoPixAsync(string endToEndId, string idDevolucao) 171 | { 172 | string url = $"/pix/api/v2/pix/{endToEndId}/devolucao/{idDevolucao}"; 173 | return await ExecutaChamadaAsyncPIX(() => clientApi.GetAsync(url)); 174 | } 175 | 176 | /* Webhook */ 177 | /// 178 | /// Endpoint para configuração do serviço de notificações acerca de Pix recebidos. 179 | /// Somente Pix associados a um txid serão notificados. 180 | /// 181 | /// Chave a ser associada 182 | /// Url a ser chamada com POST. Será concatenado `/pix` ao final. 183 | public async Task CriarWebHookAsync(string chave, string url) 184 | { 185 | await ExecutaChamadaAsyncPIX(() => clientApi.PutAsync($"/pix/api/v2/webhook/{chave}", new { webhookUrl = url })); 186 | } 187 | /// 188 | /// Endpoint para consultar Webhooks cadastrados 189 | /// 190 | public async Task ConsultarWebHooksAsync() 191 | => await ExecutaChamadaAsyncPIX(() => clientApi.GetAsync("/pix/api/v2/webhook")); 192 | /// 193 | /// Endpoint para recuperação de informações sobre o Webhook Pix. 194 | /// 195 | public async Task ConsultarWebHookAsync(string chave) 196 | => await ExecutaChamadaAsyncPIX(() => clientApi.GetAsync($"/pix/api/v2/webhook/{chave}")); 197 | /// 198 | /// Endpoint para cancelamento do webhook. Não é a única forma pela qual um webhook pode ser removido. 199 | /// 200 | public async Task CancelarWebHookAsync(string chave) 201 | => await ExecutaChamadaAsyncPIX(() => clientApi.DeleteAsync($"/pix/api/v2/webhook/{chave}")); 202 | 203 | /* Validação de IDs */ 204 | private static void validaTxID(string transactionId) 205 | { 206 | if (string.IsNullOrEmpty(transactionId)) 207 | { 208 | throw new ArgumentException($"'{nameof(transactionId)}' cannot be null or empty.", nameof(transactionId)); 209 | } 210 | if (!CS.BCB.PIX.Validadores.ValidacaoIdentificadores.ValidaTransactionId(transactionId)) 211 | { 212 | throw new ArgumentException($"'{nameof(transactionId)}' Não é valido na restrição", nameof(transactionId)); 213 | } 214 | } 215 | private static void validaIDDevolucao(string idDevolucao) 216 | { 217 | if (string.IsNullOrEmpty(idDevolucao)) 218 | { 219 | throw new ArgumentException($"'{nameof(idDevolucao)}' cannot be null or empty.", nameof(idDevolucao)); 220 | } 221 | 222 | if (!CS.BCB.PIX.Validadores.ValidacaoIdentificadores.ValidaIdDevolucao(idDevolucao)) 223 | { 224 | throw new ArgumentException($"'{nameof(idDevolucao)}' Não é valido na restrição", nameof(idDevolucao)); 225 | } 226 | } 227 | 228 | /* Não implementados */ 229 | public Task ConsultarCobrancaVencimentoAsync(string transactionId, int? revisao = null) 230 | { 231 | throw new NotImplementedException(); 232 | } 233 | public Task CriarCobrancaVencimentoAsync(string transactionId, NovaCobrancaVencimento cobranca) 234 | { 235 | throw new NotImplementedException(); 236 | } 237 | public Task ListarCobrancasVencimentoAsync(ConsultarCobrancaImediata consulta) 238 | { 239 | throw new NotImplementedException(); 240 | } 241 | public Task RevisarCobrancaVencimentoAsync(string transactionId, RevisarCobrancaVencimento cobranca) 242 | { 243 | throw new NotImplementedException(); 244 | } 245 | public Task CriarLoteCobrancaVencimentoAsync(string idLote, NovaCobrancaVencimentoLote lote) 246 | { 247 | throw new NotImplementedException(); 248 | } 249 | public Task RevisarLoteCobrancaVencimentoAsync(string idLote, RevisarCobrancaVencimentoLote lote) 250 | { 251 | throw new NotImplementedException(); 252 | } 253 | public Task ConsultarLoteCobrancaVencimentoAsync(string transactionId) 254 | { 255 | throw new NotImplementedException(); 256 | } 257 | public Task ListarLoteCobrancaVencimentoAsync(Consulta consulta) 258 | { 259 | throw new NotImplementedException(); 260 | } 261 | 262 | 263 | /* Helpers*/ 264 | private async Task ExecutaChamadaAsyncPIX(Func>> func) 265 | { 266 | await VerificaAtualizaCredenciaisAsync(); 267 | Response response = await func(); 268 | 269 | if (!response.IsSuccessStatusCode) 270 | { 271 | if (response.TryParseErrorResponseData(out CS.BCB.PIX.Models.ErroRequisicao err)) 272 | { 273 | throw new CS.BCB.PIX.Excecoes.ErroRequisicaoException(err); 274 | } 275 | } 276 | response.EnsureSuccessStatusCode(); 277 | 278 | return response.Data; 279 | } 280 | private async Task ExecutaChamadaAsyncPIX(Func> func) 281 | { 282 | await VerificaAtualizaCredenciaisAsync(); 283 | Response response = await func(); 284 | 285 | // Processa manualmente para não envelopar demais 286 | if (response.IsSuccessStatusCode) return; 287 | if (response.TryParseErrorResponseData(out CS.BCB.PIX.Models.ErroRequisicao err)) 288 | { 289 | throw new CS.BCB.PIX.Excecoes.ErroRequisicaoException(err); 290 | } 291 | // Se não era um ErroRequisição, usar o erro comum 292 | response.EnsureSuccessStatusCode(); 293 | } 294 | 295 | } 296 | -------------------------------------------------------------------------------- /Sicoob.Shared.UnitTest/ExtensionsTests/ToKvpTests.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | using Sicoob.Shared.Models.Geral; 7 | using System; 8 | using System.Linq; 9 | using Xunit; 10 | 11 | namespace Sicoob.Shared.UnitTest.ExtensionsTests 12 | { 13 | public class ToKvpTests 14 | { 15 | // Valida se serializou de acordo com o que o Sicoob quer receber 16 | [Fact] 17 | public void Extensions_ToVKP_PixConsulta() 18 | { 19 | var cons = new ConsultaRequest() 20 | { 21 | inicio = new System.DateTime(2020, 01, 01, 0, 0, 0, System.DateTimeKind.Utc), 22 | fim = new System.DateTime(2021, 12, 31, 0, 0, 0, System.DateTimeKind.Utc), 23 | 24 | cnpj = "17189722000139", 25 | 26 | paginacao = new Shared.Models.Geral.RequestPaginacao() 27 | { 28 | paginaAtual = 0, 29 | itensPorPagina = 200, 30 | } 31 | }; 32 | 33 | var kvp = cons.ToKVP(); 34 | var str = string.Join(';', kvp.Select(p => $"{p.Key}={p.Value}")); 35 | 36 | var expected = "inicio=2020-01-01T00:00:00.000+00:00;fim=2021-12-31T00:00:00.000+00:00;cnpj=17189722000139;paginacao.paginaAtual=0;paginacao.itensPorPagina=200"; 37 | 38 | Assert.Equal(str, expected); 39 | } 40 | } 41 | 42 | internal class ConsultaRequest 43 | { 44 | public DateTime inicio { get; set; } 45 | public DateTime fim { get; set; } 46 | public string? txid { get; set; } 47 | public bool? txIdPresente { get; set; } 48 | public bool? devolucaoPresente { get; set; } 49 | public string? cpf { get; set; } 50 | public string? cnpj { get; set; } 51 | 52 | public RequestPaginacao? paginacao { get; set; } 53 | 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /Sicoob.Shared.UnitTest/ModelsTests/ConfiguracaoTests/ScopeTests.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | using Sicoob.Shared.Models; 7 | using Xunit; 8 | 9 | namespace Sicoob.Shared.UnitTest.ModelsTests.ConfiguracaoTests 10 | { 11 | public class ScopeTests 12 | { 13 | [Fact] 14 | public void Models_Configuration_Scope_None() 15 | { 16 | var scope = new AuthorizationScope(); 17 | Assert.Empty(scope.ToScopeString()); 18 | } 19 | [Fact] 20 | public void Models_Configuration_Scope_All() 21 | { 22 | var scope = new AuthorizationScope() 23 | { 24 | COB_WRITE = true, 25 | COB_READ = true, 26 | COBV_WRITE = true, 27 | COBV_READ = true, 28 | LOTE_COBV_WRITE = true, 29 | LOTE_COBV_READ = true, 30 | 31 | PIX_WRITE = true, 32 | PIX_READ = true, 33 | WEBHOOK_WRITE = true, 34 | WEBHOOK_READ = true, 35 | PAYLOAD_LOCATION_WRITE = true, 36 | PAYLOAD_LOCATION_READ = true, 37 | }; 38 | Assert.Equal("cob.write cob.read cobv.write cobv.read lotecobv.write lotecobv.read pix.write pix.read webhook.write webhook.read payloadlocation.write payloadlocation.read", scope.ToScopeString()); 39 | } 40 | [Fact] 41 | public void Models_Configuration_Scope_AllRead() 42 | { 43 | var scope = new AuthorizationScope() 44 | { 45 | COB_READ = true, 46 | COBV_READ = true, 47 | LOTE_COBV_READ = true, 48 | PIX_READ = true, 49 | WEBHOOK_READ = true, 50 | PAYLOAD_LOCATION_READ = true, 51 | }; 52 | Assert.Equal("cob.read cobv.read lotecobv.read pix.read webhook.read payloadlocation.read", scope.ToScopeString()); 53 | } 54 | [Fact] 55 | public void Models_Configuration_Scope_AllWrite() 56 | { 57 | var scope = new AuthorizationScope() 58 | { 59 | COB_WRITE = true, 60 | COBV_WRITE = true, 61 | LOTE_COBV_WRITE = true, 62 | 63 | PIX_WRITE = true, 64 | WEBHOOK_WRITE = true, 65 | PAYLOAD_LOCATION_WRITE = true, 66 | }; 67 | Assert.Equal("cob.write cobv.write lotecobv.write pix.write webhook.write payloadlocation.write", scope.ToScopeString()); 68 | } 69 | [Fact] 70 | public void Models_Configuration_Scope_Pix() 71 | { 72 | var scope = new AuthorizationScope() 73 | { 74 | PIX_WRITE = true, 75 | PIX_READ = true, 76 | }; 77 | Assert.Equal("pix.write pix.read", scope.ToScopeString()); 78 | } 79 | [Fact] 80 | public void Models_Configuration_Scope_Cob() 81 | { 82 | var scope = new AuthorizationScope() 83 | { 84 | COB_WRITE = true, 85 | COB_READ = true, 86 | }; 87 | Assert.Equal("cob.write cob.read", scope.ToScopeString()); 88 | } 89 | [Fact] 90 | public void Models_Configuration_Scope_CobV() 91 | { 92 | var scope = new AuthorizationScope() 93 | { 94 | COBV_WRITE = true, 95 | COBV_READ = true, 96 | LOTE_COBV_WRITE = true, 97 | LOTE_COBV_READ = true, 98 | }; 99 | Assert.Equal("cobv.write cobv.read lotecobv.write lotecobv.read", scope.ToScopeString()); 100 | } 101 | [Fact] 102 | public void Models_Configuration_Scope_PixHook() 103 | { 104 | var scope = new AuthorizationScope() 105 | { 106 | PIX_WRITE = true, 107 | PIX_READ = true, 108 | WEBHOOK_WRITE = true, 109 | WEBHOOK_READ = true, 110 | }; 111 | Assert.Equal("pix.write pix.read webhook.write webhook.read", scope.ToScopeString()); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /Sicoob.Shared.UnitTest/Sicoob.Shared.UnitTest.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net6.0 5 | disable 6 | enable 7 | 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | runtime; build; native; contentfiles; analyzers; buildtransitive 16 | all 17 | 18 | 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | all 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Sicoob.Shared/Extensions/ClassToKVP.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SharpSistemas/SicoobAPI/ea3858cb6daf6676c2bfdcc80e2f4432bd76c1b8/Sicoob.Shared/Extensions/ClassToKVP.cs -------------------------------------------------------------------------------- /Sicoob.Shared/Extensions/ToRFC.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Shared; 7 | 8 | using System; 9 | using System.Globalization; 10 | 11 | public static class ToRFC 12 | { 13 | public const string RFC_3339_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.fffzzz"; 14 | 15 | public static string ToRFC3339(this DateTime dateTime) 16 | => dateTime.ToUniversalTime().ToString(RFC_3339_FORMAT, DateTimeFormatInfo.InvariantInfo); 17 | } 18 | -------------------------------------------------------------------------------- /Sicoob.Shared/Models/Acesso/TokenResponse.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Shared.Models.Acesso; 7 | 8 | public class TokenResponse 9 | { 10 | public string? access_token { get; set; } 11 | public string? id_token { get; set; } 12 | public int expires_in { get; set; } 13 | public int refresh_expires_in { get; set; } 14 | public string? token_type { get; set; } 15 | public int notbeforepolicy { get; set; } 16 | public string? scope { get; set; } 17 | } 18 | -------------------------------------------------------------------------------- /Sicoob.Shared/Models/AuthorizationScope.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Shared.Models; 7 | 8 | using System.Collections.Generic; 9 | 10 | public class AuthorizationScope 11 | { 12 | /* API PIX */ 13 | /// 14 | /// [API PIX] cob.write: Permissão para alteração de cobranças imediatas 15 | /// 16 | public bool COB_WRITE { get; set; } 17 | /// 18 | /// [API PIX] cob.read: Permissão para consulta de cobranças imediatas 19 | /// 20 | public bool COB_READ { get; set; } 21 | /// 22 | /// [API PIX] cobv.write: Permissão para alteração de cobranças com vencimento 23 | /// 24 | public bool COBV_WRITE { get; set; } 25 | /// 26 | /// [API PIX] cobv.read: Permissão para consulta de cobranças com vencimento 27 | /// 28 | public bool COBV_READ { get; set; } 29 | /// 30 | /// [API PIX] lotecobv.write: Permissão para alteração de lotes de cobranças com vencimento 31 | /// 32 | public bool LOTE_COBV_WRITE { get; set; } 33 | /// 34 | /// [API PIX] lotecobv.read: Permissão para consulta de lotes de cobranças com vencimento 35 | /// 36 | public bool LOTE_COBV_READ { get; set; } 37 | 38 | /// 39 | /// [API PIX] pix.write: Permissão para alteração de Pix 40 | /// 41 | public bool PIX_WRITE { get; set; } 42 | /// 43 | /// [API PIX] pix.read: Permissão para consulta de Pix 44 | /// 45 | public bool PIX_READ { get; set; } 46 | 47 | /// 48 | /// [API PIX] webhook.read: Permissão para alteração do webhook 49 | /// 50 | public bool WEBHOOK_WRITE { get; set; } 51 | /// 52 | /// [API PIX] webhook.write: Permissão para consulta do webhook 53 | /// 54 | public bool WEBHOOK_READ { get; set; } 55 | 56 | /// 57 | /// [API PIX] payloadlocation.write: Permissão para alteração de payloads 58 | /// 59 | public bool PAYLOAD_LOCATION_WRITE { get; set; } 60 | /// 61 | /// [API PIX] payloadlocation.read: Permissão para consulta de payloads 62 | /// 63 | public bool PAYLOAD_LOCATION_READ { get; set; } 64 | 65 | /* API Conta Corrente */ 66 | /// 67 | /// [API Conta Corrente] openid: Escopo de acesso para Logon para Conta Corrente 68 | /// 69 | public bool OPENID { get; set; } 70 | /// 71 | /// [API Conta Corrente] cco_extrato: Acessa dados do Extrato 72 | /// 73 | public bool CCO_EXTRATO { get; set; } 74 | /// 75 | /// [API Conta Corrente] cco_saldo: Acessa dados do Saldo 76 | /// 77 | public bool CCO_SALDO { get; set; } 78 | 79 | /* API Poupança */ 80 | /// 81 | /// [API Conta Poupança] poupanca_contas: Acessa dados das Contas 82 | /// 83 | public bool POUPANCA_CONTAS { get; set; } 84 | /// 85 | /// [API Conta Poupança] poupanca_extrato: Acessa dados do Extrato 86 | /// 87 | public bool POUPANCA_EXTRATO { get; set; } 88 | /// 89 | /// [API Conta Poupança] poupanca_saldo: Acessa dados do Saldo 90 | /// 91 | public bool POUPANCA_SALDO { get; set; } 92 | 93 | /* API Cobrança (v2) */ 94 | /// 95 | /// [API Cobrança] cobranca_boletos_consultar: Permissão de consulta de boletos 96 | /// 97 | public bool COBRANCA_BOLETOS_CONSULTAR { get; set; } 98 | /// 99 | /// [API Cobrança] cobranca_boletos_incluir: Permissão de inclusão de boletos 100 | /// 101 | public bool COBRANCA_BOLETOS_INCLUIR { get; set; } 102 | /// 103 | /// [API Cobrança] cobranca_boletos_pagador: Permissão ?? 104 | /// 105 | public bool COBRANCA_BOLETOS_PAGADOR { get; set; } 106 | /// 107 | /// [API Cobrança] cobranca_boletos_segunda_via: Permissão emissão de segunda via 108 | /// 109 | public bool COBRANCA_BOLETOS_SEGUNDA_VIA { get; set; } 110 | /// 111 | /// [API Cobrança] cobranca_boletos_descontos: Permissão ?? 112 | /// 113 | public bool COBRANCA_BOLETOS_DESCONTOS { get; set; } 114 | /// 115 | /// [API Cobrança] cobranca_boletos_abatimentos: Permissão ?? 116 | /// 117 | public bool COBRANCA_BOLETOS_ABATIMENTOS { get; set; } 118 | /// 119 | /// [API Cobrança] cobranca_boletos_valor_nominal: Permissão ?? 120 | /// 121 | public bool COBRANCA_BOLETOS_VALOR_NOMINAL { get; set; } 122 | /// 123 | /// [API Cobrança] cobranca_boletos_seu_numero: Permissão ?? 124 | /// 125 | public bool COBRANCA_BOLETOS_SEU_NUMERO { get; set; } 126 | /// 127 | /// [API Cobrança] cobranca_boletos_especie_documento: Permissão ?? 128 | /// 129 | public bool COBRANCA_BOLETOS_ESPECIE_DOCUMENTO { get; set; } 130 | /// 131 | /// [API Cobrança] cobranca_boletos_baixa: Permissão para baixa de boletos 132 | /// 133 | public bool COBRANCA_BOLETOS_BAIXA { get; set; } 134 | /// 135 | /// [API Cobrança] cobranca_boletos_rateio_credito: Permissão ?? 136 | /// 137 | public bool COBRANCA_BOLETOS_RATEIO_CREDITO { get; set; } 138 | /// 139 | /// [API Cobrança] cobranca_pagadores: Permissão de Gerência de Pagadores 140 | /// 141 | public bool COBRANCA_PAGADORES { get; set; } 142 | /// 143 | /// [API Cobrança] cobranca_boletos_negativacoes_incluir: Permissão para inclusão de negativação 144 | /// 145 | public bool COBRANCA_BOLETOS_NEGATIVACOES_INCLUIR { get; set; } 146 | /// 147 | /// [API Cobrança] cobranca_boletos_negativacoes_alterar: Permissão para alteração de negativação 148 | /// 149 | public bool COBRANCA_BOLETOS_NEGATIVACOES_ALTERAR { get; set; } 150 | /// 151 | /// [API Cobrança] cobranca_boletos_negativacoes_baixar: Permissão para baixar de negativações 152 | /// 153 | public bool COBRANCA_BOLETOS_NEGATIVACOES_BAIXAR { get; set; } 154 | /// 155 | /// [API Cobrança] cobranca_boletos_protestos_incluir: Permissão para incluir protesto 156 | /// 157 | public bool COBRANCA_BOLETOS_PROTESTOS_INCLUIR { get; set; } 158 | /// 159 | /// [API Cobrança] cobranca_boletos_protestos_alterar: Permissão para alterar protesto 160 | /// 161 | public bool COBRANCA_BOLETOS_PROTESTOS_ALTERAR { get; set; } 162 | /// 163 | /// [API Cobrança] cobranca_boletos_protestos_desistir: Permissão para remover/desistir protesto 164 | /// 165 | public bool COBRANCA_BOLETOS_PROTESTOS_DESISTIR { get; set; } 166 | /// 167 | /// [API Cobrança] cobranca_boletos_solicitacao_movimentacao_incluir: Permissão para incluir movimentação 168 | /// 169 | public bool COBRANCA_BOLETOS_SOLICITACAO_MOVIMENTACAO_INCLUIR { get; set; } 170 | /// 171 | /// [API Cobrança] cobranca_boletos_solicitacao_movimentacao_consultar: Permissão para consultar movimentação 172 | /// 173 | public bool COBRANCA_BOLETOS_SOLICITACAO_MOVIMENTACAO_CONSULTAR { get; set; } 174 | /// 175 | /// [API Cobrança] cobranca_boletos_solicitacao_movimentacao_download: Permissão para fazer download de movimentações 176 | /// 177 | public bool COBRANCA_BOLETOS_SOLICITACAO_MOVIMENTACAO_DOWNLOAD { get; set; } 178 | /// 179 | /// [API Cobrança] cobranca_boletos_prorrogacoes_data_vencimento: Permissão para prorrogar vencimentos 180 | /// 181 | public bool COBRANCA_BOLETOS_PRORROGACOES_DATA_VENCIMENTO { get; set; } 182 | /// 183 | /// [API Cobrança] cobranca_boletos_prorrogacoes_data_limite_pagamento: Permissão prorrogação de data limite 184 | /// 185 | public bool COBRANCA_BOLETOS_PRORROGACOES_DATA_LIMITE_PAGAMENTO { get; set; } 186 | /// 187 | /// [API Cobrança] cobranca_boletos_encargos_multas: Permissão alteração de encargos e multa 188 | /// 189 | public bool COBRANCA_BOLETOS_ENCARGOS_MULTAS { get; set; } 190 | /// 191 | /// [API Cobrança] cobranca_boletos_encargos_juros_mora: Permissão alteração de juros 192 | /// 193 | public bool COBRANCA_BOLETOS_ENCARGOS_JUROS_MORA { get; set; } 194 | /// 195 | /// [API Cobrança] cobranca_boletos_pix: Permissão para alterar Boleto+PIX 196 | /// 197 | public bool COBRANCA_BOLETOS_PIX { get; set; } 198 | /// 199 | /// [API Cobrança] cobranca_boletos_faixa_nn_disponiveis: Permissão ?? 200 | /// 201 | public bool COBRANCA_BOLETOS_FAIXA_NN_DISPONIVEIS { get; set; } 202 | 203 | 204 | /// 205 | /// Gera a lista de Scope utilizado na geração do Token 206 | /// 207 | public string[] ToScope() 208 | { 209 | List lst = new List(); 210 | 211 | /* API PIX */ 212 | if (COB_WRITE) lst.Add("cob.write"); 213 | if (COB_READ) lst.Add("cob.read"); 214 | 215 | if (COBV_WRITE) lst.Add("cobv.write"); 216 | if (COBV_READ) lst.Add("cobv.read"); 217 | 218 | if (LOTE_COBV_WRITE) lst.Add("lotecobv.write"); 219 | if (LOTE_COBV_READ) lst.Add("lotecobv.read"); 220 | 221 | if (PIX_WRITE) lst.Add("pix.write"); 222 | if (PIX_READ) lst.Add("pix.read"); 223 | 224 | if (WEBHOOK_WRITE) lst.Add("webhook.write"); 225 | if (WEBHOOK_READ) lst.Add("webhook.read"); 226 | 227 | if (PAYLOAD_LOCATION_WRITE) lst.Add("payloadlocation.write"); 228 | if (PAYLOAD_LOCATION_READ) lst.Add("payloadlocation.read"); 229 | 230 | /* API Conta Corrente */ 231 | if (OPENID) lst.Add("openid"); 232 | if (CCO_EXTRATO) lst.Add("cco_extrato"); 233 | if (CCO_SALDO) lst.Add("cco_saldo"); 234 | 235 | /* API Poupança */ 236 | if (POUPANCA_CONTAS) lst.Add("poupanca_contas"); 237 | if (POUPANCA_EXTRATO) lst.Add("poupanca_extrato"); 238 | if (POUPANCA_SALDO) lst.Add("poupanca_saldo"); 239 | 240 | /* API Cobrança */ 241 | if (COBRANCA_BOLETOS_CONSULTAR) lst.Add("cobranca_boletos_consultar"); 242 | if (COBRANCA_BOLETOS_INCLUIR) lst.Add("cobranca_boletos_incluir"); 243 | if (COBRANCA_BOLETOS_PAGADOR) lst.Add("cobranca_boletos_pagador"); 244 | if (COBRANCA_BOLETOS_SEGUNDA_VIA) lst.Add("cobranca_boletos_segunda_via"); 245 | if (COBRANCA_BOLETOS_DESCONTOS) lst.Add("cobranca_boletos_descontos"); 246 | if (COBRANCA_BOLETOS_ABATIMENTOS) lst.Add("cobranca_boletos_abatimentos"); 247 | if (COBRANCA_BOLETOS_VALOR_NOMINAL) lst.Add("cobranca_boletos_valor_nominal"); 248 | if (COBRANCA_BOLETOS_SEU_NUMERO) lst.Add("cobranca_boletos_seu_numero"); 249 | if (COBRANCA_BOLETOS_ESPECIE_DOCUMENTO) lst.Add("cobranca_boletos_especie_documento"); 250 | if (COBRANCA_BOLETOS_BAIXA) lst.Add("cobranca_boletos_baixa"); 251 | if (COBRANCA_BOLETOS_RATEIO_CREDITO) lst.Add("cobranca_boletos_rateio_credito"); 252 | if (COBRANCA_PAGADORES) lst.Add("cobranca_pagadores"); 253 | if (COBRANCA_BOLETOS_NEGATIVACOES_INCLUIR) lst.Add("cobranca_boletos_negativacoes_incluir"); 254 | if (COBRANCA_BOLETOS_NEGATIVACOES_ALTERAR) lst.Add("cobranca_boletos_negativacoes_alterar"); 255 | if (COBRANCA_BOLETOS_NEGATIVACOES_BAIXAR) lst.Add("cobranca_boletos_negativacoes_baixar"); 256 | if (COBRANCA_BOLETOS_PROTESTOS_INCLUIR) lst.Add("cobranca_boletos_protestos_incluir"); 257 | if (COBRANCA_BOLETOS_PROTESTOS_ALTERAR) lst.Add("cobranca_boletos_protestos_alterar"); 258 | if (COBRANCA_BOLETOS_PROTESTOS_DESISTIR) lst.Add("cobranca_boletos_protestos_desistir"); 259 | if (COBRANCA_BOLETOS_SOLICITACAO_MOVIMENTACAO_INCLUIR) lst.Add("cobranca_boletos_solicitacao_movimentacao_incluir"); 260 | if (COBRANCA_BOLETOS_SOLICITACAO_MOVIMENTACAO_CONSULTAR) lst.Add("cobranca_boletos_solicitacao_movimentacao_consultar"); 261 | if (COBRANCA_BOLETOS_SOLICITACAO_MOVIMENTACAO_DOWNLOAD) lst.Add("cobranca_boletos_solicitacao_movimentacao_download"); 262 | if (COBRANCA_BOLETOS_PRORROGACOES_DATA_VENCIMENTO) lst.Add("cobranca_boletos_prorrogacoes_data_vencimento"); 263 | if (COBRANCA_BOLETOS_PRORROGACOES_DATA_LIMITE_PAGAMENTO) lst.Add("cobranca_boletos_prorrogacoes_data_limite_pagamento"); 264 | if (COBRANCA_BOLETOS_ENCARGOS_MULTAS) lst.Add("cobranca_boletos_encargos_multas"); 265 | if (COBRANCA_BOLETOS_ENCARGOS_JUROS_MORA) lst.Add("cobranca_boletos_encargos_juros_mora"); 266 | if (COBRANCA_BOLETOS_PIX) lst.Add("cobranca_boletos_pix"); 267 | if (COBRANCA_BOLETOS_FAIXA_NN_DISPONIVEIS) lst.Add("cobranca_boletos_faixa_nn_disponiveis"); 268 | 269 | return lst.ToArray(); 270 | } 271 | /// 272 | /// Gera string utilizada na geração do Token 273 | /// 274 | /// 275 | public string ToScopeString() 276 | { 277 | return string.Join(" ", ToScope()); 278 | } 279 | 280 | public AuthorizationScope PIX_SetarPIX(bool valor) 281 | { 282 | PIX_READ = valor; 283 | PIX_WRITE = valor; 284 | return this; 285 | } 286 | public AuthorizationScope PIX_SetarCOB(bool valor) 287 | { 288 | COB_READ = valor; 289 | COB_WRITE = valor; 290 | return this; 291 | } 292 | public AuthorizationScope PIX_SetarCOBV(bool valor) 293 | { 294 | COBV_READ = valor; 295 | COBV_WRITE = valor; 296 | return this; 297 | } 298 | public AuthorizationScope PIX_SetarLote(bool valor) 299 | { 300 | LOTE_COBV_READ = valor; 301 | LOTE_COBV_WRITE = valor; 302 | return this; 303 | } 304 | public AuthorizationScope PIX_SetarWebhook(bool valor) 305 | { 306 | WEBHOOK_READ = valor; 307 | WEBHOOK_WRITE = valor; 308 | return this; 309 | } 310 | public AuthorizationScope PIX_SetarPayload(bool valor) 311 | { 312 | PAYLOAD_LOCATION_READ = valor; 313 | PAYLOAD_LOCATION_WRITE = valor; 314 | return this; 315 | } 316 | 317 | public AuthorizationScope PIX_Setar_Write(bool valor) 318 | { 319 | COB_WRITE = valor; 320 | COBV_WRITE = valor; 321 | LOTE_COBV_WRITE = valor; 322 | 323 | PIX_WRITE = valor; 324 | WEBHOOK_WRITE = valor; 325 | PAYLOAD_LOCATION_WRITE = valor; 326 | return this; 327 | } 328 | public AuthorizationScope PIX_Setar_Read(bool valor) 329 | { 330 | COB_READ = valor; 331 | COBV_READ = valor; 332 | LOTE_COBV_READ = valor; 333 | PIX_READ = valor; 334 | WEBHOOK_READ = valor; 335 | PAYLOAD_LOCATION_READ = valor; 336 | return this; 337 | } 338 | 339 | public AuthorizationScope CCorrente_Setar(bool valor) 340 | { 341 | OPENID = valor; 342 | CCO_EXTRATO = valor; 343 | CCO_SALDO = valor; 344 | return this; 345 | } 346 | public AuthorizationScope CPoupanca_Setar(bool valor) 347 | { 348 | POUPANCA_CONTAS = valor; 349 | POUPANCA_EXTRATO = valor; 350 | POUPANCA_SALDO = valor; 351 | return this; 352 | } 353 | 354 | public AuthorizationScope Cobranca_Setar(bool value) 355 | { 356 | COBRANCA_BOLETOS_CONSULTAR = value; 357 | COBRANCA_BOLETOS_INCLUIR = value; 358 | COBRANCA_BOLETOS_PAGADOR = value; 359 | COBRANCA_BOLETOS_SEGUNDA_VIA = value; 360 | COBRANCA_BOLETOS_DESCONTOS = value; 361 | COBRANCA_BOLETOS_ABATIMENTOS = value; 362 | COBRANCA_BOLETOS_VALOR_NOMINAL = value; 363 | COBRANCA_BOLETOS_SEU_NUMERO = value; 364 | COBRANCA_BOLETOS_ESPECIE_DOCUMENTO = value; 365 | COBRANCA_BOLETOS_BAIXA = value; 366 | COBRANCA_BOLETOS_RATEIO_CREDITO = value; 367 | COBRANCA_PAGADORES = value; 368 | COBRANCA_BOLETOS_NEGATIVACOES_INCLUIR = value; 369 | COBRANCA_BOLETOS_NEGATIVACOES_ALTERAR = value; 370 | COBRANCA_BOLETOS_NEGATIVACOES_BAIXAR = value; 371 | COBRANCA_BOLETOS_PROTESTOS_INCLUIR = value; 372 | COBRANCA_BOLETOS_PROTESTOS_ALTERAR = value; 373 | COBRANCA_BOLETOS_PROTESTOS_DESISTIR = value; 374 | COBRANCA_BOLETOS_SOLICITACAO_MOVIMENTACAO_INCLUIR = value; 375 | COBRANCA_BOLETOS_SOLICITACAO_MOVIMENTACAO_CONSULTAR = value; 376 | COBRANCA_BOLETOS_SOLICITACAO_MOVIMENTACAO_DOWNLOAD = value; 377 | COBRANCA_BOLETOS_PRORROGACOES_DATA_VENCIMENTO = value; 378 | COBRANCA_BOLETOS_PRORROGACOES_DATA_LIMITE_PAGAMENTO = value; 379 | COBRANCA_BOLETOS_ENCARGOS_MULTAS = value; 380 | COBRANCA_BOLETOS_ENCARGOS_JUROS_MORA = value; 381 | COBRANCA_BOLETOS_PIX = value; 382 | COBRANCA_BOLETOS_FAIXA_NN_DISPONIVEIS = value; 383 | return this; 384 | } 385 | 386 | public AuthorizationScope RemoverTodos() 387 | { 388 | return setarTodosComo(false); 389 | } 390 | 391 | /// 392 | /// Seta todos independente de novas propriedades serem criadas 393 | /// 394 | private AuthorizationScope setarTodosComo(bool valor) 395 | { 396 | var t = typeof(AuthorizationScope); 397 | foreach (var p in t.GetProperties()) 398 | { 399 | if (!p.CanRead) continue; 400 | if (!p.CanWrite) continue; 401 | if (p.PropertyType != typeof(bool)) continue; 402 | 403 | p.SetValue(this, valor); 404 | } 405 | return this; 406 | } 407 | 408 | public static AuthorizationScope PIX_SomenteLeitura() 409 | { 410 | return new AuthorizationScope().PIX_Setar_Read(true); 411 | } 412 | public static AuthorizationScope TodosPIX() 413 | { 414 | return new AuthorizationScope().PIX_Setar_Read(true).PIX_Setar_Write(true); 415 | } 416 | public static AuthorizationScope TodosContaCorrente() 417 | { 418 | return new AuthorizationScope().CCorrente_Setar(true); 419 | } 420 | public static AuthorizationScope TodosContaPoupanca() 421 | { 422 | return new AuthorizationScope().CPoupanca_Setar(true); 423 | } 424 | public static AuthorizationScope TodosCobranca() 425 | { 426 | return new AuthorizationScope().Cobranca_Setar(true); 427 | } 428 | } 429 | -------------------------------------------------------------------------------- /Sicoob.Shared/Models/Configuracao.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | 7 | using System; 8 | 9 | namespace Sicoob.Shared.Models; 10 | 11 | public class Configuracao 12 | { 13 | /// 14 | /// Url do serviço OpenId 15 | /// 16 | public string UrlAutenticacao { get; set; } = "https://auth.sicoob.com.br/auth/realms/cooperado/protocol/openid-connect/"; 17 | 18 | /// 19 | /// Id do cliente gerado pelo Sicoob no momento do cadastro do Aplicativo 20 | /// 21 | public string? ClientId { get; set; } 22 | 23 | /// 24 | /// Teste de Comunicação com API 25 | /// 26 | public bool SandBox { get; set; } 27 | 28 | /// 29 | /// Ultimo token gerado 30 | /// 31 | public ConfiguracaoToken? Token { get; set; } 32 | 33 | /// 34 | /// Caminho do certificado com chave pública 35 | /// 36 | public string? UrlCertificadoPFX { get; set; } 37 | /// 38 | /// Senha do arquivo PFX, será apagada no construtor da classe `Sicoob` 39 | /// 40 | public string? CertificadoSenha { get; set; } 41 | /// 42 | /// Scopo de autorização, depende do serviço a ser utilizado 43 | /// 44 | public AuthorizationScope Scope { get; set; } = new AuthorizationScope(); 45 | } 46 | public class ConfiguracaoAPI : Configuracao 47 | { 48 | /// 49 | /// Url do serviço de API 50 | /// 51 | public string UrlApi { get; set; } = "https://api.sicoob.com.br/"; 52 | } 53 | 54 | public class ConfiguracaoToken 55 | { 56 | /// 57 | /// Último token gerado 58 | /// 59 | public string? Token { get; set; } 60 | 61 | /// 62 | /// Data de expiração do Útimo token gerado 63 | /// 64 | public DateTime ExpiresAtUTC { get; set; } 65 | } -------------------------------------------------------------------------------- /Sicoob.Shared/Models/Geral/RequestParametros.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Shared.Models.Geral; 7 | 8 | public class RequestPaginacao 9 | { 10 | public int paginaAtual { get; set; } 11 | public int itensPorPagina { get; set; } 12 | } 13 | -------------------------------------------------------------------------------- /Sicoob.Shared/Models/Geral/ResponseErro.cs: -------------------------------------------------------------------------------- 1 | namespace Sicoob.Shared.Models.Geral; 2 | 3 | using System; 4 | using System.Linq; 5 | 6 | public class ErroRequisicao 7 | { 8 | public Mensagens[] mensagens { get; set; } 9 | 10 | public string ObterMensagemErro() 11 | { 12 | return string.Join("; ", mensagens.Select(m => m.mensagem)); 13 | } 14 | 15 | public class Mensagens 16 | { 17 | public string mensagem { get; set; } 18 | public int codigo { get; set; } 19 | } 20 | } 21 | public class ErroRequisicaoException : Exception 22 | { 23 | public ErroRequisicao DadosErro { get; } 24 | 25 | public ErroRequisicaoException(ErroRequisicao erro) 26 | : base(erro.ObterMensagemErro()) 27 | { 28 | DadosErro = erro; 29 | } 30 | 31 | public ErroRequisicaoException(ErroRequisicao erro, Exception innerException) 32 | : base(erro.ObterMensagemErro(), innerException) 33 | { 34 | DadosErro = erro; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Sicoob.Shared/Models/Geral/ResponseParametros.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Shared.Models.Geral; 7 | 8 | using System; 9 | 10 | public class ResponseParametros 11 | { 12 | public DateTime inicio { get; set; } 13 | public DateTime fim { get; set; } 14 | public Paginacao? paginacao { get; set; } 15 | 16 | public class Paginacao 17 | { 18 | public int paginaAtual { get; set; } 19 | public int itensPorPagina { get; set; } 20 | public int quantidadeDePaginas { get; set; } 21 | public int quantidadeTotalDeItens { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Sicoob.Shared/Sicoob.Shared.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 12.0 6 | disable 7 | enable 8 | 1.0.4 9 | RafaelEstevam.Net 10 | SHARP SISTEMAS LTDA 11 | Base library for Sicoob APIs for C# 12 | Base library for Sicoob APIs for C# 13 | MIT 14 | https://github.com/SharpSistemas/SicoobAPI 15 | https://github.com/SharpSistemas/SicoobAPI 16 | git 17 | SICOOB 18 | 19 | See examples and documentation on the GitHub page 20 | https://github.com/SharpSistemas/SicoobAPI 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Sicoob.Shared/Sicoob.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | 7 | using Sicoob.Shared.Models.Acesso; 8 | 9 | namespace Sicoob.Shared; 10 | 11 | using global::Sicoob.Shared.Models.Geral; 12 | using Simple.API; 13 | using System; 14 | using System.Net.Http; 15 | using System.Security.Cryptography.X509Certificates; 16 | using System.Threading.Tasks; 17 | 18 | public abstract class Sicoob 19 | { 20 | private readonly Models.Configuracao config; 21 | private readonly HttpClientHandler httpHandler; 22 | private ClientInfo clientAuth; 23 | private const string SandBoxToken = "1301865f-c6bc-38f3-9f49-666dbcfc59c3"; 24 | 25 | public DateTime ExpiresAtUTC { get; private set; } 26 | public TimeSpan ExpiresIn => ExpiresAtUTC - DateTime.UtcNow; 27 | public bool Expired => ExpiresIn.TotalSeconds < 0; 28 | 29 | public Sicoob(Models.Configuracao config, X509Certificate2? certificado = null) 30 | { 31 | this.config = config ?? throw new ArgumentNullException(nameof(config)); 32 | 33 | if (certificado == null) 34 | { 35 | certificado = new X509Certificate2(config.UrlCertificadoPFX, config.CertificadoSenha); 36 | // Após abrir o PFX, não manter a senha na memória 37 | // Não apenas setar em NULL, trocar a referência 38 | config.CertificadoSenha = "*******"; 39 | } 40 | else 41 | { 42 | if (config.UrlCertificadoPFX != null) throw new ArgumentException("Não é possível informar o caminho do certificado pois o X509Certificate2 já foi informado"); 43 | if (config.CertificadoSenha != null) throw new ArgumentException("Não é possível informar a senha do certificado pois o X509Certificate2 já foi informado"); 44 | } 45 | 46 | httpHandler = new HttpClientHandler(); 47 | httpHandler.ClientCertificates.Add(certificado); 48 | 49 | clientAuth = new ClientInfo(config.UrlAutenticacao, httpHandler); 50 | } 51 | 52 | protected void enableDebug(ClientInfo clientApi) 53 | { 54 | clientApi.SetHeader("apim-debug", "true"); // debug de OPEN-ID 55 | clientApi.BeforeSend += ClientApi_BeforeSend; 56 | clientApi.ResponseDataReceived += ClientApi_ResponseDataReceived; 57 | debugLog("[SETUP]", "STARTUP"); 58 | } 59 | private void ClientApi_ResponseDataReceived(object sender, ClientInfo.ResponseReceived e) 60 | { 61 | debugLog("<<", $"[{e.StatusCode}] RECV: {e.Content}"); 62 | } 63 | private void ClientApi_BeforeSend(object sender, HttpRequestMessage e) 64 | { 65 | string content = ""; 66 | if (e.Content != null) 67 | { 68 | if (e.Content is StringContent strCnt) 69 | { 70 | content = strCnt.ReadAsStringAsync().Result; 71 | } 72 | } 73 | 74 | debugLog(">>", $"[{e.Method}] {e.RequestUri} {content}"); 75 | } 76 | private void debugLog(string direciton, string content) 77 | { 78 | System.IO.File.AppendAllText("debug.log", $"{DateTime.Now:G} {direciton} {content}\r\n"); 79 | } 80 | 81 | public async Task SetupAsync() 82 | { 83 | setupClients(httpHandler); 84 | if (config.Token is null) 85 | await atualizaCredenciaisAsync(); 86 | else 87 | { 88 | ExpiresAtUTC = config.Token.ExpiresAtUTC; 89 | } 90 | } 91 | protected abstract void setupClients(HttpClientHandler handler); 92 | protected abstract void atualizaClients(Models.Acesso.TokenResponse token); 93 | 94 | public async Task AtualizarCredenciaisAsync() 95 | => await atualizaCredenciaisAsync(); 96 | private async Task atualizaCredenciaisAsync() 97 | { 98 | var response = await clientAuth.FormUrlEncodedPostAsync("token", new 99 | { 100 | client_id = config.ClientId, 101 | grant_type = "client_credentials", 102 | scope = config.Scope.ToScopeString(), 103 | }); 104 | 105 | if (config.SandBox) 106 | { 107 | atualizaClients(new TokenResponse(){ access_token = SandBoxToken }); 108 | var data = DateTime.Now.AddHours(1); 109 | var totalSeconds = Convert.ToInt32((DateTime.Now - data).TotalSeconds); 110 | ExpiresAtUTC = DateTime.UtcNow.AddSeconds(totalSeconds); 111 | 112 | return new TokenResponse() 113 | { 114 | access_token = SandBoxToken, 115 | expires_in = totalSeconds 116 | }; 117 | } 118 | 119 | response.EnsureSuccessStatusCode(); 120 | atualizaClients(response.Data); 121 | ExpiresAtUTC = DateTime.UtcNow.AddSeconds(response.Data.expires_in); 122 | return response.Data; 123 | } 124 | 125 | protected async Task VerificaAtualizaCredenciaisAsync() 126 | { 127 | if (ExpiresIn.TotalSeconds >= 5) 128 | return null; 129 | 130 | return await atualizaCredenciaisAsync(); 131 | } 132 | protected async Task ExecutaChamadaAsync(Func>> func) 133 | { 134 | await VerificaAtualizaCredenciaisAsync(); 135 | Response response = await func(); 136 | 137 | if (!response.IsSuccessStatusCode) 138 | { 139 | if (response.TryParseErrorResponseData(out ErroRequisicao err)) 140 | { 141 | throw new ErroRequisicaoException(err); 142 | } 143 | } 144 | response.EnsureSuccessStatusCode(); 145 | 146 | return response.Data; 147 | } 148 | protected async Task ExecutaChamadaAsync(Func> func) 149 | { 150 | await VerificaAtualizaCredenciaisAsync(); 151 | Response response = await func(); 152 | 153 | // Processa manualmente para não envelopar demais 154 | if (response.IsSuccessStatusCode) return; 155 | if (response.TryParseErrorResponseData(out ErroRequisicao err)) 156 | { 157 | throw new ErroRequisicaoException(err); 158 | } 159 | // Se não era um ErroRequisição, usar o erro comum 160 | response.EnsureSuccessStatusCode(); 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /Sicoob.Testes/Program.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | using Sicoob.Testes; 7 | 8 | System.Console.WriteLine("Escolha o Teste"); 9 | 10 | //await TestesApiPIX.Run(); 11 | //await TestesApiConta.Run_ContaCorrente(); 12 | //await TestesApiConta.Run_ContaPoupanca(); 13 | await TestesApiCobranca.Run_Cobranca(); 14 | 15 | -------------------------------------------------------------------------------- /Sicoob.Testes/Sicoob.Testes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | disable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sicoob.Testes/TestesApiCobranca.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | 7 | using Sicoob.Cobranca.Models.Shared; 8 | using Sicoob.Cobranca.Models.v2; 9 | 10 | namespace Sicoob.Testes; 11 | 12 | using Newtonsoft.Json; 13 | using Sicoob.Cobranca; 14 | using Sicoob.Shared.Models; 15 | using System; 16 | using System.IO; 17 | using System.Threading.Tasks; 18 | 19 | public static class TestesApiCobranca 20 | { 21 | internal static async Task Run_Cobranca() 22 | { 23 | // carrega do disco 24 | var cfg = JsonConvert.DeserializeObject(File.ReadAllText("config_Cob.json")) ?? throw new Exception(); 25 | //cfg.Scope.RemoverTodos(); 26 | //cfg.Scope.Cobranca_Setar(true); 27 | //File.WriteAllText("config_Cob.json", JsonConvert.SerializeObject(cfg)); 28 | 29 | var cobranca = new SicoobCobrancaV2(cfg, NumeroContrato: 000); 30 | await cobranca.SetupAsync(); 31 | 32 | /*var boleto = await cobranca.IncluirBoletos(new [] 33 | { 34 | new IncluirBoletosRequest() 35 | { 36 | numeroContrato= 25546454, 37 | modalidade= (int)Modalidade.SimplesComRegistro, 38 | numeroContaCorrente= 0, 39 | especieDocumento= "DM", 40 | dataEmissao= new DateTime(2018,09, 20).ToUniversalTime(), 41 | nossoNumero= 2588658, 42 | seuNumero= "1235512", 43 | identificacaoBoletoEmpresa= "4562", 44 | identificacaoEmissaoBoleto= (int)IdentificacaoEmissaoBoleto.BancoEmite, 45 | identificacaoDistribuicaoBoleto= (int)IdentificacaoDistribuicaoBoleto.BancoDistribui, 46 | valor= 156.23m, 47 | dataVencimento= new DateTime(2018,09, 20).ToUniversalTime(), 48 | dataLimitePagamento= new DateTime(2018,09, 20).ToUniversalTime(), 49 | valorAbatimento= 1, 50 | tipoDesconto= (int)TipoDesconto.ValorFixoAteDataInformada, 51 | dataPrimeiroDesconto= new DateTime(2018,09, 20).ToUniversalTime(), 52 | valorPrimeiroDesconto= 1, 53 | dataSegundoDesconto= new DateTime(2018,09, 20).ToUniversalTime(), 54 | valorSegundoDesconto= 0, 55 | dataTerceiroDesconto= new DateTime(2018,09, 20).ToUniversalTime(), 56 | valorTerceiroDesconto= 0, 57 | tipoMulta= (int)TipoMulta.ValorFixo, 58 | dataMulta= new DateTime(2018,09, 20).ToUniversalTime(), 59 | valorMulta= 5, 60 | tipoJurosMora= (int)TipoJurosMora.ValorPorDia, 61 | dataJurosMora= new DateTime(2018,09, 20).ToUniversalTime(), 62 | valorJurosMora= 4, 63 | numeroParcela= 1, 64 | aceite= true, 65 | codigoNegativacao= (int)CodigoNegativacao.NegativarDiasUteis, 66 | numeroDiasNegativacao= 60, 67 | codigoProtesto= (int)CodigoProtesto.ProtestarDiasCorridos, 68 | numeroDiasProtesto= 30, 69 | pagador = new DadosPagador() 70 | { 71 | numeroCpfCnpj = "98765432185", 72 | nome = "Marcelo dos Santos", 73 | endereco = "Rua 87 Quadra 1 Lote 1 casa 1", 74 | bairro = "Santa Rosa", 75 | cidade = "Luziânia", 76 | cep = "72320000", 77 | uf = "DF", 78 | email = new[] { 79 | "pagador@dominio.com.br" 80 | }, 81 | }, 82 | beneficiarioFinal = new Beneficiariofinal() 83 | { 84 | numeroCpfCnpj = "98784978699", 85 | nome = "Lucas de Lima" 86 | }, 87 | mensagensInstrucao = new Mensagensinstrucao() 88 | { 89 | tipoInstrucao = 1, 90 | mensagens = new [] { 91 | "Descrição da Instrução 1", 92 | "Descrição da Instrução 2", 93 | "Descrição da Instrução 3", 94 | "Descrição da Instrução 4", 95 | "Descrição da Instrução 5" 96 | } 97 | }, 98 | rateioCreditos = new [] { 99 | new Rateiocredito() 100 | { 101 | numeroBanco = 756, 102 | numeroAgencia = 4027, 103 | numeroContaCorrente = 0, 104 | contaPrincipal = true, 105 | codigoTipoValorRateio = 1, 106 | valorRateio = 156.23m, 107 | codigoTipoCalculoRateio = 1, 108 | numeroCpfCnpjTitular = "98765432185", 109 | nomeTitular = "Marcelo dos Santos", 110 | codigoFinalidadeTed = 10, 111 | codigoTipoContaDestinoTed = "CC", 112 | quantidadeDiasFloat = 1, 113 | dataFloatCredito = "2020-12-30" 114 | } 115 | }, 116 | gerarPdf = true, 117 | codigoCadastrarPIX = (int)CodigoCadastrarPIX.Padrao 118 | } 119 | });*/ 120 | //var bol = await cobranca.ConsultarBoletosPagador("98765432185", dataVencimentoInicio: new DateTime(2024,01,01), dataVencimentoFim: new DateTime(2024,02,24) ); 121 | //var boleto = await cobranca.ConsultarBoleto(nossoNumero: 0); 122 | //var consulta = await cobranca.ConsultarBoletosPagador(numeroCpfCnpj: "00000000000000"); 123 | //var segVia = await cobranca.ConsultarSegundaViaBoleto(1, nossoNumero: 0, gerarPdf: true); 124 | 125 | var p1 = await cobranca.SolicitarMovimentacao(Tipo.Liquidacao, new DateTime(2024, 02, 20), new DateTime(2024, 02, 23)); 126 | int codigo = p1.codigoSolicitacao; 127 | 128 | RetornoConsultaMovimentacoes? p2 = null; 129 | while (p2 == null) 130 | { 131 | Console.WriteLine("Consultando ..."); 132 | p2 = await cobranca.ConsultarSituacaoSolicitacao(codigoSolicitacao: codigo); 133 | await Task.Delay(1000); 134 | } 135 | 136 | int[] idsArquivos = p2.idArquivos; 137 | var p3 = await cobranca.BaixarMovimentacoes(codigo, idsArquivos); 138 | cfg = cfg; 139 | cfg = cfg; 140 | cfg = cfg; 141 | cfg = cfg; 142 | cfg = cfg; 143 | cfg = cfg; 144 | cfg = cfg; 145 | cfg = cfg; 146 | cfg = cfg; 147 | } 148 | } -------------------------------------------------------------------------------- /Sicoob.Testes/TestesApiConta.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Testes; 7 | 8 | using Newtonsoft.Json; 9 | using Sicoob.Conta; 10 | using Sicoob.Shared.Models; 11 | using System.IO; 12 | using System.Threading.Tasks; 13 | 14 | public static class TestesApiConta 15 | { 16 | public static async Task Run_ContaCorrente() 17 | { 18 | // carrega do disco 19 | var cfg = JsonConvert.DeserializeObject(File.ReadAllText("config_CC.json")); 20 | // salva no disco 21 | //var cfg = new ConfiguracaoAPI() 22 | //{ 23 | // ClientId = "00000000-0000-0000-0000-000000000000", // Obtém no "Aplicativo" no developers.sicoob.com.br 24 | // CertificadoSenha = "SenhaCertificado", 25 | // UrlCertificadoPFX = "caminho/do/pfx/com/chave/privada.pfx" 26 | //}; 27 | //File.WriteAllText("config_CC.json", JsonConvert.SerializeObject(cfg)); 28 | 29 | var cCorrente = new SicoobContaCorrente(cfg, 00000); 30 | await cCorrente.SetupAsync(); 31 | 32 | var extrato = await cCorrente.ObterExtratoAsync(12, 2023); 33 | var saldo = await cCorrente.ObterSaldoAsync(); 34 | } 35 | public static async Task Run_ContaPoupanca() 36 | { 37 | // carrega do disco 38 | var cfg = JsonConvert.DeserializeObject(File.ReadAllText("config_CP.json")); 39 | // salva no disco 40 | //var cfg = new ConfiguracaoAPI() 41 | //{ 42 | // ClientId = "00000000-0000-0000-0000-000000000000", // Obtém no "Aplicativo" no developers.sicoob.com.br 43 | // CertificadoSenha = "SenhaCertificado", 44 | // UrlCertificadoPFX = "caminho/do/pfx/com/chave/privada.pfx" 45 | //}; 46 | //File.WriteAllText("config_CP.json", JsonConvert.SerializeObject(cfg)); 47 | 48 | var cPoupanca = new SicoobContaPoupanca(cfg); 49 | await cPoupanca.SetupAsync(); 50 | 51 | var lista = await cPoupanca.ListarContasAsync(); 52 | var extrato = await cPoupanca.ObterExtratoAsync(1, 2020, "00000"); 53 | var saldo = await cPoupanca.ObterSaldoAsync("00000"); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Sicoob.Testes/TestesApiPIX.cs: -------------------------------------------------------------------------------- 1 | /**************************************\ 2 | * Biblioteca C# para APIs do SICOOB * 3 | * Autor: Rafael Estevam * 4 | * gh/SharpSistemas/SicoobAPI * 5 | \**************************************/ 6 | namespace Sicoob.Testes; 7 | 8 | using Newtonsoft.Json; 9 | using Sicoob.PIX; 10 | using System; 11 | using System.IO; 12 | using System.Threading.Tasks; 13 | 14 | public static class TestesApiPIX 15 | { 16 | public static async Task Run() 17 | { 18 | // carrega do disco 19 | var cfg = JsonConvert.DeserializeObject(File.ReadAllText("config_PIX.json")); 20 | // salva no disco 21 | //File.WriteAllText("config_PIX.json", JsonConvert.SerializeObject(cfg)); 22 | 23 | // Cria Objeto 24 | var sicoob = new SicoobPIX(cfg); 25 | // Configura acesso das APIs 26 | await sicoob.SetupAsync(); 27 | // A autenticação dura 300 segundos (5min) e é auto renovado pela biblioteca 28 | // Cada chamada verifica e, se necessário, atualiza o token 29 | // Chame AtualizarCredenciaisAsync() para renovar manualmente 30 | // É possível consultar dados da vigência do Token nas propriedades: 31 | // * sicoob.ExpiresIn 32 | // * sicoob.ExpiresAtUTC 33 | // * sicoob.Expired 34 | 35 | //var allHooks = await sicoob.ConsultarWebHooksAsync(); 36 | //var chaveHooks = await sicoob.ConsultarWebHookAsync("17189722000139"); 37 | 38 | //var novo = await sicoob.CriarCobrancaAsync("TESTC001F1AA20230203T092900", CS.BCB.PIX.Models.NovaCobrancaImediata.Padrao("17189722000139", 1.90M)); 39 | 40 | /* COB */ 41 | //var cobs = await sicoob.ListarCobrancasAsync(new CS.BCB.PIX.Models.ConsultarCobrancaImediata() 42 | //{ 43 | // inicio = DateTime.UtcNow.Date.AddDays(-7), 44 | // fim = DateTime.UtcNow.AddDays(1).Date, 45 | //}); 46 | 47 | /* PIX */ 48 | //var pixPeriodo = await sicoob.ListarPIXAsync(new CS.BCB.PIX.Models.ConsultarPix() 49 | //{ 50 | // inicio = DateTime.UtcNow.Date.AddDays(-7), 51 | // fim = DateTime.UtcNow.AddDays(1).Date, 52 | // //paginacao = new CS.BCB.PIX.Models.ConsultaPaginacao() 53 | // //{ 54 | // // itensPorPagina = 50, 55 | // //} 56 | //}); 57 | //var ultimoPix = await sicoob.ConsultarPIXAsync(pixPeriodo.pix[^1].endToEndId); 58 | 59 | 60 | } 61 | } 62 | --------------------------------------------------------------------------------