Post XML 与 TidHttp 无效请求

Post XML with TidHttp Invalid request

我正在尝试 post 使用 Delphi 2007 的 XML 文件与 WorldPay 进行交易,但我一直收到 "Invalid request" 错误。

这是我的代码,我不知道我做错了什么。

Var
  XDoc, ReturnStr:String;
  XMLToSend, resp: TStringStream;
  IdHTTP1:TIdHTTP;
  IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
begin   
  with Datam1.CCSetupTbl do
  begin
    XDoc := '<?xml version="1.0" encoding="UTF-8"?>' +
            '<TransactionSetup xmlns="https://certtransaction.elementexpress.com">' +
              '<Credentials>' +
                '<AccountID>' + FieldByName('M').AsString + '</AccountID>' +
                '<AccountToken>' + FieldByName('MW').AsString + '</AccountToken>' +
                '<AcceptorID>' + FieldByName('MP').AsString + '</AcceptorID>' +
              '</Credentials>' +
              '<Application>' +
                '<ApplicationID>00000</ApplicationID>' +
                '<ApplicationVersion>7.60.0</ApplicationVersion>' +
                '<ApplicationName>CPOS</ApplicationName>' +
              '</Application>' +
              '<TransactionSetup>' +
                '<TransactionSetupMethod>7</TransactionSetupMethod>' +
                '<Embedded>1</Embedded>' +
                '<CVVRequired>0</CVVRequired>' +
                '<AutoReturn>1</AutoReturn>' +
                '<ReturnURL>http://localhost</ReturnURL>' +
                '<CustomCss>body{margin-left: 50px;}</CustomCss>' +
              '</TransactionSetup>' +
              '<Transaction>' +
                '<TransactionAmount>1.00</TransactionAmount>' +
                '<MarketCode>0</MarketCode>' +
                '<ReferenceNumber>123456</ReferenceNumber>' +
                '<TicketNumber>123456</TicketNumber>' +
                '<PartialApprovedFlag>0</PartialApprovedFlag>' +
              '</Transaction>' +
              '<Terminal>' +
                '<TerminalID>01</TerminalID>' +
                '<TerminalType>0</TerminalType>' +
                '<CardholderPresentCode>0</CardholderPresentCode>' +
                '<CardInputCode>0</CardInputCode>' +
                '<TerminalCapabilityCode>0</TerminalCapabilityCode>' +
                '<TerminalEnvironmentCode>0</TerminalEnvironmentCode>' +
                '<CardPresentCode>0</CardPresentCode>' +
                '<MotoECICode>0</MotoECICode>' +
                '<CVVPresenceCode>0</CVVPresenceCode>' +
              '</Terminal>'+
              '<PaymentAccount>' +
                '<PaymentAccountType>1</PaymentAccountType>' +
                '<PaymentAccountReferenceNumber>' + CusAccount + '</PaymentAccountReferenceNumber>' +
              '</PaymentAccount>' +
            '</TransactionSetup>';
  end;
  Try
    IdHTTP1 := TIdHTTP.Create;
    with IdHTTP1 do
    begin
      Request.Accept := 'text/html';
      Request.ContentType := 'text/html';
      Request.CharSet := 'utf-8';
      Request.CacheControl := 'no-cache';
      ReadTimeout := 30000;
      ConnectTimeout := 30000;
      Request.BasicAuthentication := False;
      Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
      HTTPOptions := [hoForceEncodeParams];
    end;

    IdSSLIOHandlerSocketOpenSSL1:= TIdSSLIOHandlerSocketOpenSSL.Create;
    IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions:= [sslvTLSv1_2];
    IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method := sslvTLSv1_2;
    IdHttp1.IOHandler := IdSSLIOHandlerSocketOpenSSL1;
    XMLToSend := TStringStream.Create(XDoc);

    ReturnStr := IdHTTP1.Post('https://certtransaction.elementexpress.com', XMLToSend);
  finally
    IdHTTP1.Free;
    IdSSLIOHandlerSocketOpenSSL1.Free;
    XMLToSend.Free;
  end;

好吧,对于初学者来说,您是在告诉服务器您正在 posting HTML 而不是 XML。 'text/html' 是 XML 的错误 Content-Type

其次,如果您插入 XML 中的值碰巧包含任何保留字符,则您不会转义这些值。您确实应该使用适当的 XML 库来准备您的 post 数据。

最后,您的异常处理结构不是很好。

试试这个:

Var
  XDoc, ReturnStr: String;
  XMLToSend: TStringStream;
  IdHTTP1: TIdHTTP;
  IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
begin   
  with Datam1.CCSetupTbl do
  begin
    XDoc := ...;
  end;
  IdHTTP1 := TIdHTTP.Create;
  try
    with IdHTTP1 do
    begin
      Request.Accept := 'text/html';
      Request.ContentType := 'text/xml'; // or 'application/xml', or whatever the server actually expects...
      Request.CharSet := 'utf-8';
      Request.CacheControl := 'no-cache';
      ReadTimeout := 30000;
      ConnectTimeout := 30000;
      Request.BasicAuthentication := False;
      Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
      HTTPOptions := [hoForceEncodeParams];
    end;

    IdSSLIOHandlerSocketOpenSSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP1);
    IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1_2];
    IdHTTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL1;

    XMLToSend := TStringStream.Create(XDoc);
    try
      ReturnStr := IdHTTP1.Post('https://certtransaction.elementexpress.com', XMLToSend);
    finally
      XMLToSend.Free;
    end;
  finally
    IdHTTP1.Free;
  end;