Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/.editorconfig export-ignore
/.cursorignore export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/.github export-ignore
/.vscode export-ignore
/.cursor export-ignore
/.php-cs-fixer.php export-ignore
/.prettierrc export-ignore
/CONTRIBUTING.md export-ignore
/composer.lock export-ignore
/Makefile export-ignore
/README.md export-ignore
/AGENTS.md export-ignore
/codecov.yml export-ignore
/phpstan.neon export-ignore
/phpunit.xml.dist export-ignore
/tests export-ignore
/package.json export-ignore
/phpunit.xml export-ignore
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: 'github-actions'
directory: '/'
commit-message:
# Prefix all commit messages with "chore: "
prefix: 'chore'
schedule:
interval: 'monthly'
open-pull-requests-limit: 10
58 changes: 58 additions & 0 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Run lint and tests
on:
pull_request:
types:
- opened
- reopened
- ready_for_review
workflow_dispatch:

env:
PHP_VERSION: 8.3
PHP_EXTENSIONS: mbstring
PHP_TOOLS: composer:v2, phpunit:11

permissions:
id-token: write
contents: read

jobs:
run-tests:
if: ${{ !github.event.pull_request.draft }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- name: Install PHP ${{ env.PHP_VERSION }}
uses: shivammathur/setup-php@v2
with:
coverage: none
php-version: ${{ env.PHP_VERSION }}
extensions: ${{ env.PHP_EXTENSIONS }}
tools: ${{ env.PHP_TOOLS }}

- name: Get Composer Cache Directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v6
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-composer-

- name: Validate composer files
run: composer validate --strict

- name: Install dependencies
run: composer install --no-interaction --no-progress

- name: Security audit
run: composer audit --no-dev

- name: Static analysis
run: composer phpstan

- name: Run unit tests
run: composer test:unit
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
composer.lock
vendor
.idea
/.settings/
/.project
/.buildpath
.vscode/settings.json
/cache
32 changes: 32 additions & 0 deletions .php-cs-fixer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/**
* @see https://cs.symfony.com/doc/rules/index.html
* @see https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/f65e6a20c9ef30f2fc93d8c3e1bf6aa3bd910192/src/RuleSet/Sets/PSR12Set.php
* @see https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/f65e6a20c9ef30f2fc93d8c3e1bf6aa3bd910192/src/RuleSet/Sets/SymfonySet.php
*/
$finder = PhpCsFixer\Finder::create()
->in(__DIR__)
->name('*.php')
->exclude([
'cache',
])
->ignoreDotFiles(true)
->ignoreVCS(true);

return (new PhpCsFixer\Config())
->setParallelConfig(\PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect())
->setRiskyAllowed(false)
->setCacheFile(__DIR__ . '/cache/.php-cs-fixer.cache')
->setRules([
'@PSR12' => true,
'@Symfony' => true,
'fully_qualified_strict_types' => false, // Garantir namespaces completos
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => ['default' => 'single_space'],
'concat_space' => ['spacing' => 'one'],
'increment_style' => ['style' => 'post'],
'yoda_style' => false,
])
->setIndent(' ')
->setLineEnding("\n")
->setFinder($finder);
24 changes: 24 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"parser": "php",
"plugins": [
"@prettier/plugin-php"
],
"phpVersion": "8.3",
"printWidth": 150,
"singleQuote": true,
"trailingComma": "all",
"arrowParens": "always",
"tabWidth": 4,
"trailingCommaPHP": true,
"braceStyle": "per-cs",
"requirePragma": false,
"insertPragma": false,
"overrides": [
{
"files": "*.yml",
"options": {
"tabWidth": 2
}
}
]
}
17 changes: 17 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"recommendations": [
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"streetsidesoftware.code-spell-checker",
"streetsidesoftware.code-spell-checker-portuguese",
"usernamehw.errorlens",
"eamodio.gitlens",
"seatonjiang.gitmoji-vscode",
"devsense.phptools-vscode",
"phproberto.vscode-php-getters-setters",
"mehedidracula.php-namespace-resolver",
"junstyle.php-cs-fixer",
],
"unwantedRecommendations": []
}
44 changes: 44 additions & 0 deletions .vscode/settings.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"files.eol": "\n",
"eslint.run": "onSave",
"eslint.format.enable": true,
"editor.tabSize": 2,
"php-cs-fixer.executablePath": "${workspaceFolder}/vendor/bin/php-cs-fixer",
"[php]": {
"-editor.defaultFormatter": "junstyle.php-cs-fixer",
"editor.defaultFormatter": "DEVSENSE.phptools-vscode",
"editor.formatOnSave": true,
"editor.tabSize": 4,
"editor.insertSpaces": true,
"editor.trimAutoWhitespace": true,
"editor.bracketPairColorization.enabled": true
},
"php.format.codeStyle": "PSR-12",
"php.debug.port": 9000,
"php.stubs": [
"*",
"redis"
],
"editor.rulers": [
150
],
"files.insertFinalNewline": true,
"files.readonlyInclude": {
"**/vendor/**/*": true
},
"javascript.suggest.autoImports": true,
"typescript.suggest.autoImports": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "explicit"
},
"scss.validate": false,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[json][jsonc]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[html]": {
"editor.tabSize": 4,
"editor.formatOnSave": false
}
}
103 changes: 103 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# AGENTS.md

