Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Payment review #67

Merged
merged 62 commits into from
Oct 27, 2023
Merged

Payment review #67

merged 62 commits into from
Oct 27, 2023

Conversation

ShiroUsagi-san
Copy link
Contributor

@ShiroUsagi-san ShiroUsagi-san commented Oct 12, 2023

This PR is about the last big stone of the back-end: payment API.

For now, /payement/pay makes the request to helloasso but the post processing isn't implemented yet.
There is also some CORS issues to solve

TODO

  • /payment/refund

  • handling callbacks

  • cleaning code

  • hardening

  • documentation

  • testing

@ShiroUsagi-san ShiroUsagi-san changed the title Payment review [Draft] Payment review Oct 12, 2023
Copy link
Collaborator

@Lymkwi Lymkwi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added some nitpicks I could read in the code, now I'm going to download it and try and run it so I can get an idea of what is wrong

insalan/payment/admin.py Outdated Show resolved Hide resolved
insalan/payment/apps.py Outdated Show resolved Hide resolved
insalan/payment/tokens.py Outdated Show resolved Hide resolved
@ShiroUsagi-san ShiroUsagi-san added priority:high High Priority help wanted Extra attention is needed labels Oct 12, 2023
@Lymkwi Lymkwi force-pushed the payment branch 2 times, most recently from 9f83f95 to f686fee Compare October 13, 2023 18:53
@Lugrim Lugrim added this to the Production milestone Oct 13, 2023
insalan/settings.py Outdated Show resolved Hide resolved
insalan/settings.py Outdated Show resolved Hide resolved
insalan/payment/tokens.py Outdated Show resolved Hide resolved
Copy link
Contributor

@Lugrim Lugrim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to fix your TODOs, but that's the beginning of something

@Lymkwi
Copy link
Collaborator

Lymkwi commented Oct 14, 2023

Alright so in my opinion the one thing still absolutely needed is a callback system to implement product callbacks. That's it.

@ShiroUsagi-san
Copy link
Contributor Author

For the refund, only admins can achieve this action. This action can only be performed in the djando admin panel, with an action on a transaction. In the front, maybe a form that sends an email to email address. This will reduce the risk to be misused

@Lymkwi
Copy link
Collaborator

Lymkwi commented Oct 15, 2023

So today I added:

  • The entire hooks/callbacks system
  • Admin interface stuff for various classes we used
  • Updates to the tournament classes and their fields
  • An entire pipeline to pay for a tournament registration through the payment API

@Lymkwi
Copy link
Collaborator

Lymkwi commented Oct 20, 2023

From what I got from our last conversation, all that's left here is:

@ShiroUsagi-san
Copy link
Contributor Author

ShiroUsagi-san commented Oct 21, 2023

The only thing missing is a django action to allow admin to refund/cancel user participation in a tournament. But we getting very close to the final version 👌

@ShiroUsagi-san
Copy link
Contributor Author

ShiroUsagi-san commented Oct 23, 2023

Before merging this big piece of features, the only thing missing is to allow player to join a team. The idea is to use team password. The captain can generate it (generated randomly otherwise) and then an url with this password as a query param is given to the captain and they can invite their player with it.

@Lymkwi
Copy link
Collaborator

Lymkwi commented Oct 23, 2023

Before merging this big piece of features, the only thing missing is to allow player to join a team. The idea is to use team password. The captain can generate it (generated randomly otherwise) and then an url with this password as a query param is given to the captain and they can invite their player with it.

This is more linked with tournament code, as its pertains to the flow of joining teams, but not the flow of paying for a ticket or refunding it, provided that everything else works.

@Lymkwi Lymkwi marked this pull request as ready for review October 23, 2023 21:51
@Lymkwi Lymkwi requested a review from Lugrim October 23, 2023 21:51
Copy link
Collaborator

@Lymkwi Lymkwi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm biased

@Lymkwi Lymkwi changed the title [Draft] Payment review Payment review Oct 23, 2023
Translate the strings used for validation errors introduced in the
second to last commit, c357aaf.
Add a method that computes whether or not a team can be considered valid
at any given point, based on quotas of people who paid.

For now, the parameter `n` used is the number of people who joined the
team. Very soon, it will be changed by the number of slots in a team
(which is tournament dependent).
Add a Django admin action that triggers a refund of a transaction.
Consequently, add a hook to the payment callback class that performs
post-refund actions. For tournament, this post-refund hook finds any
registration paid linked to the tournament and user in question,
destroys it, and cancels associated tickets.
- Actually use the singleton object
- Implement an expiration date
- Check the expiration date when we get the token, refreshing it if need
  be
