日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

django 实现电子支付功能

發(fā)布時間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 django 实现电子支付功能 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

  思路:調(diào)用第三方支付 API 接口實(shí)現(xiàn)支付功能。本來想用支付寶來實(shí)現(xiàn)第三方網(wǎng)站的支付功能的,但是在實(shí)際操作中發(fā)現(xiàn)支付寶沒有 Python 接口,網(wǎng)上雖然有他人二次封裝的的 Python 接口,但是對我這個小白白來說上手還是有點(diǎn)難度,后來發(fā)現(xiàn) PayPal 有現(xiàn)成的 Django 模塊,想著以學(xué)習(xí)的目的來實(shí)現(xiàn)這一功能(其實(shí)還是自己辣雞),就決定以 PayPal 的電子支付功能來練手。

?

首先,安裝 PayPal 的 Django 模塊:django-paypal,具體介紹可以參考 GitHub上說明:https://github.com/spookylukey/django-paypal

pip install django-paypal

?

然后在 settings.py 中的 INSTALLED_APPS 將 'paypal.standard.ipn' 加入。并在 settings.py 中添加下列語句。

# 此付款機(jī)制作為測試用 PAYPAL_TEST = True # 設(shè)置收款的 PayPal 電子郵件賬戶 PAYPAL_REVEIVER_EMAIL = 'your email'

?

執(zhí)行同步數(shù)據(jù)庫操作。

./manage.py migrate

?

urls.py 中加入下列樣式。分別為付款完成通知,處理賬務(wù),顯示完成付款,取消付款操作。

url(r'^paypal/', include('paypal.standard.ipn.urls')), # 付款完成通知 url(r'^payment/(\d+)/$', views.payment), url(r'^done/$', views.payment_done), url(r'^canceled/$', views.payment_canceled),

?

PayPal 付款操作,建立含有正確數(shù)據(jù)的付款按鈕。

@login_required def payment(request, order_id):all_categories = models.Category.objects.all()try:order = models.Order.objects.get(id=order_id)except:messages.add_message(request, messages.WARNING, "訂單編號錯誤,無法處理付款。")return redirect('/myorders/')all_order_items = models.OrderItem.objects.filter(order=order)items = list()total = 0for order_item in all_order_items:t = dict()t['name'] = order_item.product.namet['price'] = order_item.product.pricet['quantity'] = order_item.quantityt['subtotal'] = order_item.product.price * order_item.quantitytotal = total + order_item.product.priceitems.append(t)host = request.get_host()paypal_dict = {"business": settings.PAYPAL_REVEIVER_EMAIL,"amount": total,"item_name": "迷你小電商商品編號:{}".format(order_id),"invoice": "invoice-{}".format(order_id),"currency_code": 'CNY',"notify_url": "http://{}{}".format(host, reverse('paypal-ipn')),"return_url": "http://{}/done/".format(host),"cancel_return": "http://{}/canceled/".format(host),}paypal_form = PayPalPaymentsForm(initial=paypal_dict)template = get_template('payment.html')html = template.render(context=locals(), request=request)return HttpResponse(html)

由于用到了 django-paypal 提供的 PayPalPaymentForm 類。因此在 views.py 的前面也要導(dǎo)入這個類。另外,因?yàn)橛玫搅?settings.py 中的常數(shù),所以也要導(dǎo)入 settings,語句如下:

from django.conf import settings from paypal.standard.forms import PayPalPaymentsForm from django.core.urlresolvers import reverse

?

付款完成。

@csrf_exempt #csrf 驗(yàn)證 def payment_done(request):template = get_template('payment_done.html')html = template.render(context=locals(), request=request)return HttpResponse(html)

?

取消付款。

@csrf_exempt def payment_canceled(request):template = get_template('payment_canceled.html')html = template.render(context=locals(), request=request)return HttpResponse(html)

?

PayPal 付款頁面。

