思路:调用第三方支付 API 接口实现支付功能。本来想用支付宝来实现第三方网站的支付功能的,但是在实际操作中发现支付宝没有 Python 接口,网上虽然有他人二次封装的的 Python 接口,但是对我这个小白白来说上手还是有点难度,后来发现 PayPal 有现成的 Django 模块,想着以学习的目的来实现这一功能(其实还是自己辣鸡),就决定以 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 中添加下列语句。

# 此付款机制作为测试用
PAYPAL_TEST = True
# 设置收款的 PayPal 电子邮件账户
PAYPAL_REVEIVER_EMAIL = 'your email'

执行同步数据库操作。

./manage.py migrate

urls.py 中加入下列样式。分别为付款完成通知,处理账务,显示完成付款,取消付款操作。

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 付款操作,建立含有正确数据的付款按钮。

@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 的前面也要导入这个类。另外,因为用到了 settings.py 中的常数,所以也要导入 settings,语句如下:

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

付款完成。

@csrf_exempt    #csrf 验证
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>产品名称</td><td width=100 align=center>单价</td><td width=100 align=center>数量</td><td width=100 align=center>小计</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>您刚刚取消了PayPal的付款</h4></div><div class='panel panel-body'><p>请再次检查您的付款,或是返回<a href='/myorders/'>我的订单</a>选用其它付款方式。</p></div><div class='panel panel-footer'></div></div></div></div>
</div>
{% endblock %}

PayPal 在处理完在线付款流程后会另外发送一个 HTTP 数据给我们的网站,我们应该编写一个处理这个信号的函数,更改我们数据库中的内容,为了确保我们设置的监听函数可以被系统加载且保持运行,在 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)

在同一文件夹下再创建一个名为 apps.py 的文件,确保上述编写的函数在一开始的时候就能够加载。

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

在同一文件夹下的 __init__.py 中加入以下语句,确保我们在应用程序初始化加载的时候,可以把我们自定义的应用程序环境设置成能够加载自定义的工作。

default_app_config = 'mysite.apps.PaymentConfig'

