Currently, We control Merchello Customer by manual.
When member login with his account, I will create new Merchello Customer by manual.
I create customer at SalePreparationOperationsController: SaveAddresses() method
if (!string.IsNullOrEmpty(model.BillingName)) {
int bupaId = 0;
if(int.TryParse(model.BillingName, out bupaId))
{
var bupa = Services.MemberService.GetById(bupaId);
var existedCustomer = MerchelloServices.CustomerService.GetByLoginName(bupa.Username);
if (existedCustomer == null)
{
var customer = new Customer(bupa.Username)
{
FirstName = bupa.Username,
LastName = bupa.Name,
Email = bupa.Email,
TaxExempt = false
};
MerchelloServices.CustomerService.Save(customer);
Session["CustomerKey"] = customer.Key;
}
else
{
Session["CustomerKey"] = existedCustomer.Key;
}
}
}
And I want to set customer key to Invoice when customer paid payment at SalePreparationBase
public virtual IPaymentResult AuthorizePayment(IPaymentGatewayMethod paymentGatewayMethod, ProcessorArgumentCollection args)
{
Mandate.ParameterNotNull(paymentGatewayMethod, "paymentGatewayMethod");
if (!IsReadyToInvoice()) return new PaymentResult(Attempt<IPayment>.Fail(new InvalidOperationException("SalesPreparation is not ready to invoice")), null, false);
// invoice
var invoice = PrepareInvoice(new InvoiceBuilderChain(this));
if (System.Web.HttpContext.Current.Session["CustomerKey"] != null)
{
var customerKey = Guid.Parse(System.Web.HttpContext.Current.Session["CustomerKey"].ToString());
invoice.CustomerKey = customerKey;
}
MerchelloContext.Services.InvoiceService.Save(invoice);
var result = invoice.AuthorizePayment(paymentGatewayMethod, args);
Finalizing.RaiseEvent(new SalesPreparationEventArgs<IPaymentResult>(result), this);
return result;
}
The problem here is you are mixing methods. SalePreparation (and the new CheckoutManager 1.14.0) rely on the CustomerContext to eventually build an invoice. The invoice is saved when you try to accept a payment to the invoice - in your case AuthorizePayment.
Internal to SalePreparation is a ItemCache collection that essentially makes a copy of the basket contacts and allows for adding additional line items like shipping and tax line items without actually altering the basket contents. These items are used by the PrepareInvoice method in the SalePreparation to generate the invoice (which again is internally saved before a payment is attempted to be applied).
An event handler is attempting to clean things up SalePreparation.Finalizing so that there are not orphaned records in the database as well as emptying the basket.
Checkout the CustomerContextBase class to give you an idea of how the customer should be managed:
Delete cache exception
Hi Rusty,
Currently, We control Merchello Customer by manual. When member login with his account, I will create new Merchello Customer by manual. I create customer at SalePreparationOperationsController: SaveAddresses() method
if (!string.IsNullOrEmpty(model.BillingName)) {
And I want to set customer key to Invoice when customer paid payment at SalePreparationBase
public virtual IPaymentResult AuthorizePayment(IPaymentGatewayMethod paymentGatewayMethod, ProcessorArgumentCollection args)
But It show error delete cache key problem.
What's problem with my code?
The problem here is you are mixing methods. SalePreparation (and the new CheckoutManager 1.14.0) rely on the CustomerContext to eventually build an invoice. The invoice is saved when you try to accept a payment to the invoice - in your case
AuthorizePayment
.Internal to SalePreparation is a
ItemCache
collection that essentially makes a copy of the basket contacts and allows for adding additional line items like shipping and tax line items without actually altering the basket contents. These items are used by thePrepareInvoice
method in the SalePreparation to generate the invoice (which again is internally saved before a payment is attempted to be applied).An event handler is attempting to clean things up
SalePreparation.Finalizing
so that there are not orphaned records in the database as well as emptying the basket.Checkout the CustomerContextBase class to give you an idea of how the customer should be managed:
https://github.com/Merchello/Merchello/blob/merchello-dev/src/Merchello.Web/Pluggable/CustomerContextBase.cs
Here is the
PrepareInvoice
method in SalePreparationhttps://github.com/Merchello/Merchello/blob/merchello-dev/src/Merchello.Core/Sales/SalePreparationBase.cs#L347
is working on a reply...