jazzband / django-payments

Universal payment handling for Django.
https://django-payments.readthedocs.io
Other
1.06k stars 282 forks source link

Add example #328

Open Abdoulkadir-ali opened 2 years ago

Abdoulkadir-ali commented 2 years ago

I've been trying to implement django-payments but so far the documentation is not helpful. A simple implementation example would solve the matter if it's possible.

It seems that both the documentation and the issues tend to be directed only at contributors, which makes it impossible to understand for outsiders.

Please document it properly Thank you

WhyNotHugo commented 2 years ago

I've been trying to implement django-payments but so far the documentation is not helpful.

Do you have any specific questions? The docs might need improvement, but understanding what's missing would be great.

A simple implementation example would solve the matter if it's possible.

The testapp included in this repo should serve as a reference; we actually use this as a sample app when we need to manually test a provider.

Abdoulkadir-ali commented 2 years ago

Thank you for your reply first of all.

For the implementation part, I'll use the testapp as a reference. Thank you for the advice.

The issue I'm having is with understanding the practical usage of it. Basically, how do I turn the testapp into something that is usable for a e-commerce website with providers forms and redirections ? So far I understood it can make payments and refund them, but the API section is not complete and I believe it's where there were going to be the explanation, I'm thinking of the get_form method for instance.

I think for more clarity you should go through the library using the following example : The client wants to buy a product > Choose a product > Buy it > Choose payment methods (Paypal/Stripe/Sofort) > Provide his banking informations through a built-in provider Form > Submit it > The provider then either confirms or refuse the payment request and returns the payment status (With guidances on how to process the responses)> Redirect to Success.html or Failure.html.

Start with this simple example and then provide link if the user wants to investigate more in a given concept (for instance Paymentclass or redirections, or understanding status)

They have a really good documentation here using the same method : https://django-paypal.readthedocs.io/en/latest/

WhyNotHugo commented 2 years ago

So far I understood it can make payments and refund them, but the API section is not complete and I believe it's where there were going to be the explanation,

What's missing? What's the question?

I'm thinking of the get_form method for instance.

https://django-payments.readthedocs.io/en/latest/api.html#payments.models.BasePayment.get_form

What's the questions about it?

I think for more clarity you should go through the library using the following example : The client wants to buy a product > Choose a product > Buy it > Choose payment methods (Paypal/Stripe/Sofort)

This is the flow that's being targeted.

Provide his banking informations through a built-in provider Form > Submit it > The provider then either confirms or refuse the payment request and returns the payment status (With guidances on how to process the responses)> Redirect to Success.html or Failure.html.

Whether a form is used or the client is redirected to the provider depends on the provider. Some payment mechanisms require redirecting the user to the provider's page and that's what we signal by raising RedirectNeeded. Other use forms where clients provide us with data (e.g.: credit card details), but those are usually the less secure ones and there's a lot of complications and risks around it.

The provider then either confirms or refuse the payment request and returns the payment status (With guidances on how to process the responses)> Redirect to Success.html or Failure.html.

The provider redirects the client to a URL. You need to define those URLs yourself, as described here: https://django-payments.readthedocs.io/en/latest/payment-model.html#create-a-payment-class

WhyNotHugo commented 2 years ago

Did you follow the docs through the Installation and Payment class steps?

Abdoulkadir-ali commented 2 years ago

Sorry for the delete it was not properly worded. Thank you for the previous explanation

Whether a form is used or the client is redirected to the provider depends on the provider. Some payment mechanisms require redirecting the user to the provider's page and that's what we signal by raising RedirectNeeded. Other use forms where clients provide us with data (e.g.: credit card details), but those are usually the less secure ones and there's a lot of complications and risks around it.

I finally understood this part as it didn't get it the first time. I just have one last question regarding payment forms. Where can I get the list of the payment methods that do not provide a form. Because if it's risky, I'd rather not implement them. If you do not have it, it's perfectly fine, Trial and error will suffice.

Sadly, yes I did read it and probably 10 times through, there are still some obscure areas i'd like you to enlighten me about. Just so you know, Installation is crystal clear, the issue I'm having is with the payment part. And lastly as you probably guessed it, I'm not expert about web developpement, I do other stuff, so pardon my lack of understanding. So I want to thank you for taking the time give further explanation, and apologize for the passive/aggressiveness in the previous comments. I was pissed as I've been trying to make it work for an entire week, and still can't understand it totally.

