예제 #1
0
    def test_issue_credit(self):
        refund = self.create_refund(self.processor_name)
        order = refund.order
        basket = order.basket
        amount = refund.total_credit_excl_tax
        currency = refund.currency
        source = order.sources.first()

        transaction_id = 'PAY-REFUND-1'
        paypal_refund = paypalrestsdk.Refund({'id': transaction_id})

        payment = Payment(
            {'transactions': [Resource({'related_resources': [Resource({'sale': Sale({'id': 'PAY-SALE-1'})})]})]})
        with mock.patch.object(Payment, 'find', return_value=payment):
            with mock.patch.object(Sale, 'refund', return_value=paypal_refund):
                self.processor.issue_credit(source, amount, currency)

        # Verify PaymentProcessorResponse created
        self.assert_processor_response_recorded(self.processor.NAME, transaction_id, {'id': transaction_id}, basket)

        # Verify Source updated
        self.assertEqual(source.amount_refunded, amount)

        # Verify PaymentEvent created
        paid_type = PaymentEventType.objects.get(code='refunded')
        order = basket.order_set.first()
        payment_event = order.payment_events.first()
        self.assert_valid_payment_event_fields(payment_event, amount, paid_type, self.processor.NAME, transaction_id)
예제 #2
0
 def get_sale(sale_id, paypal_mode, paypal_client_id, paypal_client_secret):
     return Sale.find(resource_id=sale_id,
                      api=Api({
                          'mode': paypal_mode,
                          'client_id': paypal_client_id,
                          'client_secret': paypal_client_secret
                      }))
예제 #3
0
    def test_issue_credit_error(self):
        refund = self.create_refund(self.processor_name)
        order = refund.order
        basket = order.basket
        amount = refund.total_credit_excl_tax
        currency = refund.currency
        source = order.sources.first()

        transaction_id = 'PAY-REFUND-FAIL-1'
        expected_response = {'debug_id': transaction_id}
        paypal_refund = paypalrestsdk.Refund({'error': expected_response})

        payment = Payment(
            {'transactions': [Resource({'related_resources': [Resource({'sale': Sale({'id': 'PAY-SALE-1'})})]})]})

        # Test general exception
        with mock.patch.object(Payment, 'find', return_value=payment):
            with mock.patch.object(Sale, 'refund', side_effect=ValueError):
                self.assertRaises(GatewayError, self.processor.issue_credit, source, amount, currency)
                self.assertEqual(source.amount_refunded, 0)

        # Test error response
        with mock.patch.object(Payment, 'find', return_value=payment):
            with mock.patch.object(Sale, 'refund', return_value=paypal_refund):
                self.assertRaises(GatewayError, self.processor.issue_credit, source, amount, currency)

        # Verify PaymentProcessorResponse created
        self.assert_processor_response_recorded(self.processor.NAME, transaction_id, expected_response, basket)

        # Verify Source unchanged
        self.assertEqual(source.amount_refunded, 0)
예제 #4
0
def refund_payment(p):
    sale = Sale.find(p.sale_id)
    refund = sale.refund({"amount": {"total": p.amount, "currency": "USD"}})
    if refund.success():
        print("Refund[%s] Success" % (refund.id))
    else:
        print("Unable to Refund")
        print(refund.error)
예제 #5
0
    def refund(self, amount=None):
        saleIds = self.getSaleIds()
        refundData = []

        leftToRefund = amount or 0
        for this_id in saleIds:
            # No need to continue if the full amount requested has been refunded
            if amount is not None and leftToRefund <= 0:
                break

            this_sale = Sale.find(this_id)

            if amount is not None:
                this_amount = min(float(this_sale.amount.total), leftToRefund)

                refund = this_sale.refund({
                    'amount': {
                        'total': '{0:.2f}'.format(this_amount),
                        'currency': getConstant('general__currencyCode'),
                    }
                })
            else:
                refund = this_sale.refund()

            if refund.success():
                logger.info('Refund successfully processed.')

                refundData.append({
                    'status':
                    'success',
                    'refund_id':
                    refund.id,
                    'sale_id':
                    refund.sale_id,
                    'refundAmount':
                    float(refund.amount.total),

                    # This is (annoyingly) hard-coded for now because the Paypal REST API does
                    # not yet report fees in the event of a refund.  Hopefully this can be removed
                    # soon.
                    'fees':
                    -1 * ((float(this_sale.transaction_fee.value) -
                           getConstant('paypal__fixedTransactionFee')) *
                          (float(refund.amount.total) /
                           float(this_sale.amount.total))),
                })
                leftToRefund -= this_amount
            else:
                logger.error('Error processing refund.')
                refundData.append({'status': 'error', 'errors': refund.error})

        return refundData
예제 #6
0
def sale_refund(sale_id):
    """
    paypal 退款
    sale_id: sale_id
    """
    try:
        sale = Sale.find(sale_id)
        refund = sale.refund({})
        log.info('[payment] paypal sale_id: %s refund success', sale_id)
        return refund
    except ResourceNotFound as error:
        log.info('[payment] paypal sale_id: %s refund fail', sale_id)
        return None
