diff --git a/backend/shop/views.py b/backend/shop/views.py index 40fe18c..f965e74 100644 --- a/backend/shop/views.py +++ b/backend/shop/views.py @@ -24,6 +24,8 @@ import json import os import base64 from cryptography.hazmat.primitives.ciphers.aead import AESGCM +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import padding from django.conf import settings import requests import random @@ -127,6 +129,8 @@ def get_wechat_pay_client(pay_type=WeChatPayType.NATIVE, appid=None, config=None notify_url=notify_url, cert_dir=cert_dir ) + # 保存私钥内容以便后续手动签名使用 + wxpay._private_key_content = private_key return wxpay, None except Exception as e: return None, str(e) @@ -769,12 +773,26 @@ class OrderViewSet(viewsets.ModelViewSet): # 签名串格式:appId\ntimeStamp\nnonceStr\npackage\n message_build = f"{miniprogram_appid}\n{timestamp}\n{nonce_str}\n{package}\n" - # 使用商户私钥签名 - # 注意:WeChatPayV3 对象的私钥属性名可能随版本变化,或者被封装 - # 这里我们不直接访问私钥,而是利用 SDK 提供的 sign 方法 + print(f"待签名字符串:\n{repr(message_build)}") - # 实际上 wechatpayv3 库提供了 sign 方法 - signature = wxpay.sign(message_build) + # 手动签名 + from cryptography.hazmat.backends import default_backend + + private_key_obj = serialization.load_pem_private_key( + wxpay._private_key_content.encode('utf-8'), + password=None, + backend=default_backend() + ) + + signature = base64.b64encode( + private_key_obj.sign( + message_build.encode('utf-8'), + padding.PKCS1v15(), + hashes.SHA256() + ) + ).decode('utf-8') + + print(f"生成的签名: {signature}") return Response({ 'timeStamp': timestamp,