我使用Django-paypal在我的Django应用中实现了Paypal集成 与此同时,我根据文档设置了信号接收器。 但问题是:每当有人付款时,即使我将随机发票ID与paypal字典一起传递,也会被标记为重复。
以下是我的尝试:
来自views.py:
def generate_cid():
chars = "".join([random.choice(string.ascii_lowercase) for i in range(5)])
digits = "".join([random.choice(string.digits) for i in range(4)])
cid = digits + chars
return cid
def payment_process(request):
minutes = int(request.user.tagging.count()) * 5
testhours = minutes / 60
hours = ''
if request.user.tagging.count() > 11:
# hours = str(round(testhours, 3))
hours = 5
# invoice = generate_cid()
user_info = {
"name": str(request.user.first_name + ' ' + request.user.last_name),
"hours": str(hours),
"taggedArticles": str(request.user.tagging.count()),
"email": str(request.user.email),
"date": str(datetime.date.today()),
}
paypal_dict = {
"business": settings.PAYPAL_RECEIVER_EMAIL,
"item_name": "Certificate of Completion",
"custom": json.dumps(user_info),
"invoice": str(generate_cid()),
"amount": "95.00",
"currency_code": "USD",
"notify_url": settings.host + '/users/paypal',
"return_url": settings.host + "/users/done/",
"cancel_return": settings.host + "/users/cancel/",
}
# Create the instance.
form = PayPalPaymentsForm(initial=paypal_dict)
context = {"form": form}
return render(request, "users/generateCert.html", context)
来自signals.py:
def show_me_the_money(sender, **kwargs):
ipn_obj = sender
# Undertake some action depending upon `ipn_obj`.
if ipn_obj.payment_status == ST_PP_COMPLETED:
print('Payment is completed')
user_infor = ast.literal_eval(ipn_obj.custom)
if ipn_obj.receiver_email == settings.PAYPAL_RECEIVER_EMAIL:
print('And Payment is valid')
# generate and send an email with pdf certificate file to the user's email
user_infor = ast.literal_eval(ipn_obj.custom)
user_info = {
"name": user_infor['name'],
"hours": user_infor['hours'],
"taggedArticles": user_infor['taggedArticles'],
"email": user_infor['email'],
"date": user_infor['date'],
}
html = render_to_string('users/certificate_template.html',
{'user': user_info})
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'filename=certificate_{}'.format(user_info['name']) + '.pdf'
pdf = weasyprint.HTML(string=html, base_url='http://8d8093d5.ngrok.io/users/process/').write_pdf(
stylesheets=[weasyprint.CSS(string='body { font-family: serif}')])
to_emails = [str(user_infor['email'])]
subject = "Certificate from Nami Montana"
email = EmailMessage(subject, body=pdf, from_email=settings.EMAIL_HOST_USER, to=to_emails)
email.attach("certificate_{}".format(user_infor['name']) + '.pdf', pdf, "application/pdf")
email.content_subtype = "pdf" # Main content is now text/html
email.encoding = 'us-ascii'
email.send()
@receiver(invalid_ipn_received)
def do_not_show_me_the_money(sender, **kwargs):
print('And Payment is not valid')
ipn_obj = sender
user_infor = ast.literal_eval(ipn_obj.custom)
to_emails = [str(user_infor['email'])]
subject = "Certificate"
# message = 'Enjoy your certificate.'
email = EmailMessage(subject, body='Unfortunately, there\'s something wrong with your payment.Check your'
+ 'paypal account, please!',
from_email=settings.EMAIL_HOST_USER, to=to_emails)
# email.content_subtype = "pdf" # Main content is now text/html
# email.encoding = 'us-ascii'
email.send()
valid_ipn_received.connect(show_me_the_money)
实际上,我收到的两个(成功和失败)信号在一次交易中只有很短的时间差(约2分钟)。
以下是关于如何在Django admin中收到IPN的屏幕截图:
答案 0 :(得分:0)
在 signals.py 中收到有效和无效的IPN,这就是它在发送电子邮件之前返回无效IPN的原因。
这是正确且有效的 signals.py :
def show_me_the_money(sender, **kwargs):
ipn_obj = sender
# Undertake some action depending upon `ipn_obj`.
if ipn_obj.payment_status == ST_PP_COMPLETED:
print('Payment is completed')
user_infor = ast.literal_eval(ipn_obj.custom)
if ipn_obj.receiver_email == settings.PAYPAL_RECEIVER_EMAIL:
print('And Payment is valid')
# generate and send an email with pdf certificate file to the user's email
user_infor = ast.literal_eval(ipn_obj.custom)
user_info = {
"name": user_infor['name'],
"hours": user_infor['hours'],
"taggedArticles": user_infor['taggedArticles'],
"email": user_infor['email'],
"date": user_infor['date'],
}
html = render_to_string('users/certificate_template.html',
{'user': user_info})
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'filename=certificate_{}'.format(user_info['name']) + '.pdf'
pdf = weasyprint.HTML(string=html, base_url='http://8d8093d5.ngrok.io/users/process/').write_pdf(
stylesheets=[weasyprint.CSS(string='body { font-family: serif}')])
to_emails = [str(user_infor['email'])]
subject = "Certificate from Nami Montana"
email = EmailMessage(subject, body=pdf, from_email=settings.EMAIL_HOST_USER, to=to_emails)
email.attach("certificate_{}".format(user_infor['name']) + '.pdf', pdf, "application/pdf")
email.content_subtype = "pdf" # Main content is now text/html
email.encoding = 'us-ascii'
email.send()
else:
payment_was_flagged.connect(do_not_show_me_the_money)
def do_not_show_me_the_money(sender, **kwargs):
print('And Payment is not valid')
ipn_obj = sender
user_infor = ast.literal_eval(ipn_obj.custom)
to_emails = [str(user_infor['email'])]
subject = "Certificate from Nami Montana"
# message = 'Enjoy your certificate.'
email = EmailMessage(subject, body='Unfortunately, there\'s something wrong with your payment as it\'s'
'not validated.Check your PayPal account, please!',
from_email=settings.EMAIL_HOST_USER, to=to_emails)
email.send()
valid_ipn_received.connect(show_me_the_money)
只有在付款无效的情况下才需要调用invalid_ipn。