0

I’m integrating ERPNext (Frappe Framework) with the Pakistan FBR DI API.
I’m facing a strange issue:

When I send the request using cURL, the invoice is accepted successfully.

When I send the exact same payload through ERPNext using Python requests, the API returns:

500 Internal Server Error

1. Working cURL Command

This request succeeds and FBR accepts the invoice:

curl -X POST "https://gw.fbr.gov.pk/di_data/v1/di/postinvoicedata_sb" \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json" \
  -H "Accept: */*" \
  -H "Accept-Encoding: gzip, deflate, br" \
  -H "User-Agent: Mozilla/5.0" \
  -d '{
    "invoiceType": "",
    "invoiceDate": "",
    "sellerNTNCNIC": "",
    "sellerBusinessName": "",
    "sellerAddress": "",
    "sellerProvince": "",
    "buyerNTNCNIC": "",
    "buyerBusinessName": "",
    "buyerAddress": "",
    "buyerProvince": "",
    "invoiceRefNo": "",
    "scenarioId": "SN001",
    "buyerRegistrationType": "",
    "items": [{
        "hsCode": "4819.1000",
        "productDescription": "2Sum 2g Injection TP New 2D R#06",
        "rate": "18%",
        "uoM": "Numbers,pieces,units",
        "quantity": 2500.0,
        "totalValues": 2767.1,
        "valueSalesExcludingST": 2345.0,
        "fixedNotifiedValueOrRetailPrice": 0,
        "salesTaxApplicable": 422.1,
        "salesTaxWithheldAtSource": 0,
        "extraTax": "",
        "furtherTax": 0.0,
        "sroScheduleNo": "",
        "fedPayable": 0,
        "discount": 0.0,
        "saleType": "Goods at standard rate (default)",
        "sroItemSerialNo": ""
    }]
  }'

This works perfectly.


2. Failing ERPNext / Python requests code

Inside ERPNext custom app (fbr_api.py), this block is used:

headers = {
    "Authorization": f"Bearer {token}",
    "Content-Type": "application/json",
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate, br",
    "User-Agent": "Mozilla/5.0"
}

payload = {... same JSON structure as curl ...}

response = requests.post(
    api_url,
    headers=headers,
    json=payload,  
    verify=False
)

response.raise_for_status()

This results in:

500 Server Error: Internal Server Error


4. The payload logged inside ERPNext is IDENTICAL to the working cURL payload

The headers also match.
Yet ERPNext → FBR always gives a 500 error, while cURL → FBR works.


Question:

Why does the API accept the exact same request via cURL but produces 500 error when sent using Python requests inside ERPNext (Frappe)?

Is there something different about:

  • encoding?

  • gzip handling?

  • SSL?

  • how Python constructs the raw body?

  • any hidden headers FBR expects?

Any insight would be greatly appreciated.


✔ Additional notes:

  • ERPNext is running Python 3.10

  • API endpoint is the official DI API sandbox

  • Token is valid

  • Same token + same payload always work in curl

New contributor
Marium Faisal is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
1
  • 2
    Send both requests to a service like requestcatcher.com, and see what difference you can find. Commented Nov 27 at 7:36

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.