Port required parts of Stripe SDK to lib_stripe.

This commit is contained in:
John Preston 2021-03-24 21:59:30 +04:00
parent 994dbf9eb5
commit 76b4e18518
21 changed files with 987 additions and 0 deletions

View file

@ -27,6 +27,7 @@ get_filename_component(res_loc Resources REALPATH)
include(cmake/telegram_options.cmake)
include(cmake/lib_ffmpeg.cmake)
include(cmake/lib_stripe.cmake)
include(cmake/lib_tgvoip.cmake)
include(cmake/lib_tgcalls.cmake)
include(cmake/td_export.cmake)
@ -58,6 +59,7 @@ PRIVATE
desktop-app::lib_qr
desktop-app::lib_webview
desktop-app::lib_ffmpeg
desktop-app::lib_stripe
desktop-app::external_lz4
desktop-app::external_rlottie
desktop-app::external_zlib

View file

@ -0,0 +1,18 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Stripe {
enum class BillingAddressFields {
None,
Zip,
Full,
};
} // namespace Stripe

View file

@ -0,0 +1,167 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "stripe/stripe_api_client.h"
#include "stripe/stripe_error.h"
#include "stripe/stripe_token.h"
#include "stripe/stripe_form_encoder.h"
#include <QtCore/QJsonObject>
#include <QtCore/QJsonDocument>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <crl/crl_on_main.h>
namespace Stripe {
namespace {
[[nodiscard]] QString APIURLBase() {
return "api.stripe.com/v1";
}
[[nodiscard]] QString TokenEndpoint() {
return "tokens";
}
[[nodiscard]] QString StripeAPIVersion() {
return "2015-10-12";
}
[[nodiscard]] QString SDKVersion() {
return "9.1.0";
}
[[nodiscard]] QString StripeUserAgentDetails() {
const auto details = QJsonObject{
{ "lang", "objective-c" },
{ "bindings_version", SDKVersion() },
};
return QString::fromUtf8(
QJsonDocument(details).toJson(QJsonDocument::Compact));
}
} // namespace
APIClient::APIClient(PaymentConfiguration configuration)
: _apiUrl("https://" + APIURLBase())
, _configuration(configuration) {
_additionalHttpHeaders = {
{ "X-Stripe-User-Agent", StripeUserAgentDetails() },
{ "Stripe-Version", StripeAPIVersion() },
{ "Authorization", "Bearer " + _configuration.publishableKey },
};
}
APIClient::~APIClient() {
const auto destroy = std::move(_old);
}
void APIClient::createTokenWithCard(
CardParams card,
TokenCompletionCallback completion) {
createTokenWithData(
FormEncoder::formEncodedDataForObject(card),
std::move(completion));
}
void APIClient::createTokenWithData(
QByteArray data,
TokenCompletionCallback completion) {
const auto url = QUrl(_apiUrl + '/' + TokenEndpoint());
auto request = QNetworkRequest(url);
for (const auto &[name, value] : _additionalHttpHeaders) {
request.setRawHeader(name.toUtf8(), value.toUtf8());
}
destroyReplyDelayed(std::move(_reply));
_reply.reset(_manager.post(request, data));
const auto finish = [=](Token token, Error error) {
crl::on_main([
completion,
token = std::move(token),
error = std::move(error)
] {
completion(std::move(token), std::move(error));
});
};
const auto finishWithError = [=](Error error) {
finish(Token::Empty(), std::move(error));
};
const auto finishWithToken = [=](Token token) {
finish(std::move(token), Error::None());
};
QObject::connect(_reply.get(), &QNetworkReply::finished, [=] {
const auto replyError = int(_reply->error());
const auto replyErrorString = _reply->errorString();
const auto bytes = _reply->readAll();
destroyReplyDelayed(std::move(_reply));
auto parseError = QJsonParseError();
const auto document = QJsonDocument::fromJson(bytes, &parseError);
if (!bytes.isEmpty()) {
if (parseError.error != QJsonParseError::NoError) {
const auto code = int(parseError.error);
finishWithError({
Error::Code::JsonParse,
QString("InvalidJson%1").arg(code),
parseError.errorString(),
});
return;
} else if (!document.isObject()) {
finishWithError({
Error::Code::JsonFormat,
"InvalidJsonRoot",
"Not an object in JSON reply.",
});
return;
}
const auto object = document.object();
if (auto error = Error::DecodedObjectFromResponse(object)) {
finishWithError(std::move(error));
return;
}
}
if (replyError != QNetworkReply::NoError) {
finishWithError({
Error::Code::Network,
QString("RequestError%1").arg(replyError),
replyErrorString,
});
return;
}
auto token = Token::DecodedObjectFromAPIResponse(document.object());
if (!token) {
finishWithError({
Error::Code::JsonFormat,
"InvalidTokenJson",
"Could not parse token.",
});
}
finishWithToken(std::move(token));
});
}
void APIClient::destroyReplyDelayed(std::unique_ptr<QNetworkReply> reply) {
if (!reply) {
return;
}
const auto raw = reply.get();
_old.push_back(std::move(reply));
QObject::disconnect(raw, &QNetworkReply::finished, nullptr, nullptr);
raw->deleteLater();
QObject::connect(raw, &QObject::destroyed, [=] {
for (auto i = begin(_old); i != end(_old); ++i) {
if (i->get() == raw) {
i->release();
_old.erase(i);
break;
}
}
});
}
} // namespace Stripe