So the part i'm struggling with is making a payment :

How I believe payment work when using an payment API generally speaking : Create a payment object > Submit it to the provider > Wait for response status (Payment confirmation or payment refusal) > Redirect

What I understand from the documentation https://django-payments.readthedocs.io/en/latest/usage.html : Create a payment object > Redirect to payment_view > Then it speaks about payment total amount (probably to inform the user that you can check the total) >Then it explains that Payment may have some status (waiting being the default status). > _I'm assuming that get_successful/failureurl(self) then Redirect https://django-payments.readthedocs.io/en/latest/payment-model.html

So I have question on this part : 1) Who sets the status ? I believe it should be a reponse from the provider. But it's not mentionned in this part, so, can you confirm that the provider handle the status ? And that the Payment class through the get_success_url(self) or the get_failure_url(self) then Redirect.

2) Is the payment suspended if it's refused or is it deleted from the payment class once the user has been redirected to the get_failure_url(self) method ?

3) Should I handle the status payment myself, or does the Payment class does it for me ? If it's the case how does it communicate with me about that ? I think that's probably the case. So I assume if that were the case, to access the status I'd have to get the payment.id and then through Payments.objects.filter(id=payment.id).get().status retrive its status. Am I correct ?

4) Assuming that (3) is false, and that I have to handle to status myself, and override the get_success_url/get_failure_url method. Like if it's fraud, i'd want to ban the user, if it's just a small failure, i'd like for him to retry using the same payment. How would I go about this.

Thank you for your time btw.

WhyNotHugo commented 1 year ago

I finally understood this part as it didn't get it the first time. I just have one last question regarding payment forms. Where can I get the list of the payment methods that do not provide a form. Because if it's risky, I'd rather not implement them. If you do not have it, it's perfectly fine, Trial and error will suffice.

There's no such list. I guess one would be very useful for the docs; a table of providers and the supported functionality of each.

How I believe payment work when using an payment API generally speaking : Create a payment object > Submit it to the provider > Wait for response status (Payment confirmation or payment refusal) > Redirect

You're close:

When the user is redirected back, they're redirected to one of the views that django-payments requires that you expose. This view will handle any details that the payment provider has passed back via this request, update the Payment instance, and then forward the user to Payment.get_success_url a method that you must defined. Typically, you'd show them a "thank you for your pament" page (or whichever applicable) with your own branding.

Who sets the status?

You should only read the status property, django-payments will update it for you as described above.

Is the payment suspended if it's refused or is it deleted from the payment class once the user has been redirected to the get_failure_url(self) method ?

Failed payments are not deleted; they're set to the correct status (REJECTED, ERROR, REFUNDED).

Should I handle the status payment myself, or does the Payment class does it for me ? If it's the case how does it communicate with me about that ?

The django_payments.signals.status_changed signal is raised. See https://docs.djangoproject.com/en/4.1/topics/signals/

I am now realising that this signal has zero documentation..

Ivan-Vinitskyi commented 11 months ago
  • Create payment object
  • Render the form with get_form. This may return RedirectNeeded, in which case you have to redirect the user to the portal, otherwise, render the form.
  • The user will later be redirected back.
  • Additionally, for some providers, we may get a callback. E.g.: they send a POST to a different endpoint notifying of the payment success/failure. This is useful in case the user somehow never comes back.

When the user is redirected back, they're redirected to one of the views that django-payments requires that you expose. This view will handle any details that the payment provider has passed back via this request, update the Payment instance, and then forward the user to Payment.get_success_url a method that you must defined. Typically, you'd show them a "thank you for your pament" page (or whichever applicable) with your own branding.

  1. Where do we use the payments urls in this flow?
  2. Do we need to setup Webhook (see doc) in this flow or one can just handle the result inside the view, or the change_status signal should serve for this purpose?
WhyNotHugo commented 11 months ago

I've added some docstrings that should answer this doubt:

https://github.com/jazzband/django-payments/pull/392/files

This still needs to be better integrated into the docs.