python 对接支付宝账单流程及问题处理

 可以从支付宝文档中获取适用于python的sdk方法  小程序文档 - 支付宝文档中心

问题:

        从文档中我们对python的SDK了解不多,直接拿来用有可能有网络问题,因为你的执行环境可能处于内网中,聪明的你第一时间想到加代理访问解决,可是SDK提供的接口并没有设置代理的参数

import json
from alipay.aop.api.AlipayClientConfig import AlipayClientConfig
from alipay.aop.api.DefaultAlipayClient import DefaultAlipayClient
from alipay.aop.api.request.AlipayDataDataserviceBillDownloadurlQueryRequest import \
    AlipayDataDataserviceBillDownloadurlQueryRequest
from alipay.aop.api.domain.AlipayDataDataserviceBillDownloadurlQueryModel import \
    AlipayDataDataserviceBillDownloadurlQueryModel

import logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s %(levelname)s %(message)s',
    filemode='a',)
logger = logging.getLogger('')


ALIPAY_BILL_URL_KEY = "https://openapi.alipay.com/gateway.do"
app_id = "app_id"
private_key = """private_key"""
alipay_public_key = """alipay_public_key"""
sign_type = "RSA"


alipay_client_config = AlipayClientConfig()
alipay_client_config.server_url = ALIPAY_BILL_URL_KEY
alipay_client_config.app_id = app_id
alipay_client_config.app_private_key = private_key
alipay_client_config.alipay_public_key = alipay_public_key
alipay_client_config.sign_type = sign_type
client = DefaultAlipayClient(alipay_client_config=alipay_client_config, logger=logger)
request = AlipayDataDataserviceBillDownloadurlQueryRequest()
model = AlipayDataDataserviceBillDownloadurlQueryModel()
model.bill_type = "trade"
model.bill_date = "2025-04-14"
# model.smid = alipay_bill_config["account_number"]
request.biz_model = model
# 发送请求并获取响应
response_json = client.execute(request)
response = json.loads(response_json)
print(response)
try:
    if response["bill_file_code"] == "EMPTY_DATA_WITH_BILL_FILE":
        print("bill_file_code is EMPTY_DATA_WITH_BILL_FILE")
except Exception as e:
    print(str(e))
    if response["msg"] == "Success" and response["code"] == "10000":
        print(response["bill_download_url"])
        print("downloadTradeBill completed")

解决流程:

1、下载源码:

pip install alipay-sdk-python

2、进入execute方法

可以打断点调试,这里是请求的入口

因为我们request对象没有设置表单参数,multipart_params返回的是空值

3、进入do_post方法

可以看到get_http_connection方法在构造连接对象connection,所以聪明的你一定想到了在这里可以加上代理

 4、修改源码get_http_connection方法

处理了代理问题,有可能还会遇到SSL的证书报错,那么聪明的你一定想到了忽略SSL证书认证(不建议,但可以用),完整代码如下:

def get_http_connection(url, query_string, timeout):
    import ssl
    import http.client
    url_parse_result = urlparse.urlparse(url)
    host = url_parse_result.hostname
    port = 80
    # 代理服务器配置
    proxy_url = 'http://proxy:8080'  # 写上自己对应的代理
    # 解析代理主机和端口
    proxy_host, proxy_port = proxy_url.split('://')[-1].split(':')
    # 创建一个不验证证书的 SSL 上下文
    context = ssl.create_default_context()
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE
    # 创建连接对象,这里我们实际上连接到代理服务器
    connection = http.client.HTTPSConnection(host=proxy_host, port=proxy_port, timeout=timeout, context=context)
    # 设置隧道,指定目标服务器的主机和端口
    connection.set_tunnel(host, port)

    if url.find("https") == 0:
        port = 443
        connection = http.client.HTTPSConnection(host=proxy_host, port=proxy_port, timeout=timeout, context=context)
        # 设置隧道,指定目标服务器的主机和端口
        connection.set_tunnel(host, port)
    url = url_parse_result.scheme + "://" + url_parse_result.hostname
    if url_parse_result.port:
        url += url_parse_result.port
    url += url_parse_result.path
    url += ('?' + query_string)
    return url, connection

总结:

        以上方法只适用于临时方案,感兴趣的小伙伴可以改造自己的SDK,实现添加指定参数来调用对应功能。

补充--20250603

1、如遇到私钥认证失败,可能需要将私钥由PKCS8格式转换为PKCS1格式

alipay_client_config.app_private_key = pkcs1_to_pkcs8(private_key)
#密钥格式转换
def pkcs1_to_pkcs8(pkcs8_key):
    key = "-----BEGIN PRIVATE KEY-----\n" + pkcs8_key + "\n-----END PRIVATE KEY-----"
    private_key = load_pem_private_key(key.encode(), None, default_backend())

    # 转换为PKCS1格式
    pkcs1_key = private_key.private_bytes(
        encoding=Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    )

    # 将pkcs1_key转换为字符串,以便打印或写入文件
    pkcs1_key_str = pkcs1_key.decode()
    return pkcs1_key_str.split('\n', 1)[1].rsplit('\n', 2)[0]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值