通过上述设置,我们的网站已经可以正确地接受订单并使用 PayPal 付款了,我们可以在 PayPal 开发者网站(https://developer.paypal.com/)申请一个测试账号来进行付款测试。

点击进入 dashboard 界面,点击 sandbox 下的 account 选项,我们可以在此创建一个测试账号。

点击创建账号下的 profile 选项,进入详情页,设置此账号的密码,并将 Payment Review 的功能设置为 Off。

接下来我们便可以在我们的网站中使用这个测试账号付款了,点击前往付款,调用 payment 函数,加载含有正确数据的付款按钮,点击后便跳转到 paypal 的沙盒付款页面,我们在其中填入我们之前建立好的测试账号信息,登录后便可以付款了。

付款成功后便返回我们之前编写好的付款成功页面。

注意:中国大陆的 paypal 账号不能用来测试实际支付,需要大陆以外的 paypal 账户才可测试实际支付。(真是坑。。。)

不然付款的时候会出现下列界面。

到这里,我们的付款便已经成功了,但是 PayPal 无法将支付状态通知发送到我们的应用,这是由于我们的项目运行在外部无法访问的 127.0.0.1 上。我们使用 Ngrok 来实现因特网访问开发环境。

在 Ngrok 官网 https://ngrok.com/ 下载解压文件并关联账号后,运行下列命令。

./ngrok http 8000

这个命令将在 8000 端口为本地主机创建一个通道并为其设置一个网络可以访问的主机名称,得到以下输出:

我们可以通过访问 Forwarding 中的网址来连接我们构建在本地的网站。

然后付款后便能在自己本地网站的后台管理看到 paypal ipn 的信息,我这里显示的状态是 pending,按理来说应该是 completed ,可能 paypal 设置中需要更改,这样的话需要将 signal.py 中 ST_PP_COMPLETED 修改为 ST_PP_PENDING,这样 signal.py 便能正常处理 paypal 返回的信息,将订单状态更改为已完成。

至此,我们便完成了调用 paypal 实现第三方网站支付的功能。

转载于:https://www.cnblogs.com/weixuqin/p/9358870.html

django 实现电子支付功能相关推荐

  1. B2B电商平台--ChinaPay银联电子支付功能(实战)

                                              奇迹每天都在发生,而你能把握的便是当下,未来已来.............                     ...

  2. vue+django支付功能

    vue+django支付功能 订单模型 订单模型分析 xadmin 生成订单 生成订单流程 如何生成一个唯一的订单号? 为什么要使用数据库事务处理生成订单? 发起支付 支付流程 安装第三方支付SDK ...

  3. 网银支付_【成果巡礼】企业网银支付功能上线 上海全市法院再添便民新举措...

    智慧前言 近年来,上海全市法院积极推进智慧法院建设,以移动互联网.云计算.大数据等信息技术为依托不断探索智能化应用,并充分利运用12368.移动微法院等司法服务平台开展在线诉讼服务.通过不断" ...

  4. python个人微信支付接口_Python实现微信小程序支付功能

    正文 由于最近自己在做小程序的支付,就在这里简单介绍一下讲一下用python做小程序支付这个流程.当然在进行开发之前还是建议读一下具体的流程,清楚支付的过程. 1.支付交互流程 2.获取openid( ...

  5. 浅谈第三方电子支付平台测试方法的研究

    第三方支付平台的功能和结构特点 在信用方面,第三方支付平台作为中介,在网上交易的商家和消费者之间作一个信用的中转,通过改造支付流程来约束双方的行为,从而在一定程度上缓解彼此对双方信用的猜疑,增加对网上 ...

  6. 互联网创业成功之道(三):网站支付功能配置

    在了解了互联网创业的理论知识之后,就开始实地进行网站创业的实战操作吧.在本章中将详细讲解如何搭建一个符合用户体验的网站. 一.网站的页面规划和风格设计 二.网站编程语言的选择 三.网站数据库的选择 四 ...

  7. 电子商务电子支付实训二

    电子支付 经过在网上实行多次的查询.浏览和实践,得出以下几个电子支付方法和工具: 一.电子钱包支付(通过电子钱包软件实现支付,如电子现金.电子零钱.电子信用卡等). 电子钱包有两种概念:一是纯粹的软件 ...

  8. python微信小程序抢购_Python实现微信小程序支付功能!Python确实强的一批!

    正文 由于最近自己在做小程序的支付,就在这里简单介绍一下讲一下用python做小程序支付这个流程.当然在进行开发之前还是建议读一下具体的流程,清楚支付的过程. 1.支付交互流程 2.获取openid( ...

  9. 2022-2028年中国第三方电子支付市场投资分析及前景预测报告

    [报告类型]产业研究 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了第三方电子支付行业相关概述.中国第三方电子支付行业运行环境.分析了中 ...

最新文章

  1. SmartDroid论文阅读
  2. java包名命名规范[【转】
  3. 支付宝扫一下就能体验的深度学习模型
  4. Redis 16 大应用场景,竟然这么多。。
  5. vb.net详解MDI窗体操作方法
  6. React开发(130):ant design学习指南之form中的新城多个表单
  7. python自定义assert抛出的异常
  8. python gui界面设置数据储存在哪里_Python写GUI
  9. 解决Oracle EM 乱码问题
  10. Linux使用QQ邮箱
  11. 如何用O2OA公文编辑器制作标准的红头文件?
  12. 【机器学习】 - 决策树(西瓜数据集)
  13. 计算机word正文样式怎么新建,Word 2013中样式的创建与修改 创建新样式——想象力电脑应用...
  14. java8使用并行流parallelStream以及普通迭代,并行流,普通流之间的效率对比
  15. android 环信使用方法,Android 环信的使用
  16. 解决在EasyUI中使用百度地图出现不居中和坐标图标显示异常的问题(红色代码部分)
  17. 02_搭建项目(servlet+java bean+jsp的商城教程)
  18. 100本软件开发最佳书籍排行榜
  19. OSChina 周六乱弹 ——清明节你怎么过的这么开心?
  20. 自定义AXI IP核实验——FPGA Vitis篇

热门文章

  1. git仓库的基本用法
  2. 物联网IoT接入技术分类以及华为OC平台特性
  3. JS之数组删除/添加项目方法splice
  4. 【Python练习题】程序5
  5. NOIP2007 count 统计数字
  6. day02-java关键字
  7. as3 physaxe 2d 物理引擎
  8. 那些一眼就被看出包装过的简历
  9. SSM(Spring+SpringMVC+Mybatis)框架环境搭建(整合步骤)(一)
  10. fastapi vue socket 从其他文件调用 socket 方法