Django-Paypal IPNs在Django admin中标记了重复的txn_id

问题描述 投票:-1回答:1

我已经使用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管理员中收到IPN的屏幕截图:

enter image description here

此外,从控制台:enter image description here

python django python-3.x paypal django-paypal
1个回答
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即可。

© www.soinside.com 2019 - 2024. All rights reserved.