feat: 分俱乐部付呗收款通道,默认仍走微信直连

小程序前端仍传 wechat;后台可切换 wechat/fubei,支持配置多套付呗并退款按原通道路由。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-21 20:02:24 +08:00
parent f36db77f6b
commit 5762f00d40
20 changed files with 1105 additions and 0 deletions

View File

@@ -52,6 +52,14 @@ class Club(QModel):
goeasy_appkey = models.CharField(max_length=64, blank=True, default='')
goeasy_secret = models.CharField(max_length=128, blank=True, default='')
config_json = models.JSONField(default=dict, blank=True)
# 小程序「微信支付」入口实际走哪条通道wechat=直连商户号fubei=付呗(前端仍传 wechat
mini_pay_channel = models.CharField(
max_length=16,
blank=True,
default='wechat',
verbose_name='小程序收款通道',
help_text='wechat=微信直连fubei=付呗;默认 wechat不影响现网',
)
company_uuid = models.BinaryField(max_length=16, null=True, blank=True)
sort_order = models.IntegerField(default=0)
CreateTime = models.DateTimeField(auto_now_add=True)
@@ -62,6 +70,70 @@ class Club(QModel):
verbose_name = '俱乐部'
class ClubPaymentChannel(QModel):
"""俱乐部支付通道配置(可多条;同 channel 用 is_default 选主配置)。"""
CHANNEL_CHOICES = (
('wechat_jsapi', '微信直连-小程序JSAPI'),
('wechat_v3', '微信直连-V3转账/退款'),
('alipay_wap', '支付宝-手机网站'),
('fubei_wx_mini', '付呗-微信小程序'),
)
club_id = models.CharField(max_length=16, db_index=True, verbose_name='俱乐部ID')
channel = models.CharField(max_length=32, choices=CHANNEL_CHOICES, db_index=True)
name = models.CharField(max_length=64, verbose_name='配置名称', help_text='如:主付呗、备用微信')
enabled = models.IntegerField(default=1, verbose_name='1启用0停用')
is_default = models.BooleanField(default=True, verbose_name='同通道默认配置')
sort_order = models.IntegerField(default=0, verbose_name='前端展示顺序')
sandbox = models.BooleanField(default=False, verbose_name='沙箱/联调')
app_id = models.CharField(max_length=64, blank=True, default='', verbose_name='AppID/付呗ID')
mch_id = models.CharField(max_length=64, blank=True, default='', verbose_name='商户号')
api_key_enc = models.TextField(blank=True, default='', verbose_name='API密钥/付呗Secret(加密)')
private_key_enc = models.TextField(blank=True, default='', verbose_name='应用私钥(加密)')
public_key_enc = models.TextField(blank=True, default='', verbose_name='平台公钥(加密或明文)')
cert_serial_no = models.CharField(max_length=64, blank=True, default='')
private_key_path = models.CharField(max_length=255, blank=True, default='')
platform_cert_dir = models.CharField(max_length=255, blank=True, default='')
notify_url = models.CharField(max_length=512, blank=True, default='', verbose_name='异步回调URL')
return_url = models.CharField(max_length=512, blank=True, default='', verbose_name='同步返回URL')
gateway_url = models.CharField(max_length=255, blank=True, default='', verbose_name='API网关')
mini_app_id = models.CharField(
max_length=32, blank=True, default='',
verbose_name='支付用小程序AppID',
help_text='付呗/微信JSAPI空则回落 club.wx_appid',
)
extra_json = models.JSONField(blank=True, default=dict, verbose_name='扩展配置')
remark = models.CharField(max_length=255, blank=True, default='')
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'club_payment_channel'
verbose_name = '俱乐部支付通道'
unique_together = [['club_id', 'channel', 'name']]
indexes = [
models.Index(fields=['club_id', 'channel', 'enabled'], name='idx_cpc_club_ch_en'),
models.Index(fields=['club_id', 'is_default'], name='idx_cpc_club_default'),
]
class PayChannelLedger(QModel):
"""下单时记录实际支付通道,供回调路由与退款选用(前端无感知)。"""
out_trade_no = models.CharField(max_length=64, unique=True, db_index=True, verbose_name='商户订单号')
club_id = models.CharField(max_length=16, db_index=True, default='')
channel = models.CharField(max_length=32, db_index=True, verbose_name='通道')
channel_config_id = models.IntegerField(null=True, blank=True)
biz_type = models.CharField(max_length=16, blank=True, default='', verbose_name='order/czjilu')
provider_order_sn = models.CharField(max_length=64, blank=True, default='', verbose_name='通道侧订单号')
amount_yuan = models.DecimalField(max_digits=12, decimal_places=2, default=0)
CreateTime = models.DateTimeField(auto_now_add=True)
UpdateTime = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'pay_channel_ledger'
verbose_name = '支付通道流水'
class UserWxOpenid(QModel):
"""微信 openid 与俱乐部用户绑定club_id + openid 唯一)。"""
club_id = models.CharField(max_length=16, db_index=True)