|
from django.shortcuts import render
from django_query import get_query_value
from django.db import transaction
from django_response import response
from django.shortcuts import HttpResponse
from django_logit import logit
from pywe_exception import WeChatPayException
from pywe_pay import WeChatPay
from pywe_pay_notify import check_pay_notify
from pywe_response import WXPAY_NOTIFY_FAIL, WXPAY_NOTIFY_SUCCESS
from TimeConvert import TimeConvert as tc
from django.conf import settings
from live.models import liveGoodsInfo, RoomGoodsInfo, RoomOrderInfo, RoomInfo, AnchorInfo
from account.models import UserInfo
from utils.error.errno_utils import OrderStatusCode, UserStatusCode
WECHAT = settings.WECHAT
def anchor_detail(request):
anchor_id = get_query_value(request, 'anchor_id', '')
try:
anchor = AnchorInfo.objects.get(anchor_id=anchor_id)
except:
return response()
rooms = RoomInfo.objects.filter(anchor_id=anchor_id)
rooms = [room.anchorData for room in rooms]
return response(200, 'Get Room Anchor Details Success', '获取主播详情成功', data={
'anchor': {
'anchor_id': anchor.anchor_id,
'anchor_name': anchor.anchor_name,
'anchor_avatar': anchor.anchor_avatar_url,
'anchor_intro': anchor.anchor_intro,
'banner': anchor.banner_url,
},
'rooms': rooms
})
def room_goods_detail(request):
goods_id = get_query_value(request, 'goods_id', '')
room_id = get_query_value(request, 'room_id', '')
# 校验直播间和商品
try:
room_goods_info = RoomGoodsInfo.objects.get(goods_id=goods_id, room_id=room_id)
except:
return response(400001, 'Room Goods Not Found', '直播间商品不存在')
try:
goods_info = liveGoodsInfo.objects.get(goods_id=goods_id)
except:
return response(400001, 'Live Goods Not Found', '直播商品不存在')
return response(200, 'Get Room Goods Detail Success', '获取直播间商品成功', data={
'goods_info': {
'goods_img': goods_info.goods_img_url,
'name': goods_info.name,
'price_type': goods_info.price_type,
'price': goods_info.price,
'price2': goods_info.price2,
'goods_status': room_goods_info.goods_status,
'inventory': room_goods_info.inventory,
},
'anchor_id': room_goods_info.anchor_id,
})
def room_anchor_details(request):
room_id = request.POST.get('room_id', '')
try:
room = RoomInfo.objects.get(room_id=room_id)
except:
return response()
try:
anchor = AnchorInfo.objects.get(anchor_id=room.anchor_id)
except:
return response()
rooms = RoomInfo.objects.filter(anchor_id=room.anchor_id)
rooms = [room.anchorData for room in rooms]
return response(200, 'Get Room Anchor Details Success', '获取主播详情成功', data={
'anchor': {
'anchor_id': anchor.anchor_id,
'anchor_name': anchor.anchor_name,
'anchor_avatar': anchor.anchor_avatar_url,
'anchor_intro': anchor.anchor_intro,
'banner': anchor.banner_url,
},
'rooms': rooms
})
@logit
@transaction.atomic
def live_order_create(request):
""" 订单创建 """
user_id = request.POST.get('user_id', '')
room_id = request.POST.get('room_id', '')
anchor_id = request.POST.get('anchor_id', '')
goods_id = request.POST.get('goods_id', '')
share_openid = request.POST.get('share_openid', '')
name = request.POST.get('name', '')
phone = request.POST.get('phone', '')
province = request.POST.get('province', '')
city = request.POST.get('city', '')
county = request.POST.get('county', '')
address = request.POST.get('address', '')
amount = int(request.POST.get('amount', 0))
total_fee = int(request.POST.get('total_fee', 0)) # 总金额,单位分
body = request.POST.get('body', '尖货直播') # 商品描述
# 用户校验
try:
user = UserInfo.objects.get(user_id=user_id, status=True)
user.consignee_name = name
user.consignee_phone = phone
user.consignee_province = province
user.consignee_city = city
user.consignee_county = county
user.consignee_address = address
user.save()
except UserInfo.DoesNotExist:
return response(UserStatusCode.USER_NOT_FOUND)
# 校验直播间和商品
try:
room_goods_info = RoomGoodsInfo.objects.get(goods_id=goods_id, room_id=room_id, anchor_id=anchor_id)
except:
return response(400001, 'Room Goods Not Found', description='直播间商品不存在')
# 金额校验
try:
goods_info = liveGoodsInfo.objects.get(goods_id=goods_id)
if amount * int(goods_info.price if goods_info.price_type == 1 else goods_info.price2) != total_fee:
return response(404091, 'FEE Check Fail', description='金额校验失败')
except:
return response(404091, 'FEE Check Fail', description='金额校验失败')
# 消库存
room_goods_info.inventory -= 1
room_goods_info.save()
# JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里
trade_type = 'JSAPI'
# 根据 trade_type 获取 wechat 配置
wxcfg = WECHAT.get(trade_type, {})
# WeChatPay 初始化
wxpay = WeChatPay(wxcfg.get('appID'), wxcfg.get('apiKey'), wxcfg.get('mchID'))
# 生成订单
order = RoomOrderInfo.objects.create(
user_id=user_id,
room_id=room_id,
anchor_id=anchor_id,
goods_id=goods_id,
share_openid=share_openid,
amount=amount,
total_fee=total_fee,
trade_type=trade_type,
name=name,
phone=phone,
province=province,
city=city,
county=county,
address=address,
)
try:
prepay_data = wxpay.order.create(
body=body,
notify_url=settings.API_DOMAIN + 'live/pay/notify_url',
out_trade_no=order.order_id,
total_fee=total_fee,
trade_type=trade_type,
openid=user.openid, # 可选,用户在商户appid下的唯一标识。trade_type=JSAPI,此参数必传
)
except WeChatPayException as e:
order.unifiedorder_result = e.args
order.save()
return response(OrderStatusCode.UNIFIED_ORDER_FAIL)
prepay_id = prepay_data.get('prepay_id', '')
order.prepay_id = prepay_id
order.save()
wxpay_params = wxpay.jsapi.get_jsapi_params(prepay_id)
return response(200, 'Order Create Success', '订单创建成功', {
'order_id': order.order_id,
'prepay_id': prepay_id,
'wxpay_params': wxpay_params,
})
def live_order_cancel(request):
user_id = request.POST.get('user_id', '')
order_id = request.POST.get('order_id', '')
prepay_id = request.POST.get('prepay_id', '')
try:
order = RoomOrderInfo.objects.get(user_id=user_id, order_id=order_id, prepay_id=prepay_id)
except:
return response(400001, 'Order Not Found', description='直播间订单不存在')
if order.pay_status == RoomOrderInfo.FAIL:
return response(200, 'Order Cancel Success', '订单取消成功')
order.pay_status = RoomOrderInfo.FAIL
order.save()
try:
goods_info = RoomGoodsInfo.objects.get(room_id=order.room_id, goods_id=order.goods_id, anchor_id=order.anchor_id)
goods_info.inventory += order.amount
goods_info.save()
except:
return response(400001, 'Room Goods Not Found', description='直播间商品不存在')
return response(200, 'Order Cancel Success', '订单取消成功')
def order_paid_success(order):
if order.pay_status == RoomOrderInfo.PAID:
return
order.pay_status = RoomOrderInfo.PAID
order.paid_at = tc.utc_datetime()
order.save()
try:
goods_info = RoomGoodsInfo.objects.get(room_id=order.room_id, goods_id=order.goods_id, anchor_id=order.anchor_id)
goods_info.sale_infos += [order.order_id]
goods_info.save()
except:
return
def order_paid_fail(order):
if order.pay_status == RoomGoodsInfo.FAIL:
return
order.pay_status = RoomGoodsInfo.FAIL
order.save()
try:
goods_info = RoomGoodsInfo.objects.get(room_id=order.room_id, goods_id=order.goods_id, anchor_id=order.anchor_id)
goods_info.inventory += order.amount
goods_info.save()
except:
return
@logit
@transaction.atomic
def notify_url_api(request):
""" 支付异步通知回调地址 """
notify_data, success = check_pay_notify(request.body, wx_configs=settings.WECHAT)
if not success:
return HttpResponse(WXPAY_NOTIFY_FAIL)
order = RoomOrderInfo.objects.select_for_update().get(order_id=notify_data.get('out_trade_no', ''), status=True)
order.notify_msg = request.body
order.transaction_id = notify_data.get('transaction_id', '')
order.save()
result_code = notify_data.get('result_code', '')
if result_code == 'SUCCESS':
order_paid_success(order)
else:
order_paid_fail(order)
return HttpResponse(WXPAY_NOTIFY_SUCCESS)
|