Repository navigation
feat: IPN handler + security hardening (shared-state mutation, secret exposure) - #12
Merged
Merged
Conversation
…rams HIGH-1: derive the token payment URL (/card4) from an immutable base on each request instead of appending onto the shared configuration singleton, which previously accumulated (/card4/card4) and leaked across requests. HIGH-2: drop the dead setParameter() calls that copied private_key and signature into the container parameter bag (dumped to the compiled container cache in cleartext); configuration already flows via method calls.
… default
LOW-5: the signature node previously defaulted to a placeholder
('XXXX-...'), which defeated cannotBeEmpty() — a missing signature
silently booted with a bogus value. It is now isRequired(), so the
bundle fails fast at config processing. Also declares strict_types.
LOW-6: validate orderId/amount/currency at the boundary before the try/catch so a specific input error is not masked by the generic 'Payment failed.' handler. MEDIUM-3: warn (docblock + docs) that passing raw PAN/CVV through composeCreditCardObject places the app in PCI-DSS SAQ-D scope; the hosted payment page is the recommended flow. Also declares strict_types.
2 of 3 tasks
birkof
added a commit
that referenced
this pull request
Jun 17, 2026
…egration guide (#13) Replace the outdated README stub (which claimed Symfony 3.4/4.0 support) with a grounded architecture overview plus Installation and Usage sections, and rewrite src/Resources/doc/index.md as a complete integration guide: config/bundles.php registration, required-signature config, the mandatory confirm/return routes, the outbound payment flow (auto-submit form), and the inbound IPN handling flow. Documents the IPN handler and payment-input/config hardening now on main (PR #12).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an authenticated IPN handler to the bundle and hardens the payment flow (security + quality findings from a review).
Security fixes
/card4is now derived from an immutable base per request viaresolvePaymentUrl(); the sharedNetopiaMobilPayConfigurationsingleton is no longer mutated (previously accumulated/card4/card4and leaked across requests).setParameter()calls that copiedprivate_key/signatureinto the container parameter bag (cleartext cache dump). A test asserts no secret parameters are registered.New feature — IPN handler (
src/Notification/)IpnActionenum (+Unknownfallback),IpnResultimmutable DTO (vendorNotifykept out of consumer code, money as string).NetopiaMobilPayIpnHandler(+interface):decrypt()opens the RSA envelope with the merchant private key (decrypt = authenticity), threadingcipher/ivfor aes-256-cbc on OpenSSL 3; logs only$e->getCode()on failure (no crypto-step leak);confirmResponse()/errorResponse()build<crc>viaDOMDocument(XML-escaped, non-self-closing<crc></crc>).NetopiaMobilPayConfigurationis now a single private shared service consumed by both the payment service and the publicnetopia_mobilpay.ipn_handler(autowired by interface alias).Additional hardening
signatureconfig is nowisRequired()(fail fast) instead of a placeholder default that defeatedcannotBeEmpty().declare(strict_types=1)across all bundle classes.Test Plan
vendor/bin/phpunit→ 33 tests, 134 assertions/card4/card4accumulationopenssl_seal→decrypt; plus empty/garbage payload throw<crc></crc>ack non-self-closing;errorResponsesets type/code and XML-escapes messagephp -lclean on all sources<crc></crc>ack format against a live Netopia sandbox before production use