## Contexto do projeto

- Projeto: `developercielo/api-3.0-php`.
- Tipo: SDK/biblioteca PHP para integração com a [API 3.0 E-commerce da Cielo](https://docs.cielo.com.br/ecommerce-cielo/docs/sobre-api-ecommerce).
- Namespace principal: `Cielo\` (autoload PSR-0 em `src/`).
- Ponto de entrada: `Cielo\API30\Ecommerce\CieloEcommerce`.

## Stack e versoes

- PHP: `^8.2` (CI e PHPStan configurados para 8.3).
- Extensoes obrigatorias: `curl`, `json`.
- Composer: `^2.x`.
- Dependencias: `psr/log` (logging opcional via `LoggerInterface`).
- Qualidade: PHPUnit 12, PHPStan 2, PHP-CS-Fixer 3 (dev).

## Estrutura do codigo

- `src/Cielo/API30/Merchant.php`: credenciais do lojista (`MerchantId`, `MerchantKey`).
- `src/Cielo/API30/Environment.php`: interface de ambiente (URLs da API).
- `src/Cielo/API30/Ecommerce/Environment.php`: implementacao sandbox/producao.
- `src/Cielo/API30/Ecommerce/CieloEcommerce.php`: facade principal (create, capture, cancel, query, tokenize).
- `src/Cielo/API30/Ecommerce/Sale.php`: pedido/venda com builder fluente.
- `src/Cielo/API30/Ecommerce/Payment.php`: pagamento (credito, debito, pix, boleto, etc.).
- `src/Cielo/API30/Ecommerce/Customer.php`, `Address.php`, `CreditCard.php`, `RecurrentPayment.php`: modelos de dominio.
- `src/Cielo/API30/Ecommerce/CieloSerializable.php`: contrato de serializacao JSON (`JsonSerializable` + `populate`).
- `src/Cielo/API30/Ecommerce/Request/AbstractRequest.php`: base HTTP (cURL, headers, tratamento de resposta).
- `src/Cielo/API30/Ecommerce/Request/*Request.php`: requisicoes especificas (`CreateSale`, `UpdateSale`, `QuerySale`, etc.).
- `src/Cielo/API30/Ecommerce/Request/CieloRequestException.php`, `CieloError.php`: erros da API.
- `tests/Unit/*`: testes unitarios (namespace `TestApp\`).
- `tests/E2E/*`: testes end-to-end (quando existirem; exigem credenciais reais).

## Padroes de implementacao

- `CieloEcommerce` delega operacoes para classes `*Request`; nao colocar logica HTTP diretamente na facade.
- Modelos de dominio implementam `CieloSerializable` para montar payloads e desserializar respostas.
- Builders fluentes em `Sale` e `Payment` (`$sale->payment(15700)->creditCard(...)`).
- Requisicoes usam cURL com TLS 1.2, headers `MerchantId`/`MerchantKey` e `RequestId` unico.
- Logging via `Psr\Log\LoggerInterface` e opcional; quando presente, dados de cartao sao mascarados em `AbstractRequest`.
- Preserve compatibilidade retroativa: e um SDK publicado consumido por aplicacoes de pagamento.

## Diretrizes para alteracoes

- Evite quebrar assinaturas publicas sem justificativa clara e sem atualizar testes.
- Para novos meios de pagamento ou operacoes, siga o padrao existente: modelo + request + metodo em `CieloEcommerce`.
- Mantenha coesao por modulo (`Ecommerce`, `Request`, modelos de dominio).
- Consulte o manual oficial da Cielo para campos, codigos de erro e fluxos de autenticacao (debito, 3DS, etc.).
- O SDK monta transacoes; redirecionamento do usuario (debito, boleto, pix) fica a cargo da aplicacao consumidora.

## Qualidade e convencoes

- Arquivos em UTF-8 e quebra de linha `LF`.
- Indentacao: preferir `4 espacos` (codigo legado pode conter tabs em trechos antigos).
- Convencoes: classe `PascalCase`, metodo/variavel `camelCase`, constante `SCREAMING_SNAKE_CASE`.
- Analise estatica: `phpstan.neon` (nivel 5, PHP 8.3).
- Sempre adicionar/atualizar testes quando alterar comportamento publico.
- Toda alteracao deve terminar com analise estatica e testes antes de concluir a tarefa.

## Comandos relevantes

- Validacao completa local: `composer test` (PHPStan + PHPUnit, exclui grupo `payment`).
- PHPStan: `composer phpstan`
- Checar formato: `composer format:check`
- Corrigir formato: `composer format:fix`
- Lint padrao do projeto: `composer lint`
- PHPUnit (todos os testes, exceto grupo `payment`): `composer phpunit`
- Testes unitarios: `composer test:unit`
- Testes E2E: `composer test:e2e` (requer credenciais e ambiente configurados)
- Validar `composer.json`: `composer validate --strict`
- Auditoria de seguranca: `composer audit --no-dev`

## Seguranca e limites

- Nunca commitar credenciais: `MerchantId`, `MerchantKey`, tokens de cartao, dados de cartao reais.
- Nunca registrar CVV, numero completo de cartao ou chaves em logs, mensagens de erro ou dumps de debug.
- O SDK ja mascara numero de cartao em logs de debug; preserve esse comportamento ao alterar `AbstractRequest`.
- Evitar alterar `vendor/` e arquivos gerados automaticamente.
- Em erros/excecoes, evitar expor respostas brutas da API com dados sensiveis ao usuario final.
- Testes que chamam a API real devem usar `@group payment` e ficar fora da suite padrao.
- Validar entradas de modelos (valores em centavos, bandeiras, tipos de pagamento) ao adicionar novos campos.

## Testes e validacao final (obrigatorio)

- Ao finalizar qualquer alteracao, executar obrigatoriamente:
- `composer phpstan`
- `composer test:unit`
- Para alteracoes que impactam integracao HTTP ou fluxos de pagamento, rodar tambem `composer test:e2e` quando aplicavel.
- Se houver falha em qualquer comando, corrigir e rodar novamente ate passar.
- Nao considerar tarefa concluida sem evidenciar que analise estatica e testes passaram.

## Commits (obrigatorio)

Usar Conventional Commits em ingles (en-US):

- `<tipo>(<escopo>): <mensagem curta em en-US>`
- Tipos: `feat`, `fix`, `refactor`, `chore`, `docs`, `style`, `perf`, `test`, `build`, `ci`, `revert`

Exemplos:

- `feat(ecommerce): adicionar suporte a novo meio de pagamento`
- `fix(request): corrigir mascaramento de cartao nos logs de debug`
- `test(unit): cobrir serializacao de pagamento pix`
Loading