View file

@ -0,0 +1,44 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "stripe/stripe_payment_configuration.h"
#include "stripe/stripe_card_params.h"
#include "stripe/stripe_callbacks.h"
#include <QtNetwork/QNetworkAccessManager>
#include <QtCore/QString>
#include <map>
namespace Stripe {
class APIClient final {
public:
explicit APIClient(PaymentConfiguration configuration);
~APIClient();
void createTokenWithCard(
CardParams card,
TokenCompletionCallback completion);
void createTokenWithData(
QByteArray data,
TokenCompletionCallback completion);
private:
void destroyReplyDelayed(std::unique_ptr<QNetworkReply> reply);
QString _apiUrl;
PaymentConfiguration _configuration;
std::map<QString, QString> _additionalHttpHeaders;
QNetworkAccessManager _manager;
std::unique_ptr<QNetworkReply> _reply;
std::vector<std::unique_ptr<QNetworkReply>> _old;
};
} // namespace Stripe

View file

@ -0,0 +1,19 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <functional>
namespace Stripe {
class Error;
class Token;
using TokenCompletionCallback = std::function<void(Token, Error)>;
} // namespace Stripe

View file

@ -0,0 +1,117 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "stripe/stripe_card.h"
#include "stripe/stripe_decode.h"
namespace Stripe {
Card::Card(
QString id,
QString last4,
CardBrand brand,
quint32 expMonth,
quint32 expYear)
: _cardId(id)
, _last4(last4)
, _brand(brand)
, _expMonth(expMonth)
, _expYear(expYear) {
}
Card Card::Empty() {
return Card(QString(), QString(), CardBrand::Unknown, 0, 0);
}
[[nodiscard]] CardBrand BrandFromString(const QString &brand) {
if (brand == "visa") {
return CardBrand::Visa;
} else if (brand == "american express") {
return CardBrand::Amex;
} else if (brand == "mastercard") {
return CardBrand::MasterCard;
} else if (brand == "discover") {
return CardBrand::Discover;
} else if (brand == "jcb") {
return CardBrand::JCB;
} else if (brand == "diners club") {
return CardBrand::DinersClub;
} else {
return CardBrand::Unknown;
}
}
[[nodiscard]] CardFundingType FundingFromString(const QString &funding) {
if (funding == "credit") {
return CardFundingType::Credit;
} else if (funding == "debit") {
return CardFundingType::Debit;
} else if (funding == "prepaid") {
return CardFundingType::Prepaid;
} else {
return CardFundingType::Other;
}
}
Card Card::DecodedObjectFromAPIResponse(QJsonObject object) {
if (!ContainsFields(object, {
u"id",
u"last4",
u"brand",
u"exp_month",
u"exp_year"
})) {
return Card::Empty();
}
const auto string = [&](QStringView key) {
return object.value(key).toString();
};
const auto cardId = string(u"id");
const auto last4 = string(u"last4");
const auto brand = BrandFromString(string(u"brand").toLower());
const auto expMonth = object.value("exp_month").toInt();
const auto expYear = object.value("exp_year").toInt();
auto result = Card(cardId, last4, brand, expMonth, expYear);
result._name = string(u"name");
result._dynamicLast4 = string(u"dynamic_last4");
result._funding = FundingFromString(string(u"funding"));
result._fingerprint = string(u"fingerprint");
result._country = string(u"country");
result._currency = string(u"currency");
result._addressLine1 = string(u"address_line1");
result._addressLine2 = string(u"address_line2");
result._addressCity = string(u"address_city");
result._addressState = string(u"address_state");
result._addressZip = string(u"address_zip");
result._addressCountry = string(u"address_country");
// TODO incomplete, not used.
//result._allResponseFields = object;
return result;
}
bool Card::empty() const {
return _cardId.isEmpty();
}
QString CardBrandToString(CardBrand brand) {
switch (brand) {
case CardBrand::Amex: return "American Express";
case CardBrand::DinersClub: return "Diners Club";
case CardBrand::Discover: return "Discover";
case CardBrand::JCB: return "JCB";
case CardBrand::MasterCard: return "MasterCard";
case CardBrand::Unknown: return "Unknown";
case CardBrand::Visa: return "Visa";
}
std::abort();
}
} // namespace Stripe

