lelivrescolaire/payment-sips-bundle
A Symfony bundle for integrating the SIPS payment gateway into PHP applications. It provides service configuration and payment handling support to simplify setting up SIPS transactions and routing payment requests through the gateway.
This is a thin Sylius/Symfony bridge to the ATOS SIPS gateway, last touched in 2015 and now archived. Treat the source as the documentation: there are no maintained docs, zero dependents, and no community to ask. Read, in order:
DependencyInjection/Configuration.php — the only authoritative list of config keys.Resources/config/services.xml — service IDs and which class actually talks to SIPS.CaptureActionInterface / NotifyActionInterface).composer.json — pin down the Sylius/Symfony/PHP versions it was written against before you plan anything.Install (pin a commit, since there is no maintained release line):
{
"repositories": [{ "type": "vcs", "url": "https://github.com/lelivrescolaire/KptivePaymentSipsBundle" }],
"require": { "lelivrescolaire/payment-sips-bundle": "dev-master#<commit>" }
}
Register the bundle (Symfony 2-era AppKernel):
new Kptive\PaymentSipsBundle\KptivePaymentSipsBundle(),
Minimal configuration — the keys mirror SIPS request fields (merchant_id, merchant_country, numeric currency, pathfile, return URLs); confirm exact names against Configuration.php:
kptive_payment_sips:
merchant_id: "%sips_merchant_id%"
merchant_country: "fr"
currency: 978 # ISO 4217 numeric, EUR
pathfile: "%kernel.root_dir%/config/sips/pathfile"
normal_return_url: "sylius_payment_after_url"
automatic_return_url: "sips_notify"
First use case: add a payment method in Sylius admin using the SIPS gateway factory, point it at the ATOS test merchant ID and test pathfile, then run one checkout end-to-end. You should be redirected to SIPS' paymentInit, pay with a test card, land back on normal_return_url, and see the order transition to paid. If that loop works, everything else is configuration.
Gateway factory + offsite redirect. The bundle's job is to populate a SIPS request from the Sylius Payment (amount, currency, order reference) and hand the browser an auto-submitting form to SIPS. Keep the bundle's action class thin and put your own order-state logic in a listener or an overridden service.
Return handling — validate, don't trust. SIPS returns a single DATA parameter containing a base64/url-encoded response. Decode it through the bundle's response object rather than by hand, then verify all four things before marking a payment paid:
$response = $this->sips->decodeResponse($request->query->get('DATA'));
if ($response->getCode() !== '00') { /* declined */ }
if ((int) $response->getAmount() !== $payment->getAmount()) { /* tampering */ }
if ($response->getCurrency() !== 978) { /* mismatch */ }
if ($response->getMerchantId() !== $expectedMerchant) { /* mismatch */ }
Two return channels. Use normal_return_url for the customer-facing "thanks / retry" page and automatic_return_url for the reliable server-to-server notification. Only finalize the order from the automatic callback (or from a successfully validated normal return), and make the handler idempotent keyed on the SIPS transaction reference — browsers refresh, users double-submit, and gateways retry.
Recurring / subscription flows. For the subscription use case, the first payment carries SIPS' recurring fields and you persist the returned transaction reference/alias; subsequent charges are issued server-side against that reference, not through a browser redirect. Map SIPS' schedule to your own subscription interval and always record the raw recurring response — you will need it for reconciliation.
Testing. Wrap the response parser in a unit test that feeds it sample DATA strings (valid, duplicate, amount-mismatch, declined). Integration testing should always be against the ATOS test environment, never by replaying a production response.
composer require just works.DATA decoding is the classic bug. SIPS url-encodes then base64-encodes; + turns into a space if you use urldecode instead of rawurldecode, and the response silently fails validation. Decode once, log both raw and decoded.978, not EUR. Mixing this up produces gateway-side rejections with unhelpful codes.pathfile is the #1 deployment failure. It must be an absolute path to a file that references the SIPS request/response binaries, those binaries must be executable, and exec/proc_open must not be disabled. Shared hosting usually fails here.DATA is the only thing that tells you whether SIPS called you or not.Resources/config/services.xml service IDs are your only seams — override or decorate there first; fork only if you need to change the request-building logic.How can I help you explore Laravel packages today?