The client's web interface for payments inside service

Веб-интерфейс клиента для платежей внутри сервиса. Шаблон.

ShariX Developer d57f2fe905 Fix payments payment template block syntax 5 days ago
acquiring 52b62a985e adding cov certificate and other 1 month ago
admin ca2c9b3622 Stage 11.5 commercial settlements and offline policy 1 month ago
apiviews d83047a8a6 better payments scheme 1 month ago
fiscal 6838eb8b7e large refactoring 3 months ago
fonts d21297e8b7 fonts for pdf generation 5 months ago
forms b8ebe7a05e adding subscription 2 months ago
gateways 6838eb8b7e large refactoring 3 months ago
legacy_migrations 92dc177a55 Stage 7.6.6-A canonical migration baselines 1 month ago
lib 92dc177a55 Stage 7.6.6-A canonical migration baselines 1 month ago
locale 986c5d81d3 Stage 14.6 financial workspace clarity 1 month ago
management ca2c9b3622 Stage 11.5 commercial settlements and offline policy 1 month ago
migrations e2153c966b Stage 19.7: make payment migration historical-compatible 1 month ago
models ca2c9b3622 Stage 11.5 commercial settlements and offline policy 1 month ago
serializer e393fb726d changes for payments 2 months ago
services df10ee9ae8 Stage 14.6-14.7 financial clarity and closeout 1 month ago
templates d57f2fe905 Fix payments payment template block syntax 5 days ago
templatetags 986c5d81d3 Stage 14.6 financial workspace clarity 1 month ago
tests e2153c966b Stage 19.7: make payment migration historical-compatible 1 month ago
transports 63ba694720 stage 3 module health 1 month ago
views 63ba694720 stage 3 module health 1 month ago
.gitignore 741f9611b4 Stage 7.6.6-A track retired migration aliases 1 month ago
CODING_POLICY.md 07cde402ae Stage 14.1 progressive UI policy and ownership baseline 1 month ago
LICENSE 8de17e909c stage 16.1 1 month ago
README.md ca2c9b3622 Stage 11.5 commercial settlements and offline policy 1 month ago
RELEASE_POLICY.md e424cdf936 Stage 19.6 release policy and system release projection 1 month ago
apps.py a39ba9f856 Stage 8 reference environment and Stage 9.2 onboarding stabilization 1 month ago
checks.py a39ba9f856 Stage 8 reference environment and Stage 9.2 onboarding stabilization 1 month ago
demo_reference.py a39ba9f856 Stage 8 reference environment and Stage 9.2 onboarding stabilization 1 month ago
license ru.md 989aecf69f Загрузить файлы '' 3 years ago
license.md fe82381562 Обновить 'license.md' 3 years ago
page_help.py df10ee9ae8 Stage 14.6-14.7 financial clarity and closeout 1 month ago
sharix_access.py c164e871e9 adding subscription model 2 months ago
sharix_health.py 63ba694720 stage 3 module health 1 month ago
sharix_menu.py b8ebe7a05e adding subscription 2 months ago
sharix_onboarding.py 17d56515df Stage 10.4-10.6 onboarding and navigation completion 1 month ago
signals.py 6838eb8b7e large refactoring 3 months ago
subscription_category_integration.py b8ebe7a05e adding subscription 2 months ago
tables.py b757d06516 Django 5.2 1 month ago
urls.py b8ebe7a05e adding subscription 2 months ago

README.md

ShariX Open payments

payments is the shared financial library used by ShariX Open and also installed on ShariX Platform. The same repository therefore has two consumers with different orchestration responsibilities.

Ownership modes

The installed Open project selects exactly one payment owner with PAYMENT_PROCESSING_MODE:

  • service — the local payments package performs acquiring and the local order-payment lifecycle;
  • platform — Open delegates payment operations to the Platform payment API;
  • free — paid operations are disabled.

Mixed ownership is not supported. Platform-specific service API routing, settlement orchestration and metaservice logic do not belong in this package. Likewise, Open order/ticket lifecycle code must not be imported by the generic acquiring adapter.

ShariX Platform installs the same payments repository and already consumes shared models/services such as balances and corporate payment helpers. Changes to this repository must therefore remain compatible with both deployments.

Acquiring architecture

