def capture(token: str, django_user_id=None) -> PagarmePayment: pagarme_transaction = transaction.find_by_id(token) try: return find_payment_by_transaction(pagarme_transaction['id']) except PagarmePayment.DoesNotExist: pass # payment must be captured payment, all_payments_items = PagarmePayment.from_pagarme_transaction( pagarme_transaction) captured_transaction = transaction.capture(token, {'amount': payment.amount}) if django_user_id is None: try: user = _user_factory(captured_transaction) except ImpossibleUserCreation: pass else: django_user_id = user.id if django_user_id is not None: profile = UserPaymentProfile.from_pagarme_dict(django_user_id, captured_transaction) profile.save() payment.user_id = django_user_id payment.extract_boleto_data(captured_transaction) with django_transaction.atomic(): payment.save() payment.items.set(all_payments_items) notification = PagarmeNotification( status=captured_transaction['status'], payment=payment) notification.save() for listener in _payment_status_changed_listeners: listener(payment_id=payment.id) return payment
def _save_notification(payment_id, current_status): """ Will save the notication depending on last status and current status raise Invalid Current Status in case current status is incompatible with last status :param payment_id: :param current_status: :return: """ last_notification = PagarmeNotification.objects.filter(payment_id=payment_id).order_by('-creation').first() last_status = '' if last_notification is None else last_notification.status if current_status in _impossible_states.get(last_status, {}): raise InvalidNotificationStatusTransition(f'Invalid transition {last_status} -> {current_status}') notification = PagarmeNotification(status=current_status, payment_id=payment_id).save() for listener in _payment_status_changed_listeners: listener(payment_id=payment_id) return notification
def test_invalid_transition(status_from, status_to, pagarme_payment): PagarmeNotification(status=status_from, payment=pagarme_payment).save() with pytest.raises(facade.InvalidNotificationStatusTransition): facade._save_notification(pagarme_payment.id, status_to) assert PagarmePayment.objects.count() == 1
def test_repeated_notification_not_saved(status, pagarme_payment): PagarmeNotification(status=status, payment=pagarme_payment).save() with pytest.raises(facade.InvalidNotificationStatusTransition): facade._save_notification(pagarme_payment.id, status) assert PagarmePayment.objects.count() == 1