Пример #1
0
def create_pending_payment(order, config, amount=NOTSET):
    """Create a placeholder payment entry for the order.
    This is done by step 2 of the payment process."""
    key = str(config.KEY.value)
    if amount == NOTSET:
        amount = Decimal("0.00")

    # Kill old pending payments
    payments = order.payments.filter(transaction_id__exact="PENDING",
                                     payment__exact=key)
    ct = payments.count()
    if ct > 0:
        log.debug("Deleting %i expired pending payment entries for order #%i",
                  ct, order.id)

        for pending in payments:
            pending.delete()

    log.debug("Creating pending %s payment for %s", key, order)

    try:
        exchange_rate = order.currency.exchange_rates.latest().rate
    except ExchangeRate.DoesNotExist:
        exchange_rate = Decimal("1.00")

    orderpayment = OrderPayment(
        order=order,
        amount=amount,
        exchange_rate=exchange_rate,
        payment=key,
        transaction_id="PENDING",
    )
    orderpayment.save()

    return orderpayment
Пример #2
0
def create_pending_payment(order, config, amount=NOTSET):
    """Create a placeholder payment entry for the order.
    This is done by step 2 of the payment process."""
    key = unicode(config.KEY.value)
    if amount == NOTSET:
        amount = Decimal("0.00")

    # Kill old pending payments
    payments = order.payments.filter(
        transaction_id__exact="PENDING",
        payment__exact=key
    )
    ct = payments.count()
    if ct > 0:
        log.debug("Deleting %i expired pending payment entries for order #%i", ct, order.id)

        for pending in payments:
            pending.delete()

    log.debug("Creating pending %s payment for %s", key, order)

    orderpayment = OrderPayment(
        order=order,
        amount=amount,
        payment=key,
        transaction_id="PENDING"
    )
    orderpayment.save()

    return orderpayment
Пример #3
0
def create_pending_payment(order, config, amount=NOTSET):
    """Create a placeholder payment entry for the order.
    This is done by step 2 of the payment process."""
    key = unicode(config.KEY.value)
    if amount == NOTSET:
        amount = Decimal("0.00")

    # Kill old pending payments
    payments = order.payments.filter(transaction_id__exact="PENDING",
                                     payment__exact=key)
    ct = payments.count()
    if ct > 0:
        log.debug("Deleting %i expired pending payment entries for order #%i",
                  ct, order.id)

        for pending in payments:
            pending.delete()

    log.debug("Creating pending %s payment for %s", key, order)

    orderpayment = OrderPayment(order=order,
                                amount=amount,
                                payment=key,
                                transaction_id="PENDING")
    orderpayment.save()

    return orderpayment
Пример #4
0
    def testSmallPayment(self):
        order = TestOrderFactory()
        order.recalculate_total(save=False)

        paytype = config_value("PAYMENT", "MODULES")[0]
        pmt = OrderPayment(order=order, payment=paytype, amount=Decimal("0.000001"))
        pmt.save()

        self.assertTrue(order.is_partially_paid)
Пример #5
0
    def testSmallPayment(self):
        order = TestOrderFactory()
        order.recalculate_total(save=False)

        paytype = config_value("PAYMENT", "MODULES")[0]
        pmt = OrderPayment(order=order,
                           payment=paytype,
                           amount=Decimal("0.000001"))
        pmt.save()

        self.assertTrue(order.is_partially_paid)
Пример #6
0
    def testBalanceMethods(self):
        order = TestOrderFactory()
        order.recalculate_total(save=False)
        price = order.total
        subtotal = order.sub_total

        self.assertEqual(subtotal, Decimal("25.00"))
        self.assertEqual(price, Decimal("35.00"))
        self.assertEqual(order.balance, price)

        paytype = config_value("PAYMENT", "MODULES")[0]
        pmt = OrderPayment(order=order,
                           payment=paytype,
                           amount=Decimal("5.00"))
        pmt.save()

        self.assertEqual(order.balance, Decimal("30.00"))
        self.assertEqual(order.balance_paid, Decimal("5.00"))

        self.assertTrue(order.is_partially_paid)

        pmt = OrderPayment(order=order,
                           payment=paytype,
                           amount=Decimal("30.00"))
        pmt.save()

        self.assertEqual(order.balance, Decimal("0.00"))
        self.assertFalse(order.is_partially_paid)
        self.assertTrue(order.paid_in_full)
