|
# -*- 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 live import views as live_views
from live.models import RoomOrderInfo
from pay.models import OrderInfo
from utils.error.errno_utils import KOLStatusCode, OrderStatusCode, PackGoodsStatusCode, PackStatusCode, UserStatusCode
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 OrderInfo.DoesNotExist:
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)
except OrderInfo.DoesNotExist:
return HttpResponse(WXPAY_NOTIFY_FAIL)
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)
|