Bank protocol code lives under payments/acquiring/:

  • base.py — provider-neutral result and gateway contract;
  • registry.py — provider registration and capabilities;
  • factory.py — selection of a provider for a new operation and strict lookup of the provider recorded by an existing operation;
  • <provider>.py — protocol implementation for one bank/provider.

New operations use PAYMENTS_ACQUIRING_PROVIDER. Existing operations always continue through the provider code persisted with that operation; silently switching an existing payment to the current default provider is forbidden.

The current built-in provider is:

PAYMENTS_ACQUIRING_PROVIDER=vtb

A future bank must be added through the acquiring registry. Provider-specific branches must not be spread through bindings.py, order lifecycle, web or mobile code.

VTB reference contract

When the VTB adapter is changed, compare the merchant REST semantics with both:

  1. the current VTB integration documentation used by the project;
  2. the currently working ShariX Platform implementation, in particular: sxplatform/services/payments/gateways/vtb.py, sxplatform/services/payments/gateway_payments.py and sxplatform/services/payments/bindings.py.

Platform code is a behavioural reference for the bank protocol, not a source of Platform-specific orchestration for Open. Where Platform and this shared adapter differ, first determine whether the difference is provider protocol or consumer-specific orchestration.

Authentication

The current ShariX VTB merchant REST integration authenticates with:

VTB_API_USERNAME=...
VTB_API_PASSWORD=...

VTB_API_TOKEN is legacy configuration. A compatibility settings getter may remain temporarily for old installations/imports, but the shared VTB adapter does not use the token for requests.

Card binding

The canonical card-binding flow is:

register.do
  clientId=<user id>
  features=FORCE_CREATE_BINDING
        ↓
VTB hosted payment form
        ↓
getOrderStatusExtended.do
        ↓
orderStatus == 2
bindingInfo.bindingId is present
        ↓
store exactly that bindingId
        ↓
getBindings.do
        ↓
enrich/synchronise mask and expiry for the same bindingId

createBinding.do is not part of this canonical flow. Completion must never pick an arbitrary pre-existing active card when the current operation did not return its own bindingId.

Saved-card payment and holds

The shared adapter currently exposes the provider-neutral operations required by Open and future Platform reuse:

  • register payment;
  • register payment with a new binding;
  • query payment status;
  • list bindings;
  • pay by saved binding;
  • register a two-stage hold;
  • capture a hold;
  • cancel/reverse a hold;
  • refund, including the existing raw-sum refund variant;
  • deactivate a saved binding;
  • query VTB receipt status for the Platform compatibility facade.

Provider callbacks/status reconciliation remain the responsibility of the consumer's payment service layer.

Removing a ready card is also a provider operation: consumers must call deactivate_binding() for the provider recorded on the binding before they mark the local binding inactive. A failed remote deactivation must not be reported to the user as a successful delete.

VTB configuration

The root .env.example is the canonical list of Open deployment settings. The important values are:

VTB_API_USERNAME=...
VTB_API_PASSWORD=...
VTB_API_REGISTER_URL=...
VTB_API_REGISTER_PREAUTH_URL=...
VTB_API_PAYMENT_ORDER_BINDING_URL=...
VTB_API_DEPOSIT_URL=...
VTB_API_REVERSE_URL=...
VTB_API_REFUND_URL=...
VTB_API_RAW_SUM_REFUND_URL=...
VTB_API_GET_ORDER_STATUS_URL=...
VTB_API_GET_BINDINGS_URL=...
VTB_API_UNBIND_URL=...
VTB_API_GET_RECEIPT_STATUS_URL=...  # required only by consumers using gateway receipt reconciliation
VTB_API_VERIFY_TLS=true
VTB_API_CONNECT_TIMEOUT_SECONDS=5
VTB_API_READ_TIMEOUT_SECONDS=20

Sandbox/production routing is explicit. Do not put credentials, PAN or CVC in logs, API responses or stored diagnostic payloads. Acquiring response snapshots must pass through the acquiring redaction helper before persistence.

TLS trust for VTB

With VTB_API_VERIFY_TLS=true the shared VTB adapter prefers the operating system CA bundle. On ALT Linux p11 the server administrator must keep the packages listed in conf/system-packages/alt-p11.required.txt installed and updated; this includes ca-certificates-digital.gov.ru for Russian Trusted CA. The application does not download certificates and does not install OS packages. After a CA package update run update-ca-trust and verify the application path:

