|
# -*- coding: utf-8 -*-
import json
from functools import reduce
from django.conf import settings
from django.db import transaction
from django.shortcuts import HttpResponse
from django_logit import logit
from django_response import response
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 account.models import UserInfo
from goods.models import GoodsInfo, PackGoodsInfo, PackGoodsSaleInfo, PackInfo
from kol.models import KOLInfo
from pay.models import OrderInfo
from live.models import RoomOrderInfo
from utils.error.errno_utils import KOLStatusCode, OrderStatusCode, PackGoodsStatusCode, PackStatusCode, UserStatusCode
from live import views as live_views
WECHAT = settings.WECHAT
@logit
@transaction.atomic
def wx_order_create_api(request):
""" 订单创建 """
kol_id = request.POST.get('kol_id', '')
user_id = request.POST.get('user_id', '')
pack_id = request.POST.get('pack_id', '')
goods_info = json.loads(request.POST.get('goods_info', '[]'))
name = request.POST.get('name', '')
phone = request.POST.get('phone', '')
address = request.POST.get('address', '')
# 用户校验
try:
user = UserInfo.objects.get(user_id=user_id, status=True)
user.consignee_name = name
user.consignee_phone = phone
user.consignee_address = address
user.save()
except UserInfo.DoesNotExist:
return response(UserStatusCode.USER_NOT_FOUND)
# kol校验
try:
kol = KOLInfo.objects.get(kol_id=kol_id, status=True)
except KOLInfo.DoesNotExist:
return response(KOLStatusCode.KOL_NOT_FOUND)
# 包校验
try:
pack = PackInfo.objects.get(kol_id=kol_id, pack_id=pack_id, status=True)
except PackInfo.DoesNotExist:
return response(PackStatusCode.PACK_NOT_FOUND)
body = request.POST.get('body', '') # 商品描述
total_fee = int(request.POST.get('total_fee', 0)) # 总金额,单位分
# 包-商品校验
for g in goods_info:
try:
good = PackGoodsInfo.objects.get(pack_id=pack_id, good_id=g.get('good_id', ''))
if good.inventory - g.get('num', 0) < 0:
return response(PackGoodsStatusCode.PACK_GOODS_INVENTORY_SHORTAGE)
except PackGoodsInfo.DoesNotExist:
return response(PackGoodsStatusCode.PACK_GOODS_NOT_FOUND)
# 金额校验
amount = 0
for g in goods_info:
try:
good = GoodsInfo.objects.get(good_id=g.get('good_id', ''))
except GoodsInfo.DoesNotExist:
continue
amount = amount + good.price * g.get('num', 0)
if amount != total_fee:
return response(OrderStatusCode.FEE_CHECK_FAIL)
# 消库存
for g in goods_info:
try:
good = PackGoodsInfo.objects.get(pack_id=pack_id, good_id=g.get('good_id', ''))
good.inventory -= g.get('num', 0)
good.save()
except PackGoodsInfo.DoesNotExist:
continue
# 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 = OrderInfo.objects.create(
user_id=user_id,
pack_id=pack_id,
kol_id=kol_id,
goods_info=goods_info,
total_fee=total_fee,
trade_type=trade_type,
name=name,
phone=phone,
address=address,
)
try:
prepay_data = wxpay.order.create(
body=body,
notify_url=settings.API_DOMAIN + 'pay/wx/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()
if trade_type == 'JSAPI' or trade_type == 'MINIAPP':
wxpay_params = wxpay.jsapi.get_jsapi_params(prepay_id)
elif trade_type == 'APP':
wxpay_params = wxpay.order.get_appapi_params(prepay_id)
return response(200, 'Order Create Success', '订单创建成功', {
'order_id': order.order_id,
'prepay_id': prepay_id,
'wxpay_params': wxpay_params,
})
def 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 = OrderInfo.objects.get(user_id=user_id, order_id=order_id, prepay_id=prepay_id)
except:
return response()
if order.pay_status == OrderInfo.FAIL:
return response(200, 'Order Cancel Success', '订单取消成功')
order.pay_status = OrderInfo.FAIL
order.save()
for g in order.goods_info:
try:
good = PackGoodsInfo.objects.get(pack_id=order.pack_id, good_id=g.get('good_id', ''))
good.inventory += g.get('num', 0)
good.save()
except PackGoodsInfo.DoesNotExist:
continue
return response(200, 'Order Cancel Success', '订单取消成功')
def order_paid_success(order):
if order.pay_status == OrderInfo.PAID:
return
order.pay_status = OrderInfo.PAID
order.paid_at = tc.utc_datetime()
order.save()
PackGoodsSaleInfo.objects.create(
pack_id=order.pack_id,
user_id=order.user_id,
saleinfo=order.goods_info
)
for g in order.goods_info:
try:
good = PackGoodsInfo.objects.get(pack_id=order.pack_id, good_id=g.get('good_id', ''))
good.has_sale_num += g.get('num', 0)
good.save()
except PackGoodsInfo.DoesNotExist:
continue
def order_paid_fail(order):
if order.pay_status == OrderInfo.FAIL:
return
order.pay_status = OrderInfo.FAIL
order.save()
for g in order.goods_info:
try:
good = PackGoodsInfo.objects.get(pack_id=order.pack_id, good_id=g.get('good_id', ''))
good.inventory += g.get('num', 0)
good.save()
except PackGoodsInfo.DoesNotExist:
continue
@logit
@transaction.atomic
def wx_notify_url_api(request):
""" 支付异步通知回调地址 """
notify_data, success = check_pay_notify(request.body, wx_configs=settings.WECHAT)
if not success:
return HttpResponse(WXPAY_NOTIFY_FAIL)
#尖货接龙订单
try:
order = OrderInfo.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)
except:
return HttpResponse(WXPAY_NOTIFY_FAIL)
return HttpResponse(WXPAY_NOTIFY_SUCCESS)
|