Beispiel #1
0
def process_transaction(transaction_id):
    try:
        transaction = Transaction.objects.get(id=transaction_id,
                                              estado=Estado.submitted)
    except DoesNotExist:
        abort(401)

    order = transaction.get_order()
    transaction.save()

    order.monto = order.monto / 100

    res = order.registra()

    if res is not None and res.id > 0:
        transaction.stp_id = res.id
        transaction.events.append(
            Event(type=EventType.completed, metadata=str(res)))
        transaction.save()
        return 201, transaction
    else:
        transaction.events.append(
            Event(type=EventType.error, metadata=str(res)))
        transaction.save()
        return 400, res
Beispiel #2
0
def re_execute_transactions(speid_id):
    """Retry send a transaction to STP, it takes the values
    of the event created before
    """
    transaction = Transaction.objects.get(speid_id=speid_id)

    if transaction is None:
        raise ValueError('Transaction not found')

    order = transaction.get_order()
    transaction.save()

    order.monto = order.monto / 100

    res = order.registra()

    if res is not None and res.id > 0:
        transaction.stp_id = res.id
        transaction.events.append(
            Event(type=EventType.completed, metadata=str(res)))
    else:
        transaction.events.append(
            Event(type=EventType.error, metadata=str(res)))

    transaction.save()
Beispiel #3
0
def execute(order_val: dict):
    # Get version
    version = 0
    if "version" in order_val:
        version = order_val['version']
    if time_in_range(START_DOWNTIME, STOP_DOWNTIME, datetime.utcnow().time()):
        raise ScheduleError
    transaction = Transaction()
    try:
        input = factory.create(version, **order_val)
        transaction = input.transform()

        if not clabe.validate_clabe(transaction.cuenta_beneficiario) and (
                not luhnmod10.valid(transaction.cuenta_beneficiario)):
            raise MalformedOrderException()
    except (MalformedOrderException, TypeError, ValueError):
        transaction.set_state(Estado.error)
        transaction.save()
        raise MalformedOrderException()

    try:
        prev_trx = Transaction.objects.get(speid_id=transaction.speid_id)
        # Si la transacción ya esta como succeeded termina
        # Puede suceder cuando se corre la misma tarea tiempo después
        # Y la transacción ya fue confirmada por stp
        assert prev_trx.estado != Estado.succeeded
        transaction = prev_trx
        transaction.events.append(Event(type=EventType.retry))
    except DoesNotExist:
        transaction.events.append(Event(type=EventType.created))
        transaction.save()
        pass
    except AssertionError:
        # Para evitar que se vuelva a mandar o regresar se manda la excepción
        raise ResendSuccessOrderException()

    if transaction.monto > MAX_AMOUNT:
        transaction.events.append(Event(type=EventType.error))
        transaction.save()
        raise MalformedOrderException()

    now = datetime.utcnow()
    try:
        # Return transaction after 2 hours of creation
        assert (now - transaction.created_at) < timedelta(hours=2)
        transaction.create_order()
    except (
            AssertionError,
            InvalidAccountType,
            InvalidAmount,
            InvalidInstitution,
            InvalidTrackingKey,
            PldRejected,
            ValidationError,
    ):
        transaction.set_state(Estado.failed)
        transaction.save()
Beispiel #4
0
def test_event():
    received = Event(type=EventType.received)
    completed = Event(type=EventType.completed)
    transaction = Transaction(events=[received, completed])
    transaction.save()
    id_trx = transaction.id
    transaction = Transaction.objects.get(id=id_trx)
    assert len(transaction.events) == 2
    assert transaction.events[0].type == received.type
    assert transaction.events[1].type == completed.type
    transaction.delete()
Beispiel #5
0
def execute(order_val):
    # Get version
    version = 0
    if "version" in order_val:
        version = order_val['version']

    transaction = Transaction()
    try:
        input = factory.create(version, **order_val)
        transaction = input.transform()

        if not clabe.validate_clabe(transaction.cuenta_beneficiario) and (
                not luhnmod10.valid(transaction.cuenta_beneficiario)):
            raise MalformedOrderException()
    except (MalformedOrderException, TypeError, ValueError):
        transaction.set_state(Estado.error)
        transaction.save()
        raise MalformedOrderException()

    try:
        prev_trx = Transaction.objects.get(speid_id=transaction.speid_id)
        transaction = prev_trx
        transaction.events.append(Event(type=EventType.retry))
    except DoesNotExist:
        transaction.events.append(Event(type=EventType.created))
        pass

    if transaction.monto > MAX_AMOUNT:
        transaction.events.append(Event(type=EventType.error))
        transaction.save()
        raise MalformedOrderException()

    order = transaction.get_order()
    transaction.save()

    # Send order to STP
    order.monto = order.monto / 100

    res = order.registra()

    if res is not None and res.id > 0:
        transaction.stp_id = res.id
        transaction.events.append(
            Event(type=EventType.completed, metadata=str(res)))
    else:
        transaction.events.append(
            Event(type=EventType.error, metadata=str(res)))

    transaction.save()
Beispiel #6
0
def process_outgoing_transactions(self, transactions: list):
    for request_dic in transactions:
        try:
            transaction = Transaction.objects.get(
                speid_id=request_dic['speid_id'])
        except DoesNotExist:
            continue

        action = request_dic['action']
        if action == Estado.succeeded.value:
            new_estado = Estado.succeeded
            event_type = EventType.completed
        elif action == Estado.failed.value:
            new_estado = Estado.failed
            event_type = EventType.error
        else:
            raise ValueError('Invalid event type')

        if transaction.estado == new_estado:
            continue
        else:
            transaction.estado = new_estado
        transaction.set_state(transaction.estado)
        transaction.events.append(
            Event(type=event_type, metadata=str('Reversed by recon task')))
        transaction.save()
