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
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
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
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)
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)
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
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
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
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
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
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()
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()