ed83f2bef866878c845a92a867de610f62f1fd9R2">2
+
|
|
|
3
|
+from django.conf import settings
|
|
|
4
|
+from django.db import transaction
|
|
|
5
|
+from django.shortcuts import HttpResponse
|
|
|
6
|
+from django_logit import logit
|
|
|
7
|
+from django_response import response
|
|
|
8
|
+from pywe_exception import WeChatPayException
|
|
|
9
|
+from pywe_pay import WeChatPay
|
|
|
10
|
+from pywe_pay_notify import check_pay_notify
|
|
|
11
|
+from pywe_response import WXPAY_NOTIFY_FAIL, WXPAY_NOTIFY_SUCCESS
|
|
|
12
|
+from pywe_sign import check_signature
|
|
|
13
|
+from TimeConvert import TimeConvert as tc
|
|
|
14
|
+import json
|
|
|
15
|
+from functools import reduce
|
|
|
16
|
+
|
|
|
17
|
+from account.models import UserInfo
|
|
|
18
|
+from goods.models import PackInfo, PackGoodsInfo, GoodsInfo
|
|
|
19
|
+from kol.models import KOLInfo
|
|
|
20
|
+from pay.models import OrderInfo
|
|
|
21
|
+from utils.error.errno_utils import (PackStatusCode, KOLStatusCode, PackGoodsStatusCode, OrderStatusCode, UserStatusCode,
|
|
|
22
|
+ WithdrawStatusCode)
|
|
|
23
|
+
|
|
|
24
|
+
|
|
|
25
|
+WECHAT = settings.WECHAT
|
|
|
26
|
+
|
|
|
27
|
+
|
|
|
28
|
+@logit
|
|
|
29
|
+@transaction.atomic
|
|
|
30
|
+def wx_order_create_api(request):
|
|
|
31
|
+ """ 订单创建 """
|
|
|
32
|
+ kol_id = request.POST.get('kol_id', '')
|
|
|
33
|
+ user_id = request.POST.get('user_id', '')
|
|
|
34
|
+ pack_id = request.POST.get('pack_id', '')
|
|
|
35
|
+ goods_info = json.loads(request.POST.get('goods_info', '[]'))
|
|
|
36
|
+
|
|
|
37
|
+ name = request.POST.get('name', '')
|
|
|
38
|
+ phone = request.POST.get('phone', '')
|
|
|
39
|
+ address = request.POST.get('address', '')
|
|
|
40
|
+
|
|
|
41
|
+ # 用户校验
|
|
|
42
|
+ try:
|
|
|
43
|
+ user = UserInfo.objects.get(user_id=user_id, status=True)
|
|
|
44
|
+ except UserInfo.DoesNotExist:
|
|
|
45
|
+ return response(UserStatusCode.USER_NOT_FOUND)
|
|
|
46
|
+
|
|
|
47
|
+ # kol校验
|
|
|
48
|
+ try:
|
|
|
49
|
+ kol = KOLInfo.objects.get(kol_id=kol_id, status=True)
|
|
|
50
|
+ except KOLInfo.DoesNotExist:
|
|
|
51
|
+ return response(KOLStatusCode.KOL_NOT_FOUND)
|
|
|
52
|
+
|
|
|
53
|
+ # 包校验
|
|
|
54
|
+ try:
|
|
|
55
|
+ pack = PackInfo.objects.get(kol_id=kol_id, pack_id=pack_id, status=True)
|
|
|
56
|
+ except PackInfo.DoesNotExist:
|
|
|
57
|
+ return response(PackStatusCode.PACK_NOT_FOUND)
|
|
|
58
|
+
|
|
|
59
|
+ body = request.POST.get('body', '') # 商品描述
|
|
|
60
|
+ total_fee = int(request.POST.get('total_fee', 0)) # 总金额,单位分
|
|
|
61
|
+
|
|
|
62
|
+ #包-商品校验
|
|
|
63
|
+ for g in goods_info:
|
|
|
64
|
+ try:
|
|
|
65
|
+ PackGoodsInfo.objects.get(pack_id=pack_id, good_id=g.good_id)
|
|
|
66
|
+ except PackGoodsInfo.DoesNotExist:
|
|
|
67
|
+ return response(PackGoodsStatusCode.PACK_GOODS_NOT_FOUND)
|
|
|
68
|
+
|
|
|
69
|
+ # 金额校验
|
|
|
70
|
+ if reduce(lambda g1, g2: g1.price + g2.price, goods_info) != total_fee:
|
|
|
71
|
+ return response(OrderStatusCode.FEE_CHECK_FAIL)
|
|
|
72
|
+
|
|
|
73
|
+ # JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里
|
|
|
74
|
+ trade_type = 'JSAPI'
|
|
|
75
|
+
|
|
|
76
|
+ # 根据 trade_type 获取 wechat 配置
|
|
|
77
|
+ wxcfg = WECHAT.get(trade_type, {})
|
|
|
78
|
+ # WeChatPay 初始化
|
|
|
79
|
+ wxpay = WeChatPay(wxcfg.get('appID'), wxcfg.get('apiKey'), wxcfg.get('mchID'))
|
|
|
80
|
+
|
|
|
81
|
+ # 生成订单
|
|
|
82
|
+ order = OrderInfo.objects.create(
|
|
|
83
|
+ user_id=user_id,
|
|
|
84
|
+ pack_id=pack_id,
|
|
|
85
|
+ kol_id=kol_id,
|
|
|
86
|
+ goods_info=goods_info,
|
|
|
87
|
+ total_fee=total_fee,
|
|
|
88
|
+ trade_type=trade_type,
|
|
|
89
|
+ name=name,
|
|
|
90
|
+ phone=phone,
|
|
|
91
|
+ address=address,
|
|
|
92
|
+ )
|
|
|
93
|
+
|
|
|
94
|
+ try:
|
|
|
95
|
+ prepay_data = wxpay.order.create(
|
|
|
96
|
+ body=body,
|
|
|
97
|
+ notify_url=settings.API_DOMAIN + '/wx/notify_url',
|
|
|
98
|
+ out_trade_no=order.order_id,
|
|
|
99
|
+ total_fee=total_fee,
|
|
|
100
|
+ trade_type=trade_type,
|
|
|
101
|
+ openid=user.openid, # 可选,用户在商户appid下的唯一标识。trade_type=JSAPI,此参数必传
|
|
|
102
|
+ )
|
|
|
103
|
+ except WeChatPayException as e:
|
|
|
104
|
+ order.unifiedorder_result = e.message
|
|
|
105
|
+ order.save()
|
|
|
106
|
+ return response(OrderStatusCode.WX_UNIFIED_ORDER_FAIL)
|
|
|
107
|
+
|
|
|
108
|
+ prepay_id = prepay_data.get('prepay_id', '')
|
|
|
109
|
+ order.prepay_id = prepay_id
|
|
|
110
|
+ order.save()
|
|
|
111
|
+
|
|
|
112
|
+ if trade_type == 'JSAPI' or trade_type == 'MINIAPP':
|
|
|
113
|
+ wxpay_params = wxpay.jsapi.get_jsapi_params(prepay_id)
|
|
|
114
|
+ elif trade_type == 'APP':
|
|
|
115
|
+ wxpay_params = wxpay.order.get_appapi_params(prepay_id)
|
|
|
116
|
+
|
|
|
117
|
+ return response(200, 'Order Create Success', u'订单创建成功', {
|
|
|
118
|
+ 'order_id': order.order_id,
|
|
|
119
|
+ 'prepay_id': prepay_id,
|
|
|
120
|
+ 'wxpay_params': wxpay_params,
|
|
|
121
|
+ })
|
|
|
122
|
+
|
|
|
123
|
+
|
|
|
124
|
+def order_paid_success(order):
|
|
|
125
|
+ if order.pay_status == OrderInfo.PAID:
|
|
|
126
|
+ return
|
|
|
127
|
+
|
|
|
128
|
+ order.pay_status = OrderInfo.PAID
|
|
|
129
|
+ order.paid_at = tc.utc_datetime()
|
|
|
130
|
+ order.save()
|
|
|
131
|
+
|
|
|
132
|
+
|
|
|
133
|
+def order_paid_fail(order):
|
|
|
134
|
+ if order.pay_status == OrderInfo.FAIL:
|
|
|
135
|
+ return
|
|
|
136
|
+
|
|
|
137
|
+ order.pay_status = OrderInfo.FAIL
|
|
|
138
|
+ order.save()
|
|
|
|
@@ -1,3 +1,5 @@
|
|
1
|
1
|
pywe_miniapp==1.1.5
|
|
2
|
2
|
pywe-oauth==1.1.1
|
|
3
|
3
|
pywe-pay==1.0.13
|
|
|
4
|
+pywe-pay-notify==1.0.4
|
|
|
5
|
+pywe-response==1.0.1
|
|
|
|
@@ -2,6 +2,17 @@
|
|
2
|
2
|
|
|
3
|
3
|
from StatusCode import BaseStatusCode, StatusCodeField
|
|
4
|
4
|
|
|
|
5
|
+class UserStatusCode(BaseStatusCode):
|
|
|
6
|
+ USER_NOT_FOUND = StatusCodeField(400001, 'User Not Found', description=u'用户不存在')
|
|
|
7
|
+
|
|
|
8
|
+class KOLStatusCode(BaseStatusCode):
|
|
|
9
|
+ KOL_NOT_FOUND = StatusCodeField(400001, 'KOL Not Found', description=u'KOL不存在')
|
|
|
10
|
+
|
|
|
11
|
+class PackStatusCode(BaseStatusCode):
|
|
|
12
|
+ PACK_NOT_FOUND = StatusCodeField(100001, 'Pack Not Found', description=u'包不存在')
|
|
|
13
|
+
|
|
|
14
|
+class PackGoodsStatusCode(BaseStatusCode):
|
|
|
15
|
+ PACK_GOODS_NOT_FOUND = StatusCodeField(100001, 'Pack Goods Not Found', description=u'包商品不存在')
|
|
5
|
16
|
|
|
6
|
17
|
class ParamStatusCode(BaseStatusCode):
|
|
7
|
18
|
""" 4000xx 参数相关错误码 """
|