|
# -*- coding: utf-8 -*-
from django.conf import settings
from django.db import transaction
from django.http import JsonResponse
from django.shortcuts import HttpResponse
from pay.models import OrderInfo
from utils.error.errno_utils import OrderStatusCode
from utils.error.response_utils import response
from logit import logit
from TimeConvert import TimeConvert as tc
from wechatpy import WeChatPay, WeChatPayException
import xmltodict
WECHAT = settings.WECHAT
@logit
@transaction.atomic
def wx_order_create_api(request):
"""
订单创建
:param request:
:return:
"""
from_uid = request.POST.get('from_uid', '')
to_lid = request.POST.get('to_lid', '')
to_uid = request.POST.get('to_uid', '')
body = request.POST.get('body', '') # 商品描述
total_fee = int(request.POST.get('total_fee', 0)) # 总金额,单位分
# JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里
trade_type = request.POST.get('trade_type', '')
# 根据 trade_type 获取 wechat 配置
wechat = WECHAT.get(trade_type, {})
# WeChatPay 初始化
wxpay = WeChatPay(wechat.get('appID'), wechat.get('apiKey'), wechat.get('mchID'))
# 生成订单
order = OrderInfo.objects.create(from_uid=from_uid, to_lid=to_lid, to_uid=to_uid, total_fee=total_fee)
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=trade_type,
# user_id=None, # 可选,用户在商户appid下的唯一标识。trade_type=JSAPI,此参数必传
)
except WeChatPayException:
return response(OrderStatusCode.WX_UNIFIED_ORDER_FAIL)
prepay_id = prepay_data.get('prepay_id', '')
if trade_type == 'JSAPI':
wxpay_params = wxpay.jsapi.get_jsapi_params(prepay_id)
elif trade_type == 'APP':
wxpay_params = wxpay.order.get_appapi_params(prepay_id)
return JsonResponse({
'status': 200,
'data': {
'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()
@logit
@transaction.atomic
def wx_notify_url_api(request):
"""
支付异步通知回调地址
:param request:
:return:
"""
try:
data = xmltodict.parse(request.body)['xml']
except xmltodict.ParsingInterrupted:
# 解析 XML 失败
return HttpResponse(settings.WXPAY_NOTIFY_FAIL)
out_trade_no = data.get('out_trade_no', '')
return_code = data.get('return_code', '')
result_code = data.get('result_code', '')
if return_code != 'SUCCESS' or result_code != 'SUCCESS':
return HttpResponse(settings.WXPAY_NOTIFY_FAIL)
try:
order = OrderInfo.objects.get(order=out_trade_no)
except OrderInfo.DoesNotExist:
return HttpResponse(settings.WXPAY_NOTIFY_FAIL)
order_paid_success(order)
return HttpResponse(settings.WXPAY_NOTIFY_SUCCESS)
|