View file

@ -0,0 +1,80 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <QtCore/QString>
class QJsonObject;
namespace Stripe {
enum class CardBrand {
Visa,
Amex,
MasterCard,
Discover,
JCB,
DinersClub,
Unknown,
};
enum class CardFundingType {
Debit,
Credit,
Prepaid,
Other,
};
class Card final {
public:
Card(const Card &other) = default;
Card &operator=(const Card &other) = default;
Card(Card &&other) = default;
Card &operator=(Card &&other) = default;
~Card() = default;
[[nodiscard]] static Card Empty();
[[nodiscard]] static Card DecodedObjectFromAPIResponse(
QJsonObject object);
[[nodiscard]] bool empty() const;
[[nodiscard]] explicit operator bool() const {
return !empty();
}
private:
Card(
QString id,
QString last4,
CardBrand brand,
quint32 expMonth,
quint32 expYear);
QString _cardId;
QString _name;
QString _last4;
QString _dynamicLast4;
CardBrand _brand = CardBrand::Unknown;
CardFundingType _funding = CardFundingType::Other;
QString _fingerprint;
QString _country;
QString _currency;
quint32 _expMonth = 0;
quint32 _expYear = 0;
QString _addressLine1;
QString _addressLine2;
QString _addressCity;
QString _addressState;
QString _addressZip;
QString _addressCountry;
};
[[nodiscard]] QString CardBrandToString(CardBrand brand);
} // namespace Stripe

View file

@ -0,0 +1,33 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "stripe/stripe_card_params.h"
namespace Stripe {
QString CardParams::RootObjectName() const {
return "card";
}
std::map<QString, QString> CardParams::formFieldValues() const {
return {
{ "number", number },
{ "cvc", cvc },
{ "name", name },
{ "address_line1", addressLine1 },
{ "address_line2", addressLine2 },
{ "address_city", addressCity },
{ "address_state", addressState },
{ "address_zip", addressZip },
{ "address_country", addressCountry },
{ "exp_month", QString::number(expMonth) },
{ "exp_year", QString::number(expYear) },
{ "currency", currency },
};
}
} // namespace Stripe

View file

@ -0,0 +1,33 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "stripe/stripe_form_encodable.h"
namespace Stripe {
class CardParams final : public FormEncodable {
public:
QString RootObjectName() const override;
std::map<QString, QString> formFieldValues() const override;
QString number;
quint32 expMonth = 0;
quint32 expYear = 0;
QString cvc;
QString name;
QString addressLine1;
QString addressLine2;
QString addressCity;
QString addressState;
QString addressZip;
QString addressCountry;
QString currency;
};
} // namespace Stripe

View file

@ -0,0 +1,23 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "stripe/stripe_decode.h"
namespace Stripe {
[[nodiscard]] bool ContainsFields(
const QJsonObject &object,
std::vector<QStringView> keys) {
for (const auto &key : keys) {
if (object.value(key).isUndefined()) {
return false;
}
}
return true;
}
} // namespace Stripe

View file

@ -0,0 +1,18 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <QtCore/QJsonObject>
namespace Stripe {
[[nodiscard]] bool ContainsFields(
const QJsonObject &object,
std::vector<QStringView> keys);
} // namespace Stripe

View file