<!-- payment.html (mshop project) --> {% extends "base.html" %} {% block title %}選擇您的付款方式{% endblock %} {% block content %} <div class='container'> {% for message in messages %}<div class='alert alert-{{message.tags}}'>{{ message }}</div> {% endfor %}<div class='row'><div class='col-md-12'><div class='panel panel-default'><div class='panel-heading' align=center><h3>歡迎光臨迷你小電商</h3>{% if user.socialaccount_set.all.0.extra_data.name %}{{user.socialaccount_set.all.0.extra_data.name}}<br/><img src='{{user.socialaccount_set.all.0.get_avatar_url}}' width='100'>{% else %}Welcome: {{ user.username }}{% endif %}</div></div></div></div><div class='row'><div class='col-sm-12'><div class='panel panel-info'><div class='panel panel-heading'><h4>在線付款(訂單編號:{{order.id}})</h4></div><div class='panel panel-body'>{% for item in items %}{% if forloop.first %}<table border=1><tr><td width=300 align=center>產(chǎn)品名稱</td><td width=100 align=center>單價</td><td width=100 align=center>數(shù)量</td><td width=100 align=center>小計(jì)</td></tr>{% endif %}<div class='listgroup'><div class='listgroup-item'><tr><td>{{ item.name }}</td><td align=right>{{ item.price }}</td><td align=center>{{ item.quantity }}</td><td align=right>{{ item.subtotal }}</td></tr></div></div>{% if forloop.last %}</table>{% endif %}{% empty %}<em>此訂單是空的</em>{% endfor %}{{ paypal_form.render }}</div><div class='panel panel-footer'>NT$:{{ total }}元</div></div></div></div> </div> {% endblock %}

?

付款完成頁面。

<!-- payment_done.html (mshop project) --> {% extends "base.html" %} {% block title %}Pay using PayPal{% endblock %} {% block content %} <div class='container'> {% for message in messages %}<div class='alert alert-{{message.tags}}'>{{ message }}</div> {% endfor %}<div class='row'><div class='col-md-12'><div class='panel panel-default'><div class='panel-heading' align=center><h3>歡迎光臨迷你小電商</h3>{% if user.socialaccount_set.all.0.extra_data.name %}{{user.socialaccount_set.all.0.extra_data.name}}<br/><img src='{{user.socialaccount_set.all.0.get_avatar_url}}' width='100'>{% else %}Welcome: {{ user.username }}{% endif %}</div></div></div></div><div class='row'><div class='col-sm-12'><div class='panel panel-info'><div class='panel panel-heading'><h4>從PayPal付款成功</h4></div><div class='panel panel-body'>感謝您的支持,我們會盡快處理您的訂單。</div><div class='panel panel-footer'></div></div></div></div> </div> {% endblock %}

?

取消付款頁面。

<!-- payment_canceled.html (mshop project) --> {% extends "base.html" %} {% block title %}PayPal 付款取消通知{% endblock %} {% block content %} <div class='container'> {% for message in messages %}<div class='alert alert-{{message.tags}}'>{{ message }}</div> {% endfor %}<div class='row'><div class='col-md-12'><div class='panel panel-default'><div class='panel-heading' align=center><h3>歡迎光臨迷你小電商</h3>{% if user.socialaccount_set.all.0.extra_data.name %}{{user.socialaccount_set.all.0.extra_data.name}}<br/><img src='{{user.socialaccount_set.all.0.get_avatar_url}}' width='100'>{% else %}Welcome: {{ user.username }}{% endif %}</div></div></div></div><div class='row'><div class='col-sm-12'><div class='panel panel-info'><div class='panel panel-heading'><h4>您剛剛?cè)∠薖ayPal的付款</h4></div><div class='panel panel-body'><p>請?jiān)俅螜z查您的付款,或是返回<a href='/myorders/'>我的訂單</a>選用其它付款方式。</p></div><div class='panel panel-footer'></div></div></div></div> </div> {% endblock %}

?

PayPal 在處理完在線付款流程后會另外發(fā)送一個 HTTP 數(shù)據(jù)給我們的網(wǎng)站,我們應(yīng)該編寫一個處理這個信號的函數(shù),更改我們數(shù)據(jù)庫中的內(nèi)容,為了確保我們設(shè)置的監(jiān)聽函數(shù)可以被系統(tǒng)加載且保持運(yùn)行,在 views.py 的同級目錄中建立一個名為 signal.py 文件。

