Commit Graph

3 Commits

Author SHA1 Message Date
jordi fita mas 7e39e5f549 Create new drafts if trying to modify an already pending payment
This can happen when the customer reaches the payment page, but then
returns back to the booking form via the back button: the browser
remembers the URI with the cart slug, trying to make it ready, and then
it fails because it is already pending.

I did not like the idea of modifying a payment that is already not
a draft, because it seems to me that can lead to errors if we receive
Redsys notifications of payments that are being changed back to draft.
In fact, i believe that draft payments maybe should go to a different
relation altogether, so that i can prevent UPDATE on payment by guests,
but maybe i am going overboard now.
2024-02-13 20:16:12 +01:00
jordi fita mas 990a614897 Change draft_payment return type to row of payment
This way i can use the function in the from clause of the query that
i already had to do to get the totals formatted with to_price.  In this
case, i believe it is better to leave out Go’s function because it would
force me to perform two queries.

Instead of binding a nullable string pointer with the payment’s slug,
i wanted to use pgtype’s zeronull.Text type, but it can not work in this
case because it encodes the value as a text, while the parameters is
uuid.  I can not use zero.UUID, because it is a [16]byte array, while i
have it in a string.

Thus, had to create my own ZeroNullUUID type that use a string as a base
but encodes it as a UUID.
2024-02-13 19:51:39 +01:00
jordi fita mas e4636592c5 Add payment relation and use it to compute the booking’s cart
I had to add the payment concept separate from the booking, unlike other
eCommerce solutions that subsume the two into a single “order”, like
WooCommerce, because bookings should be done in a separate Camper
instance that will sync to the public instance, but the payment is done
by the public instance.  There will be a queue or something between
the public and the private instance to pass along the booking
information once the payment is complete, but the public instance still
needs to keep track of payments without creating bookings.

To compute the total for that payment i had to do the same as was doing
until now for the cart.  To prevent duplications, or having functions
with complex return types, i now create a “draft” payment while the
user is filling in the form, and compute the cart there; from Go i only
have to retrieve the data from the relation, that simplifies the work,
actually.

Since the payment is computed way before customers enter their details,
i can not have that data in the same payment relation, unless i allow
NULL values.  Allowing NULL values means that i can create a payment
without customer, thus i moved all customer details to a separate
relation.  It still allows payment without customer, but at least there
are no NULL values.

Draft payments should be removed after a time, but i believe this needs
to be done in a cronjob or similar, not in the Go application.

To update the same payment while filling the same booking form, i now
have a hidden field with the payment slug.  A competent developer would
have used a cookie or something like that; i am not competent.
2024-02-12 05:21:00 +01:00