开源web框架django知识总结(二十二)
支付
提示:
- 如果用户选择的支付方式是 “支付宝” ,在点击《去支付》时对接支付宝的支付系统。
支付宝介绍
支付宝开放平台入口
- https://open.alipay.com/platform/home.htm
1.使用手机上的支付宝扫码登录
2. 创建应用和沙箱环境
1.创建应用
2.沙箱环境
支付宝提供给开发者的模拟支付的环境。跟真实环境是分开的。
沙箱应用:https://openhome.alipay.com/platform/appDaily.htm?tab=info 配置支付宝“应用公钥”,“支付宝公钥”
沙箱账号:https://openhome.alipay.com/platform/appDaily.htm?tab=account
买家账号sdkywg1362@sandbox.com
登录密码111111
支付密码111111
用户名称沙箱环境
证件类型身份证(IDENTITY_CARD)
证件号码847038195010111148
账户余额
2016215.53充值取现
3. 支付宝开发文档
-
文档主页:https://openhome.alipay.com/developmentDocument.htm -
电脑网站支付产品介绍:https://docs.open.alipay.com/270 -
电脑网站支付快速接入:https://docs.open.alipay.com/270/105899/ -
API列表:https://docs.open.alipay.com/270/105900/ -
SDK文档:https://docs.open.alipay.com/270/106291/ -
Python支付宝SDK: https://github.com/fzlee/alipay/blob/master/README.zh-hans.md
- SDK安装:
pip install python-alipay-sdk==2.0.1
- 电脑网站支付流程
5.新建apps --> payment,注册,添加主路由,添加子urls.py
6.配置RSA2公/私钥
提示:
- 阿尔法商城私钥加密数据,阿尔法商城公钥解密数据。
- 支付宝私钥加密数据,支付宝公钥解密数据。
1.生成 阿尔法商城公/私钥
========================================================
对接支付宝系统
订单支付功能
提示:
- 订单支付触发页面:《order_success.html》 和 《user_center_order.html》
- 我们实现订单支付功能时,只需要向支付宝获取登录链接即可,进入到支付宝系统后就是用户向支付宝进行支付的行为。
1.请求方式
选项 | 方案 |
---|
请求方法 | GET | 请求地址 | /payment/(?P<order_id>\d+)/ |
2.请求参数:路径参数
参数名 | 类型 | 是否必传 | 说明 |
---|
order_id | int | 是 | 订单编号 |
3.响应结果:JSON
字段 | 说明 |
---|
code | 状态码 | errmsg | 错误信息 | alipay_url | 支付宝登录链接 |
4.后端接口定义和实现
payment.views.py
from django.views import View
from django.http import JsonResponse
from django.conf import settings
from orders.models import OrderInfo
from .models import Payment
from alipay import AliPay
import os
class PaymentView(View):
def get(self, request, order_id):
try:
order = OrderInfo.objects.get(pk=order_id)
except OrderInfo.DoesNotExist as e:
print(e)
return JsonResponse({'code': 400, 'errmsg': '订单不存在!'}, status=404)
alipay_url = None
with open(os.path.join(settings.BASE_DIR, 'apps/payment/keys/app_private_key.pem'), "r") as f:
app_private_key = f.read()
with open(os.path.join(settings.BASE_DIR, 'apps/payment/keys/app_public_key.pem'), "r") as f:
alipay_public_key = f.read()
alipay = AliPay(
appid=settings.ALIPAY_APPID,
app_notify_url=None,
app_private_key_string=app_private_key,
alipay_public_key_string=alipay_public_key,
sign_type='RSA2',
debug=settings.ALIPAY_DEBUG
)
order_string = alipay.api_alipay_trade_page_pay(
subject='阿尔法商城%s'%order_id,
out_trade_no=order_id,
total_amount=float(order.total_amount),
return_url=settings.ALIPAY_RETURN_URL
)
alipay_url = settings.ALIPAY_URL + '?' + order_string
return JsonResponse({
'code': 0,
'errmsg': 'ok',
'alipay_url': alipay_url
})
5.支付宝SDK配置参数
dev.py
ALIPAY_APPID = '2016102500755751'
ALIPAY_DEBUG = True
ALIPAY_URL = 'https://openapi.alipaydev.com/gateway.do'
ALIPAY_RETURN_URL = "http://127.0.0.1/pay_success.html"
=================================
保存订单支付结果
1. 支付结果数据说明
- 用户订单支付成功后,支付宝会将用户重定向到
http://127.0.0.1:8000/payment/status/ ,并携带支付结果数据。 - 参考统一收单下单并支付页面接口:https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay?scene=API002020081300013629
- 定义支付结果模型类
from django.db import models
from aerf_mall.utils.BaseModel import BaseModel
from orders.models import OrderInfo
class Payment(BaseModel):
"""支付信息模型类"""
order = models.ForeignKey(OrderInfo,
on_delete=models.CASCADE,
verbose_name='订单')
trade_id = models.CharField(max_length=100,
unique=True,
null=True,
blank=True,
verbose_name="支付编号")
class Meta:
db_table = 'tb_payment'
verbose_name = '支付信息'
verbose_name_plural = verbose_name
3. 保存订单支付结果
1.请求方式
选项 | 方案 |
---|
请求方法 | GET | 请求地址 | /payment/status/ |
2.请求参数:路径参数
参考统一收单下单并支付页面接口中的《页面回跳参数》
3.响应结果:HTML
pay_success.html
4.后端接口定义和实现
注意:保存订单支付结果的同时,还需要修改订单的状态为待评价
class PaymentStatusView(View):
def put(self, request):
data = request.GET
data = data.dict()
sign = data.pop('sign')
with open(os.path.join(settings.BASE_DIR, 'apps/payment/keys/app_private_key.pem'), "r") as f:
app_private_key = f.read()
with open(os.path.join(settings.BASE_DIR, 'apps/payment/keys/app_public_key.pem'), "r") as f:
alipay_public_key = f.read()
alipay = AliPay(
appid=settings.ALIPAY_APPID,
app_notify_url=None,
app_private_key_string=app_private_key,
alipay_public_key_string=alipay_public_key,
sign_type='RSA2',
debug=settings.ALIPAY_DEBUG
)
if not alipay.verify(
data,
signature=sign
):
return JsonResponse({'code': 400, 'errmsg': '支付失败!'}, status=400)
order_id = data.get('out_trade_no')
trade_id = data.get('trade_no')
try:
Payment.objects.create(
order_id=order_id,
trade_id=trade_id,
)
except Exception as e:
print(e)
return JsonResponse({
'code': 400,
'errmsg': '支付订单保存失败!'
})
OrderInfo.objects.filter(
order_id=order_id
).update(
status=OrderInfo.ORDER_STATUS_ENUM['UNSEND']
)
return JsonResponse({
'code': 0,
'errmsg': 'ok',
'trade_id': trade_id
})
payment.urls.py
from django.urls import re_path
from . import views
urlpatterns = [
re_path(r'^payment/(?P<order_id>\d+)/$', views.PaymentView.as_view()),
re_path(r'^payment/status/$', views.PaymentStatusView.as_view()),
]
|