Beispiel #7
0
def execute_create_account(account_dict: dict):
    account_val = AccountValidation(**account_dict)  # type: ignore
    # Look for previous accounts
    account = account_val.transform()
    try:
        previous_account = Account.objects.get(cuenta=account.cuenta)
    except DoesNotExist:
        account.events.append(Event(type=EventType.created))
        account.save()
    else:
        account = previous_account
        account.events.append(Event(type=EventType.retry))

    if account.estado is Estado.succeeded:
        return

    account.create_account()
Beispiel #8
0
def migrate_from_csv(transactions, events, requests):
    """
    Hace la migración de una base de datos Postgres a MongoDB, los datos deben
     ser exportados a CSV antes de ser ejecutado, se puede utilizar el archivo
     scripts/migrate_postgres_mongo.sh para ejecutar la tarea completa
    :param transactions: Archivo CSV con los datos de las transacciones
    :param events: Archivo CSV con los eventos relacionados a las transacciones
    :param requests: Archivo CSV con los requests
    :return:
    """
    transactions_list = pandas.read_csv(
        transactions,
        converters=dict(institucion_ordenante=lambda x: str(x),
                        institucion_beneficiaria=lambda x: str(x),
                        cuenta_ordenante=lambda x: str(x),
                        cuenta_beneficiario=lambda x: str(x)))
    transactions_list = transactions_list.where(
        (pandas.notnull(transactions_list)), None)
    events_list = pandas.read_csv(events)
    events_list = events_list.where((pandas.notnull(events_list)), None)
    transactions = []
    for _, t in transactions_list.iterrows():
        t['stp_id'] = t['orden_id']
        del t['orden_id']
        if t['estado'] in ['ND', 'success', 'liquidacion']:
            t['estado'] = 'succeeded'
        t['institucion_beneficiaria'] = str(t['institucion_beneficiaria'])
        t['cuenta_ordenante'] = str(t['cuenta_ordenante'])
        t['cuenta_beneficiario'] = str(t['cuenta_beneficiario'])

        transaction = Transaction(**t)

        transaction_events = events_list[events_list.transaction_id == t['id']]
        for _, e in transaction_events.iterrows():
            transaction.events.append(
                Event(type=EventType[e['type']],
                      metadata=e['meta'],
                      created_at=datetime.strptime(e['created_at'],
                                                   '%Y-%m-%d %H:%M:%S.%f')))

        transaction.id = None
        transactions.append(transaction)

    requests_list = pandas.read_csv(requests)
    requests_list = requests_list.where((pandas.notnull(requests_list)), None)
    requests = []
    for _, r in requests_list.iterrows():
        r['method'] = r['method'].upper()
        request = Request(**r)
        request.id = None
        requests.append(request)

    Request.objects.insert(requests)
    for transaction in transactions:
        transaction.save()
Beispiel #9
0
def callback_spei_transaction(transaction_id, transaction_status):
    """Establece el estado de la transacción,
    valores permitidos succeeded y failed"""
    transaction = Transaction.objects.get(id=transaction_id)
    if transaction_status == Estado.succeeded.value:
        transaction.estado = Estado.succeeded
        event_type = EventType.completed
    elif transaction_status == Estado.failed.value:
        transaction.estado = Estado.failed
        event_type = EventType.error
    else:
        raise ValueError('Invalid event type')
    set_status_transaction(transaction.speid_id, transaction.estado.value)
    transaction.events.append(
        Event(type=event_type, metadata=str('Reversed by SPEID command')))
    transaction.save()
def test_transaction():
    transaction = Transaction(
        concepto_pago='PRUEBA',
        institucion_ordenante='646',
        cuenta_beneficiario='072691004495711499',
        institucion_beneficiaria='072',
        monto=1020,
        nombre_beneficiario='Ricardo Sánchez',
        nombre_ordenante='BANCO',
        cuenta_ordenante='646180157000000004',
        rfc_curp_ordenante='ND',
        speid_id='speid_id',
    )
    transaction.events.append(Event(type=EventType.created))
    transaction.events.append(Event(type=EventType.received))
    transaction.events.append(Event(type=EventType.retry))
    transaction.events.append(Event(type=EventType.retry))
    transaction.events.append(Event(type=EventType.error))
    transaction.events.append(Event(type=EventType.completed))

    transaction.save()
    trx_saved = Transaction.objects.get(id=transaction.id)
    assert transaction.concepto_pago == trx_saved.concepto_pago
    assert transaction.institucion_beneficiaria == (
        trx_saved.institucion_beneficiaria)
    assert transaction.cuenta_beneficiario == trx_saved.cuenta_beneficiario
    assert transaction.institucion_beneficiaria == (
        trx_saved.institucion_beneficiaria)
    assert transaction.monto == trx_saved.monto
    assert transaction.nombre_beneficiario == trx_saved.nombre_beneficiario
    assert transaction.nombre_ordenante == trx_saved.nombre_ordenante
    assert transaction.cuenta_ordenante == trx_saved.cuenta_ordenante
    assert transaction.rfc_curp_ordenante == trx_saved.rfc_curp_ordenante
    assert transaction.speid_id == trx_saved.speid_id
    assert len(trx_saved.events) == 6
    transaction.delete()
Beispiel #11
0
def retry_incoming_transactions(speid_ids: List[str]) -> None:
    for speid_id in speid_ids:
        transaction = Transaction.objects.get(speid_id=speid_id)
        transaction.events.append(Event(type=EventType.retry))
        transaction.confirm_callback_transaction()
        transaction.save()