@ -0,0 +1,83 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "stripe/stripe_error.h"
#include "stripe/stripe_decode.h"
namespace Stripe {
Error Error::DecodedObjectFromResponse(QJsonObject object) {
const auto entry = object.value("error");
if (!entry.isObject()) {
return Error::None();
}
const auto error = entry.toObject();
const auto string = [&](QStringView key) {
return error.value(key).toString();
};
const auto type = string(u"type");
const auto message = string(u"message");
const auto parameterSnakeCase = string(u"param");
// There should always be a message and type for the error
if (message.isEmpty() || type.isEmpty()) {
return {
Code::API,
"GenericError",
"Could not interpret the error response "
"that was returned from Stripe."
};
}
auto parameterWords = parameterSnakeCase.isEmpty()
? QStringList()
: parameterSnakeCase.split('_', Qt::SkipEmptyParts);
auto first = true;
for (auto &word : parameterWords) {
if (first) {
first = false;
} else {
word = word[0].toUpper() + word.midRef(1);
}
}
const auto parameter = parameterWords.join(QString());
if (type == "api_error") {
return { Code::API, "GenericError", message, parameter };
} else if (type == "invalid_request_error") {
return { Code::InvalidRequest, "GenericError", message, parameter };
} else if (type != "card_error") {
return { Code::Unknown, type, message, parameter };
}
const auto code = string(u"code");
const auto cardError = [&](const QString &description) {
return Error{ Code::Card, description, message, parameter };
};
if (code == "incorrect_number") {
return cardError("IncorrectNumber");
} else if (code == "invalid_number") {
return cardError("InvalidNumber");
} else if (code == "invalid_expiry_month") {
return cardError("InvalidExpiryMonth");
} else if (code == "invalid_expiry_year") {
return cardError("InvalidExpiryYear");
} else if (code == "invalid_cvc") {
return cardError("InvalidCVC");
} else if (code == "expired_card") {
return cardError("ExpiredCard");
} else if (code == "incorrect_cvc") {
return cardError("IncorrectCVC");
} else if (code == "card_declined") {
return cardError("CardDeclined");
} else if (code == "processing_error") {
return cardError("ProcessingError");
} else {
return cardError(code);
}
}
} // namespace Stripe

View file

@ -0,0 +1,65 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <QtCore/QString>
class QJsonObject;
namespace Stripe {
class Error {
public:
enum class Code {
None = 0, // Non-Stripe errors.
JsonParse = -1,
JsonFormat = -2,
Network = -3,
Unknown = 8,
Connection = 40, // Trouble connecting to Stripe.
InvalidRequest = 50, // Your request had invalid parameters.
API = 60, // General-purpose API error (should be rare).
Card = 70, // Something was wrong with the given card (most common).
Cancellation = 80, // The operation was cancelled.
CheckoutUnknown = 5000, // Checkout failed
CheckoutTooManyAttempts = 5001, // Too many incorrect code attempts
};
Error(
Code code,
const QString &description,
const QString &message,
const QString &parameter = QString())
: _code(code)
, _description(description)
, _message(message)
, _parameter(parameter) {
}
[[nodiscard]] static Error None() {
return Error(Code::None, QString(), QString());
}
[[nodiscard]] static Error DecodedObjectFromResponse(QJsonObject object);
[[nodiscard]] bool empty() const {
return (_code == Code::None);
}
[[nodiscard]] explicit operator bool() const {
return !empty();
}
private:
Code _code = Code::None;
QString _description;
QString _message;
QString _parameter;
};
} // namespace Stripe

View file

@ -0,0 +1,24 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <QtCore/QString>
#include <map>
namespace Stripe {
class FormEncodable {
public:
[[nodiscard]] virtual QString RootObjectName() const = 0;
// TODO incomplete, not used: nested complex structures not supported.
[[nodiscard]] virtual std::map<QString, QString> formFieldValues() const
= 0;
};
} // namespace Stripe

View file

@ -0,0 +1,40 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "stripe/stripe_form_encoder.h"
#include <QStringList>
#include <QUrl>
namespace Stripe {
QByteArray FormEncoder::formEncodedDataForObject(
FormEncodable &object) {
const auto root = object.RootObjectName();
const auto values = object.formFieldValues();
auto result = QByteArray();
auto keys = std::vector<QString>();
for (const auto &[key, value] : values) {
if (!value.isEmpty()) {
keys.push_back(key);
}
}
std::sort(begin(keys), end(keys));
const auto encode = [](const QString &value) {
return QUrl::toPercentEncoding(value);
};
for (const auto &key : keys) {
const auto fullKey = root.isEmpty() ? key : (root + '[' + key + ']');
if (!result.isEmpty()) {
result += '&';
}
result += encode(fullKey) + '=' + encode(values.at(key));
}
return result;
}
} // namespace Stripe

View file

@ -0,0 +1,21 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "stripe/stripe_form_encodable.h"
namespace Stripe {
class FormEncoder {
public:
[[nodiscard]] static QByteArray formEncodedDataForObject(
FormEncodable &object);
};
} // namespace Stripe

View file

