了解在 django-paypal 中放置 IPN 接收函数的位置
Understanding where to put the IPN reciever function in django-paypal
关于为 paypal-ipn
设置接收器功能,我有一个与 post here 类似的问题
我们正在尝试做的(我不认识这个人,但我想我们在这个话题上是一致的)是了解如何推断出接收 paypal IPN 信号的路径,然后我们可以在其中更新django 数据库。
我已经按照说明 here
实施了 django-paypal API
总的来说,我所做的是在 views.py 中创建一个视图,如下所示
def payment_page(request):
"""This fucntion returns payment page for the form"""
if not request.session.get('form-submitted', False):
return HttpResponseRedirect(reverse('grap_main:error_page'))
else:
amount = set_payment()
paypal_dict = {
"business": "business@gmail.com",
"amount": str(amount),
"item_name": "2017 USGF Championships",
"notify_url": "https://15b6b6cb.ngrok.io" + reverse('paypal-ipn'),
"return_url": "https://15b6b6cb.ngrok.io/Confirm",
"cancel_return": "https://15b6b6cb.ngrok.io/RegistrationForm",
}
form = PayPalPaymentsForm(initial=paypal_dict)
context = confirm_information()
context["amount"] = amount
context["form"] = form
request.session['form-submitted'] = False
valid_ipn_received.connect(show_me_the_money)
return render(request, "grap_main/payment.html", context)
然后我有 payment.html 然后只需使用文档中建议的行即可创建贝宝按钮
{{ form.render }}
现在我可以收到一个 POST 到我在文档中指定的贝宝 url 但是我不知道我应该把我的信号函数放在哪里,一旦有人有完成购买。
def show_me_the_money(sender, **kwargs):
"""signal function"""
ipn_obj = sender
if ipn_obj.payment_status == ST_PP_COMPLETED:
print 'working'
else:
print "not working"
现在我在视图 payment_page() 中调用这个函数但是我知道这是在 POST 到 paypal 之前并且不正确
我不明白应该在哪里调用 show_me_the_money() 函数。我习惯于创建一个从 html 脚本调用的视图,如下所示
def register(request):
"""aquire information from new entry"""
if request.method != 'POST':
form = RegisterForm()
else:
if 'refill' in request.POST:
form = RegisterForm()
else:
form = RegisterForm(data=request.POST)
if form.is_valid():
form.save()
request.session['form-submitted'] = True
return HttpResponseRedirect(reverse('grap_main:payment_page'))
.html
<form action="{% url 'grap_main:register' %}" method='post' class="form">
{% csrf_token %}
{% bootstrap_form form %}
<br>
{% buttons %}
<center>
<button name='submit' class="btn btn-primary">Submit</button>
</center>
{% endbuttons %}
</form>
我认为我需要在用户完成购买后调用该函数,但我不知道如何在我的代码中确定那个时间点 window。我想确保我处理的案例是用户完成付款后并不总是 return 到商家网站。
关于此主题的任何帮助不仅对我有益,而且对较早的 poster 也有益。我希望在解决这个问题时制作一个教程,以帮助其他可能也遇到困难的人。
请注意,我还使用 ngrok 来确保我的项目可以访问 paypal IPN 服务。我也在使用两个 urls.py 文件,主要的文件看起来是这样
urlpatterns = [
url(r'^paypal/', include('paypal.standard.ipn.urls')),
url(r'^admin/', admin.site.urls),
url(r'', include('grap_main.urls', namespace='grap_main')),
]
其中 'grap_main.urls' 是我网站的所有特定视图,例如
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^Confirm', views.confirm, name='confirm'),
url(r'^Events', views.events, name='events'),
.........]
[更新]:忘记提及您编写的代码的放置位置和方式(如果您愿意,可以使用处理程序)。在 handlers.py
文件中这样写:
# grap_main/signals/handlers.py
from paypal.standard.ipn.signals import valid_ipn_received, invalid_ipn_received
@receiver(valid_ipn_received)
def show_me_the_money(sender, **kwargs):
"""Do things here upon a valid IPN message received"""
...
@receiver(invalid_ipn_received)
def do_not_show_me_the_money(sender, **kwargs):
"""Do things here upon an invalid IPN message received"""
...
虽然信号(和处理程序)可以存在于任何地方,但一个很好的约定是将它们存储在应用程序的 signals
目录中。因此,您的 grap_main
应用程序的结构应如下所示:
project/
grap_main/
apps.py
models.py
views.py
...
migrations/
signals/
__init__.py
signals.py
handlers.py
现在,为了加载 handlers
,在 grap_main/apps.py
中写入(或添加)这个
# apps.py
from django.apps.config import AppConfig
class GrapMainConfig(AppConfig):
name = 'grapmain'
verbose_name = 'grap main' # this name will display in the Admin. You may translate this value if you want using ugettex_lazy
def ready(self):
import grap_main.signals.handlers
最后,在您的 settings.py
文件中,在 INSTALLED_APPS
设置下,不要使用 'grap_main'
:
# settings.py
INSTALLED_APPS = [
... # other apps here
'grap_main.apps.GrapMainConfig',
... # other apps here
]
一些旁注:
使用 encrypted buttons 而不是使用标准表单呈现贝宝按钮。这样您就可以防止对表格进行任何潜在的修改(主要是价格变化)。
几个月前我就在你的轨道上使用了不起的 django-paypal
包。但是,我需要将我的项目升级到 Python 3。但是因为我使用了 encrypted buttons
我无法升级。为什么?因为加密按钮依赖于 M2Crypto
不支持 Python 3. 我做了什么?我放弃了 django-paypal
并加入了 Braintree
,这是一家 PayPal 公司。现在,我不仅可以接受 PayPal 付款,还可以接受信用卡付款。全部 Python 3!
这很尴尬,但问题是我没有使用测试企业帐户...我实施了 nik_m 建议的答案,所以我建议您也这样做。放置函数:
def show_me_the_money(sender, **kwargs):
"""signal function"""
ipn_obj = sender
if ipn_obj.payment_status == ST_PP_COMPLETED:
print 'working'
else:
print "not working"
valid_ipn_received.connect(show_me_the_money)
在 handlers.py
关于为 paypal-ipn
设置接收器功能,我有一个与 post here 类似的问题我们正在尝试做的(我不认识这个人,但我想我们在这个话题上是一致的)是了解如何推断出接收 paypal IPN 信号的路径,然后我们可以在其中更新django 数据库。
我已经按照说明 here
实施了 django-paypal API总的来说,我所做的是在 views.py 中创建一个视图,如下所示
def payment_page(request):
"""This fucntion returns payment page for the form"""
if not request.session.get('form-submitted', False):
return HttpResponseRedirect(reverse('grap_main:error_page'))
else:
amount = set_payment()
paypal_dict = {
"business": "business@gmail.com",
"amount": str(amount),
"item_name": "2017 USGF Championships",
"notify_url": "https://15b6b6cb.ngrok.io" + reverse('paypal-ipn'),
"return_url": "https://15b6b6cb.ngrok.io/Confirm",
"cancel_return": "https://15b6b6cb.ngrok.io/RegistrationForm",
}
form = PayPalPaymentsForm(initial=paypal_dict)
context = confirm_information()
context["amount"] = amount
context["form"] = form
request.session['form-submitted'] = False
valid_ipn_received.connect(show_me_the_money)
return render(request, "grap_main/payment.html", context)
然后我有 payment.html 然后只需使用文档中建议的行即可创建贝宝按钮
{{ form.render }}
现在我可以收到一个 POST 到我在文档中指定的贝宝 url 但是我不知道我应该把我的信号函数放在哪里,一旦有人有完成购买。
def show_me_the_money(sender, **kwargs):
"""signal function"""
ipn_obj = sender
if ipn_obj.payment_status == ST_PP_COMPLETED:
print 'working'
else:
print "not working"
现在我在视图 payment_page() 中调用这个函数但是我知道这是在 POST 到 paypal 之前并且不正确 我不明白应该在哪里调用 show_me_the_money() 函数。我习惯于创建一个从 html 脚本调用的视图,如下所示
def register(request):
"""aquire information from new entry"""
if request.method != 'POST':
form = RegisterForm()
else:
if 'refill' in request.POST:
form = RegisterForm()
else:
form = RegisterForm(data=request.POST)
if form.is_valid():
form.save()
request.session['form-submitted'] = True
return HttpResponseRedirect(reverse('grap_main:payment_page'))
.html
<form action="{% url 'grap_main:register' %}" method='post' class="form">
{% csrf_token %}
{% bootstrap_form form %}
<br>
{% buttons %}
<center>
<button name='submit' class="btn btn-primary">Submit</button>
</center>
{% endbuttons %}
</form>
我认为我需要在用户完成购买后调用该函数,但我不知道如何在我的代码中确定那个时间点 window。我想确保我处理的案例是用户完成付款后并不总是 return 到商家网站。
关于此主题的任何帮助不仅对我有益,而且对较早的 poster 也有益。我希望在解决这个问题时制作一个教程,以帮助其他可能也遇到困难的人。
请注意,我还使用 ngrok 来确保我的项目可以访问 paypal IPN 服务。我也在使用两个 urls.py 文件,主要的文件看起来是这样
urlpatterns = [
url(r'^paypal/', include('paypal.standard.ipn.urls')),
url(r'^admin/', admin.site.urls),
url(r'', include('grap_main.urls', namespace='grap_main')),
]
其中 'grap_main.urls' 是我网站的所有特定视图,例如
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^Confirm', views.confirm, name='confirm'),
url(r'^Events', views.events, name='events'),
.........]
[更新]:忘记提及您编写的代码的放置位置和方式(如果您愿意,可以使用处理程序)。在 handlers.py
文件中这样写:
# grap_main/signals/handlers.py
from paypal.standard.ipn.signals import valid_ipn_received, invalid_ipn_received
@receiver(valid_ipn_received)
def show_me_the_money(sender, **kwargs):
"""Do things here upon a valid IPN message received"""
...
@receiver(invalid_ipn_received)
def do_not_show_me_the_money(sender, **kwargs):
"""Do things here upon an invalid IPN message received"""
...
虽然信号(和处理程序)可以存在于任何地方,但一个很好的约定是将它们存储在应用程序的 signals
目录中。因此,您的 grap_main
应用程序的结构应如下所示:
project/
grap_main/
apps.py
models.py
views.py
...
migrations/
signals/
__init__.py
signals.py
handlers.py
现在,为了加载 handlers
,在 grap_main/apps.py
# apps.py
from django.apps.config import AppConfig
class GrapMainConfig(AppConfig):
name = 'grapmain'
verbose_name = 'grap main' # this name will display in the Admin. You may translate this value if you want using ugettex_lazy
def ready(self):
import grap_main.signals.handlers
最后,在您的 settings.py
文件中,在 INSTALLED_APPS
设置下,不要使用 'grap_main'
:
# settings.py
INSTALLED_APPS = [
... # other apps here
'grap_main.apps.GrapMainConfig',
... # other apps here
]
一些旁注:
使用 encrypted buttons 而不是使用标准表单呈现贝宝按钮。这样您就可以防止对表格进行任何潜在的修改(主要是价格变化)。
几个月前我就在你的轨道上使用了不起的
django-paypal
包。但是,我需要将我的项目升级到 Python 3。但是因为我使用了encrypted buttons
我无法升级。为什么?因为加密按钮依赖于M2Crypto
不支持 Python 3. 我做了什么?我放弃了django-paypal
并加入了Braintree
,这是一家 PayPal 公司。现在,我不仅可以接受 PayPal 付款,还可以接受信用卡付款。全部 Python 3!
这很尴尬,但问题是我没有使用测试企业帐户...我实施了 nik_m 建议的答案,所以我建议您也这样做。放置函数:
def show_me_the_money(sender, **kwargs):
"""signal function"""
ipn_obj = sender
if ipn_obj.payment_status == ST_PP_COMPLETED:
print 'working'
else:
print "not working"
valid_ipn_received.connect(show_me_the_money)
在 handlers.py