123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- 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 paginator import pagination
- 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
- from account.models import UserIncomeExpensesInfo, UserInfo
- from group.models import GroupPhotoInfo, GroupPhotoOrderInfo
- from pay.models import OrderInfo
- from photo.models import PhotosInfo
- from utils.error.errno_utils import (GroupPhotoStatusCode, OrderStatusCode, UserStatusCode, WechatStatusCode,
- WithdrawStatusCode)
- from utils.price_utils import get_group_photo_price
- from utils.redis.rbrief import set_brief_info
- from utils.redis.rorder import set_lensman_order_record
- from utils.wx_utils import get_trade_type, get_user_openid
- WECHAT = settings.WECHAT
- @logit
- @transaction.atomic
- def wx_order_create_api(request):
- """ 订单创建 """
- group_id = request.POST.get('group_id', '')
- user_id = request.POST.get('user_id', '')
- photo_id = request.POST.get('photo_id', '')
- photo_type = request.POST.get('photo_type', 'nomark')
- photo_type_int = OrderInfo.ORIGIN if photo_type == 'origin' else OrderInfo.NOMARK
-
- try:
- user = UserInfo.objects.get(user_id=user_id)
- except UserInfo.DoesNotExist:
- return response(UserStatusCode.USER_NOT_FOUND)
-
- try:
- group_photo = GroupPhotoInfo.objects.get(photo_id=photo_id, status=True)
- except GroupPhotoInfo.DoesNotExist:
- return response(GroupPhotoStatusCode.GROUP_PHOTO_NOT_FOUND)
-
- if OrderInfo.objects.filter(photo_id=photo_id, photo_type=photo_type_int, from_uid=user_id, pay_status=OrderInfo.PAID, status=True).exists():
- return response(OrderStatusCode.WX_ORDER_PAID_ALREADY_EXISTS)
- body = request.POST.get('body', '')
- total_fee = int(request.POST.get('total_fee', 0))
-
- if get_group_photo_price(group_photo, photo_type) != total_fee:
- return response(OrderStatusCode.FEE_CHECK_FAIL)
-
- from_uid = user_id
- to_uid = group_photo.lensman_id or group_photo.user_id
-
- trade_type = request.POST.get('trade_type', '')
-
- wxcfg = WECHAT.get(trade_type, {})
-
- wxpay = WeChatPay(wxcfg.get('appID'), wxcfg.get('apiKey'), wxcfg.get('mchID'))
-
- order = OrderInfo.objects.create(
- group_id=group_id,
- photo_id=photo_id,
- lensman_photo_id=group_photo.lensman_photo_id,
- photo_type=photo_type_int,
- from_uid=from_uid,
- to_uid=to_uid,
- session_id=group_photo.session_id,
- total_fee=total_fee,
- trade_type=trade_type,
- )
- try:
- prepay_data = wxpay.order.create(
- body=body,
- notify_url=settings.API_DOMAIN + '/wx/notify_url',
- out_trade_no=order.order_id,
- total_fee=total_fee,
- trade_type=get_trade_type(trade_type),
- openid=get_user_openid(user, trade_type),
- )
- 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
- if order.photo_type == OrderInfo.NOMARK:
- order.photo_status = OrderInfo.FETCHED
- order.pay_status = OrderInfo.PAID
- order.paid_at = tc.utc_datetime()
- order.save()
- porder, created = GroupPhotoOrderInfo.objects.select_for_update().get_or_create(
- group_id=order.group_id,
- session_id=order.session_id,
- user_id=order.from_uid,
- photo_id=order.photo_id,
- lensman_photo_id=order.lensman_photo_id,
- )
- photo = PhotosInfo.objects.get(
- lensman_id=order.to_uid,
- session_id=order.session_id,
- photo_id=order.lensman_photo_id,
- )
- if order.photo_type == OrderInfo.NOMARK:
- porder.m_photo_path = photo.m_photo_path
- elif order.photo_type == OrderInfo.ORIGIN:
- porder.r_photo_path = photo.r_photo_path
- porder.save()
- set_lensman_order_record(porder)
- to_uid = order.to_uid
- total_fee = order.total_fee
- try:
- user = UserInfo.objects.select_for_update().get(user_id=to_uid)
- except UserInfo.DoesNotExist:
- return
- if order.photo_type == OrderInfo.NOMARK:
-
- amount, freeze_income_amount = total_fee, 0
- user.balance += amount
-
- set_brief_info(to_uid, order.photo_type, total_fee)
-
- UserIncomeExpensesInfo.objects.create(
- user_id=to_uid,
- photo_id=order.photo_id,
- type=UserIncomeExpensesInfo.INCOME,
- amount=amount,
- balance=user.balance,
- freeze_income_amount=freeze_income_amount,
- freeze_income_balance=user.freeze_income_balance,
- remark=u'图片购买',
- )
- elif order.photo_type == OrderInfo.ORIGIN:
- amount, freeze_income_amount = 0, total_fee
- user.freeze_income_balance += freeze_income_amount
- user.save()
- def order_paid_fail(order):
- if order.pay_status == OrderInfo.FAIL:
- return
- order.pay_status = OrderInfo.FAIL
- order.save()
- @logit
- @transaction.atomic
- def wx_order_query_api(request):
- """ 订单查询 """
- order_id = request.POST.get('order_id', '')
- transaction_id = request.POST.get('transaction_id', '')
- try:
- order = OrderInfo.objects.select_for_update().get(order_id=order_id, status=True)
- except OrderInfo.DoesNotExist:
- return response(OrderStatusCode.WX_ORDER_NOT_FOUND)
- if order.pay_status == OrderInfo.PAID:
- return response(200, 'Order Pay Success', u'订单支付成功')
- elif order.pay_status == OrderInfo.FAIL:
- return response(OrderStatusCode.WX_ORDER_PAY_FAIL)
-
- wxcfg = WECHAT.get(order.trade_type, {})
-
- wxpay = WeChatPay(wxcfg.get('appID'), wxcfg.get('apiKey'), wxcfg.get('mchID'))
-
- query_data = wxpay.order.query(transaction_id, order_id)
-
- if not check_signature(query_data, wxcfg.get('apiKey')):
- return response(OrderStatusCode.SIGN_CHECK_FAIL)
- order.notify_msg = query_data
- order.transaction_id = query_data.get('transaction_id', '')
- order.save()
-
- trade_state = query_data.get('trade_state')
-
- if trade_state == 'SUCCESS':
- order_paid_success(order)
- return response(200, 'Order Pay Success', u'订单支付成功')
- elif trade_state == 'NOTPAY':
- return response(OrderStatusCode.WX_ORDER_NOT_PAY)
- elif trade_state == 'USERPAYING':
- return response(OrderStatusCode.WX_ORDER_PAYING)
- else:
- order_paid_fail(order)
- return response(OrderStatusCode.WX_ORDER_PAY_FAIL)
- @logit
- @transaction.atomic
- def wx_order_list_api(request):
- """ 订单列表 """
- user_id = request.POST.get('user_id', '')
- page = int(request.POST.get('page', 1))
- num = int(request.POST.get('num', settings.ORDER_NUM_PER_PAGE))
- orders = OrderInfo.objects.filter(from_uid=user_id, pay_status=OrderInfo.PAID, status=True).order_by('-pk')
- orders, left = pagination(orders, page, num)
- orders = [order.data(user_id) for order in orders]
- return response(200, 'Get Order List Success', u'获取订单列表成功', {
- 'orders': orders,
- 'left': left,
- })
- @logit
- @transaction.atomic
- def wx_order_detail_api(request):
- """ 订单详情 """
- user_id = request.POST.get('user_id', '')
- order_id = request.POST.get('order_id', '')
- try:
- order = OrderInfo.objects.get(order_id=order_id, status=True)
- except OrderInfo.DoesNotExist:
- return response(OrderStatusCode.WX_ORDER_NOT_FOUND)
- if user_id not in [order.from_uid, order.to_uid]:
- return response(OrderStatusCode.NO_DETAIL_PERMISSION)
- return response(200, 'Get Order Detail Success', u'获取订单详情成功', order.data(user_id))
- @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)
- @logit
- @transaction.atomic
- def wx_balance_withdraw_api(request):
- user_id = request.POST.get('user_id', '')
-
- try:
- user = UserInfo.objects.select_for_update().get(user_id=user_id)
- except UserInfo.DoesNotExist:
- return response(UserStatusCode.USER_NOT_FOUND)
-
- trade_type = request.POST.get('trade_type', '')
-
- withdraw_type = request.POST.get('withdraw_type', 'TRANSFER')
- amount = int(request.POST.get('amount', 0))
- if not user.openid:
- return response(WechatStatusCode.OPENID_NOT_FOUND)
- if user.balance < amount:
- return response(WithdrawStatusCode.BALANCE_NOT_ENOUGH)
-
- wxcfg = WECHAT.get(trade_type, {})
-
- wxpay = WeChatPay(wxcfg.get('appID'), wxcfg.get('apiKey'), wxcfg.get('mchID'), mch_cert=wxcfg.get('mch_cert'), mch_key=wxcfg.get('mch_key'))
- if withdraw_type == 'TRANSFER':
- ret_data = wxpay.transfer.transfer(user.openid, amount, u'摄影师余额提现,企业付款', check_name='NO_CHECK')
- elif withdraw_type == 'PACKET':
- wxrpk = wxcfg.get('redpack', {})
- ret_data = wxpay.redpack.send(
- user.openid,
- amount,
- send_name=wxrpk.get('SEND_NAME'),
- nick_name=wxrpk.get('NICK_NAME'),
- act_name=wxrpk.get('ACT_NAME'),
- wishing=wxrpk.get('WISHING'),
- remark=wxrpk.get('REMARK'),
- )
-
- user.balance -= amount
- user.save()
- return response(200, 'Withdraw Success', u'提现成功', {})
|