Riverty Payments: Technical Details
Technical details of Riverty Payments for Sylius - payment flow diagram, admin operations, data model and tables, migrations, plugin structure, security and tests
Riverty Payments: Technical Details
This documentation always describes the latest published version.
Flow of a payment
graph TD
A["Storefront Twig hook"] --> D["Payment request command bus"]
B["Shop API request"] --> D
D --> E["Command provider of the plugin"]
E --> F["Handler: authorization or status"]
F --> G["Riverty client"]
G --> H["Riverty API"]
F --> I["Payment request and payment state machine"]
I --> J["HTTP response provider, storefront only"]
J --> K["Redirect to Riverty or to the order"]
- The storefront and the Shop API both trigger a payment request, which Sylius processes through its command bus.
- The command provider of the plugin (gateway
riverty) picks the command for authorization or status. - The handlers ask the Riverty API through the Riverty client and move the state machine of the payment request and the one of the payment forward together. The core does not link the two, the plugin does.
- Only the storefront uses the HTTP response provider: it redirects to the hosted checkout or back to the order. A headless client reads
redirect_urlfrom the response data.
Capture, void and refund
The admin actions run through POST routes with a CSRF token per operation (capture, void, refund, each for the whole order or for chosen items), plus create-methods and check-contract for the settings. The bookkeeping of captured, voided and refunded items is kept on the transaction.
Data model
erDiagram
SETTINGS ||--o{ CREDENTIAL : "has"
SETTINGS {
string channel_code
bool show_installment_teaser
bool capture_on_shipment
int expiry_warning_days
datetime last_expiry_digest_at
string existing_customer_data_mode
}
CREDENTIAL {
string country_code
bool sandbox
string encrypted_test_key
string encrypted_live_key
}
TRANSACTION {
string order_reference
string status
int captured_amount
int voided_amount
int refunded_amount
datetime expiry_notified_at
}
PAYMENT ||--o| TRANSACTION : "belongs to"
API_CALL {
datetime created_at
string request_type
string order_reference
}
| Table | Purpose |
|---|---|
mmd_sylius_riverty_settings |
One row per channel (unique channel_code) |
mmd_sylius_riverty_credential |
One entry per country and settings row, deleted together with the settings |
mmd_sylius_riverty_transaction |
One Riverty transaction per order reference, reference to sylius_payment (set to empty when the payment is deleted) |
mmd_sylius_riverty_api_call |
API log without references, so a rollback never loses it, with indexes on time and order reference |
Amounts are stored as integers in the smallest unit, plus running totals for captured, voided and refunded. The items are kept as JSON on the transaction. The status is an enum. The expiration date is the raw value from Riverty, the 30-day limit is calculated separately from the creation time.
Migrations
| Version | Content |
|---|---|
Version20261101090000 |
Settings and credentials tables |
Version20261101100000 |
Transactions table |
Version20261102090000 |
Instalment example option |
Version20261103090000 |
Warning window, time of the last digest, notification time of the transaction |
Version20261104090000 |
API log table |
Version20261105090000 |
Capture on shipment option |
Version20261106090000 |
Order history option (column existing_customer_data_mode, default disabled) |
Plugin structure
src/
Api/ Riverty client, requests and responses
ApiLog/ Recorder, sanitizer, purger
Availability/ Query for the available payment methods
Command/ mmd:riverty:setup, mmd:riverty:reconcile
Controller/Admin Transaction and settings actions
Entity/ Settings, credentials, transaction, API call
EventListener/ Capture on shipment, blocking the Sylius buttons
Expiry/ 30-day monitoring and digest
Form/ Settings, credentials, gateway, checkout field
Mapping/ Building the request to Riverty
Migrations/
Payment/ Authorization, status, operations
PaymentRequest/ Connection to Sylius payment requests
Provisioning/ Create payment methods, check contract
RiskData/ Order history of the customer for Riverty
Security/ Encryption
Twig/ Functions for admin and storefront
config/ grids, routes, twig_hooks, services
templates/ admin and shop
translations/ German and English
Security
- API keys and identification numbers are encrypted with a key derived from
APP_SECRET(OpenSSL). - The API log is written through its own database connection, bypassing the ORM, and masks personal data.
- All admin actions run as POST with a CSRF token.
Tests
The checks run in the Docker stack of the repository:
make phpunit
make phpstan
make ecs
make behat
Behat has three suites: checkout, settings and order. Riverty answers from a script, so nothing leaves the machine and no API key is needed.