Пример #7
0
def record_payment(order, config, amount=NOTSET, transaction_id=""):
    """Convert a pending payment into a real payment."""
    key = unicode(config.KEY.value)
    if amount == NOTSET:
        amount = order.balance

    log.debug("Recording %s payment of %s for %s", key, amount, order)
    payments = order.payments.filter(transaction_id__exact="PENDING",
                                     payment__exact=key)
    ct = payments.count()
    if ct == 0:
        log.debug("No pending %s payments for %s", key, order)
        orderpayment = OrderPayment(order=order,
                                    amount=amount,
                                    payment=key,
                                    transaction_id=transaction_id)

    else:
        orderpayment = payments[0]
        orderpayment.amount = amount
        orderpayment.transaction_id = transaction_id

        if ct > 1:
            for payment in payments[1:len(payments)]:
                payment.transaction_id = "ABORTED"
                payment.save()

    orderpayment.time_stamp = datetime.now()
    orderpayment.save()

    if order.paid_in_full:
        order.order_success()

    return orderpayment
Пример #8
0
def record_payment(order, config, amount=NOTSET, transaction_id=""):
    """Convert a pending payment into a real payment."""
    key = unicode(config.KEY.value)
    if amount == NOTSET:
        amount = order.balance
        
    log.debug("Recording %s payment of %s for %s", key, amount, order)
    payments = order.payments.filter(transaction_id__exact="PENDING", 
        payment__exact=key)
    ct = payments.count()
    if ct == 0:
        log.debug("No pending %s payments for %s", key, order)
        orderpayment = OrderPayment(order=order, amount=amount, payment=key,
            transaction_id=transaction_id)
    
    else:
        orderpayment = payments[0]
        orderpayment.amount = amount
        orderpayment.transaction_id = transaction_id

        if ct > 1:
            for payment in payments[1:len(payments)]:
                payment.transaction_id="ABORTED"
                payment.save()
            
    orderpayment.time_stamp = datetime.now()
    orderpayment.save()
    
    if order.paid_in_full:
        order.order_success()
    
    return orderpayment
Пример #9
0
    def testBalanceMethods(self):
        order = TestOrderFactory()
        order.recalculate_total(save=False)
        price = order.total
        subtotal = order.sub_total

        self.assertEqual(subtotal, Decimal("25.00"))
        self.assertEqual(price, Decimal("35.00"))
        self.assertEqual(order.balance, price)

        paytype = config_value("PAYMENT", "MODULES")[0]
        pmt = OrderPayment(order=order, payment=paytype, amount=Decimal("5.00"))
        pmt.save()

        self.assertEqual(order.balance, Decimal("30.00"))
        self.assertEqual(order.balance_paid, Decimal("5.00"))

        self.assertTrue(order.is_partially_paid)

        pmt = OrderPayment(order=order, payment=paytype, amount=Decimal("30.00"))
        pmt.save()

        self.assertEqual(order.balance, Decimal("0.00"))
        self.assertFalse(order.is_partially_paid)
        self.assertTrue(order.paid_in_full)
Пример #10
0
def create_pending_payment(order, config, amount=NOTSET):
    """Create a placeholder payment entry for the order.
    This is done by step 2 of the payment process."""
    key = str(config.KEY.value)
    if amount == NOTSET:
        amount = Decimal("0.00")

    # Kill old pending payments
    payments = order.payments.filter(
        transaction_id__exact="PENDING", payment__exact=key
    )
    ct = payments.count()
    if ct > 0:
        log.debug(
            "Deleting %i expired pending payment entries for order #%i", ct, order.id
        )

        for pending in payments:
            pending.delete()

    log.debug("Creating pending %s payment for %s", key, order)

    try:
        exchange_rate = order.currency.exchange_rates.latest().rate
    except ExchangeRate.DoesNotExist:
        exchange_rate = Decimal("1.00")

    orderpayment = OrderPayment(
        order=order,
        amount=amount,
        exchange_rate=exchange_rate,
        payment=key,
        transaction_id="PENDING",
    )
    orderpayment.save()

    return orderpayment
Пример #11
0
def record_payment(order, config, amount=NOTSET, transaction_id=""):
    """Convert a pending payment into a real payment."""
    key = str(config.KEY.value)
    if amount == NOTSET:
        amount = order.balance

    log.debug("Recording %s payment of %s for %s", key, amount, order)
    payments = order.payments.filter(transaction_id__exact="PENDING",
                                     payment__exact=key)
    ct = payments.count()
    if ct == 0:
        log.debug("No pending %s payments for %s", key, order)

        try:
            exchange_rate = order.currency.exchange_rates.latest().rate
        except ExchangeRate.DoesNotExist:
            exchange_rate = Decimal("1.00")

        orderpayment = OrderPayment(
            order=order,
            amount=amount,
            exchange_rate=exchange_rate,
            payment=key,
            transaction_id=transaction_id,
        )

    else:
        orderpayment = payments[0]
        orderpayment.amount = amount
        orderpayment.transaction_id = transaction_id

        if ct > 1:
            for payment in payments[1:len(payments)]:
                payment.transaction_id = "ABORTED"
                payment.save()

    orderpayment.time_stamp = datetime.now()
    orderpayment.save()

    if order.paid_in_full:
        order.order_success()

    return orderpayment
