rewrite for eet 2.0 api version v4
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
#include "eetv4client.h"
|
||||
|
||||
#include "eetv4signer.h"
|
||||
#include "eetv4soap.h"
|
||||
|
||||
#include <QEventLoop>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QTimer>
|
||||
#include <QUuid>
|
||||
|
||||
namespace
|
||||
{
|
||||
void setError(QString *error, const QString &message)
|
||||
{
|
||||
if (error != nullptr)
|
||||
{
|
||||
*error = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EetV4Client::EetV4Client(EetV4ClientConfig config)
|
||||
: m_config(std::move(config))
|
||||
{
|
||||
}
|
||||
|
||||
bool EetV4Client::sendSale(const EetV4SaleRequest &request,
|
||||
const QString &pkcs12Path,
|
||||
const QByteArray &pkcs12Password,
|
||||
EetV4Response *response,
|
||||
QString *error) const
|
||||
{
|
||||
if (response == nullptr)
|
||||
{
|
||||
setError(error, QStringLiteral("A response output object is required."));
|
||||
return false;
|
||||
}
|
||||
*response = {};
|
||||
if (!m_config.endpoint.isValid() || m_config.endpoint.scheme() != QLatin1String("https") ||
|
||||
m_config.endpoint.host().isEmpty())
|
||||
{
|
||||
setError(error, QStringLiteral("EET endpoint must be a valid HTTPS URL."));
|
||||
return false;
|
||||
}
|
||||
if (m_config.timeoutMilliseconds <= 0)
|
||||
{
|
||||
setError(error, QStringLiteral("EET timeout must be positive."));
|
||||
return false;
|
||||
}
|
||||
|
||||
const QByteArray bodyId = QByteArrayLiteral("id-") +
|
||||
request.messageUuid.toString(QUuid::WithoutBraces).toLatin1();
|
||||
QString soapError;
|
||||
const QByteArray unsignedSoap = EetV4Soap::serializeUnsigned(request, bodyId, &soapError);
|
||||
if (unsignedSoap.isEmpty())
|
||||
{
|
||||
setError(error, soapError);
|
||||
return false;
|
||||
}
|
||||
QString signingError;
|
||||
const QByteArray signedSoap = EetV4Signer::signSoap(
|
||||
unsignedSoap, pkcs12Path, pkcs12Password, &signingError);
|
||||
if (signedSoap.isEmpty())
|
||||
{
|
||||
setError(error, signingError);
|
||||
return false;
|
||||
}
|
||||
|
||||
QNetworkAccessManager networkAccessManager;
|
||||
QNetworkRequest networkRequest(m_config.endpoint);
|
||||
if (!m_config.sslConfiguration.isNull())
|
||||
{
|
||||
networkRequest.setSslConfiguration(m_config.sslConfiguration);
|
||||
}
|
||||
networkRequest.setHeader(QNetworkRequest::ContentTypeHeader,
|
||||
QStringLiteral("text/xml; charset=utf-8"));
|
||||
networkRequest.setRawHeader("Accept", "text/xml");
|
||||
QNetworkReply *reply = networkAccessManager.post(networkRequest, signedSoap);
|
||||
|
||||
QEventLoop eventLoop;
|
||||
QTimer timeout;
|
||||
timeout.setSingleShot(true);
|
||||
bool timedOut = false;
|
||||
QObject::connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
|
||||
QObject::connect(&timeout, &QTimer::timeout, reply, [&] {
|
||||
timedOut = true;
|
||||
reply->abort();
|
||||
});
|
||||
timeout.start(m_config.timeoutMilliseconds);
|
||||
eventLoop.exec();
|
||||
timeout.stop();
|
||||
|
||||
if (timedOut)
|
||||
{
|
||||
setError(error, QStringLiteral("EET request timed out."));
|
||||
reply->deleteLater();
|
||||
return false;
|
||||
}
|
||||
if (reply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
setError(error, reply->errorString());
|
||||
reply->deleteLater();
|
||||
return false;
|
||||
}
|
||||
|
||||
const QByteArray responseSoap = reply->readAll();
|
||||
const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
reply->deleteLater();
|
||||
QString verificationError;
|
||||
if (!EetV4Signer::verifySoap(responseSoap, &verificationError))
|
||||
{
|
||||
setError(error, statusCode >= 300
|
||||
? QStringLiteral("EET endpoint returned HTTP status %1 and an invalid "
|
||||
"SOAP signature: %2.")
|
||||
.arg(statusCode)
|
||||
.arg(verificationError)
|
||||
: verificationError);
|
||||
return false;
|
||||
}
|
||||
QString responseError;
|
||||
if (!EetV4ResponseParser::parseSoap(responseSoap, response, &responseError))
|
||||
{
|
||||
setError(error, statusCode >= 300
|
||||
? QStringLiteral("EET endpoint returned HTTP status %1: %2.")
|
||||
.arg(statusCode)
|
||||
.arg(responseError)
|
||||
: responseError);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user