Markus Michalski FAQ

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

Deutsche Version

Back to overview

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"]
  1. The storefront and the Shop API both trigger a payment request, which Sylius processes through its command bus.
  2. The command provider of the plugin (gateway riverty) picks the command for authorization or status.
  3. 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.
  4. Only the storefront uses the HTTP response provider: it redirects to the hosted checkout or back to the order. A headless client reads redirect_url from 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

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.