Q:

Remove payment option from Sitecore Commerce and use Commerce as "ordering system"

We will be in a process of migrating solution made with Sitecore Commerce 8.2.1 to Sitecore Commerce 9 Update 1 soon.
One of the requirements was to handle all orders without payment using Commerce server basically as "ordering" system. After order was created, we called external webservice that notified financial systems on company side and invoice was generated outside of Sitecore Commerce. This was more B2B commerce system.
We were doing this by creating "fake" federated payment with same amount of money (for products and shipping) to even it and be able to order. Without this we couldn't create order. This was a temporary fix to this problem.
During upgrade, we would like to optimize this to be more transparent to all parties. So if no payment is made in Sitecore Commerce we also won't do any "fake" payment with federated payment. 
Would it be possible to achieve this by turning off payment policy or how can we achieve this ordering scenario without payments?

A:

As of 9.0.1, CreateOrderBlock (the first OOTB block in ICreateOrderPipeline) validates that the payment total equals the grand total of the order and aborts the pipeline if it does not.
However, since the validation is not on the payment objects but on Order.Totals.PaymentsTotal it should be pretty easy to work around.
I would recommend adding a block before (AddTemporaryPaymentsTotal) and after (RemoveTemporaryPaymentsTotal) the CreateOrderBlock:
// AddTemporaryPaymentsTotal
cart.Totals.PaymentsTotal = order.Totals.GrandTotal;

// RemoveTemporaryPaymentsTotal
order.Totals.PaymentsTotal = new Money(order.Totals.GrandTotal.CurrencyCode, 0M);

CreateOrderBlock doesn't actually persist anything, so the temporary value won't be made available to anything else.
You could also replace CreateOrderBlock and patch out the validation check but I would advise against it. The existing block has a fair bit of logic which may cause problems when you upgrade again.

