对接支付宝系统
一、订单支付功能
提示:
- 订单支付触发页面:《order_success.html》 和 《user_center_order.html》
- 我们实现订单支付功能时,只需要向支付宝获取登录链接即可,进入到支付宝系统后就是用户向支付宝进行支付的行为。
1.请求方式
选项方案请求方法GET请求地址/payment/(?P\d+)/总路由:
# payment
url(r'^', include('payment.urls', namespace='payment')),
子路由:
from django.conf.urls import url
from . import views
urlpatterns = [
# 支付
url(r'payment/(?P\d+)/', views.PaymentView.as_view()),
]
2.请求参数:路径参数
参数名类型是否必传说明order_idint是订单编号3.响应结果:JSON
字段说明code状态码errmsg错误信息alipay_url支付宝登录链接4.后端接口定义和实现
from django.shortcuts import render
from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin
import os
from orders.models import OrderInfo
from django import http
from alipay import AliPay
from django.conf import settings
# Create your views here.
# 测试账号:xxxxxx@sandbox.com
class PaymentView(LoginRequiredMixin, View):
"""订单支付功能"""
def get(self, request, order_id):
# 查询要支付的订单
user = request.user
try:
order = OrderInfo.objects.get(order_id=order_id, user=user, status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
except OrderInfo.DoesNotExist:
return http.HttpResponseForbidden('订单信息错误')
# 创建支付宝支付对象
alipay = AliPay( # 传递公共参数,对接任何接口都需要传递的
appid=settings.ALIPAY_APPID, # 应用ID
app_notify_url=None, # 默认回调url, 如果采用同步通知就不传
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 # 指定是否是开发环境
)
# 生成登录支付宝连接
order_string = alipay.api_alipay_trade_page_pay(
out_trade_no=order_id, # 订单编号
total_amount=str(order.total_amount), # 订单支付金额
subject="美多商城%s" % order_id, # 订单标题
return_url=settings.ALIPAY_RETURN_URL, # 同步通知的回调地址,如果不是同步的就不传
)
# 响应登录支付宝连接
# 真实环境电脑网站支付网关:https://openapi.alipay.com/gateway.do? + order_string
# 沙箱环境电脑网站支付网关:https://openapi.alipaydev.com/gateway.do? + order_string
alipay_url = settings.ALIPAY_URL + "?" + order_string
return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'alipay_url': alipay_url})
5.支付宝SDK配置参数【在settings.py中配置】
ALIPAY_APPID = '2016082100308123'
ALIPAY_DEBUG = True
ALIPAY_URL = 'https://openapi.alipaydev.com/gateway.do'
ALIPAY_RETURN_URL = 'http://www.meiduo.site:8000/payment/status/'
二、保存订单支付结果
1. 支付结果数据说明
-
用户订单支付成功后,支付宝会将用户重定向到
http://www.meiduo.site:8000/payment/status/
,并携带支付结果数据。 -
参考统一收单下单并支付页面接口:https://docs.open.alipay.com/270/alipay.trade.page.pay
提示:
我们需要将订单编号
和交易流水号
进行关联存储,方便用户和商家后续使用。
from django.db import models
from meiduo_mall.utils.models import BaseModel
from orders.models import OrderInfo
# Create your models here.
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

1.请求方式
选项方案请求方法GET请求地址/payment/status/from django.conf.urls import url
from . import views
urlpatterns = [
# 支付
url(r'payment/(?P\d+)/', views.PaymentView.as_view()),
# 保存订单状态
url(r'^payment/status/$', views.PaymentStatusView.as_view()),
]
2.请求参数:路径参数
参考统一收单下单并支付页面接口中的《页面回跳参数》
3.响应结果:HTML
pay_success.html
4.后端接口定义和实现
注意:保存订单支付结果的同时,还需要修改订单的状态为待评价
# 测试账号:xxxxxx0@sandbox.com
class PaymentStatusView(View):
"""保存订单支付结果"""
def get(self, request):
# 获取前端传入的请求参数
query_dict = request.GET # 获取所有要查询的字符串
data = query_dict.dict() # 将查询的字符串参数的类型转换成标准的字典类型
# 获取并从请求参数中剔除signature
signature = data.pop('sign') # signature不能参与签名验证
# 创建支付宝支付对象
alipay = AliPay(
appid=settings.ALIPAY_APPID,
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
)
# 校验这个重定向是否是alipay重定向过来的
success = alipay.verify(data, signature) # 验证正确为True
# 如果验证通过,需要将支付宝的支付信息状态进行处理(将美多商城的订单ID和支付宝的订单ID绑定,修改订单状态)
if success:
# 读取order_id
order_id = data.get('out_trade_no')
# 读取支付宝流水号
trade_id = data.get('trade_no')
# 保存Payment模型类数据
Payment.objects.create(
order_id=order_id,
trade_id=trade_id
)
# 修改订单状态为待评价
OrderInfo.objects.filter(order_id=order_id, status=OrderInfo.ORDER_STATUS_ENUM['UNPAID']).update(
status=OrderInfo.ORDER_STATUS_ENUM["UNCOMMENT"])
# 响应trade_id
context = {
'trade_id': trade_id
}
return render(request, 'pay_success.html', context)
else:
# 订单支付失败,重定向到我的订单
return http.HttpResponseForbidden('非法请求')
5.渲染支付成功页面信息
订单支付成功
您的订单已成功支付,支付交易号:{{ trade_id }}
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?
立即登录/注册


微信扫码登录