Django集成PhonePe支付遇多类错误,请求排查并调出支付界面
我在Django项目中集成PhonePe支付时,出现了Service unavailable、internal server error错误,并且在pay函数的responseData = response.json()这一行触发了JSONDecodeError。目前只希望能成功调出支付界面,不确定错误出自我的代码还是PhonePe端,相关代码如下:
def calculate_sha256_string(input_string): # Create a new SHA-256 hash object sha256 = SHA256.new() # Update hash with the encoded string sha256.update(input_string.encode('utf-8')) # Return the hexadecimal representation of the hash return sha256.hexdigest() def base64_encode(input_dict): # Convert the dictionary to a JSON string json_data = jsons.dumps(input_dict) # Encode the JSON string to bytes data_bytes = json_data.encode('utf-8') # Perform Base64 encoding and return the result as a string return base64.b64encode(data_bytes).decode('utf-8') def pay(request): MAINPAYLOAD = { "merchantId": "PGTESTPAYUAT", "merchantTransactionId": shortuuid.uuid(), "merchantUserId": "MUID123", "amount": 10000, "redirectUrl": "http://127.0.0.1:8000/return-to-me", "redirectMode": "POST", "callbackUrl": "http://127.0.0.1:8000/return-to-me", "mobileNumber": "9999999999", "paymentInstrument": { "type": "PAY_PAGE" } } # SETTING INDEX = "1" ENDPOINT = "/pg/v1/pay" SALTKEY = "099eb0cd-02cf-4e2a-8aca-3e6c6aff0399" base64String = base64_encode(MAINPAYLOAD) mainString = base64String + ENDPOINT + SALTKEY sha256Val = calculate_sha256_string(mainString) checkSum = sha256Val + '###' + INDEX print("Checksum:", checkSum) # Payload Send headers = { 'accept': 'application/json', 'Content-Type': 'application/json', 'X-VERIFY': checkSum } payload = { 'request': base64String } print("Sending request to PhonePe API:") print("URL:", 'https://api-preprod.phonepe.com/apis/pg-sandbox/pg/v1/pay') print("Headers:", headers) print("Payload:", payload) response = requests.post('https://api-preprod.phonepe.com/apis/pg-sandbox/pg/v1/pay', headers=headers, json=payload) print("Raw Response Content:") print(response.text) responseData = response.json() #getting error here print("Response from PhonePe API:") print(responseData) # Print the raw response content redirect_url = responseData['data']['instrumentResponse']['redirectInfo']['url'] print("Redirect URL:", redirect_url) return redirect(redirect_url) def payment_return(request): INDEX = "1" SALTKEY = "099eb0cd-02cf-4e2a-8aca-3e6c6aff0399" form_data = request.form form_data_dict = dict(form_data) # respond_json_data = jsonify(form_data_dict) # 1.In the live please match the amount you get byamount you send also so that hacker can't pass static value. # 2.Don't take Marchent ID directly validate it with yoir Marchent ID if request.form.get('transactionId'): request_url = 'https://api-preprod.phonepe.com/apis/pg-sandbox/pg/v1/status/PGTESTPAYUAT/' + request.form.get('transactionId') sha256_Pay_load_String = '/pg/v1/status/PGTESTPAYUAT/' + request.form.get('transactionId') + SALTKEY sha256_val = calculate_sha256_string(sha256_Pay_load_String) checksum = sha256_val + '###' + INDEX # Payload Send headers = { 'Content-Type': 'application/json', 'X-VERIFY': checksum, 'X-MERCHANT-ID': request.form.get('transactionId'), 'accept': 'application/json', } response = requests.get(request_url, headers=headers) #print(response.text); return render('main/try.html', page_respond_data=form_data_dict, page_respond_data_varify=response.text)
排查关键点
- JSONDecodeError直接原因:当PhonePe返回非JSON格式响应(比如500错误的HTML页面)时,调用
response.json()必然报错。先查看你打印的response.text内容,确认返回的是不是有效JSON。如果是HTML错误页,说明请求本身就没被正确处理。 - 序列化函数错误:
base64_encode里用了jsons.dumps,应该是标准库的json.dumps(多了个s),这会导致字典序列化失败或格式不符合PhonePe要求,最终签名校验不通过,触发服务端错误。 - 签名校验逻辑:严格按照PhonePe文档核对签名计算步骤,
mainString = base64String + ENDPOINT + SALTKEY的拼接顺序、字符编码必须完全正确,不能有多余的空格或换行符。 - 请求参数与端点:沙箱API端点
https://api-preprod.phonepe.com/apis/pg-sandbox/pg/v1/pay是正确的,但要确保MAINPAYLOAD里的参数格式符合要求,比如amount单位是派萨(10000对应100卢比),这点你当前是对的。 - 回调地址可访问性:沙箱环境下本地
127.0.0.1可以用于跳转,但如果PhonePe需要主动回调你的服务,本地开发需要用ngrok等工具暴露公网端口,否则回调会失败。 - 错误处理缺失:当前代码未处理请求失败的情况,建议先判断响应状态码再解析JSON:
if response.status_code == 200: try: responseData = response.json() except JSONDecodeError: print("无效JSON响应:", response.text) else: print(f"请求失败,状态码: {response.status_code},响应内容: {response.text}") - return视图参数错误:
payment_return里的render调用缺少第一个参数request,且上下文参数格式错误,正确写法是:return render(request, 'main/try.html', { 'page_respond_data': form_data_dict, 'page_respond_data_varify': response.text if 'response' in locals() else '' })
内容的提问来源于stack exchange,提问作者Himanshu Pandey
相关产品推荐
相关产品推荐

