def test_paybc_system_factory(session, public_user_mock): """Assert a paybc service is returned.""" from pay_api.factory.payment_system_factory import PaymentSystemFactory # noqa I001; errors out the test case # Test for CC and CP instance = PaymentSystemFactory.create(payment_method='CC', corp_type='CP') assert isinstance(instance, PaybcService) assert isinstance(instance, PaymentSystemService) # Test for CC and CP with zero fees instance = PaymentSystemFactory.create(fees=0, payment_method='CC', corp_type='CP') assert isinstance(instance, InternalPayService) assert isinstance(instance, PaymentSystemService) # Test for PAYBC Service instance = PaymentSystemFactory.create_from_system_code( PaymentSystem.PAYBC.value) assert isinstance(instance, PaybcService) assert isinstance(instance, PaymentSystemService) # Test for Internal Service instance = PaymentSystemFactory.create_from_system_code( PaymentSystem.INTERNAL.value) assert isinstance(instance, InternalPayService) assert isinstance(instance, PaymentSystemService) # Test for BCOL Service instance = PaymentSystemFactory.create_from_system_code( PaymentSystem.BCOL.value) assert isinstance(instance, BcolService) assert isinstance(instance, PaymentSystemService)
def test_invalid_pay_system(session, public_user_mock): """Test invalid data.""" from pay_api.factory.payment_system_factory import PaymentSystemFactory # noqa I001; errors out the test case from pay_api.exceptions import BusinessException with pytest.raises(BusinessException) as excinfo: PaymentSystemFactory.create(payment_method=None, corp_type=None) assert excinfo.value.code == Error.INVALID_CORP_OR_FILING_TYPE.name with pytest.raises(BusinessException) as excinfo: PaymentSystemFactory.create(payment_method='XXX', corp_type='XXX') assert excinfo.value.code == Error.INVALID_CORP_OR_FILING_TYPE.name with pytest.raises(BusinessException) as excinfo: PaymentSystemFactory.create_from_system_code('XXX', 'XXXX') assert excinfo.value.code == Error.INVALID_CORP_OR_FILING_TYPE.name
def build_pay_system_url(payment: Payment, transaction_id: uuid, pay_return_url: str): """Build pay system url which will be used to redirect to the payment system.""" current_app.logger.debug('<build_pay_system_url') pay_system_service: PaymentSystemService = PaymentSystemFactory.create_from_system_code( payment_system=payment.payment_system_code ) invoice = InvoiceModel.find_by_payment_id(payment.id) invoice_reference = InvoiceReference.find_active_reference_by_invoice_id(invoice.id) return_url = f'{pay_return_url}/{payment.id}/transaction/{transaction_id}' current_app.logger.debug('>build_pay_system_url') return pay_system_service.get_payment_system_url(Invoice.populate(invoice), invoice_reference, return_url)
def delete_payment(cls, payment_id: int): # pylint: disable=too-many-locals,too-many-statements """Delete payment related records. Does the following; 1. Check if payment is eligible to be deleted. 2. Mark the payment and invoices records as deleted. 3. Publish message to queue """ current_app.logger.debug('<delete_payment') # update transaction function will update the status from PayBC _update_active_transactions(payment_id) payment: Payment = Payment.find_by_id(payment_id, skip_auth_check=True) _check_if_payment_is_completed(payment) # Create the payment system implementation pay_service: PaymentSystemService = PaymentSystemFactory.create_from_system_code( payment.payment_system_code) # Cancel all invoices for invoice in payment.invoices: invoice_reference = InvoiceReference.find_active_reference_by_invoice_id( invoice.id) payment_account = PaymentAccount.find_by_pay_system_id( credit_account_id=invoice.credit_account_id, internal_account_id=invoice.internal_account_id, bcol_account_id=invoice.bcol_account_id) pay_service.cancel_invoice( payment_account=payment_account, inv_number=invoice_reference.invoice_number) invoice.invoice_status_code = InvoiceStatus.DELETED.value for line in invoice.payment_line_items: line.line_item_status_code = LineItemStatus.CANCELLED.value invoice.save() invoice_reference.status_code = InvoiceReferenceStatus.CANCELLED.value invoice_reference.save() payment.payment_status_code = PaymentStatus.DELETED.value payment.save() current_app.logger.debug('>delete_payment')
def update_transaction(payment_identifier: int, transaction_id: uuid, # pylint: disable=too-many-locals receipt_number: str): """Update transaction record. Does the following: 1. Find the payment record with the id 2. Find the invoice record using the payment identifier 3. Call the pay system service and get the receipt details 4. Save the receipt record 5. Change the status of Invoice 6. Change the status of Payment 7. Update the transaction record """ transaction_dao: PaymentTransactionModel = PaymentTransactionModel.find_by_id_and_payment_id( transaction_id, payment_identifier ) if not transaction_dao: raise BusinessException(Error.INVALID_TRANSACTION_ID) if transaction_dao.status_code == TransactionStatus.COMPLETED.value: raise BusinessException(Error.INVALID_TRANSACTION) payment: Payment = Payment.find_by_id(payment_identifier, skip_auth_check=True) if payment.payment_status_code == PaymentStatus.COMPLETED.value: raise BusinessException(Error.COMPLETED_PAYMENT) pay_system_service: PaymentSystemService = PaymentSystemFactory.create_from_system_code( payment_system=payment.payment_system_code ) invoice = Invoice.find_by_payment_identifier(payment_identifier, skip_auth_check=True) invoice_reference = InvoiceReference.find_active_reference_by_invoice_id(invoice.id) payment_account = PaymentAccount.find_by_pay_system_id( credit_account_id=invoice.credit_account_id, internal_account_id=invoice.internal_account_id, bcol_account_id=invoice.bcol_account_id) try: receipt_details = pay_system_service.get_receipt(payment_account, receipt_number, invoice_reference) txn_reason_code = None except ServiceUnavailableException as exc: txn_reason_code = exc.status receipt_details = None if receipt_details: # Find if a receipt exists with same receipt_number for the invoice receipt = PaymentTransaction.__save_receipt(invoice, receipt_details) invoice.paid = receipt.receipt_amount if invoice.paid == invoice.total: invoice.invoice_status_code = InvoiceStatus.PAID.value payment.payment_status_code = PaymentStatus.COMPLETED.value payment.save() invoice_reference.status_code = InvoiceReferenceStatus.COMPLETED.value invoice_reference.save() invoice.save() transaction_dao.status_code = TransactionStatus.COMPLETED.value else: transaction_dao.status_code = TransactionStatus.FAILED.value transaction_dao.transaction_end_time = datetime.now() # Publish status to Queue PaymentTransaction.publish_status(transaction_dao, payment, invoice.filing_id) transaction_dao = transaction_dao.save() transaction = PaymentTransaction() transaction._dao = transaction_dao # pylint: disable=protected-access transaction.pay_system_reason_code = txn_reason_code current_app.logger.debug('>update_transaction') return transaction