エラーの概要
WeChat Payの統一注文インターフェース(Unified Order)を使用しているシステムにおいて、リクエストの送信時に以下のXML解析エラーが発生するケースがあります。
解析 XML 出错 (位置: /body): <unspecified file>(1): expected <
このエラーは、APIサーバーが受信したリクエストボディの先頭がXML形式として正しくない場合に出力されます。特に、以前は正常に動作していたコードが突然エラーになる場合、API側のボディ解析ロジックが厳格化された可能性があります。
原因の特定
問題の原因は、HTTP POSTリクエストを送信する際のデータ構築方法にあります。多くの実装例ではデータをキーと値のペアとして送信しますが、WeChat PayのAPIはXML文字列そのものをボディとして直接受信することを期待しています。
例えば、リクエストボディを構築する際に body=<xml>...</xml> のように、データの前に body= というキー名を付加してしまうと、API側はXMLの開始タグ(<)を検出できず、前述の解析エラーをスローします。以前の実装では緩く処理されていたこの形式が、現在ではエラーとして判定されるようになったようです。
修正後の実装コード(C#)
以下は、この問題を解決するための修正版コードです。このコードでは、HttpWebRequest を使用してリクエストを構築し、XML文字列をバイト配列に変換した後、プレフィックスなしでリクエストストリームへ直接書き込んでいます。
public static string RequestWeChatPayment(string apiUrl, string xmlData)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(apiUrl);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
// XMLデータをUTF-8エンコードのバイト配列に変換
byte[] requestBuffer = Encoding.UTF8.GetBytes(xmlData);
request.ContentLength = requestBuffer.Length;
// リクエストストリームにデータを書き込み
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(requestBuffer, 0, requestBuffer.Length);
}
// レスポンスの読み込み
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
この修正により、リクエストボディには純粋なXML文字列のみが含まれるようになり、WeChat PayサーバーによるXML解析が正常に完了するようになります。