Minimal e-shop for Tryton

I don’t see much activity on github regarding Nereid. Any point in particular ?

No.

You were looking for a ready made e-commerce solution for Tryton and there were no links to these in the discussion. I just provided it.

Have you tried the nereid-webshop?

yes andIneedtoadd20characterstovalidatemyanswer:-)

1 Like

It was evaluated to be included in base of Tryton. But there was many concerns about being too much coupled with the view and model. So this means that creating a website was done using the Tryton client and also that it is trytond who is serving the web page.
The preferred approach was to use existing framework like Flask and built simple component to ease access to Tryton data (like Flask-Tryton).

Hi Sergei,

I sent an email to the general Tryton mailing list on this subject but I thought I would try this discussion board as it is an audience more targeted to what I am interested in accomplishing. I apologise in advance for the length but hope it sparks some further discussion and keeps things moving along…

A colleague and I have gotten quite far along in developing exactly what was proposed here (a basic e-shop using Tryton as a back-end). I took my colleague’s prototype Flask application (which used Pickle as a face backend) and adapted it using flask-tryton, with the strategy of keeping as much as possible to stock Tryton modules on the back end. Indeed it has been quite easy to get to build an e-shop and we hope to contribute our efforts to be the basis of a standard GPLed solution that could be incorporated into the Tryton project in general.

Payment processing is indeed the most significant piece of the solution that is not yet provided in a ready-made solution which brought me to this discussion. As suggested I have installed account_payment to get familiar with it and intend in the next few days to develop a “process method” for an online web based payment gateway with the provider’s API calls being made directly between the client’s web browser and the provider, and the resulting token/result code/auth number/etc (or the decline result if that happens instead) then submitted to Tryton to store the payment record. We are in the final stages of devloping the part on cart checkout that talks to a payment gateway called “Beanstream” (a service that is used fairly commonly where I am located in Canada), and I’m now in the early stages of creating an “account_payment_beanstream” module.

As Sergi (pokoli) has confirmed I have discovered a payment does no accounting moves, but it can be associated with the “accounts receivable” move line of a posted invoice. This is where I run into some difficulty in understanding the workflow of account_payment (strictly working through the Tryton client at this point):

  1. If I set an invoice to “paid” state, I cannot associate a payment to the applicable move line of the invoice (I think it is excluded from the domain because it has been reconciled).

  2. If I leave the invoice in the “posted” state the AR payment line of the invoice can be selected for the payment record, and I can go through the manual process to put the payment into the “succeeded” state. However, the account moves are not made so the billing party still shows the outstanding balance. Furthermore the invoice is still in “posted” state but the “amount to pay” is zero. Apparently if there is a “succeeded” account_payment record it is counted against the balance owing on the invoice regardless of actual account moves! I cannot “pay” the invoice because I cannot enter any amount over zero, and entering zero doesn’t advance the invoice to “paid”!

  3. I can create a payment without a line, then do the “pay” on the invoice which sets the right state and accounting moves, however I cannot go back and set the payment line because of problem #1 (if I do try and trick by most means I get the error “The value of the field “Line” on “Payment” is not valid according to its domain.”).

  4. In the Tryton client with the “manual” process, I FINALLY figured out a “hack” way to make it work: I put the invoice into “posted”, then “lines to pay” shows the line I want and I create a payment from it. As soon as that happens the invoice cannot be paid unless I delete the payment or else approve->process->fail it. Once it is in FAILED state the invoice “amount to pay” comes back and I can set the invoice to “paid”, then I can go back to the payment and put it to “succeeded”. The end result appears to be OK! The accounting looks right, the invoice says “paid” and has 0 amount to pay (doesn’t count things twice and get negative or anything), and I have may payment record! However this is a really nonsense way to do it, and I suspect that what I have to do is code the invoice payment action to happen within my “beanstream” process method while in some way working around the issue of any non-failed payment record referring to the invoice’s AR account move line blocking me from doing so.

So, considering the scenario of a “web cart checkout” what is the appropriate solution to this conundrum? I get either correct accounting or correct payment record tracking–but not both, unless I perform some black magic! Here is what I am thinking of doing with my payment gateway process method:

  1. The user finishes shopping and decides to “check out”. The application we have persists the user’s cart as a “sale” record in Tryton, which is kept in “draft” state until the payment is attempted.

  2. Once the response from the payment provider is returned to the browser it is submitted to our application which creates a payment with a move line set to None and immediately sets it to “approved” and calls my new “process” method as described below:

  3. If the result is “NOT APPROVED” or “DECLINED” (they are both failures but subtly different but the process here is the same) we set the payment to “failed” and the user can try again. NOTE that the sale is still in draft and there is no invoice yet so as to best handle “abandoned carts”. QUESTION: I notice payment records can be switched between success and failure at will, so there is the option of reusing the same record for retries. However I do not plan on doing that so I can keep information about declines for support and diagnostic purposes. Each attempt would be its own payment record. Would that be considered the best way of doing things?

  4. If the result is “APPROVED” then the payment process would a) process the sale, b) post the created invoice, c) pay the invoice, d) change the draft payment record’s account move line from None to the AR line of the invoice and finally e) change the account_payment state to “succeeded”. QUESTION: If the user required multiple attempts to pay for the sale what would be the best way to organise the payment records such that failed attempts can be fairly easily linked to a sale–could I use payment groups for this purpose, where most payment groups would just be one payment but some might include some failed attempts as well and I would build some kind of reference between the sale and the payment group, or would it be better do ignore payment groups and reference each payment to the sale individually? I was thinking to use payment groups, but let me know if that is too strange of a way to do it.

