datatrans/gateway/refunding.py
def refund(amount: Money, payment_id: str) -> Refund:
    """
    Refunds (partially or completely) a previously authorized and settled payment.
    :param amount: The amount and currency we want to refund. Must be positive, in the same currency
    as the original payment, and not exceed the amount of the original payment.
    :param payment_id: The id of the payment to refund.
    :return: a Refund (either successful or not).
    """
    if amount.amount <= 0:
        raise ValueError('Refund takes a strictly positive amount')
    payment = Payment.objects.get(pk=payment_id)
    if not payment.success:
        raise ValueError('Only successful payments can be refunded')
    if payment.amount.currency != amount.currency:
        raise ValueError('Refund currency must be identical to original payment currency')
    if amount.amount > payment.amount.amount:
        raise ValueError('Refund amount exceeds original payment amount')

    logger.info('refunding-payment', amount=str(amount),
                payment=dict(amount=str(payment.amount), transaction_id=payment.transaction_id,
                             masked_card_number=payment.masked_card_number))

    client_ref = '{}-r'.format(payment.client_ref)

    request_xml = build_refund_request_xml(amount=amount,
                                           original_transaction_id=payment.transaction_id,
                                           client_ref=client_ref,
                                           merchant_id=payment.merchant_id)

    logger.info('sending-refund-request', url=datatrans_processor_url, data=request_xml)

    response = requests.post(
        url=datatrans_processor_url,
        headers={'Content-Type': 'application/xml'},
        data=request_xml)

    logger.info('processing-refund-response', response=response.content)

    refund_response = parse_refund_response_xml(response.content)
    refund_response.save()
    refund_response.send_signal()

    return refund_response
def refund(amount: Money, payment_id: str) -> Refund:
    """
    Refunds (partially or completely) a previously authorized and settled payment.
    :param amount: The amount and currency we want to refund. Must be positive, in the same currency
    as the original payment, and not exceed the amount of the original payment.
    :param payment_id: The id of the payment to refund.
    :return: a Refund (either successful or not).
    """
    if amount.amount <= 0:
        raise ValueError('Refund takes a strictly positive amount')
    payment = Payment.objects.get(pk=payment_id)
    if not payment.success:
        raise ValueError('Only successful payments can be refunded')
    if payment.amount.currency != amount.currency:
        raise ValueError('Refund currency must be identical to original payment currency')
    if amount.amount > payment.amount.amount:
        raise ValueError('Refund amount exceeds original payment amount')

    logger.info('refunding-payment', amount=str(amount),
                payment=dict(amount=str(payment.amount), transaction_id=payment.transaction_id,
                             masked_card_number=payment.masked_card_number))

    client_ref = '{}-r'.format(payment.client_ref)

    request_xml = build_refund_request_xml(amount=amount,
                                           original_transaction_id=payment.transaction_id,
                                           client_ref=client_ref,
                                           merchant_id=payment.merchant_id)

    logger.info('sending-refund-request', url=datatrans_processor_url, data=request_xml)

    response = requests.post(
        url=datatrans_processor_url,
        headers={'Content-Type': 'application/xml'},
        data=request_xml)

    logger.info('processing-refund-response', response=response.content)

    refund_response = parse_refund_response_xml(response.content)
    refund_response.save()
    refund_response.send_signal()

    return refund_response
Refunds (partially or completely) a previously authorized and settled payment.
    :param amount: The amount and currency we want to refund. Must be positive, in the same currency
    as the original payment, and not exceed the amount of the original payment.
    :param payment_id: The id of the payment to refund.
    :return: a Refund (either successful or not).