italiamultimedia / xpay
A PHP component/library.
v0.0.3
2023-12-06 16:04 UTC
Requires
- php: ^8.2
- psr/log: ^3
- webservco/data: ^0
Requires (Dev)
- pds/skeleton: ^1
- phan/phan: ^5
- php-parallel-lint/php-console-highlighter: ^1
- php-parallel-lint/php-parallel-lint: ^1
- phpcompatibility/php-compatibility: ^9
- phpmd/phpmd: ^2
- phpstan/phpstan: ^1
- phpstan/phpstan-phpunit: ^1
- phpstan/phpstan-strict-rules: ^1
- phpunit/phpunit: ^10
- slevomat/coding-standard: ^8
- squizlabs/php_codesniffer: ^3
- vimeo/psalm: ^5
- webservco/coding-standards: ^0
README
An XPay (Nexi) implementation.
Usage
Currently implemented functionality: Pagamento semplice
1) Extend class AbstractPaymentService
- implement
createCancelUrl
,createNotificationUrl
,createReturnUrl
;
final class PaymentService extends AbstractPaymentService implements PaymentServiceInterface { protected function createCancelUrl(string $orderId): string { ... } protected function createNotificationUrl(string $orderId): string { ... } protected function createReturnUrl(string $orderId): string { ... } }
2) Extend class AbstractRequestInputService
- optionally implement your own validation rules;
final class RequestInputService extends AbstractRequestInputService implements RequestInputServiceInterface { public const KEY_LANGUAGE = 'lang'; public const KEY_ORDER_ID = 'orderId'; protected function getValidationRule(string $key): string { return match ($key) { self::KEY_ORDER_ID => '/^[a-f0-9]{42}$/', default => parent::getValidationRule($key), }; } protected function validateInput(string $key, string $value): bool { if ($key === self::KEY_LANGUAGE) { return $this->validateLanguageCode($value); } return parent::validateInput($key, $value); } }
4) Payment request
<!doctype html> <html> <head> ... </head> <body> <form id="payment_form" method="POST" action="<?=$paymentService->getApiUrl()?>"> <?php foreach ( $paymentService->createPaymentRequestParameters( $languageCode, $orderId, $orderInformation->total, ) as $key => $value ) { ?> <input type="hidden" name="<?=$key?>" value="<?=$value?>" /> <?php } ?> <button type="submit" class="btn btn-primary"> <?=$languageCode === 'it' ? 'Acquista ora' : 'Buy now'?> </button> </form> <script> document.getElementById('payment_form').submit(); </script> </body> </html>
5) Return page
// Validate order (get info from storage) ... /** * Special situation: "mac" can be missing from the request. * Eg. try to pay already paid transaction. * In that situation we don't want to have a transaction error, however we also can not trust the request. * Simply do not process transaction. */ $processTransaction = true; try { // Try to get mac $requestInputService->getValidatedString(RequestInput::MAC); } catch (OutOfBoundsException) { $processTransaction = false; } if ($processTransaction) { // Validate transaction. Uses input data (_GET or _POST). $paymentService->validateTransaction(); // Store transaction result. ... } // Redirect back to website. ...
Development
# Lint composer check:lint && \ # Code style composer check:phpcs && \ # PHPStan composer check:phpstan && \ # Phan composer check:phan && \ # PHPMD composer check:phpmd && \ # Psalm composer check:psalm