Which brings me to the sales reference in that last point: Given the way a typical e-shop works where payment transactions are immediate (not batched) and generally approved before posting (or even creating) invoices they could potentially never be associated with an invoice (if a customer abandons the cart sale after transaction failure) but we would want to retain a complete transaction history for many good reasons. As such we have to build in some kind of reference to sales that does not rely on invoices or account moves. Here is what I am proposing: a very simple module (would I call it sale_payment or sale_account_payment, or account_payment_sale…I’m thinking the first one?) that creates a Many2Many relationship between sales and payment groups. Then my payment processing method would have this as a dependency and I would be able to implement something like discussed above–put all the payment attempts in a group that is linked to a sale, and optionally if the sale is completed I could optionally set the payment records’ move lines to link them to the invoice if desired.

The reasoning for many2many is as follows:

  1. that simple module could be applicable to many use cases: if a batch payment method was used to process payment for multiple sales then it could choose to make one payment group for the batch that has references to many different sales

  2. the same model would also handle the use case I have for my own consulting business, where virtually all my sales involve progress payments (either against one invoice or multiple invoices within the sale). Such payments are usually weeks apart so wouldn’t be processed as a batch. In this case I would probably have one sale that has references to many payment groups.

That is the direction I was thinking of but I wanted to make sure that is in line with the vision of the developers who created the sale and account_payment modules. I also noticed that serious consideration has been made to develop a payment module for stripe. I have not seen anything online for source codes or design proposals however, so I wanted to see where that was at and if it is that far along I wanted to make sure I follow the same patterns for consistency.

Thanks for reading this REALLY long post. If it is suggested it could be turned into a new blueprint discussion. Let me know!

1 Like

Thanks for explaining! :grinning:

Thanks for your sarcasm. =]
Would you please share about your experience with nereid-webshop?

@fmorato:
Bottom line on NEREID was:
NEREID is a maximum e-shop, designed as a full solution. It doesn’t address my specific points (bad luck), implementing, modifying and maintaning would be far too expensive for small businesses.
My conclusion is that in case NEREID is adapted to a prospect’s request, I’d rather cooperate with fulfil.io to deliver the solution, and a minimal e-shop for Tryton, basic and well born is useful to my natural market.

FYI, I found interesting the methodology used by https://shopinvader.com/
The idea to re-use an existing e-commerce software which is pluggable enough to replace some part of the backend by the Tryton backend, seems the best way to achieve this goal without reinventing the wheels.

Indeed you should check the module sale_payment, its purpose is mainly for sale from e-commerce. It allows to register a payment for a quoted sale and once the payment succeed it validate the sale automatically. And the payment will be used to pay the created invoice.

Indeed I participated in the development of the sale_payment module and have since deployed it in production. It was a good fit for the flask based e-shop we deployed. It was a one-off project however we are in the process of cleaning up the code to modularise/package it better and address a couple of things for version 4.8

I just found this project https://www.vuestorefront.io/. It is a webshop front-end, back-end agnostic and mobile first.
It would just require to implement the proper API for a Tryton backend.

2 Likes

Wow, this looks very promising but we still need to have some backend module to store the cart and all the other e-shop information. Probably this can be re-used for other webshop backend (like a flask-tryton one for example)

I think the sale order can be used as cart. We could just have a flag or a state to say it is the current cart for the user.

But the sale order requires a party to be entered and for a cart you may not now the related party until the cart is processed.

So I’m wondering if it won’t be better to use a separate model to store the cart that should be latter converted to sale: once the order is confirmed an we know all the required information.

Indeed this will duplicate a lot of code. For example for shipping cost, promotion, coupon etc.
So for me, the party required is not really a problem, we can create the party up front. If it is a new customer, it is not a problem we need this new party. If it is an existing then we can just merge the parties once the user is logged.

I’m still reading about Vue Frontstore and it is still difficult for me to understand what it is.
IIUC, it results in a ready to use solution for e-shop

  • running both on a browser and a smartphone
  • integrating elastic search and cached operations
  • on the bleeding edge of techno
  • synchronizing data and operations from/to a backbone server

In this case I unsderstand we would have to develop a kind of connector module for VF so the backbone can be Tryton.
It seems from this discussion that the impact on Tryton would be limited and VF doesn’t require a lot of modules to manage the e-shop (like nereid).
And probably, VF is easy to install apart of Tryton for deployment.

I think it would be a perfect fit for a minimal e-shop. Would you see problems in scaling, or in addressing more complex requirements of sites or in customizing at an affordable cost ?

Am I correct so far ?
If I am, that sounds magic, indeed.

For me, I still understand how we should integrate the payment methods like Stripe.
The architecture is clearly designed to scale.
The customization maybe require some knowledge but customization is already a dedicated project. Simple usage may be OK with the default layout.

Indeed there is a Stripe integration. So the payment token is just send as additional payment information.

Until we have more information about the party, we can use the session id for party name.

I don’t think that’s a good idea because the user may be already known but still has not logged in. So I think it’s better to allow to have sales without a party.

The name is not required on party so no need to have any trick here.

Indeed it should not be too complicated to make party only required in none draft state.
My proposal about temporary party comes from what we implemented for https://www.jurassicfruit.com/ but it was because we could not change the required on sale at that time.