You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python Requests库调用SOAP接口返回500错误的排查与解决

Fixing 500 Internal Error in Sunat e-Factura SOAP Call with Python Requests

Let's break down why you're hitting that 500 error and fix your SOAP call step by step. The env:Client fault code tells us the issue is with the structure or content of your request, not the server itself. Here are the key problems and fixes:

1. Base64 Encoding Returns Bytes (Not a String)

When you use base64.b64encode(file.read()), it returns a bytes object (e.g., b'dGVzdA=='). Rendering this directly into your XML will include the b' prefix, which invalidates the base64 content. You need to decode it to a UTF-8 string first.

Fix:

invoice_file_data = base64.b64encode(file.read()).decode('utf-8')

2. Duplicate WSSE Authentication

You're adding WSSE credentials both in the XML header and using the WSSEAuth library. This creates conflicting authentication headers, which Sunat's server rejects. Stick with one method—WSSEAuth is cleaner and avoids manual XML header mistakes.

Fix:
Remove the entire <wsse:Security> block from your XML template, since WSSEAuth will automatically generate the correct WSSE header.

3. Incorrect Content-Type Header

Your current headers split content-type and charset into separate fields, but SOAP requires combining them into a single Content-Type value. Also, Requests automatically calculates Content-Length for you—setting it manually can lead to mismatches if you miscalculate the encoded length.

Fix:
Update your headers to:

headers = {
    'Content-Type': 'text/xml; charset=iso-8859-1'
}

4. Requesting the WSDL URL Instead of the Service Endpoint

You're sending the POST request to the WSDL URL (...?wsdl), but SOAP calls need to target the actual service endpoint (without the ?wsdl suffix).

Fix:
Use the endpoint URL instead:

# Production endpoint
SERVICE_URL = 'https://e-factura.sunat.gob.pe/ol-ti-itcpfegem/billService'
# Beta endpoint (for testing)
# SERVICE_URL = 'https://e-beta.sunat.gob.pe/ol-ti-itcpfegem-beta/billService'

Revised Code & Template

Updated Python Code

import os
import pystache
import requests
import base64
from wsse.client.requests.auth import WSSEAuth

# Configuration
invoice_file_name = '10101010101-03-F004-00000001.zip'
invoice_file_path = 'path_to/10101010101-03-F004-00000001.zip'
sunat_ruc = '20100066603'
sunat_user = 'MODDATOS'
sunat_pass = 'moddatos'
# Use service endpoint, not WSDL URL
SERVICE_URL = 'https://e-factura.sunat.gob.pe/ol-ti-itcpfegem/billService'
# SERVICE_URL = 'https://e-beta.sunat.gob.pe/ol-ti-itcpfegem-beta/billService'

# Read and encode invoice file correctly
with open(invoice_file_path, 'rb') as file:
    invoice_file_data = base64.b64encode(file.read()).decode('utf-8')

# Load and render XML template
xml_send_bill_path = os.path.join(
    os.path.dirname(os.path.abspath(__file__)),
    'templates',
    'send_bill.xml'
)
with open(xml_send_bill_path, 'r') as file:
    xml_send_bill = file.read()

xml_send_bill_string = pystache.render(xml_send_bill, {
    'InvoiceFileName': invoice_file_name,
    'InvoiceFileContent': invoice_file_data
})

# Encode request and set headers
encoded_request = xml_send_bill_string.encode('iso-8859-1')
headers = {
    'Content-Type': 'text/xml; charset=iso-8859-1'
}

# Send request with WSSEAuth (no need for manual WSSE header)
response = requests.post(
    url=SERVICE_URL,
    data=encoded_request,
    headers=headers,
    auth=WSSEAuth(f"{sunat_ruc}{sunat_user}", sunat_pass)
)

print("response.status_code", response.status_code)
print("response.text", response.text)

Updated XML Template (send_bill.xml)

<?xml version='1.0' encoding='ISO-8859-1' standalone='no'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.sunat.gob.pe">
<soapenv:Body>
<ser:sendBill>
<fileName>{{InvoiceFileName}}</fileName>
<contentFile>{{{InvoiceFileContent}}}</contentFile>
</ser:sendBill>
</soapenv:Body>
</soapenv:Envelope>

Additional Checks

  • Verify your invoice ZIP file follows Sunat's exact format (includes the required XML and signature files).
  • Double-check that you're using the correct credentials (RUC + username + password) for your target environment (production vs beta).
  • If you still hit issues, enable debug logging to inspect the full request headers and body:
    import logging
    logging.basicConfig(level=logging.DEBUG)
    

内容的提问来源于stack exchange,提问作者Carlos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:29:46