Command process_payments will take all payments in state IMPORTED (with optional date limitation). For each payment, it calls one or more payment processors, until one of them succeeds or all processors return negative answer. If any payment processor returns True, payment will be marked as PROCESSED. Otherwise, payment will be marked as DEFERRED (new payment state).
Every processor is a Python class, that MUST implement following methods:
process_payment(BankPayment) -> bool
This method will return True if payment is recognized and processed by the processor. Otherwise, this method returns False.
Add field uuid of type UUIDField to BankPayment model in order to generate nice unique identifier for each payment. Values will be generated by uuid.uuid4() function.
This identifier will be used by payment processors in communication with various systems to prevent data mismatch in case of broken connection or other unexpected events.
Add new web interface for choosing purpose of payment. Any payment in state imported or deferred can be manually assigned its purpose. Each payment processor has to advertise the required items for manual assignment.
Add field processor to BankPayment model. Fill this field when payment is processed.
Add field objective to BankPayment model. This field will be filled with value returned by payment processor for each individual payment.
Each payment processor must return iterable of tuples instead of iterable of booleans. In tuple, there will be processing result followed by objective:
(True, 'Registrar payment')
Add django.admin interface to handle payments and allow manual assigning the purpose.
Add new field client_id to edit form. This field will be used to manually assign the payment, but it won't be saved into database.
Each payment processor must implement new method assign_payment(self, payment: BankPayment, client_id: str) -> Tuple[bool, str]. This method will be used to manually assign payment using client_id.
Remove view PaymentListView.
Add new field default_objective to each payment processor to advertize human readable payment processor description.
Processing payments now takes one payment at a time and feeds it to the processor. However, in some cases (such as communication through REST API) sending payments in bulk is much more efficient. We should extend the interface to allow bulk processing.
Proposed implementation
Add new method process_payments(self, payments: Iterable[BankPayment]) -> Iterable[bool] to processors.common.AbstractPaymentProcessor.
Drop old method process_payment(self, payment: BankPayment) -> bool from processors.common.AbstractPaymentProcessor.
Add new payment processor (see #12) for FRED backend. Communication with FRED backend will be done through CORBA interface. Method process_payment will be implemented as follows:
processor asks backend whether it recognizes the variable symbol
if no, processor returns False
if yes, processor saves invoice details and continue
processor asks backend to create invoice; in return, it will recieve total amount of credits that should be added to registrar account
processor asks backend to add designated amount of credits to registrar account in appropriate zone