一:了解对接支付宝支付沙箱环境过程:
二:准备工作:
1: 创建应用payment:
1:创建应用
python3 ../manage.py startapp payment
2:注册应用dev.py:
INSTALLED_APPS = [
\'apps.payment\',
]
3:注册总路由和子路由:
urlpatterns = [
path("", include(\'apps.payment.urls\')),
]
urlpatterns = [
]
2:安装alipay第三方包:
pip install python-alipay-sdk==1.8.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
3:配置RSA2公私密钥:
3.1:在payment里面创建keys文件夹专门存储密钥:
3.2:生成美多商城公私密钥:
(django_env) python@ubuntu:~/Desktop/meimei_project/meiduo_mall/apps$ cd payment/keys
(django_env) python@ubuntu:~/Desktop/meimei_project/meiduo_mall/apps/payment/keys$ openssl
OpenSSL> genrsa -out app_private_key.pem 2048
Generating RSA private key, 2048 bit long modulus
........................................................................................................................................................+++
................................................+++
e is 65537 (0x10001)
OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem
writing RSA key
OpenSSL> exit
3.3:密钥交换:
3.4:增加配置信息:
# 对接支付宝
ALIPAY_APPID = \'自己的ID\' # 应用ID
ALIPAY_DEBUG = True # 调试模式,对接沙箱应用时为True,对接正式应用时为False
ALIPAY_URL = \'https://openapi.alipaydev.com/gateway.do\' # 对接支付宝的网关,如果对接沙箱应用就是测试网关
ALIPAY_RETURN_URL = "http://www.meiduo.site:8080/pay_success.html" # 支付成功后的回调地址
三:视图实现:
1:编辑apps/payment/views.py实现视图
# 支付接口1:扫码支付页面url获取
import os
from alipay import AliPay
from django.conf import settings
from django.http import JsonResponse
from django.views import View
from apps.orders.models import OrderInfo
class PaymentView(View):
def get(self, request, order_id):
# 1、提取参数
# 2、校验参数
# 3、业务处理 —— 调用支付宝sdk获取扫码支付url
# (1)、构建alipay支付对象
alipay = AliPay(
settings.ALIPAY_APPID, # 支付应用id
app_notify_url=None, # 支付成功之后,支付宝回调地址
app_private_key_path=os.path.join(
os.path.dirname(os.path.abspath(__file__)),
\'keys/app_private_key.pem\'
),
alipay_public_key_path=os.path.join(
os.path.dirname(os.path.abspath(__file__)),
\'keys/alipay_public_key.pem\'
),
sign_type=\'RSA2\',
debug=settings.ALIPAY_DEBUG
)
try:
order = OrderInfo.objects.get(pk=order_id)
except OrderInfo.DoesNotExist as e:
print(e)
return JsonResponse({\'code\': 400, \'errmsg\': \'订单不存在\'})
# (2)、找对象里面的方法获取支付参数
# api_alipay_trade_page_pay:获取网页端支付页面url参数
query_params = 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, # 用户支付成功,请求美多的页面
)
# 扫码支付要么链接是:\'https://openapi.alipaydev.com/gateway.do?<支付参数>\'
# (3)、拼接支付扫码页面url
alipay_url = settings.ALIPAY_URL + \'?\' + query_params
# 4、构建响应
return JsonResponse({\'code\': 0, \'errmsg\': \'ok\', \'alipay_url\': alipay_url})
2:路由:
from django.urls import re_path
from . import views
urlpatterns = [
# 支付接口1:获取扫码支付页面url
re_path(r\'^payment/(?P<order_id>\d+)/$\', views.PaymentView.as_view()),
]
3:编辑apps/payment/models.py新建模型类迁移建表
from django.db import models
from apps.orders.models import OrderInfo
from meiduo_mall.utils.models import BaseModel
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\'
4:迁移建表:
python3 manage.py makemigrations
python3 manage.py migrate
5:编辑apps/payment/views.py实现视图
# 接口二:支付成功,订单号绑定
class PaymentStatusView(View):
def get(self, request):
alipay = AliPay(
settings.ALIPAY_APPID, # 支付应用id
app_notify_url=None, # 支付成功之后,支付宝回调地址
app_private_key_path=os.path.join(
os.path.dirname(os.path.abspath(__file__)),
\'keys/app_private_key.pem\'
),
alipay_public_key_path=os.path.join(
os.path.dirname(os.path.abspath(__file__)),
\'keys/alipay_public_key.pem\'
),
sign_type=\'RSA2\',
debug=settings.ALIPAY_DEBUG
)
# 1、校验支付宝参数
data = request.GET # Django查询字符串参数,类型是QueryDict
data = data.dict() # QueryDict 转化成 dict
sign = data.get(\'sign\') # 签名 --> 使用该签名参数校验支付数据的有效性
if not alipay.verify(data, signature=sign):
# 校验失败,参数有误
return JsonResponse({\'code\': 400, \'errmsg\': \'支付有误\'})
out_trade_no = data.get(\'out_trade_no\') # 接口1中传递的order_id
trade_no = data.get(\'trade_no\') # 支付宝订单流水号
try:
Payment.objects.create(
order_id=out_trade_no, # 美多订单号
trade_id=trade_no # 支付宝订单流水号
)
except Exception as e:
print(e)
return JsonResponse({\'code\': 500, \'errmsg\': \'新建支付订单失败\'})
order = OrderInfo.objects.get(pk=out_trade_no)
order.status = OrderInfo.ORDER_STATUS_ENUM[\'UNSEND\']
order.save()
# 2、绑定美多商城订单
return JsonResponse({\'code\': 0, \'errmsg\': \'ok\', \'trade_id\': trade_no})
6:配置路由:
from django.urls import re_path
from . import views
urlpatterns = [
# 支付接口2:绑定支付订单
re_path(r\'^payment/status/$\', views.PaymentStatusView.as_view()),
]