|
# -*- coding: utf-8 -*-
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 pywe_sign import check_signature
from TimeConvert import TimeConvert as tc
import json
from functools import reduce
from account.models import UserInfo
from goods.models import PackInfo, PackGoodsInfo, GoodsInfo, PackGoodsSaleInfo
from kol.models import KOLInfo
from pay.models import OrderInfo
from utils.error.errno_utils import (PackStatusCode, KOLStatusCode, PackGoodsStatusCode, OrderStatusCode, UserStatusCode,
WithdrawStatusCode)
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)
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:
PackGoodsInfo.objects.get(pack_id=pack_id, good_id=g.get('good_id', ''))
except PackGoodsInfo.DoesNotExist:
return response(PackGoodsStatusCode.PACK_GOODS_NOT_FOUND)
# 金额校验
if reduce(lambda g1, g2: g1.get('price', 0) * g1.get('num', 0) + g2.get('price', 0) * g2.get('num', 0), goods_info) != total_fee:
return response(OrderStatusCode.FEE_CHECK_FAIL)
# 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.message
order.save()
return response(OrderStatusCode.WX_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', u'订单创建成功', {
'order_id': order.order_id,
'prepay_id': prepay_id,
'wxpay_params': wxpay_params,
})
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.create(
pack_id=order.pack_id,
user_id=order.user_id,
saleinfo=order.goods_info
)
def order_paid_fail(order):
if order.pay_status == OrderInfo.FAIL:
return
order.pay_status = OrderInfo.FAIL
order.save()
@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)
|