- 支付宝支付其实就是两步,首先,前端向后端请求订单(预付单),然后拿到订单之后请求后端去支付,后端自己去配置一些参数,然后将一个url返回给前端,前端拿到url去请求,就会返回一个支付宝二维码,用户扫码成功之后,会向请求后端的一个接口去返回支付接口,如果后端验签成功,修改订单状态即可(注意,支付宝支付还需要 支付宝公钥 用于验签 app私钥 用于加密)
- 支付宝公钥在你后端的文件名称:alipay_public_key.pem 打开文件之后把甲方给你的公钥放在这中间-----BEGIN PUBLIC KEY----- -----END PUBLIC KEY----- app私钥:app_private_key.pem -----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY----- app公钥(其实这个不用配置,只是单纯的写出来):app_public_key.pem -----BEGIN PUBLIC KEY----- -----END PUBLIC KEY-----
- 参考:支付宝开发文档 支付宝第三方sdk 支付宝转账旧版本
class PaymentView(CreateAPIView, UpdateAPIView):
"""订单支付"""
permission_classes = [IsAuthenticated]
serializer_class = PaymentSerializer
def get(self, request):
"""订单管理去支付接口"""
order_id = request.query_params.get('order_id',None)
if not order_id:
return APIResponse.fail(message='请求参数错误')
order = OrderInfo.objects.filter(order_id=order_id,is_delete=False).first()
if not order:
return APIResponse.fail(message='该订单已被删除')
address = Address.objects.filter(id=order.address_id).select_related('user','province','city','district').first()
address_serializer = UserAddressSerializer(address)
response = {
'order_id':order.order_id,
# 商品总数
'total_count':order.total_count,
# 订单总金额
'total_amount':order.total_amount,
# 订单实付金额
'actual_amount':order.actual_amount,
# 运费
'freight':order.freight,
'store_name':order.seller,
'store_id':order.seller_id,
# 使用优惠券名称
'use_coupon_name':order.use_coupon_name,
'address':address_serializer.data
}
if order.order_type == 1:
# 面料商品
goods = OrderGoods.objects.filter(order=order,goods_type=1,status=1)
for fabric in goods:
sku = FabricSKU.objects.filter(id=fabric.sku_id).first()
fabric.image = sku.fabrics.default_image_url if sku else ''
else:
# 款式商品
goods = OrderGoods.objects.filter(order=order,goods_type=2,status=1)
for product in goods:
sku = StylistProduct.objects.filter(id=product.sku_id).first()
product.image = sku.cover if sku else ''
response['goods'] = OrderGoodsSerializer(goods, many=True).data
return APIResponse.success(data=response, message='OK')
def create(self, request, *args, **kwargs):
"""此接口的支付为app pc端共同接口 app支付接口要多携带一个参数为pay_type:app"""
data = request.data
pay_type = data.pop('pay_type', None)
serializer = self.get_serializer(data=data)
if not serializer.is_valid():
message = ','.join(
serializer.errors[key] for key in serializer.errors if isinstance(serializer.errors[key], str))
if not message:
message = ','.join(
serializer.errors[key][0] for key in serializer.errors if isinstance(serializer.errors[key], list))
return APIResponse.fail(message=message)
user = request.user
total_amount = Decimal(0)
# 实付金额
actual_amount = Decimal(0)
data = serializer.validated_data
order_list = data['orders']
pay_method = data['pay_method']
order_id_list = data['order_list']
for order in order_list:
total_amount += order.total_amount
actual_amount += order.actual_amount
pay_order_id = generate_order_id(user.id)
# 更新订单的支付方式
OrderInfo.objects.filter(order_id__in=order_id_list).update(pay_method=pay_method)
# 支付宝支付
if pay_method == 2:
alipay = AliPayUtils(pay_order_id, actual_amount, 'order')
alipay_url = alipay.get_pay_url()
# 添加第三方支付记录
PayOrder.objects.create(id=pay_order_id,pay_method=1,amount=actual_amount,orders=order_id_list)
response = {
"alipay_url": alipay_url,
'order_id': pay_order_id
}
return APIResponse.success(data=response,message='OK')
```python
import os
from alipay import AliPay # 下载的sdk
from django.conf import settings
def get_alipay():
app_private_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/app_private_key.pem")
alipay_public_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/alipay_public_key.pem")
# 配置接入支付宝的公共参数
alipay = AliPay(
appid=settings.ALIPAY_APPID,
app_notify_url=None, # 默认回调url
app_private_key_string=open(app_private_path).read(),
# 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
alipay_public_key_string=open(alipay_public_path).read(),
sign_type="RSA2", # RSA 或者 RSA2
debug=settings.ALIPAY_DEBUG # 默认False
)
return alipay
class AliPayUtils(object):
"""支付宝支付工具"""
def __init__(self,order_id,price,type='order'):
self.order_id = order_id
self.price = price
self.type = type
def get_pay_url(self):
if self.type == 'order':
notify_url = settings.ALIPAY_ORDER_NOTIFY_URL
elif self.type == 'balance':
notify_url = settings.ALIPAY_BALANCE_NOTIFY_URL
else:
notify_url = settings.ALIPAY_RECHARGE_NOTIFY_URL
alipay = get_alipay()
order_string = alipay.api_alipay_trade_page_pay(
out_trade_no=self.order_id, # 订单号
# 订单总金额
total_amount=str(self.price),
subject='one_fashion订单%s' % self.order_id, # 标题
return_url=settings.ALIPAY_RETURN_URL, # 支付成功后的回调地址(前端支付成功的页面)
notify_url=notify_url # 支付异步通知的后端url
)
return settings.ALIPAY_URL + '?' + order_string
# 支付宝接入参数
ALIPAY_APPID = ""
ALIPAY_URL = "https://openapi.alipay.com/gateway.do"
ALIPAY_DEBUG = False # 沙箱环境为True 正式的为Fasle
ALIPAY_ORDER_NOTIFY_URL = 'https://www.XXXXX.com/alipay/order/result/' # 支付宝回调接口
ALIPAY_RETURN_URL = 'https://www.XXX.com/mall/payCode' # 支付宝支付成功前端页面
支付宝回调后端接口:
class ALiPayOrderResultView(APIView):
"""接受商品订单支付宝异步支付结果"""
def post(self, request):
data = request.data.copy()
data = data.dict()
signature = data.pop("sign")
alipay = get_alipay()
# verification
success = alipay.verify(data, signature) # 至于支付宝官网里面的什么验签的排序什么的skd已经帮我们做好了
if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
# 取出支付宝流水号
trade_id = data['trade_no']
# 取出订单号
out_trade_no = data['out_trade_no']
pay_order = PayOrder.objects.filter(id=out_trade_no).first()
if pay_order:
try:
order_id_list = eval(pay_order.orders)
except:
order_id_list = []
if order_id_list:
orders = OrderInfo.objects.filter(order_id__in=order_id_list)
# 更新订单状态,发送短信通知
send_updat_order_status_sms(orders)
pay_order.trade_id = trade_id
pay_order.save()
return Response({'return_code': 'SUCCESS', 'return_msg': 'OK'})
return Response({'return_code': 'FAIL', 'return_msg': 'SIGNERROR'})
这样整个流程就可以了,至于支付宝异步返回的几个参数都是代表的什么,大家就去看官网吧