支付宝沙箱的概念
支付宝开放平台 如果从www.alipay.com访问,选择我是开发者。
-
支付宝扫码登录
-
身份:自研开发者
-
控制台>开发服务>沙箱>沙箱应用 沙箱:协助开发者进行接口开发及主要功能联调的==模拟环境==,目前仅支持网页&移动应用和小程序两种应用类型
使用沙箱环境不需要创建应用,只有真实项目开发才需要创建应用,并且上线时要使用真实支付环境测试;注意沙箱的维护时间,在维护期间使用会出现不可预期的错误。
支付宝沙箱商家应用RSA2密钥生成
支付宝开放平台开发助手_支付宝开放平台开发助手-快应用文档类资源-CSDN下载
这个软件可以快速根据公钥生成私钥
加签内容配置>>>>应用公钥>>>>粘贴自己的公钥内容>>>>复制支付宝的公钥,并保存,名字自定(alipay_public_key.pem), 注意内容格式与自己的公钥相同。
按照如下格式,保存支付宝公钥:
-----BEGIN RSA PUBLIC KEY-----
XXXXX 复制的支付宝公钥
-----END RSA PUBLIC KEY-----
目前已有三个密钥文件,在项目根目录下创建一个keys目录,将这三个密钥文件放入的keys项目中。
支付接口
需要安装支付宝客户端SDK
pip install python-alipay-sdk -i https://pypi.tuna.tsinghua.edu.cn/simple/ #使用清华源
#查看pip freeze
订单编号生成
from uuid import UUID
from uuid import uuid1,uuid3
order_id = str(uuid1())
#或者
ns = UUID(int=1234567891234) #int为128bits的整数
order_id = uuid3(name="laufing", namespace=ns).hex
订单支付
生成订单后,就需要生成支付地址,并返回给前端,前端重定向到支付宝服务器完成支付。 django后端的代码:
#在订单orders应用中的views.py模块,定义如下类
from alipay import AliPay
from rest_framework.views import APIView
class MyAliPay(APIView):
def __init__(self, **kwargs):
super().__init__(**kwargs)
#初始化alipay对象
self.alipay = AliPay(
appid = '你的支付宝沙箱应用的id', #
app_private_key_string = '你的私钥',
alipay_public_key_string = '支付宝公钥',
app_notify_url = None, #回调地址
sign_type = 'RSA2', #签名算法
debug = True, #请求来到支付宝沙箱
)
#定义生成支付地址的方法
def get_trade_url(self, order_id, total_price):
order_string = self.alipay.api_alipay_trade_page_pay(
subject = '商家收款',
out_trade_no = order_id,
total_amount = total_price,
return_url = 'http://127.0.0.1:8000/orders/pay/result/',
notify_url = '异步通知地址'
)
return 'https://openapi.alipaydev.com/gateway.do?' + order_string
然后令创建订单的视图类继承MyAliPay类,视图类内部在创建订单完成后调用get_trade_url生成支付地址。最后将支付地址返回给前端。 后面就是浏览器与支付宝服务端的交互。
支付成功的回调
在前端完成支付后,支付宝沙箱服务端会做如下两件事:
-
向前端返回支付结果及return_url 回调,浏览器展示支付结果后然后重定向到return_url这个地址, 即GET return_url?支付参数
-
向django应用发送异步通知,通知当前支付结果,即POST notify_url。 注意,只有django应用部署到公网时,支付宝异步通知的POST 请求才能到达django。
django代码:
#配置路由
path('pay/result/', CheckPayResult.as_view())
#处理回调的视图类
class CheckPayResult(MyAliPay):
#处理前端的回调请求
def get(self, request):
#获取交易数据,
#前端回调return_url时,会以查询字符串的形式带来支付宝的交易数据
print("rest_framework获取数据:", request.query_params)
#django代码获取get参数
order_id = request.GET.get("out_trade_no")
result = self.alipay.api_alipay_trade_query(order_id)
print("支付结果:", result)
if result.get("trade_status") == "TRADE_SUCCESS":
print("支付成功!")
status = 1
else:
print("支付失败!")
status = 0
#返回响应
return HttpResponse("支付%s"%('成功' if status else '失败'))
#处理支付宝的异步通知 post notify_url
#需项目部署到公网
def post(self, request):
#解析数据
data_dict = {k:v for k, v in request.POST.items()}
print("支付宝post请求:", data_dict)
#验证是否支付宝发送过来的请求
#获取签名信息
sign = data_dict.pop("sign")
print("签名信息:", sign)
# 验证签证是否是伪造
validate_result = self.alipay.verify(data_dict, sign)
if validate_result:
#是支付宝发送过来的post请求
#是否支付成功
if data_dict.get("trade_status") == "TRADE_SUCCESS":
#支付成功
#给支付宝的响应
return HttpResponse("success")
else:
return Response({"code":204, "msg":"非法请求!"})