Oh, I got it now...my bad, I was looking at records of Orders that were not confirmed (right after checkout step 2), which in fact should not even exist in the database records if they are not confirmed...weird.
In order to fix this issue I had to unfortunately modify the core files of Satchmo, so the following code is a suggestion that you can take on your own risk of having some other functionality broken or not being able to update Satchmo with newer versions.
Basically I decided to remove the creation of 'pending_payment' at step 2 and instead create pending payment at the last step 3, simultaneously removing the 'self.record_payment' line from processor.py of COD. Nevertheless, the orders are still being saved in the database after step 2, otherwise I received bunch of errors. You can still tweak the 'status' of orders though, so I managed to define orders after step 2 with status 'Temp' and after confirmation with status 'New'.
So here are the files affected:
/payment/forms.py
class SimplePayShipForm, method save()
def save(self, request, cart, contact, payment_module, data=None):
form_presave.send(SimplePayShipForm, form=self)
if data is None:
data = self.cleaned_data
self.order = get_or_create_order(request, cart, contact, data)
if payment_module and payment_module.KEY.value != "COD": #this is the modified line
processor_module = payment_module.MODULE.load_module('processor')
processor = processor_module.PaymentProcessor(payment_module)
self.orderpayment = processor.create_pending_payment(order=self.order)
else:
self.orderpayment = None
form_postsave.send(SimplePayShipForm, form=self)
Also in the same file, class PaymentContactInfoForm, method save() you can add after self.order = get_or_create_order(request, cart, contact, self.cleaned_data) to define the 'Temp' status:
self.order.add_status(status='Temp', notes = "This order has not been confirmed yet")
/payment/views/confirm.py class ConfirmController:
def _onSuccess(self, controller):
"""Handles a success in payment. If the order is paid-off, sends success, else return page to pay remaining."""
if controller.paymentModule.KEY.value == "COD" or controller.order.paid_in_full: #modified line
controller.cart.empty()
for item in controller.order.orderitem_set.all():
if item.product.is_subscription:
item.completed = True
item.save()
try:
curr_status = controller.order.orderstatus_set.latest()
except OrderStatus.DoesNotExist:
curr_status = None
if (curr_status is None) or (curr_status.notes and curr_status.status == "New") or (curr_status.notes and curr_status.status == "Temp"): #modified line
controller.order.add_status(status='New', notes = "Order successfully submitted")
else:
# otherwise just update and save
if not curr_status.notes:
curr_status.notes = _("Order successfully submitted")
curr_status.save()
#Redirect to the success page
url = controller.lookup_url('satchmo_checkout-success')
return HttpResponseRedirect(url)
else:
url = controller.order.get_balance_remaining_url()
return HttpResponseRedirect(url)
payment/utils.py
def get_or_create_order(request, working_cart, contact, data):
"""Get the existing order from the session, else create using
the working_cart, contact and data"""
shipping = data.get('shipping', None)
discount = data.get('discount', None)
notes = data.get('notes', None)
try:
order = Order.objects.from_request(request)
if order.status != '' and order.status != 'Temp': #modified line
# This order is being processed. We should not touch it!
order = None
except Order.DoesNotExist:
order = None
update = bool(order)
if order:
# make sure to copy/update addresses - they may have changed
order.copy_addresses()
order.save()
if discount is None and order.discount_code:
discount = order.discount_code
else:
# Create a new order.
order = Order(contact=contact)
pay_ship_save(order, working_cart, contact,
shipping=shipping, discount=discount, notes=notes, update=update)
return order
/payment/modules/cod/processor.py
def capture_payment(self, testing=False, order=None, amount=None):
"""
COD is always successful.
"""
if not order:
order = self.order
if amount is None:
amount = order.balance
payment = self.create_pending_payment(order, amount)
#payment = self.record_payment(order=order, amount=amount,
# transaction_id="COD", reason_code='0')
return ProcessorResult(self.key, True, _('COD Pending'), payment)
This is all I did I believe, I hope it could guide you whatever you decide to do!