- Add timeout parameters to the request calls, and propagate/log on
  errors if need be
- Refactor some code
Transform all HelloAsso variables into constants in the settings of the
whole project.

Also adds organization slug, and normalizes variable names.
- Fix tests (I hate timezones)
- Fix a leak of data that resulted in all tournament information being
  visible in the `event/<id>/tournaments/` dereferencement route, which
  did not take into account the `is_announced` key
- Fix ticket creation missing a mandatory key (tournament)
- Fix bug where despite buying a player ticket, you could end up
  validating a manager one
- Change fetch_registration method to determine your type of
  registration from your product, not from the fact that a registration
  is available
- Introduct the preparation hook to detect if a single registration of
  the correct type is ready to be paid before payment is initiated
Similar to Transactions, Payments cannot be deleted or manipulated, only
viewed.
Register the order_id (which is not the same as the intent id) into a
Transaction, also displaying it in the admin view
The grant_type used to retrieve an OAuth token is different whether or
not you are using client credentials (first login), or refreshing a
token (refreshes). Without this patch, initial obtention of tokens is
impossible.
Properly redirect the user… by not redirecting them. Redirects in Django
only really work within the same domain, so instead we return the URL in
a JSON reply, and will let the frontend do its magic.

At the same time, we move the call to the prepare_hook after creation of
the transaction object (for validation purposes), but before the intent
creation on HelloAsso's side. If the hooks return `False`, then
something is wrong, and we cannot proceed with payment, needing instead
to delete the Transaction.
Implement the notification channel that receives and handles two kinds
of messages:
- Order: those messages give us the layout of payments (typically here
  for us only one of them) and order number associated with our
  transaction, which we can add and update into the database
- Payment: those messages let us known the status of a payment, which
  can trigger validation or invalidation of a transaction (invalidation
  has not been tested yet, as notifications only come when a payment
  succeeds)

Properly implement refunding by iterating over defined payments for a
transaction and refunding them individually. Note that that part has not
been entirely tested yet, because our credentials do not allow us to
refund yet.
Properly handle the fact that we could get notified about a transaction
we do not know
- Remove the transaction refund admin action, mostly by commenting it
  out
- Normalize state methods, so that if you want to change the state of an
  action, you do not have to run the hooks yourself or touch the
  transaction or verify states or anything (it also logs stuff)
- Add Refunded as a supported Payment message type
@Lymkwi
Copy link
Collaborator

Lymkwi commented Oct 26, 2023

Rebased.

Abandon all hope, ye who reads this PR

default=ProductCategory.PIZZA,
choices=ProductCategory.choices,
)
associated_tournament = models.ForeignKey(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we keep this field or use a more generic foreignKey?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could try and work out how to do a more generic foreign key now to be honest

I'm just worried about breaking things and not being able to fix them before merge, but I can try and check if it's feasible at least

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as you want, you did a huge work here

Copy link
Contributor

@Lugrim Lugrim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, the real test will be the preprod, and the small missing bits that we talked about on Discord aren't needed to merge this PR and should be added later

@@ -54,8 +54,9 @@ class Meta:
"""Meta options of the serializer"""

model = Tournament
read_only_fields = ("id",)
fields = ["id", "event", "game", "name", "teams", "logo"]
read_only_fields = ("id","manager_price_onsite", "manager_price_onsite",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cashprize is readonly I think

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure, it should be editable in case of new partnership increasing the cashprize I guess?

Copy link
Contributor Author

@ShiroUsagi-san ShiroUsagi-san Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't it for the fetching endpoint ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are serializers, access rights should be managed in views (for example a ReadOnly | IsAdmin), however since we've put prices and all read-only, I guess we can do the same with the cashprize to be sure 🤷‍♀️

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you're right

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'll set them we read-only on serialization and editable in admin view

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait actually everything should be read-only?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed

Copy link
Contributor Author

@ShiroUsagi-san ShiroUsagi-san left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from a minor change, this seems good

We had `manager_price_onsite` in there twice.
@Lymkwi Lymkwi merged commit 9a45e6e into dev Oct 27, 2023
4 checks passed
@Lymkwi Lymkwi deleted the payment branch October 27, 2023 09:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed priority:high High Priority
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants