This commit is contained in:
doudou201703
2026-08-02 14:07:04 +08:00
commit 046fac6dc1
339 changed files with 19435 additions and 0 deletions
@@ -0,0 +1,67 @@
import requests
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.routers import DefaultRouter
from rest_framework.viewsets import ViewSet
from sixGuoDjango import BaseResponse, ResData
from wechat_数据库.雪花算法.雪花算法工具 import generator
from wechat_项目工具包.微信支付工具包.微信支付类 import paymentCategory, wechatPay
class 代金券接口ViewSets(ViewSet):
@action(detail=False, methods=["get", "post", "put", "delete"], url_path="send_coupons")
def 发放指定代金券接口(self, request: Request):
""""""
self_mini_openid = request.data.get("self_mini_openid", None)
self_mini_unionid = request.data.get("self_mini_unionid", None)
发放接口 = f"https://api.mch.weixin.qq.com/v3/marketing/favor/users/{self_mini_openid}/coupons"
out_request_no = generator.generate_str()
发放的数据 = {
"stock_id": "22512292", # 发放的批次号
"out_request_no": out_request_no, # 【商户单据号】商户此次发放凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性
"appid": "wxf612e825377328f0",
"stock_creator_mchid": "1700383419", # 创建批次的商户号】批次创建方商户号。
# "coupon_value": 100, # 指定面额发券,面额】指定面额发券场景,券面额,其他场景不需要填,单位:分。
}
返回签名后的 = wechatPay(payment=paymentCategory).构造签名串(uri=发放接口, body_data=发放的数据, method="POST")
data = requests.post(url=发放接口, json=发放的数据, headers=返回签名后的)
print(data.json())
httpResData = BaseResponse(resData=ResData(listData=[""], dictData={"couponsMessages": "发券成功"}), ).model_dump()
return Response(data=data.json(), status=status.HTTP_200_OK)
@action(detail=False, methods=["get", "post", "put", "delete"], url_path="setting_url")
def 设置代金券消息通知地址(self, request: Request):
""""""
self_user_unionid = request.data.get("self_user_unionid", None)
self_mini_openid = request.data.get("self_mini_openid", None)
请求接口 = f"https://api.mch.weixin.qq.com//v3/marketing/favor/callbacks"
请求数据 = {
"mchid": paymentCategory.mchid,
"notify_url": "https://xiao.sixgou.com/coupons/coupons_callback/",
}
headers = wechatPay(payment=paymentCategory).构造签名串(uri=请求接口, body_data=请求数据)
data = requests.post(url=请求接口, json=请求数据, headers=headers)
print("请求后的结果", data.json()) # 请求后的结果 {'notify_url': 'https://xiao.sixgou.com/coupons/coupons_callback/', 'update_time': '2026-03-25T23:51:54+08:00'}
httpResData = BaseResponse(resData=ResData(listData=[""], dictData={"couponsMessages": "发券成功"}), ).model_dump()
return Response(data=httpResData, status=status.HTTP_200_OK)
@action(detail=False, methods=["post"], url_path="coupons_callback")
def 代金券的回调接口(self, request: Request):
""""""
self_user_unionid = request.data.get("self_user_unionid", None)
self_mini_openid = request.data.get("self_mini_openid", None)
# 回调解密内容 = wechatPay(payment=paymentCategory).callBack回调解密(headers=request.headers, response_body=request.body)
# print("回调解密内容", 回调解密内容)
wechat_data支付回调数据 = wechatPay(payment=paymentCategory).callBack回调解密(headers=request.headers, response_body=request.data, )
print(wechat_data支付回调数据, "wechat_data支付回调数据🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 ")
print("🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 🍏🍎 🍏")
httpResData = BaseResponse(resData=ResData(listData=[""], dictData={"demo": "xiaozizi"}), ).model_dump()
return Response(data=httpResData, status=status.HTTP_200_OK)
代金券接口ViewSetsRouter = DefaultRouter()
代金券接口ViewSetsRouter.register(prefix="", viewset=代金券接口ViewSets, basename="")
@@ -0,0 +1,101 @@
import pydash
from django.core.handlers.wsgi import WSGIRequest
from django.db import models
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.routers import DefaultRouter
from rest_framework.viewsets import ViewSet
from sixGuoDjango import BaseResponse, ResData
from wechat_数据库.雪花算法.雪花算法工具 import generator
from wechat_项目工具包.微信支付工具包.微信支付类 import paymentCategory, wechatPay
class six商家转账ViewSets(ViewSet):
@action(detail=False, methods=["post"], url_path="transfer")
def six发起转账(self, request: Request):
""" """
self_mini_openid = request.data.get("self_mini_openid", None)
self_mini_unionid = request.data.get("self_mini_unionid", None)
提取积分值 = request.data.get("提取积分值", None)
# 逻辑一: 先比较积分值是否超出提现的金额
# 积分值sum = share分享者积分.objects.filter(share分享者unionid=self_mini_unionid).values("share分享者unionid").annotate(xiao_age_sum=models.Sum("share分享积分值"), ) # 只有value(字段1,字段2)二个值完全相同的才会分配为一组
# 添加 order_by
# result = 积分值sum.order_by("share分享者unionid").first()
# print(result)
# xiao_age_sum = pydash.get(obj=result, path="xiao_age_sum")
# print(xiao_age_sum)
# httpResData = BaseResponse(resData=ResData(listData=[""], dictData={"demo": xiao_age_sum}), ).model_dump()
httpResData = BaseResponse(resData=ResData(listData=[""], dictData={"demo": {}}), ).model_dump()
return Response(data=httpResData, status=status.HTTP_200_OK)
if xiao_age_sum > 0 and xiao_age_sum >= 提取积分值:
pass
# 说明这里可以提现
# 业务逻辑 第一步.需要判断这个用户是否已经领过 新手红包 如何判断, 查询新手红包数据库,如果对象存在,则直接不能再领取了;
out_bill_no = generator.generate_str()
transfer_amount = 10 # 必须参数转账的金额
transferAccountsBody = {
"appid": paymentCategory.appid,
"out_bill_no": out_bill_no, # 必填 integer【商户单号】
# 商户系统内部的商家单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一
"transfer_scene_id": "1000",
# 必填 integer【转账场景ID】 该笔转账使用的转账场景,可前往“商户平台-产品中心-商家转账”中申请。如:1000(现金营销),1006(企业报销)等
# "openid":"ohQkD7A-N93kljcFmkCyG6e_D9vg",
"openid": self_mini_openid, # 必填 integer【收款用户OpenID】 用户在商户appid下的唯一标识。发起转账前需获取到用户的OpenID,获取方式详见参数说明。
# "user_name":"757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45", # 【收款用户姓名】
# 收款方真实姓名。需要加密传入,支持标准RSA算法和国密算法,公钥由微信侧提供。
"transfer_amount": transfer_amount, # 必填 integer【转账金额】 转账金额单位为“分”。
"transfer_remark": "新会员开通有礼", # 必填 string(32)【转账备注】 转账备注,用户收款时可见该备注信息,UTF8编码,最多允许32个字符
"notify_url": "https://xiao.sixgou.com/demopay/transfer_back/",
# 选填【通知地址】 异步接收微信支付结果通知的回调地址,通知url必须为公网可访问的URL,必须为HTTPS,不能携带参数。
"user_recv_perception": "现金奖励", # 选填 【用户收款感知】 用户收款时感知到的收款原因将根据转账场景自动展示默认内容。如有其他展示需求,
# 必填 array[TransferSceneReportInfo] 【转账场景报备信息】 各转账场景下需报备的内容,商户需要按照所属转账场景规则传参,详见转账场景报备信息字段说明。
"transfer_scene_report_infos": [
{
"info_type": "活动名称", # 必填 string(15)【信息类型】 不能超过15个字符,商户所属转账场景下的信息类型,此字段内容为固定值
"info_content": "新会员有礼", # 必填 【信息内容】 不能超过32个字符,商户所属转账场景下的信息内容,商户可按实际业务场景自定义传参
},
{
"info_type": "奖励说明", "info_content": "注册会员抽奖一等奖",
},
],
}
# wechat_data = wechatPay(payment=paymentCategory).transferAccounts商家转账到零钱(transferAccountsBody=transferAccountsBody)
# print("返回的数据", wechat_data)
# package_info = jmespath.search(data=wechat_data, expression="package_info")
# create_time = jmespath.search(data=wechat_data, expression="create_time")
# out_bill_no = jmespath.search(data=wechat_data, expression="out_bill_no")
# state = jmespath.search(data=wechat_data, expression="state")
# transfer_bill_no = jmespath.search(data=wechat_data, expression="transfer_bill_no")
# WechatTransferOrder.objects.create(
# out_bill_no=out_bill_no, transfer_bill_no=transfer_bill_no, wx_create_time=create_time,
# state=state, transfer_amount=transfer_amount, package_info=package_info
# )
# 前端调用的数据 = {
# "mchId": paymentCategory.mchid, "appId": paymentCategory.appid, "package": package_info,
# }
# # 操作数据库,减掉提取的积分值
# share分享者积分.objects.create(share分享者unionid=self_mini_unionid, share分享类型="提取积分", share分享积分=-1)
httpResData = BaseResponse(resData=ResData(listData=[""], dictData={"demo": "xiaozizi"}), ).model_dump()
return Response(data=httpResData, status=status.HTTP_200_OK)
else:
pass
httpResData = BaseResponse(resData=ResData(listData=[""], dictData={"demo": "xiaozizi"}), ).model_dump()
return Response(data=httpResData, status=status.HTTP_200_OK)
# 说明这里不能提现
httpResData = BaseResponse(resData=ResData(listData=[""], dictData={}), ).model_dump()
return Response(data=httpResData, status=status.HTTP_200_OK)
@action(detail=False, methods=["post"], url_path="transfer_back")
def six发起转账回调(self, request: WSGIRequest | Request):
pass
wechat_data = wechatPay(payment=paymentCategory).callBack回调解密(response_body=request.body, headers=request.headers)
print(wechat_data)
return Response()
six商家转账ViewSetsRouter = DefaultRouter()
six商家转账ViewSetsRouter.register(prefix="", viewset=six商家转账ViewSets, basename="")
@@ -0,0 +1,189 @@
import secrets
import jmespath
import orjson
import pydash
from django.core.handlers.wsgi import WSGIRequest
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.routers import DefaultRouter
from rest_framework.viewsets import ViewSet
from sixGuoDjango import ResData, BaseResponse
from wechat_数据库.支付订单数据库.商品订单数据 import order订单
from wechat_数据库.雪花算法.雪花算法工具 import generator
from wechat_项目工具包.微信支付工具包.微信支付类 import paymentCategory, wechatPay
class 微信支付ViewSets( ViewSet ):
@action( detail=False, methods=[ "post" ], url_path="jsapi" )
def 小程序支付jsapi( self, request: Request ) -> Response:
""""""
url_pay = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi" # 发起请求的链接
self_mini_openid = request.data.get( "self_mini_openid", False ) #
order商品数据 = request.data.get( "order商品数据", None )
order用户配送地址 = request.data.get( "order用户配送地址", None )
order商品数量 = request.data.get( "order商品数量", None )
order商品总价 = request.data.get( "order商品总价", None )
order商品ID = request.data.get( "order商品ID", None )
share订单分享者ID = request.data.get( "share订单分享者ID", None ) # 当前是否有上级对象
order订单类型 = request.data.get( "order订单类型", None )
superior_unionid = request.data.get( "superior_unionid", None ) # 当前是否有上级对象
out_trade_no = f"{generator.generate_id( )}"
print( self_mini_openid, "我的id拿不到了吗", order商品数据 )
body = {
"mchid": paymentCategory.mchid, # 【直连商户号】 直连商户号
"out_trade_no": out_trade_no, # 【商户订单号】 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一。
"appid": paymentCategory.appid, # 【公众号 或者 小程序ID】
"description": "测试支付接口", # 【商品描述】 商品描述要
"notify_url": "https://xiao.sixgou.com/demopay/jsapi_callback/", # 回调地址要
"amount": {
"total": 1, # 【总金额】 订单总金额,单位为分。
"currency": "CNY", # 【货币类型】 CNY:人民币,境内商户号仅支持人民币。
}, # 【支付者】 支付者信息。
"attach": orjson.dumps( { "share订单分享者ID": share订单分享者ID }, option=orjson.OPT_SORT_KEYS, ).decode( encoding="utf-8" ),
"payer": {
# "openid": "ohQkD7A-N93kljcFmkCyG6e_D9vg", # 【用户标识】 用户在普通商户AppID下的唯一标识。 下单前需获取到用户的OpenID,详见OpenID获取
"openid": self_mini_openid, # 【用户标识】 用户在普通商户AppID下的唯一标识。 下单前需获取到用户的OpenID,详见OpenID获取
},
} # 请求的数据
wechat_data = wechatPay( payment=paymentCategory ).getpay_jsapi( uri=url_pay, body_data=body, method="POST" )
print( wechat_data )
payData = jmespath.search( data=wechat_data, expression="response" )
order订单.objects.create( order支付商家侧订单号=out_trade_no,
order商品总价=order商品总价, order商品数据=order商品数据, order商品数量=order商品数量,
order商品ID=order商品ID, order支付数据=body, order支付状态="支付中", order订单类型=order订单类型,
order支付都ID=self_mini_openid, order用户配送地址=order用户配送地址,
)
httpResData = BaseResponse( resData=ResData( listData=[ "" ], dictData=payData ), ).model_dump( )
return Response( data=httpResData, status=status.HTTP_200_OK )
@action( detail=False, methods=[ "post" ], url_path="navite" )
def 二维码支付( self, request: WSGIRequest | Request ) -> Response:
"""
生成收款的二维码链接,可以让用户来扫码支付
:param request:
:return:
"""
out_trade_no = f"{generator.generate_id( )}"
native_body = {
"mchid": paymentCategory.mchid, # 服务商户号
"out_trade_no": out_trade_no, # 商户系统内部订单号
"appid": paymentCategory.appid, # 服务商应用ID
"description": "测试", # 商品的描述信息
"notify_url": "https://server.xiao.band/demopay/callback_navite/", # 回调地址
"amount": { "total": 1, "currency": "CNY" },
}
res_data = wechatPay( payment=paymentCategory ).getpay_navite( navite_body=native_body )
print( res_data )
code_url = jmespath.search( data=res_data, expression="code_url" )
print( code_url )
import segno
qr = segno.make_qr( content="------", )
data = qr.png_data_uri( scale=5 )
qr.save( out="myqr.png" )
httpResData = BaseResponse( resData=ResData( listData=[ "" ], dictData={ "demo": data } ), ).model_dump( )
return Response( data=httpResData, status=status.HTTP_200_OK, )
@action( detail=False, methods=[ "post" ], url_path="qrCode" )
def 付款码支付( self, request: Request ):
"""
扫用户付款码的测试接口
:param request:
"""
nonce_str = secrets.token_hex( 10 ) # 随机字符串
order_random = f"{generator.generate_id( )}"
auth_code = request.data.get( "auth_code", False ) # 前端扫码读取的付款码的数据信息
# auth_code = "123497182327333282" # TODO 扫码支付付款码,设备读取用户微信中的条码或者二维码信息(这个值需要小程序端,扫码,将数据传递进来)
# fu_kuan_data 是微信官方要求组装的数据类型
fu_kuan_data = {
"appid": paymentCategory.appid, # 小程序的appid
"mch_id": paymentCategory.mchid, # 微信支付分配的商户号
"nonce_str": nonce_str, # 随机字符串
"out_trade_no": order_random, # 商户订单号
"body": "test",
"auth_code": auth_code,
"total_fee": 1, # 订单总金额,单位为分,只能为整数,详见支付金额(必填)
}
wechat_data = wechatPay( payment=paymentCategory ).getpay_code扫用户付款码( body_data=fu_kuan_data )
print( wechat_data )
# return_code 通信返回码:'SUCCESS' 表示与微信服务器通信成功,'FAIL' 表示通信失败(如网络或参数错误)
return_code = jmespath.search( data=wechat_data, expression="xml.return_code" )
# return_msg 通信返回信息:当 return_code 为 'FAIL' 时,此字段包含错误描述;成功时通常为 'OK'
return_msg = jmespath.search( data=wechat_data, expression="xml.return_msg" )
# result_code 业务结果码:'SUCCESS' 表示支付成功,'FAIL' 表示支付失败(需结合 err_code 分析,但此处未提取)
result_code = jmespath.search( data=wechat_data, expression="xml.result_code" )
# mch_id 商户号(MCH ID):微信支付分配给商户的唯一标识
mch_id = jmespath.search( data=wechat_data, expression="xml.mch_id" )
# appid 公众号或小程序的 AppID:发起支付的应用身份标识
appid = jmespath.search( data=wechat_data, expression="xml.appid" )
# nonce_str 随机字符串:用于防止重放攻击,由商户生成并随请求发送,微信原样返回
nonce_str = jmespath.search( data=wechat_data, expression="xml.nonce_str" )
# openid 用户在当前 AppID 下的唯一标识(OpenID):可用于关联用户账户
openid = jmespath.search( data=wechat_data, expression="xml.openid" )
# total_fee 订单总金额(单位:分):例如 '1' 表示 0.01 元
total_fee = jmespath.search( data=wechat_data, expression="xml.total_fee" )
# cash_fee_type 现金支付币种:目前微信支付仅支持 'CNY'(人民币)
cash_fee_type = jmespath.search( data=wechat_data, expression="xml.cash_fee_type" )
# transaction_id 微信支付系统生成的唯一交易单号:用于对账、退款、查询等操作
transaction_id = jmespath.search( data=wechat_data, expression="xml.transaction_id" )
# 商户系统内部订单号:由商户在调用支付接口时传入,用于关联自身业务订单
out_trade_no = jmespath.search( data=wechat_data, expression="xml.out_trade_no" )
# 附加数据:商户在支付请求中可自定义传入,微信原样返回(常用于传递门店ID、商品类型等)
attach = jmespath.search( data=wechat_data, expression="xml.attach" )
# time_end 支付完成时间:格式为 yyyyMMddHHmmss,例如 '20260304233708' 表示 2026年03月04日 23:37:08
time_end = jmespath.search( data=wechat_data, expression="xml.time_end" )
httpResData = BaseResponse( resData=ResData( listData=[ "" ], dictData={ "demo": "xiaozizi" } ), ).model_dump( )
return Response( data=httpResData, status=status.HTTP_200_OK )
@action( detail=False, methods=[ "post" ], url_path="jsapi_callback" )
def jsapi支付回调测试接口( self, request: Request ) -> Response:
""" 微信支付成功后的回调接口 """
dict_body = request.data
wechat_data支付回调数据 = wechatPay( payment=paymentCategory ).callBack回调解密( headers=request.headers, response_body=dict_body, )
print( "\n🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 \n", wechat_data支付回调数据, "\n🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 🍊 🍎 🍏 \n" )
out_trade_no = jmespath.search( data=wechat_data支付回调数据, expression="out_trade_no" )
trade_state_desc = pydash.get( obj=wechat_data支付回调数据, path="trade_state_desc" )
self_mini_openid = pydash.get( obj=wechat_data支付回调数据, path="payer.openid" )
# 调用异步方法 : 作用 (发起订单录入接口调用)
# 更新 拼团订单的 支付状态
生成物流的订单号 = generator.generate_str( )
order订单.objects.filter( order支付商家侧订单号=out_trade_no ).update( order支付数据=wechat_data支付回调数据, order支付状态=trade_state_desc,
order物流状态=order订单.order订单choosies物流状态.待发货.value, order物流订单号=生成物流的订单号
)
# 在这里还需要处理是否给上级添加积分
share订单分享者ID = pydash.get( obj=orjson.loads( pydash.get( obj=wechat_data支付回调数据, path="attach" ) ), path="share订单分享者ID" )
httpResData = BaseResponse( resData=ResData( listData=[ "" ], dictData={ "demo": "xiaozizi" } ), ).model_dump( )
return Response( data=httpResData, status=status.HTTP_200_OK )
@action( detail=False, methods=[ "post" ], url_path="callback_navite" )
def 二维码支付回调( self, request: WSGIRequest | Request ):
"""注释"""
二维码支付回调数据 = wechatPay( payment=paymentCategory ).callBack回调解密( headers=request.headers, response_body=request.body, )
print( "二维码支付回调数据=>::", 二维码支付回调数据 )
return Response( data={ "msg": "success" } )
微信支付ViewSetsRouter = DefaultRouter( )
微信支付ViewSetsRouter.register( prefix="", viewset=微信支付ViewSets, basename="" )