role_scope 数据权限底座、form_service 默认角色/租户管理员/删用户/审计 改经 SDK;ugm/payment/stats 裸查询委托;删除 commission/payment/stats 冗余 manager/engine;修复 user_detail 潜伏 ImportError。"
195 lines
7.4 KiB
Python
195 lines
7.4 KiB
Python
import logging
|
|
from rest_framework.views import APIView
|
|
from rest_framework.response import Response
|
|
from gvsdsdk.payment.manager import PaymentManager, PaymentError
|
|
from gvsds.apps.payment.serializers import (
|
|
GatewayConfigCreateSerializer,
|
|
GatewayConfigSerializer,
|
|
PaymentRequestSerializer,
|
|
RefundRequestSerializer,
|
|
TransferRequestSerializer,
|
|
TransactionSerializer,
|
|
)
|
|
from gvsdsdk.payment.gateways.registry import payment_registry
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _ok(data=None, msg='success'):
|
|
return {'code': 200, 'msg': msg, 'data': data}
|
|
|
|
|
|
def _err(msg, code=400):
|
|
return {'code': code, 'msg': msg, 'data': None}
|
|
|
|
|
|
def _get_tenant(request):
|
|
return request.headers.get('X-Tenant-UUID', '') or getattr(request, 'tenant_uuid', '')
|
|
|
|
|
|
class GatewayConfigView(APIView):
|
|
|
|
def get(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
configs = PaymentManager(tenant).ListConfigs(status=1)
|
|
data = GatewayConfigSerializer(configs, many=True).data
|
|
return Response(_ok(data))
|
|
|
|
def post(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
ser = GatewayConfigCreateSerializer(data=request.data)
|
|
if not ser.IsValid():
|
|
return Response(_err(ser.errors, 400), status=400)
|
|
manager = PaymentManager(tenant)
|
|
config = manager.ConfigureGateway(
|
|
platform=ser.ValidatedData['Platform'],
|
|
app_id=ser.ValidatedData.get('AppID', ''),
|
|
mch_id=ser.ValidatedData.get('MchID', ''),
|
|
api_key=ser.ValidatedData.get('APIKeyEncrypted', ''),
|
|
private_key=ser.ValidatedData.get('PrivateKeyEncrypted', ''),
|
|
public_key=ser.ValidatedData.get('PublicKeyEncrypted', ''),
|
|
cert_path=ser.ValidatedData.get('CertPath', ''),
|
|
cert_key_path=ser.ValidatedData.get('CertKeyPath', ''),
|
|
notify_url=ser.ValidatedData.get('NotifyURL', ''),
|
|
return_url=ser.ValidatedData.get('ReturnURL', ''),
|
|
extra=ser.ValidatedData.get('ConfigExtra', {}),
|
|
set_default=ser.ValidatedData.get('SetDefault', False),
|
|
)
|
|
return Response(_ok(GatewayConfigSerializer(config).data), status=201)
|
|
|
|
def delete(self, request):
|
|
tenant = _get_tenant(request)
|
|
platform = request.data.get('Platform')
|
|
if not tenant or not platform:
|
|
return Response(_err('缺少租户或平台', 400), status=400)
|
|
manager = PaymentManager(tenant)
|
|
manager.DisableConfig(platform)
|
|
return Response(_ok(msg='配置已禁用'))
|
|
|
|
|
|
class PayView(APIView):
|
|
|
|
def post(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
ser = PaymentRequestSerializer(data=request.data)
|
|
if not ser.IsValid():
|
|
return Response(_err(ser.errors, 400), status=400)
|
|
manager = PaymentManager(tenant)
|
|
try:
|
|
tx = manager.Pay(
|
|
platform=ser.ValidatedData['Platform'],
|
|
amount=ser.ValidatedData['Amount'],
|
|
subject=ser.ValidatedData.get('Subject', ''),
|
|
body=ser.ValidatedData.get('Body', ''),
|
|
method=ser.ValidatedData.get('Method', 'jsapi'),
|
|
open_id=ser.ValidatedData.get('OpenID', ''),
|
|
client_ip=ser.ValidatedData.get('ClientIP', ''),
|
|
extra=ser.ValidatedData.get('Extra', {}),
|
|
expire_minutes=ser.ValidatedData.get('ExpireMinutes', 30),
|
|
)
|
|
except PaymentError as e:
|
|
return Response(_err(str(e), 400), status=400)
|
|
data = TransactionSerializer(tx).data
|
|
data['prepay_info'] = getattr(tx, '_prepay_info', {})
|
|
return Response(_ok(data), status=201)
|
|
|
|
|
|
class QueryView(APIView):
|
|
|
|
def get(self, request, out_trade_no):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
manager = PaymentManager(tenant)
|
|
try:
|
|
result = manager.Query(out_trade_no)
|
|
except PaymentError as e:
|
|
return Response(_err(str(e), 404), status=404)
|
|
return Response(_ok({
|
|
'success': result.Success,
|
|
'out_trade_no': result.OutTradeNO,
|
|
'transaction_id': result.TransactionID,
|
|
'trade_state': result.TradeState,
|
|
'trade_state_desc': result.TradeStateDesc,
|
|
'total_amount': str(result.TotalAmount),
|
|
}))
|
|
|
|
|
|
class RefundView(APIView):
|
|
|
|
def post(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
ser = RefundRequestSerializer(data=request.data)
|
|
if not ser.IsValid():
|
|
return Response(_err(ser.errors, 400), status=400)
|
|
manager = PaymentManager(tenant)
|
|
try:
|
|
tx = manager.Refund(
|
|
out_trade_no=ser.ValidatedData['OutTradeNO'],
|
|
amount=ser.ValidatedData['Amount'],
|
|
reason=ser.ValidatedData.get('Reason', ''),
|
|
platform=ser.ValidatedData.get('Platform'),
|
|
extra=ser.ValidatedData.get('Extra', {}),
|
|
)
|
|
except PaymentError as e:
|
|
return Response(_err(str(e), 400), status=400)
|
|
return Response(_ok(TransactionSerializer(tx).data), status=201)
|
|
|
|
|
|
class TransferView(APIView):
|
|
|
|
def post(self, request):
|
|
tenant = _get_tenant(request)
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 401), status=401)
|
|
ser = TransferRequestSerializer(data=request.data)
|
|
if not ser.IsValid():
|
|
return Response(_err(ser.errors, 400), status=400)
|
|
manager = PaymentManager(tenant)
|
|
try:
|
|
tx = manager.Transfer(
|
|
platform=ser.ValidatedData['Platform'],
|
|
amount=ser.ValidatedData['Amount'],
|
|
payee_account=ser.ValidatedData.get('PayeeAccount', ''),
|
|
payee_name=ser.ValidatedData.get('PayeeName', ''),
|
|
description=ser.ValidatedData.get('Description', ''),
|
|
transfer_type=ser.ValidatedData.get('TransferType', 'wallet'),
|
|
extra=ser.ValidatedData.get('Extra', {}),
|
|
)
|
|
except PaymentError as e:
|
|
return Response(_err(str(e), 400), status=400)
|
|
return Response(_ok(TransactionSerializer(tx).data), status=201)
|
|
|
|
|
|
class NotifyView(APIView):
|
|
authentication_classes = []
|
|
permission_classes = []
|
|
|
|
def post(self, request, platform):
|
|
tenant = request.headers.get('X-Tenant-UUID', '')
|
|
if not tenant:
|
|
return Response(_err('缺少租户标识', 400), status=400)
|
|
headers = {k: v for k, v in request.META.items() if k.startswith('HTTP_')}
|
|
manager = PaymentManager(tenant)
|
|
tx = manager.HandleNotify(
|
|
platform=platform,
|
|
raw_data=request.body,
|
|
headers=headers,
|
|
)
|
|
if tx is None:
|
|
return Response(_err('回调处理失败', 400), status=400)
|
|
return Response(_ok(TransactionSerializer(tx).data))
|
|
|
|
|
|
class ChannelListView(APIView):
|
|
|
|
def get(self, request):
|
|
return Response(_ok(payment_registry.list_all_info())) |