Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4409675
PRE-3167 feat: create PaymentOutputDTO
hdelaforce-payplug Feb 10, 2026
9ad1094
PRE-3166 feat: create PaymentInputDTO
hdelaforce-payplug Feb 10, 2026
1f0b2fa
Merge pull request #1 from payplug/PRE-3166-create-PaymentInputDTO
hdelaforce-payplug Feb 16, 2026
eaf43ac
Merge pull request #2 from payplug/PRE-3167-create-PaymentOutputDTO
hdelaforce-payplug Feb 16, 2026
c454b35
PRE-3183 feat: Create trait dependencies loader
hdelaforce-payplug Feb 10, 2026
513747c
PRE-3182 feat: Create payment gateway
hdelaforce-payplug Feb 10, 2026
e692c26
PRE-3168 feat: Create Api Service
hdelaforce-payplug Feb 11, 2026
1101ba8
Merge pull request #4 from payplug/PRE-3182-create-payment-gateway
hdelaforce-payplug Feb 16, 2026
31880b0
Merge pull request #3 from payplug/PRE-3183-create-trait-dependencies…
hdelaforce-payplug Feb 16, 2026
8ee1390
Merge pull request #5 from payplug/PRE-3168-create-api-service
hdelaforce-payplug Feb 17, 2026
b8ec971
PRE-3185 feat: Create payment input&output dto mock
hdelaforce-payplug Feb 18, 2026
3ce4c41
PRE-3186 feat: Create payment action
hdelaforce-payplug Feb 11, 2026
0b0c659
Merge pull request #7 from payplug/PRE-3185-create-dto-mock
hdelaforce-payplug Feb 24, 2026
5a0ffde
Merge pull request #6 from payplug/PRE-3186-create-payment-action
hdelaforce-payplug Feb 24, 2026
56788fd
PRE-3192 feat: Create payment link gateway
hdelaforce-payplug Mar 12, 2026
552f94c
Merge pull request #8 from payplug/PRE-3192-create-payment-link-gateway
hdelaforce-payplug Mar 17, 2026
9d8abbb
PRE-3104 fix: Fix gateway name in load method
hdelaforce-payplug Mar 18, 2026
1cdace7
Pre 3104 create payment link (#12)
hdelaforce-payplug Mar 23, 2026
c46c3c3
PRE-3250: adding qualityCode tools and preCommit hooks
adumont-payplug Mar 18, 2026
81965f0
PRE-3254: passing php-cs-fixer to lint the code base
adumont-payplug Mar 18, 2026
9464821
PRE-3254: code quality fixing for level 6
adumont-payplug Mar 18, 2026
e14e4b0
PRE-3255: upgrading phpStan level to 8 and fixe some logic
adumont-payplug Mar 19, 2026
08c045c
PRE-3251: adding CI to generate release in php 7.2 (#15)
adumont-payplug Mar 26, 2026
ce3d7a9
PRE-3169 feat: set coverage vendor
hdelaforce-payplug Feb 11, 2026
71f4f90
PRE-3169: fixing TU with new workflow
adumont-payplug Mar 26, 2026
3cda0f8
PRE-3169: renameTest unit folder
adumont-payplug Mar 26, 2026
f5c297a
PRE-3169: Fix API method call on resource creation
hdelaforce-payplug Mar 30, 2026
1810a98
PRE-3169: Set min php version required to 8.1
hdelaforce-payplug May 22, 2026
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
34 changes: 34 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## Description
<!-- Provide a clear summary of the changes and the problem it solves. -->
<!-- Include any relevant context or background information. -->

**Motivation:**

**Related issue(s):** Closes #

---

## Type of Change
<!-- check the corresponding checkbox(es) with an "x" -->
- 🐛 Bug fix (non-breaking change that fixes an issue) [ ]
- ✨ New feature (non-breaking change that adds functionality) [ ]
- 💥 Breaking change (fix or feature that causes existing functionality to change and that could impact other libs) [ ]
- 🔧 Refactor (no functional changes, code improvement only) [ ]
- 📦 Dependency update [ ]
- 🔒 Security fix [ ]
- 📝 Documentation update [ ]

---

## Checklist
### Code Quality
- [ ] Code is linted and formatted
- [ ] No unnecessary commented-out code or debug logs
- [ ] No hardcoded values (use env variables or config)

### Testing
- [ ] Unit tests added / updated

### Security & Ops
- [ ] No sensitive data or secrets introduced
- [ ] Logging and error handling are appropriate
110 changes: 110 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: CI

on:
push:
branches-ignore:
- main # main is never pushed to directly; releases are tag-driven
tags:
- '*'
pull_request:
branches:
- develop
types: [opened, synchronize, reopened, closed]

jobs:
# -----------------------------------------------------------------------
# 1. QUALITY — static analysis & code style on PHP 8.4 source
# Runs on: push to feature branch | PR opened/updated → develop
# -----------------------------------------------------------------------
quality:
if: github.ref_type != 'tag' && github.event.action != 'closed'
uses: payplug/template-ci/.github/workflows/php-quality.yml@main
with:
php-version: '8.4'

# -----------------------------------------------------------------------
# 2. DOWNGRADE — transpile src/ + tests/ to PHP 7.2
# Runs on: push to feature branch | PR opened/updated → develop
# -----------------------------------------------------------------------
downgrade:
if: github.ref_type != 'tag' && github.event.action != 'closed'
needs: quality
uses: payplug/template-ci/.github/workflows/php-downgrade.yml@main
with:
php-version: '8.4'
artifact-name: 'payplug-core-php72'
artifact-retention-days: 7

# -----------------------------------------------------------------------
# 3. VALIDATE — install the downgraded package under PHP 7.2
# Runs on: push to feature branch | PR opened/updated → develop
# -----------------------------------------------------------------------
validate:
if: github.ref_type != 'tag' && github.event.action != 'closed'
needs: downgrade
uses: payplug/template-ci/.github/workflows/php-validate.yml@main
with:
php-version: '7.2'
artifact-name: 'payplug-core-php72'

# -----------------------------------------------------------------------
# 4. TEST — run unit tests against the downgraded PHP 7.2 code
# Runs on: push to feature branch | PR opened/updated → develop
# -----------------------------------------------------------------------
test-php72:
if: github.ref_type != 'tag' && github.event.action != 'closed'
needs: validate
uses: payplug/template-ci/.github/workflows/php-test-php72.yml@main
with:
php-version: '7.2'
artifact-name: 'payplug-core-php72'
test-namespace: 'PayplugPluginCore\tests\'

# -----------------------------------------------------------------------
# 5. PUSH-DIST — push transpiled code to dist/{php-target}/{branch}
# Runs in parallel with validate, as soon as downgrade succeeds.
# On feature branch push → dist/php72/feature/xxxx
# On push to develop → dist/php72/develop
# -----------------------------------------------------------------------
push-dist:
if: github.ref_type != 'tag' && github.event.action != 'closed'
needs: validate
permissions:
contents: write
uses: payplug/template-ci/.github/workflows/php72-push-dist.yml@main
with:
artifact-name: 'payplug-core-php72'
source-branch: ${{ github.head_ref || github.ref_name }}
php-target: 'php72'

# -----------------------------------------------------------------------
# 6. PACKAGE — zip and store the artifact on PR merged → develop
# -----------------------------------------------------------------------
package:
if: github.ref_type != 'tag' && github.event.action != 'closed'
uses: payplug/template-ci/.github/workflows/php-package.yml@main
with:
php-version: '8.4'
zip-prefix: 'payplug-plugin-core-php72'

# -----------------------------------------------------------------------
# 7. CLEANUP-DIST — delete dist/php72/feature/xxxx when PR is merged
# -----------------------------------------------------------------------
cleanup-dist:
if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true
permissions:
contents: write
uses: payplug/template-ci/.github/workflows/php72-delete-dist.yml@main
with:
source-branch: ${{ github.head_ref }}
php-target: 'php72'

# -----------------------------------------------------------------------
# 8. RELEASE — create a GitHub Release from a tag on main
# -----------------------------------------------------------------------
release:
if: github.event_name == 'push' && github.ref_type == 'tag'
uses: payplug/template-ci/.github/workflows/php-release.yml@main
with:
php-version: '8.4'
zip-prefix: 'payplug-plugin-core-php72'
10 changes: 8 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,11 @@ node_modules
# Vendor
vendor

# unit tests
tests
# PHP CS Fixer
.php-cs-fixer.php
.php-cs-fixer.cache

# PHPStan
var/
payplug-core/
.claude
24 changes: 24 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

$finder = PhpCsFixer\Finder::create()
->in([
__DIR__ . '/src',
__DIR__ . '/tests',
])
->name('*.php');

return (new PhpCsFixer\Config())
->setRiskyAllowed(true)
->setRules([
'@PSR12' => true,
'@PHP84Migration' => true,
'array_syntax' => ['syntax' => 'short'],
'no_unused_imports' => true,
'ordered_imports' => ['sort_algorithm' => 'alpha'],
'single_quote' => true,
'trailing_comma_in_multiline' => true,
'declare_strict_types' => true,
'void_return' => true,
'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'namespaced'],
])
->setFinder($finder);
24 changes: 24 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
FROM php:8.1-cli

# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
unzip \
curl \
&& rm -rf /var/lib/apt/lists/*

# Install additional extensions via pecl
RUN pecl install xdebug \
&& docker-php-ext-enable xdebug

# Configure Xdebug — mode is controlled at runtime via XDEBUG_MODE env var
RUN echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
&& echo "xdebug.client_port=9003" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
&& echo "xdebug.start_with_request=trigger" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

# Install Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

WORKDIR /app

CMD ["php", "-a"]
70 changes: 70 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
.PHONY: build up down shell install update test stan lint fix debug release

DC = docker compose
PHP = $(DC) run --rm php
PHP_DEBUG = XDEBUG_MODE=debug $(DC) run --rm php

## Docker
build:
$(DC) build

up:
$(DC) up -d

down:
$(DC) down

shell:
$(PHP) bash

## Composer
comp-install:
$(PHP) composer install

update:
$(PHP) composer update

## Quality
test-unit:
$(PHP) vendor/bin/phpunit tests

test-unit-inte:
$(PHP) vendor/bin/phpunit tests --group integration

test-unit-units:
$(PHP) vendor/bin/phpunit tests --group units

tu-dep:
$(PHP) vendor/bin/phpunit tests --display-phpunit-deprecations

stan:
$(PHP) vendor/bin/phpstan analyse

cs-lint:
$(PHP) vendor/bin/php-cs-fixer fix --diff --dry-run

cs-fix:
$(PHP) vendor/bin/php-cs-fixer fix

rector-dry:
$(PHP) vendor/bin/rector process --dry-run

## Release (downgrade src/ to PHP 7.2 into payplug-core/)
release:
rm -rf payplug-core && mkdir payplug-core && cp -r src payplug-core/ && cp -r tests payplug-core/
$(PHP) vendor/bin/rector process --config rector.php
$(PHP) php scripts/generate-release-composer.php

## Debug (Xdebug step-debug enabled)
debug:
$(PHP_DEBUG) bash

## CI (runs all checks)
ci: stan cs-lint test-unit

install: build update comp-install

audit:
$(PHP) composer audit

security: audit
14 changes: 14 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,17 @@ Module core for Payplug integration. Enables management of payments, merchants,

## Next step Dev :
- [ ] Develop endpoint to create a payment link


## Quick start:

```bash
composer install # Hooks are installed automatically
composer cs:fix # Manual code formatting
composer hooks:install # Reinstall hooks if needed
composer hooks:install # Reinstall hooks if needed

composer phpunit:unit # Run only unitary phpUnit tests
composer phpunit:inte # Run only integration phpUnit tests
composer phpunit:all # Run all phpUnit tests
```
73 changes: 73 additions & 0 deletions Security.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Security Report

## ⚠️ <ins>_This report is internal only_</ins> ⚠️

### Critical
1. API Bearer Token Handling — `src/Utilities/Services/Api.php`
The secret API key is stored as a plain string property, passed through getter methods, and could leak in stack traces if exceptions occur.

Recommendation: Never store tokens as plain strings. Obfuscate in any debug output (show last 4 chars only). Clear from memory when no longer needed.

### High
2. Unvalidated URLs Passed to Payment API — src/Gateways/AbstractPaymentGateway.php:28-39
return_url, cancel_url, and notification_url from the DTO are forwarded to the Payplug API without any validation. This opens the door to open redirect and phishing attacks.
``` PHP
'return_url' => $urls['return'], // no validation
'cancel_url' => $urls['cancel'],
```
Recommendation: Validate with ``filter_var($url, FILTER_VALIDATE_URL)``, enforce HTTPS, and optionally restrict to your domain.

3. Empty Whitelist Arrays — `src/Utilities/Traits/DependenciesLoader.php:11-15`
`$allowed_services` and `$allowed_gateways` are initialized empty and never populated, so in_array() checks always evaluate against an empty array — the whitelist mechanism is effectively disabled.

Recommendation: Populate these arrays with the actual allowed values at initialization.

4. Dynamic Class Instantiation — `src/Gateways/PaymentGateway.php:17-20`
The payment method name (user input) is used directly to construct a class name, with no whitelist enforced.
``` PHP
$class = '\PayplugPluginCore\Gateways\Payment\\'
. str_replace('_', '', ucwords($payment_method_name, '_'))
. 'PaymentGateway';
```
Recommendation: Validate against an explicit whitelist (e.g., ['standard', 'apple_pay', 'google_pay']) before building the class name.

5. Exception Message Information Disclosure — src/Utilities/Services/Api.php:82
Raw exception messages are re-thrown to callers, potentially leaking internal configuration details or API information.

Recommendation: Log full errors server-side, expose only generic messages to callers.

### Medium
6. Unvalidated Array Key Access — `src/Gateways/AbstractPaymentGateway.php:33-39`
Direct array access (`$customer['billing']`, `$urls['return']`, etc.) without checking key existence. Will cause PHP warnings/errors on incomplete data.

Recommendation: Use `$array['key'] ?? null` or `array_key_exists()`.

7. Missing Input Validation on Payment Method — `src/Actions/PaymentAction.php:25-27`
Only a null check is performed. No format, length, or character validation.

`// todo: add a validator to check if the given paymentDTO is usable ← still a TODO`

Recommendation: Implement the noted validator, enforce an allowed-values whitelist.

8. Silent Type Coercion in DTO Hydration — `src/Models/Entities/PaymentInputDTO.php:64-71`
Invalid values are silently cast (e.g., `(int) "abc" → 0`) instead of being rejected.

Recommendation: Validate before casting; return meaningful errors for type mismatches.

Low / Informational

| Issue | File |
|-------|---------------------------------------------------------------------------------------------------------------|
| 9 | Internal parameter names exposed in exception messages src/Gateways/Payment/StandardPaymentGateway.php:40 |
| 10 | Generic \Exception used everywhere (hard to distinguish errors) src/Utilities/Exceptions/PayplugException.php |
| 11 | Xdebug included in Docker build (should be dev-only) Dockerfile |


### Priority Action Plan

- Immediate: Add URL validation for `return_url / cancel_url / notification_url`
- Immediate: Populate and enforce service/gateway whitelists
- Short term: Add payment method whitelist validation
- Short term: Implement the `TODO` validator in `PaymentAction`
- Short term: Replace raw exception propagation with a safe error translation layer
- Medium term: Custom exception hierarchy + secure token handling
Loading
Loading