1
This commit is contained in:
@@ -27,6 +27,8 @@ const AdminPaymentConfig: React.FC = () => {
|
|||||||
wechat_cert_serial_no: map['payment_wechat_cert_serial_no'] || '',
|
wechat_cert_serial_no: map['payment_wechat_cert_serial_no'] || '',
|
||||||
wechat_api_v3_key: map['payment_wechat_api_v3_key'] || '',
|
wechat_api_v3_key: map['payment_wechat_api_v3_key'] || '',
|
||||||
wechat_notify_url: map['payment_wechat_notify_url'] || '',
|
wechat_notify_url: map['payment_wechat_notify_url'] || '',
|
||||||
|
wechat_public_key: map['payment_wechat_public_key'] || '',
|
||||||
|
wechat_public_key_id: map['payment_wechat_public_key_id'] || '',
|
||||||
alipay_app_id: map['payment_alipay_app_id'] || '',
|
alipay_app_id: map['payment_alipay_app_id'] || '',
|
||||||
alipay_private_key: map['payment_alipay_private_key'] || '',
|
alipay_private_key: map['payment_alipay_private_key'] || '',
|
||||||
alipay_public_key: map['payment_alipay_public_key'] || '',
|
alipay_public_key: map['payment_alipay_public_key'] || '',
|
||||||
@@ -58,6 +60,8 @@ const AdminPaymentConfig: React.FC = () => {
|
|||||||
payment_wechat_cert_serial_no: values.wechat_cert_serial_no || '',
|
payment_wechat_cert_serial_no: values.wechat_cert_serial_no || '',
|
||||||
payment_wechat_api_v3_key: values.wechat_api_v3_key || '',
|
payment_wechat_api_v3_key: values.wechat_api_v3_key || '',
|
||||||
payment_wechat_notify_url: values.wechat_notify_url || '',
|
payment_wechat_notify_url: values.wechat_notify_url || '',
|
||||||
|
payment_wechat_public_key: values.wechat_public_key || '',
|
||||||
|
payment_wechat_public_key_id: values.wechat_public_key_id || '',
|
||||||
payment_alipay_enabled: String(alipayEnabled),
|
payment_alipay_enabled: String(alipayEnabled),
|
||||||
payment_alipay_app_id: values.alipay_app_id || '',
|
payment_alipay_app_id: values.alipay_app_id || '',
|
||||||
payment_alipay_private_key: values.alipay_private_key || '',
|
payment_alipay_private_key: values.alipay_private_key || '',
|
||||||
@@ -188,6 +192,24 @@ const AdminPaymentConfig: React.FC = () => {
|
|||||||
<Form.Item name="wechat_notify_url" label="回调地址" extra="用户支付成功后,微信会主动通知此地址,服务器收到通知后给用户加积分">
|
<Form.Item name="wechat_notify_url" label="回调地址" extra="用户支付成功后,微信会主动通知此地址,服务器收到通知后给用户加积分">
|
||||||
<Input placeholder="https://yourdomain.com/api/payments/wechat/callback" size="large" disabled={!wechatEnabled} />
|
<Input placeholder="https://yourdomain.com/api/payments/wechat/callback" size="large" disabled={!wechatEnabled} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="wechat_public_key"
|
||||||
|
label="微信平台公钥"
|
||||||
|
extra="(可选)微信支付平台公钥,用于验证回调签名"
|
||||||
|
>
|
||||||
|
<Input.TextArea
|
||||||
|
rows={4}
|
||||||
|
placeholder="微信支付平台公钥内容"
|
||||||
|
disabled={!wechatEnabled}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
name="wechat_public_key_id"
|
||||||
|
label="微信平台公钥ID"
|
||||||
|
extra="(可选)对应平台公钥的ID"
|
||||||
|
>
|
||||||
|
<Input placeholder="平台公钥ID" size="large" disabled={!wechatEnabled} />
|
||||||
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
|||||||
@@ -112,8 +112,11 @@ async def wechat_callback(request: Request, db: AsyncSession = Depends(get_db)):
|
|||||||
cert_serial_no = db_configs.get("payment_wechat_cert_serial_no", "")
|
cert_serial_no = db_configs.get("payment_wechat_cert_serial_no", "")
|
||||||
api_v3_key = db_configs.get("payment_wechat_api_v3_key", "")
|
api_v3_key = db_configs.get("payment_wechat_api_v3_key", "")
|
||||||
appid = db_configs.get("payment_wechat_appid", "")
|
appid = db_configs.get("payment_wechat_appid", "")
|
||||||
|
public_key = db_configs.get("payment_wechat_public_key", "")
|
||||||
|
public_key_id = db_configs.get("payment_wechat_public_key_id", "")
|
||||||
|
notify_url = db_configs.get("payment_wechat_notify_url", "")
|
||||||
|
|
||||||
client = _get_wechat_client(mch_id, private_key, cert_serial_no, api_v3_key, appid)
|
client = _get_wechat_client(mch_id, private_key, cert_serial_no, api_v3_key, appid, notify_url, public_key, public_key_id)
|
||||||
if not client:
|
if not client:
|
||||||
logger.error("WeChat client not initialized for callback")
|
logger.error("WeChat client not initialized for callback")
|
||||||
return {"code": "SUCCESS", "message": "OK"}
|
return {"code": "SUCCESS", "message": "OK"}
|
||||||
|
|||||||
@@ -357,7 +357,9 @@ def _get_wechat_client(
|
|||||||
cert_serial_no: str,
|
cert_serial_no: str,
|
||||||
api_v3_key: str,
|
api_v3_key: str,
|
||||||
appid: str,
|
appid: str,
|
||||||
notify_url: str = ""
|
notify_url: str = "",
|
||||||
|
public_key: str = None,
|
||||||
|
public_key_id: str = None
|
||||||
):
|
):
|
||||||
"""Get or create a WeChat Pay client. Recreated if config changes."""
|
"""Get or create a WeChat Pay client. Recreated if config changes."""
|
||||||
global _wechat_client, _wechat_mch_id
|
global _wechat_client, _wechat_mch_id
|
||||||
@@ -375,28 +377,25 @@ def _get_wechat_client(
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import os
|
# 初始化微信支付客户端
|
||||||
# 创建并确保微信支付证书目录存在
|
wechatpay_args = {
|
||||||
wechat_cert_dir = os.path.abspath(os.path.join(
|
"wechatpay_type": WeChatPayType.NATIVE,
|
||||||
os.path.dirname(os.path.dirname(__file__)),
|
"mchid": mch_id,
|
||||||
"..",
|
"private_key": private_key.strip(),
|
||||||
"storage",
|
"cert_serial_no": cert_serial_no,
|
||||||
"wechat_certs"
|
"appid": appid,
|
||||||
))
|
"apiv3_key": api_v3_key,
|
||||||
os.makedirs(wechat_cert_dir, exist_ok=True)
|
"notify_url": notify_url,
|
||||||
logger.info("WeChat Pay platform certificates will be stored in: %s", wechat_cert_dir)
|
}
|
||||||
logger.info(f"mch_id={mch_id}, cert_serial_no={cert_serial_no}, appid={appid}, notify_url={notify_url}, api_v3_key={api_v3_key}, private_key={private_key}")
|
# 如果配置了 public_key 和 public_key_id,就使用它们,否则不设置
|
||||||
# 初始化微信支付客户端,cert_dir=None,让 SDK 在线获取证书
|
if public_key and public_key_id:
|
||||||
_wechat_client = WeChatPay(
|
wechatpay_args["public_key"] = public_key
|
||||||
wechatpay_type=WeChatPayType.NATIVE,
|
wechatpay_args["public_key_id"] = public_key_id
|
||||||
mchid=mch_id,
|
logger.info("Using configured platform public key")
|
||||||
private_key=private_key.strip(),
|
else:
|
||||||
cert_serial_no=cert_serial_no,
|
logger.info("No platform public key configured, will try to download")
|
||||||
appid=appid,
|
|
||||||
apiv3_key=api_v3_key,
|
_wechat_client = WeChatPay(**wechatpay_args)
|
||||||
notify_url=notify_url,
|
|
||||||
cert_dir=wechat_cert_dir, # 不缓存证书,每次都从微信服务器获取
|
|
||||||
)
|
|
||||||
_wechat_mch_id = mch_id
|
_wechat_mch_id = mch_id
|
||||||
logger.info("WeChat Pay client initialized successfully")
|
logger.info("WeChat Pay client initialized successfully")
|
||||||
return _wechat_client
|
return _wechat_client
|
||||||
@@ -424,11 +423,13 @@ def _create_wechat_order(order: PaymentOrder, db_configs: dict[str, str]) -> str
|
|||||||
api_v3_key = db_configs.get("payment_wechat_api_v3_key", "")
|
api_v3_key = db_configs.get("payment_wechat_api_v3_key", "")
|
||||||
appid = db_configs.get("payment_wechat_appid", "")
|
appid = db_configs.get("payment_wechat_appid", "")
|
||||||
notify_url = db_configs.get("payment_wechat_notify_url", "")
|
notify_url = db_configs.get("payment_wechat_notify_url", "")
|
||||||
|
public_key = db_configs.get("payment_wechat_public_key", "")
|
||||||
|
public_key_id = db_configs.get("payment_wechat_public_key_id", "")
|
||||||
if not all([mch_id, private_key, cert_serial_no, api_v3_key, appid]):
|
if not all([mch_id, private_key, cert_serial_no, api_v3_key, appid]):
|
||||||
logger.warning("WeChat payment config missing in database")
|
logger.warning("WeChat payment config missing in database")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
client = _get_wechat_client(mch_id, private_key, cert_serial_no, api_v3_key, appid, notify_url)
|
client = _get_wechat_client(mch_id, private_key, cert_serial_no, api_v3_key, appid, notify_url, public_key, public_key_id)
|
||||||
if client is None:
|
if client is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -471,8 +472,11 @@ async def _close_wechat_order(db: AsyncSession, order: PaymentOrder, db_configs:
|
|||||||
cert_serial_no = db_configs.get("payment_wechat_cert_serial_no", "")
|
cert_serial_no = db_configs.get("payment_wechat_cert_serial_no", "")
|
||||||
api_v3_key = db_configs.get("payment_wechat_api_v3_key", "")
|
api_v3_key = db_configs.get("payment_wechat_api_v3_key", "")
|
||||||
appid = db_configs.get("payment_wechat_appid", "")
|
appid = db_configs.get("payment_wechat_appid", "")
|
||||||
|
public_key = db_configs.get("payment_wechat_public_key", "")
|
||||||
|
public_key_id = db_configs.get("payment_wechat_public_key_id", "")
|
||||||
|
notify_url = db_configs.get("payment_wechat_notify_url", "")
|
||||||
|
|
||||||
client = _get_wechat_client(mch_id, private_key, cert_serial_no, api_v3_key, appid)
|
client = _get_wechat_client(mch_id, private_key, cert_serial_no, api_v3_key, appid, notify_url, public_key, public_key_id)
|
||||||
if client is None:
|
if client is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -503,8 +507,11 @@ async def _query_wechat_order(db: AsyncSession, order: PaymentOrder, db_configs:
|
|||||||
cert_serial_no = db_configs.get("payment_wechat_cert_serial_no", "")
|
cert_serial_no = db_configs.get("payment_wechat_cert_serial_no", "")
|
||||||
api_v3_key = db_configs.get("payment_wechat_api_v3_key", "")
|
api_v3_key = db_configs.get("payment_wechat_api_v3_key", "")
|
||||||
appid = db_configs.get("payment_wechat_appid", "")
|
appid = db_configs.get("payment_wechat_appid", "")
|
||||||
|
public_key = db_configs.get("payment_wechat_public_key", "")
|
||||||
|
public_key_id = db_configs.get("payment_wechat_public_key_id", "")
|
||||||
|
notify_url = db_configs.get("payment_wechat_notify_url", "")
|
||||||
|
|
||||||
client = _get_wechat_client(mch_id, private_key, cert_serial_no, api_v3_key, appid)
|
client = _get_wechat_client(mch_id, private_key, cert_serial_no, api_v3_key, appid, notify_url, public_key, public_key_id)
|
||||||
if client is None:
|
if client is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -545,8 +552,11 @@ async def _refund_wechat_order(
|
|||||||
cert_serial_no = db_configs.get("payment_wechat_cert_serial_no", "")
|
cert_serial_no = db_configs.get("payment_wechat_cert_serial_no", "")
|
||||||
api_v3_key = db_configs.get("payment_wechat_api_v3_key", "")
|
api_v3_key = db_configs.get("payment_wechat_api_v3_key", "")
|
||||||
appid = db_configs.get("payment_wechat_appid", "")
|
appid = db_configs.get("payment_wechat_appid", "")
|
||||||
|
public_key = db_configs.get("payment_wechat_public_key", "")
|
||||||
|
public_key_id = db_configs.get("payment_wechat_public_key_id", "")
|
||||||
|
notify_url = db_configs.get("payment_wechat_notify_url", "")
|
||||||
|
|
||||||
client = _get_wechat_client(mch_id, private_key, cert_serial_no, api_v3_key, appid)
|
client = _get_wechat_client(mch_id, private_key, cert_serial_no, api_v3_key, appid, notify_url, public_key, public_key_id)
|
||||||
if client is None:
|
if client is None:
|
||||||
return {"success": False, "message": "微信支付客户端初始化失败"}
|
return {"success": False, "message": "微信支付客户端初始化失败"}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user