python manage.py check_acquiring_tls

The command performs only an HTTPS/TLS connection check and does not initiate a payment. VTB_API_VERIFY_TLS=false remains an explicit diagnostic override and should not be used in normal operation.

Provider-facing order numbers

New acquiring registrations use short readable unique orderNumber values. Order operations start with the local ShariX order id (for example o54-hold-1844-...), while card binding and personal advance operations use bind-u... and adv-u.... The VTB orderId/mdOrder returned by the gateway is a different identifier and remains stored separately. Provider-facing numbers are capped at 32 ASCII characters.

Required checks after acquiring changes

At minimum run:

python -m compileall -q payments
python manage.py check

For VTB changes also run a sandbox smoke covering registration, binding completion (bindingInfo.bindingId), binding refresh, saved-card payment/hold, capture/reverse and refund as applicable.

Because Platform installs this same repository, verify that Platform can still import and use the shared models/services before updating a Platform deployment.

Platform can route its legacy sxplatform.services.payments.gateways facade through this provider layer. The facade may translate result/exception types, but must not duplicate bank endpoint URLs, request payload construction or VTB response semantics. A guarded cutover is preferred when a deployment has not yet passed the shared-provider sandbox smoke.

Customer actions at the order payment gate

A missing usable card is not an acquiring failure. The shared payment contract uses status=requires_customer_action with the provider-neutral customer action code=bind_card, target=client, reason=no_ready_binding. Open and Platform consumers decide how that action is presented; the payments package must not import ticket handlers, web routes, or mobile navigation. Gateway/configuration errors remain failed and must never be converted to bind_card.

When a payment method becomes ready, a product-specific integration layer may wake or resume its own workflow. ShariX Open does this from dbsynce, after complete_card_binding() succeeds.

Additional compensation processing fee (financial snapshot v3)

Confirmed provider execution costs remain a 1:1 reimbursement and are not part of ordinary Platform/Metaservice/Company commission bases. An optional processing fee is configured by AdditionalCompensationFeePolicy with resolution Service -> ServiceCategory -> NONE. Supported modes are NONE, FIXED, PERCENT, and FIXED_PLUS_PERCENT; percent is calculated from the confirmed compensation amount.

New distributions use snapshot schema v3. economic_gross_amount deliberately keeps its v2 meaning (service + compensation); the amount charged to the client is explicit as customer_charge_gross_amount = service + compensation + compensation_processing_fee_amount. Ordinary commission base remains service_gross_amount. Bonus is capped by service_gross_amount and never finances reimbursement or the processing fee.

The processing fee has a separate idempotent ledger posting. Its recipient is selected only by the current payment owner: PlatformBalance in Platform mode, MetaserviceBalance in Service mode. Shared payments contains no Platform ORM imports; Platform-owned orchestration materializes its own recipient through the shared balance contract.

Canonical migration baseline on Open and Platform

Stage 7.6.6 gives payments one committed migration graph for both products. Platform no longer disables payments migrations or relies on syncdb. Existing Platform tables adopt the validated baseline through the shared adoption command; later migrations, including the processing-fee migration, run through ordinary Django migrate.

Stage 7.6.6 schema-only Platform transition

The historical Platform installation mode that disabled the payments migration loader is retired. The canonical baseline manifest may explicitly adopt the validated Platform schema through 0049_payment_attempt_environment; before recording that checkpoint, payments.services.migration_baseline.schema_only_checkpoint_hook verifies and idempotently reproduces the durable effects of historical data migrations. Migration 0050_additional_compensation_fee_policy is never faked by this transition and must run normally.

Stage 11.5 Service -> Platform commercial settlement

PlatformCommercialSettlement records one immutable completed-calendar-month obligation for a Service. It reuses existing payment facts rather than recomputing order commission:

  • transaction Platform share = existing distribution_platform_income ledger;
  • closed-module monthly subscriptions = calendar-day prorated policy/entitlement history delivered by Platform;
  • total obligation is represented by the existing ClosingDocuments contract;
  • no fake order or second payment ledger is created.

The activation day is billable and final successful revoke day is excluded. A subscription policy revision effective inside the month changes the daily rate from that date. Existing period snapshots are idempotent and are never silently recalculated after later policy changes.

Operational/manual generation for one month:

./venv/bin/python manage.py generate_platform_commercial_settlement --month YYYY-MM --json