cyllene-digital / sylius-axepta-plugin
Axepta BNP Paribas payment gateway for Sylius 2.1+.
Package info
github.com/CylleneDigital/SyliusAxeptaPlugin
Type:sylius-plugin
pkg:composer/cyllene-digital/sylius-axepta-plugin
Requires
- php: ^8.2
- ext-hash: *
- ext-mbstring: *
- payum/core: ^1.7
- psr/log: ^3.0
- sylius/sylius: ^2.1
- symfony/config: ^6.4 || ^7.4
- symfony/dependency-injection: ^6.4 || ^7.4
- symfony/form: ^6.4 || ^7.4
- symfony/http-foundation: ^6.4 || ^7.4
- symfony/http-kernel: ^6.4 || ^7.4
- symfony/messenger: ^6.4 || ^7.4
- symfony/routing: ^6.4 || ^7.4
- symfony/service-contracts: ^3.0
- symfony/validator: ^6.4 || ^7.4
- symfony/yaml: ^6.4 || ^7.4
- twig/twig: ^3.10
Requires (Dev)
- behat/behat: ^3.16
- dbrekelmans/bdi: ^1.4
- dmore/behat-chrome-extension: ^1.4
- dmore/chrome-mink-driver: ^2.9
- friends-of-behat/mink: ^1.11
- friends-of-behat/mink-browserkit-driver: ^1.6
- friends-of-behat/mink-debug-extension: ^2.1
- friends-of-behat/mink-extension: ^2.7
- friends-of-behat/page-object-extension: ^0.3
- friends-of-behat/suite-settings-extension: ^1.1
- friends-of-behat/symfony-extension: ^2.6
- friends-of-behat/variadic-extension: ^1.6
- nyholm/psr7: ^1.8
- phpstan/phpstan: ^2.2
- phpstan/phpstan-doctrine: ^2.0
- phpstan/phpstan-webmozart-assert: ^2.0
- phpunit/phpunit: ^10.5
- sylius-labs/coding-standard: ^4.4
- sylius-labs/suite-tags-extension: ~0.2
- sylius/test-application: ^2.0.0@alpha
- symfony/browser-kit: ^6.4 || ^7.4
- symfony/debug-bundle: ^6.4 || ^7.4
- symfony/dotenv: ^6.4 || ^7.4
- symfony/http-client: ^6.4 || ^7.4
- symfony/intl: ^6.4 || ^7.4
- symfony/runtime: ^6.4 || ^7.4
- symfony/web-profiler-bundle: ^6.4 || ^7.4
- symfony/webpack-encore-bundle: ^2.2
This package is auto-updated.
Last update: 2026-08-11 11:32:13 UTC
README
Sylius Axepta BNP Paribas Plugin
Integration of the Axepta BNP Paribas payment gateway for Sylius 2.1+.
Axepta® is a registered trademark of BNP Paribas. This plugin is an independent integration, neither affiliated with, sponsored by, nor endorsed by BNP Paribas. No BNP Paribas or Axepta logo ships with this package.
Compatibility
| Component | Versions |
|---|---|
| PHP | ^8.2 |
| Sylius | ^2.1 |
| Symfony | ^6.4 or ^7.4 |
What this plugin does
Card payment through the card form hosted by the bank (payssl.aspx): the customer is
redirected, enters their card at BNP, and the shop is notified server-to-server.
This plugin implements Axepta BNP Paribas Online 1.0, the generation with
.aspxendpoints. BNP also offers Online 2.0, a REST API with OAuth 2.0 authentication: that is not a version of the same protocol but a separate product, and this plugin does not cover it. No end of support for 1.0 has been announced to date; check that point with your account manager if you are starting a fresh integration.
- Both payment mechanisms of Sylius 2: Payum and PaymentRequest;
- configuration in the back office, per channel;
- overridable redirect page, usable without JavaScript;
- notifications authenticated by HMAC-SHA256, idempotent.
You never see a card number. Payment happens entirely at BNP: your shop stays outside the PCI-DSS SAQ-D scope - SAQ-A is what applies. That does not relieve you of your own obligations, but this plugin adds nothing to them.
The flow
sequenceDiagram
autonumber
participant C as Customer
participant S as Your shop
participant B as BNP payment page
C->>S: Confirms the order
S->>S: Builds the signed and encrypted request
S-->>C: Transition page, self-submitting form
C->>B: Card details, 3-D Secure
B-->>S: Notification, server to server
S->>S: Verifies the MAC, advances the payment
S-->>B: 200 OK
B-->>C: Sends the browser back
C->>S: Lands on the return route
S-->>C: Thank-you page or order page
Loading
Two properties of that sequence matter more than the rest, and both cost an incident before being understood:
Step 5 is what counts, not step 8. The order turns paid on the notification, never on the browser coming back. A customer closing their tab right after paying must still see their order paid. Conversely, a browser coming back proves nothing: it may arrive before the notification, or never arrive at all.
Step 7 must be a 200. A 404 or a 500 there triggers 8 retries from the bank spread over
~21 h 36. The whole notification handling is built around that: no exception surfaces, an unreadable
message is a non-event, and a double notification - the nominal case at BNP - changes nothing rather
than failing.
Installation
composer require cyllene-digital/sylius-axepta-plugin
The Flex recipe registers the bundle and imports the routes. What it cannot do for you - the payment encryption key and the trusted proxies - breaks payments without an error message when skipped.
Every step, and the infrastructure points not to forget:
docs/installation.md.
Configuration
Configuration → Payment methods → Create, gateway "Axepta - BNP Paribas". Fill in the merchant identifier and the two keys supplied by BNP.
⚠️ There is only one endpoint. The MID is what determines whether you are in test or in production - a test MID and a production MID are two distinct identifiers on the same platform. A configuration mistake sends real transactions to production.
Every setting, the key rotation procedure and its pitfall:
docs/configuration.md.
Documentation
| Page | What it covers |
|---|---|
| Installation | Bundle, routes, encryption key, trusted proxies, and the infrastructure points nobody handles unless they are named |
| Configuration | Gateway settings, key rotation, logging, customising the redirect page |
| Payum or PaymentRequest | Which path to pick, and why their notification URLs differ |
| The protocol | What the plugin sends and accepts, telling what BNP guarantees from what was merely observed |
| Acceptance testing | The runbook against the real platform, to walk through before every major version |
| Versioning and support | Public API, internals, support policy |
Sylius 2 offers two payment mechanisms and the plugin implements both; the choice is made per
payment method through usePayum. Standard checkout, take Payum. API or headless, take
PaymentRequest. Both have taken real payments on the BNP test environment.
A flaw is reported privately: SECURITY.md. Do not open it as a public issue.
Status
Exercised against the real BNP platform, on both payment paths: accepted payment, refused card then a fresh attempt, server-to-server notification and signature verification, replayed notification, accented description in ISO-8859-1, and twelve-character merchant reference. The nominal cycles were replayed on the code as it stands; the remaining cases come from an earlier campaign, on a slightly older revision.
The continuous integration matrix is green across the eighteen advertised combinations: PHP 8.2 to 8.5, Symfony 6.4 and 7.4, Sylius 2.1 and 2.2, and MySQL 8.4, MariaDB 11.4 and PostgreSQL 17. The run against the real platform was carried out on PHP 8.4 / Sylius 2.2 / Symfony 7.4 - the only combination on which a payment was actually taken.
Sylius 2.0 is not supported: its cart test context did not restore the security token before 2.1, so the end-to-end scenarios cannot be played there. We would rather not advertise a compatibility we have no way of exercising.
The scope stops at one-off card payment: refund, cancellation, deferred capture, instalments and alternative payment means are not part of it, and all of them would need BNP's server-to-server API, which this plugin never calls.
Contributing
CONTRIBUTING.md - bringing up the test stack, standards, what has to pass.
Provenance and licence
Released under the MIT licence - see LICENSE.
The Blowfish implementation follows Bruce Schneier's public algorithm. The protocol follows the public Axepta BNP Paribas documentation (https://docs.axepta.bnpparibas).
Package: cyllene-digital/sylius-axepta-plugin
Maintained by Cyllene, on GitHub as @CylleneDigital