Пример #12
0
def record_payment(order, config, amount=NOTSET, transaction_id=""):
    """Convert a pending payment into a real payment."""
    key = str(config.KEY.value)
    if amount == NOTSET:
        amount = order.balance

    log.debug("Recording %s payment of %s for %s", key, amount, order)
    payments = order.payments.filter(
        transaction_id__exact="PENDING", payment__exact=key
    )
    ct = payments.count()
    if ct == 0:
        log.debug("No pending %s payments for %s", key, order)

        try:
            exchange_rate = order.currency.exchange_rates.latest().rate
        except ExchangeRate.DoesNotExist:
            exchange_rate = Decimal("1.00")

        orderpayment = OrderPayment(
            order=order,
            amount=amount,
            exchange_rate=exchange_rate,
            payment=key,
            transaction_id=transaction_id,
        )

    else:
        orderpayment = payments[0]
        orderpayment.amount = amount
        orderpayment.transaction_id = transaction_id

        if ct > 1:
            for payment in payments[1 : len(payments)]:
                payment.transaction_id = "ABORTED"
                payment.save()

    orderpayment.time_stamp = datetime.now()
    orderpayment.save()

    if order.paid_in_full:
        order.order_success()

    return orderpayment
Пример #13
0
def cron_rebill(request=None):
    """Rebill customers with expiring recurring subscription products
    This can either be run via a url with GET key authentication or
    directly from a shell script.
    """
    #TODO: support re-try billing for failed transactions

    if request is not None:
        if not config_value('PAYMENT', 'ALLOW_URL_REBILL'):
            return bad_or_missing(request, _("Feature is not enabled."))
        if 'key' not in request.GET or request.GET['key'] != config_value('PAYMENT','CRON_KEY'):
            return HttpResponse("Authentication Key Required")

    expiring_subscriptions = OrderItem.objects.filter(expire_date__gte=datetime.now()).order_by('order', 'id', 'expire_date')
    for item in expiring_subscriptions:
        if item.product.is_subscription:#TODO - need to add support for products with trial but non-recurring
            if item.product.subscriptionproduct.recurring_times and item.product.subscriptionproduct.recurring_times + item.product.subscriptionproduct.get_trial_terms().count() == OrderItem.objects.filter(order=item.order, product=item.product).count():
                continue
            if item.expire_date == datetime.date(datetime.now()) and item.completed:
                if item.id == OrderItem.objects.filter(product=item.product, order=item.order).order_by('-id')[0].id:
                    #bill => add orderitem, recalculate total, porocess card
                    new_order_item = OrderItem(order=item.order, product=item.product, quantity=item.quantity, unit_price=item.unit_price, line_item_price=item.line_item_price)
                    #if product is recurring, set subscription end
                    if item.product.subscriptionproduct.recurring:
                        new_order_item.expire_date = item.product.subscriptionproduct.calc_expire_date()
                    #check if product has 2 or more trial periods and if the last one paid was a trial or a regular payment.
                    ordercount = item.order.orderitem_set.all().count()
                    if item.product.subscriptionproduct.get_trial_terms().count() > 1 and item.unit_price == item.product.subscriptionproduct.get_trial_terms(ordercount - 1).price:
                        new_order_item.unit_price = item.product.subscriptionproduct.get_trial.terms(ordercount).price
                        new_order_item.line_item_price = new_order_item.quantity * new_order_item.unit_price
                        new_order_item.expire_date = item.product.subscriptionproduct.get_trial_terms(ordercount).calc_expire_date()
                    new_order_item.save()
                    item.order.recalculate_total()
#                    if new_order_item.product.subscriptionproduct.is_shippable == 3:
#                        item.order.total = item.order.total - item.order.shipping_cost
#                        item.order.save()
                    payments = item.order.payments.all()[0]
                    #list of ipn based payment modules.  Include processors that use 3rd party recurring billing.
                    ipn_based = ['PAYPAL']
                    if not payments.payment in ipn_based and item.order.balance > 0:
                        #run card
                        #Do the credit card processing here & if successful, execute the success_handler
                        from satchmo.configuration import config_get_group
                        payment_module = config_get_group('PAYMENT_%s' % payments.payment)
                        credit_processor = payment_module.MODULE.load_module('processor')
                        processor = credit_processor.PaymentProcessor(payment_module)
                        processor.prepareData(item.order)
                        results, reason_code, msg = processor.process()
        
                        log.info("""Processing %s recurring transaction with %s
                            Order #%i
                            Results=%s
                            Response=%s
                            Reason=%s""", payment_module.LABEL.value, payment_module.KEY.value, item.order.id, results, reason_code, msg)

                        if results:
                            #success handler
                            item.order.add_status(status='Pending', notes = "Subscription Renewal Order successfully submitted")
                            new_order_item.completed = True
                            new_order_item.save()
                            orderpayment = OrderPayment(order=item.order, amount=item.order.balance, payment=unicode(payment_module.KEY.value))
                            orderpayment.save()
    return HttpResponse()