@ -0,0 +1,26 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "stripe/stripe_address.h"
#include <QtCore/QString>
namespace Stripe {
struct PaymentConfiguration {
QString publishableKey;
// PaymentMethodType additionalPaymentMethods; // Apply Pay
BillingAddressFields requiredBillingAddressFields
= BillingAddressFields::None;
QString companyName;
// QString appleMerchantIdentifier; // Apple Pay
// bool smsAutofillDisabled = true; // Mobile only
};
} // namespace Stripe

View file

@ -0,0 +1,13 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include <QtCore/QString>
#include <QtCore/QDateTime>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonValue>
#include <QtCore/QJsonDocument>

View file

@ -0,0 +1,65 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "stripe/stripe_token.h"
#include "stripe/stripe_decode.h"
namespace Stripe {
QString Token::tokenId() const {
return _tokenId;
}
bool Token::livemode() const {
return _livemode;
}
Card Token::card() const {
return _card;
}
Token Token::Empty() {
return Token(QString(), false, QDateTime());
}
Token Token::DecodedObjectFromAPIResponse(QJsonObject object) {
if (!ContainsFields(object, { u"id", u"livemode", u"created" })) {
return Token::Empty();
}
const auto tokenId = object.value("id").toString();
const auto livemode = object.value("livemode").toBool();
const auto created = QDateTime::fromTime_t(
object.value("created").toDouble());
auto result = Token(tokenId, livemode, created);
const auto card = object.value("card");
if (card.isObject()) {
result._card = Card::DecodedObjectFromAPIResponse(card.toObject());
}
// TODO incomplete, not used.
//const auto bankAccount = object.value("bank_account");
//if (bankAccount.isObject()) {
// result._bankAccount = bankAccount::DecodedObjectFromAPIResponse(
// bankAccount.toObject());
//}
//result._allResponseFields = object;
return result;
}
bool Token::empty() const {
return _tokenId.isEmpty();
}
Token::Token(QString tokenId, bool livemode, QDateTime created)
: _tokenId(std::move(tokenId))
, _livemode(livemode)
, _created(std::move(created)) {
}
} // namespace Stripe

View file

@ -0,0 +1,49 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "stripe/stripe_card.h"
#include <QtCore/QDateTime>
class QJsonObject;
namespace Stripe {
class Token {
public:
Token(const Token &other) = default;
Token &operator=(const Token &other) = default;
Token(Token &&other) = default;
Token &operator=(Token &&other) = default;
~Token() = default;
[[nodiscard]] QString tokenId() const;
[[nodiscard]] bool livemode() const;
[[nodiscard]] Card card() const;
[[nodiscard]] static Token Empty();
[[nodiscard]] static Token DecodedObjectFromAPIResponse(
QJsonObject object);
[[nodiscard]] bool empty() const;
[[nodiscard]] explicit operator bool() const {
return !empty();
}
private:
Token(QString tokenId, bool livemode, QDateTime created);
QString _tokenId;
bool _livemode = false;
QDateTime _created;
Card _card = Card::Empty();
};
} // namespace Stripe

View file

@ -0,0 +1,47 @@
# This file is part of Telegram Desktop,
# the official desktop application for the Telegram messaging service.
#
# For license and copyright information please follow this link:
# https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
add_library(lib_stripe OBJECT)
add_library(desktop-app::lib_stripe ALIAS lib_stripe)
init_target(lib_stripe)
set(stripe_src_loc ${src_loc}/payments)
target_precompile_headers(lib_stripe PRIVATE ${stripe_src_loc}/stripe/stripe_pch.h)
nice_target_sources(lib_stripe ${stripe_src_loc}
PRIVATE
stripe/stripe_address.h
stripe/stripe_api_client.cpp
stripe/stripe_api_client.h
stripe/stripe_callbacks.h
stripe/stripe_card.cpp
stripe/stripe_card.h
stripe/stripe_card_params.cpp
stripe/stripe_card_params.h
stripe/stripe_decode.cpp
stripe/stripe_decode.h
stripe/stripe_error.cpp
stripe/stripe_error.h
stripe/stripe_form_encodable.h
stripe/stripe_form_encoder.cpp
stripe/stripe_form_encoder.h
stripe/stripe_payment_configuration.h
stripe/stripe_token.cpp
stripe/stripe_token.h
stripe/stripe_pch.h
)
target_include_directories(lib_stripe
PUBLIC
${stripe_src_loc}
)
target_link_libraries(lib_stripe
PUBLIC
desktop-app::lib_crl
desktop-app::external_qt
)