예제 #7
0
def ride_booking_refund(ride_booking):
    refund_total = ride_booking.ride.price_with_fee * \
                   ride_booking.seats_count
    payment = Payment.find(ride_booking.paypal_payment_id)
    sale_id = payment.transactions[0].related_resources[0]['sale'].id
    sale = Sale.find(sale_id)

    refund = sale.refund({
        "amount": {
            "total": '{0:.2f}'.format(refund_total),
            "currency": "USD"
        }
    })

    if not refund.success():
        raise Exception("Cannot create a refund:\n{0}".format(refund.error))
예제 #8
0
    def refund(self, amount=None):
        saleIds = self.getSaleIds()
        refundData = []

        leftToRefund = amount or 0
        for this_id in saleIds:
            # No need to continue if the full amount requested has been refunded
            if amount is not None and leftToRefund <= 0:
                break

            this_sale = Sale.find(this_id)

            if amount is not None:
                this_amount = min(float(this_sale.amount.total), leftToRefund)

                refund = this_sale.refund({
                    'amount': {
                        'total': '{0:.2f}'.format(this_amount),
                        'currency': getConstant('general__currencyCode'),
                    }
                })
            else:
                refund = this_sale.refund()

            if refund.success():
                logger.info('Refund successfully processed.')

                refundData.append({
                    'status': 'success',
                    'refund_id': refund.id,
                    'sale_id': refund.sale_id,
                    'refundAmount': float(refund.amount.total),

                    # This is (annoyingly) hard-coded for now because the Paypal REST API does
                    # not yet report fees in the event of a refund.  Hopefully this can be removed
                    # soon.
                    'fees': -1 * (
                        (float(this_sale.transaction_fee.value) - getConstant('paypal__fixedTransactionFee')) *
                        (float(refund.amount.total) / float(this_sale.amount.total))
                    ),
                })
                leftToRefund -= this_amount
            else:
                logger.error('Error processing refund.')
                refundData.append({'status': 'error', 'errors': refund.error})

        return refundData
예제 #9
0
def RefundOrder(capture_id, refund_amount=0, currency_code="EUR"):
    """Use the following function to refund an capture.
		Pass a valid capture ID as an argument."""
    sale = Sale.find(capture_id)

    refund = sale.refund(
        {"amount": {
            "total": refund_amount,
            "currency": currency_code
        }})

    if refund.success():
        print("Refund[%s] Success" % (refund.id))
        return True  # Return True if the Refund was successfull
    else:
        print(refund.error)
        return False  # Return False if the Refund failed
예제 #10
0
 def paypal_api_refund(self, order, refund_amount=False):
     # 搜索出发票 支付过的一般来说 应该就只有一条
     invoice = order.invoice_ids.filtered(lambda x: x.state == 'paid')
     assert len(invoice) == 1, _('The inspection found that there were at least two paid invoices or the invoices were not paid for the order. The system could not identify which invoice was refunded.')
     txn = self.env['payment.transaction'].search([('reference', 'like', invoice.number)])
     txn = txn.filtered(lambda x: x.state == 'done')
     assert len(txn) == 1, _('Invoice number: "%s" Detected that payment has been made many times or has not been paid, the system cannot determine the serial number' % invoice.number)
     x_str = 'mode' if txn.acquirer_id.environment == 'prod' else 'sandbox'
     api = Api(mode=x_str, client_id=txn.acquirer_id.paypal_api_client_id, client_secret=txn.acquirer_id.paypal_api_client_secret)
     sale = Sale.find(txn.acquirer_reference, api=api)
     sale.refund({
         "amount": {
             "total": refund_amount if refund_amount else txn.amount,
             "currency": txn.currency_id.name
         }
     })
     return txn.acquirer_reference
예제 #11
0
# #SaleRefund Sample
# This sample code demonstrate how you can
# process a refund on a sale transaction created
# using the Payments API.
# API used: /v1/payments/sale/{sale-id}/refund
from paypalrestsdk import Sale
import logging
logging.basicConfig(level=logging.INFO)

sale = Sale.find("7DY409201T7922549")

# Make Refund API call
# Set amount only if the refund is partial
refund = sale.refund({
  "amount": {
    "total": "0.01",
    "currency": "USD" } })

# Check refund status
if refund.success():
  print("Refund[%s] Success"%(refund.id))
else:
  print("Unable to Refund")
  print(refund.error)
예제 #12
0
# Get Details of a Sale Transaction Sample
# This sample code demonstrates how you can retrieve
# details of completed Sale Transaction.
# API used: /v1/payments/sale/{sale-id}
from paypalrestsdk import Sale, ResourceNotFound
import logging

logging.basicConfig(level=logging.INFO)

try:
    # Get Sale object by passing sale id
    sale = Sale.find("7DY409201T7922549")
    print(("Got Sale details for Sale[%s]" % (sale.id)))

except ResourceNotFound as error:
    print("Sale Not Found")
예제 #13
0
    refunded_amount = refund['amount']
    id = refund['id']

    # Construct write line for the charge
    delimiter = ";"
    columns = (str(person), str(refunded_amount), str(id))
    line = delimiter.join(columns) + "\n"

    # Write line to file
    csv_file.write(line)

    # Try to refund, if it fails a message will be printed indicating that.
    try:
        # Actual refund

        sale = Sale.find(refund['id'])

        refund = sale.refund(
            {"amount": {
                "total": refund['amount'],
                "currency": "GBP"
            }})

        if refund.success():
            response = "PROCESSED PROPERLY! \n"
        else:
            print(refund.error)
    except:
        response = "***********FAILED TO PROCESS*********** \n"

        # Output post-request string