from mysite import models from paypal.standard.models import ST_PP_COMPLETED from paypal.standard.ipn.signals import valid_ipn_receiveddef payment_notfication(sender, **kwargs):ipn_obj = senderif ipn_obj.payment_status == ST_PP_COMPLETED:order_id = ipn_obj.invocie.split('-')[-1]order = models.Order.objects.get(id = order_id)order_id.paid = Trueorder.save()valid_ipn_received.connect(payment_notfication)

?

在同一文件夾下再創(chuàng)建一個名為 apps.py 的文件,確保上述編寫的函數(shù)在一開始的時候就能夠加載。

from django.apps import AppConfigclass PaymentConfig(AppConfig):name = 'mysite'verbose_name = 'Mysite'def ready(self):import mysite.signal

?

在同一文件夾下的 __init__.py 中加入以下語句,確保我們在應(yīng)用程序初始化加載的時候,可以把我們自定義的應(yīng)用程序環(huán)境設(shè)置成能夠加載自定義的工作。

default_app_config = 'mysite.apps.PaymentConfig'

?

通過上述設(shè)置,我們的網(wǎng)站已經(jīng)可以正確地接受訂單并使用 PayPal 付款了,我們可以在 PayPal 開發(fā)者網(wǎng)站(https://developer.paypal.com/)申請一個測試賬號來進(jìn)行付款測試。

?

點(diǎn)擊進(jìn)入 dashboard 界面,點(diǎn)擊 sandbox 下的 account 選項(xiàng),我們可以在此創(chuàng)建一個測試賬號。

?

點(diǎn)擊創(chuàng)建賬號下的 profile 選項(xiàng),進(jìn)入詳情頁,設(shè)置此賬號的密碼,并將 Payment Review 的功能設(shè)置為 Off。

?

接下來我們便可以在我們的網(wǎng)站中使用這個測試賬號付款了,點(diǎn)擊前往付款,調(diào)用 payment 函數(shù),加載含有正確數(shù)據(jù)的付款按鈕,點(diǎn)擊后便跳轉(zhuǎn)到 paypal 的沙盒付款頁面,我們在其中填入我們之前建立好的測試賬號信息,登錄后便可以付款了。

?

付款成功后便返回我們之前編寫好的付款成功頁面。

?

注意:中國大陸的 paypal 賬號不能用來測試實(shí)際支付,需要大陸以外的 paypal 賬戶才可測試實(shí)際支付。(真是坑。。。)

不然付款的時候會出現(xiàn)下列界面。

?

到這里,我們的付款便已經(jīng)成功了,但是?PayPal 無法將支付狀態(tài)通知發(fā)送到我們的應(yīng)用,這是由于我們的項(xiàng)目運(yùn)行在外部無法訪問的 127.0.0.1 上。我們使用 Ngrok 來實(shí)現(xiàn)因特網(wǎng)訪問開發(fā)環(huán)境。

?

?在?Ngrok 官網(wǎng)?https://ngrok.com/?下載解壓文件并關(guān)聯(lián)賬號后,運(yùn)行下列命令。

./ngrok http 8000

?

這個命令將在?8000 端口為本地主機(jī)創(chuàng)建一個通道并為其設(shè)置一個網(wǎng)絡(luò)可以訪問的主機(jī)名稱,得到以下輸出:

我們可以通過訪問 Forwarding 中的網(wǎng)址來連接我們構(gòu)建在本地的網(wǎng)站。

然后付款后便能在自己本地網(wǎng)站的后臺管理看到 paypal ipn 的信息,我這里顯示的狀態(tài)是 pending,按理來說應(yīng)該是 completed ,可能 paypal 設(shè)置中需要更改,這樣的話需要將 signal.py 中 ST_PP_COMPLETED 修改為 ST_PP_PENDING,這樣 signal.py 便能正常處理 paypal 返回的信息,將訂單狀態(tài)更改為已完成。

?

至此,我們便完成了調(diào)用 paypal 實(shí)現(xiàn)第三方網(wǎng)站支付的功能。

?

轉(zhuǎn)載于:https://www.cnblogs.com/weixuqin/p/9358870.html

總結(jié)

以上是生活随笔為你收集整理的django 实现电子支付功能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。