Пример #14
0
def cron_rebill(request=None):
    """Rebill customers with expiring recurring subscription products
    This can either be run via a url with GET key authentication or
    directly from a shell script.
    """
    #TODO: support re-try billing for failed transactions

    if request is not None:
        if not config_value('PAYMENT', 'ALLOW_URL_REBILL'):
            return bad_or_missing(request, _("Feature is not enabled."))
        if 'key' not in request.GET or request.GET['key'] != config_value(
                'PAYMENT', 'CRON_KEY'):
            return HttpResponse("Authentication Key Required")

    expiring_subscriptions = OrderItem.objects.filter(
        expire_date__gte=datetime.now()).order_by('order', 'id', 'expire_date')
    for item in expiring_subscriptions:
        if item.product.is_subscription:  #TODO - need to add support for products with trial but non-recurring
            if item.product.subscriptionproduct.recurring_times and item.product.subscriptionproduct.recurring_times + item.product.subscriptionproduct.get_trial_terms(
            ).count() == OrderItem.objects.filter(
                    order=item.order, product=item.product).count():
                continue
            if item.expire_date == datetime.date(
                    datetime.now()) and item.completed:
                if item.id == OrderItem.objects.filter(
                        product=item.product,
                        order=item.order).order_by('-id')[0].id:
                    #bill => add orderitem, recalculate total, porocess card
                    new_order_item = OrderItem(
                        order=item.order,
                        product=item.product,
                        quantity=item.quantity,
                        unit_price=item.unit_price,
                        line_item_price=item.line_item_price)
                    #if product is recurring, set subscription end
                    if item.product.subscriptionproduct.recurring:
                        new_order_item.expire_date = item.product.subscriptionproduct.calc_expire_date(
                        )
                    #check if product has 2 or more trial periods and if the last one paid was a trial or a regular payment.
                    ordercount = item.order.orderitem_set.all().count()
                    if item.product.subscriptionproduct.get_trial_terms(
                    ).count(
                    ) > 1 and item.unit_price == item.product.subscriptionproduct.get_trial_terms(
                            ordercount - 1).price:
                        new_order_item.unit_price = item.product.subscriptionproduct.get_trial.terms(
                            ordercount).price
                        new_order_item.line_item_price = new_order_item.quantity * new_order_item.unit_price
                        new_order_item.expire_date = item.product.subscriptionproduct.get_trial_terms(
                            ordercount).calc_expire_date()
                    new_order_item.save()
                    item.order.recalculate_total()
                    #                    if new_order_item.product.subscriptionproduct.is_shippable == 3:
                    #                        item.order.total = item.order.total - item.order.shipping_cost
                    #                        item.order.save()
                    payments = item.order.payments.all()[0]
                    #list of ipn based payment modules.  Include processors that use 3rd party recurring billing.
                    ipn_based = ['PAYPAL']
                    if not payments.payment in ipn_based and item.order.balance > 0:
                        #run card
                        #Do the credit card processing here & if successful, execute the success_handler
                        from satchmo.configuration import config_get_group
                        payment_module = config_get_group('PAYMENT_%s' %
                                                          payments.payment)
                        credit_processor = payment_module.MODULE.load_module(
                            'processor')
                        processor = credit_processor.PaymentProcessor(
                            payment_module)
                        processor.prepareData(item.order)
                        results, reason_code, msg = processor.process()

                        log.info(
                            """Processing %s recurring transaction with %s
                            Order #%i
                            Results=%s
                            Response=%s
                            Reason=%s""", payment_module.LABEL.value,
                            payment_module.KEY.value, item.order.id, results,
                            reason_code, msg)

                        if results:
                            #success handler
                            item.order.add_status(
                                status='Pending',
                                notes=
                                "Subscription Renewal Order successfully submitted"
                            )
                            new_order_item.completed = True
                            new_order_item.save()
                            orderpayment = OrderPayment(
                                order=item.order,
                                amount=item.order.balance,
                                payment=unicode(payment_module.KEY.value))
                            orderpayment.save()
    return HttpResponse()