/*
This file is part of TALER
(C) 2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see
*/
/**
* @file taler-merchant-httpd_contract.h
* @brief shared logic for contract terms handling
* @author Christian Blättler
*/
#include "taler-merchant-httpd.h"
#include
/**
* Possible versions of the contract terms.
*/
enum TALER_MerchantContractVersion
{
/**
* Version 0
*/
TALER_MCV_V0 = 0,
/**
* Version 1
*/
TALER_MCV_V1 = 1
};
/**
* Possible token classes.
*/
enum TALER_MerchantContractTokenClass
{
/**
* Token class subscription
*/
TALER_MCTC_SUBSCRIPTION = 0,
/**
* Token class discount
*/
TALER_MCTC_DISCOUNT = 1
};
/**
* Possible input types for the contract terms.
*/
enum TALER_MerchantContractInputType
{
/**
* Input type coin
*/
TALER_MCIT_COIN = 0,
/**
* Input type token
*/
TALER_MCIT_TOKEN = 1
};
/**
* Contract input (part of the v1 contract terms).
*/
struct TALER_MerchantContractInput
{
/**
* Type of the input.
*/
enum TALER_MerchantContractInputType type;
union
{
/**
* Coin-based input (ration).
*/
struct
{
/**
* Price to be paid.
*/
struct TALER_Amount price;
/**
* Base URL of the ration authority.
*/
const char *ration_authority_url;
} coin;
/**
* Token-based input.
*/
struct
{
/**
* Label of the token authority in the 'token_authorities'
* array on the top-level.
*/
const char *token_authority_label;
/**
* Number of tokens of this type required. Defaults to one if the
* field is not provided.
*/
unsigned int number;
} token;
} details;
};
/**
* Possible output types for the contract terms.
*/
enum TALER_MerchantContractOutputType
{
/**
* Output type coin
*/
TALER_MCOT_COIN = 0,
/**
* Output type token
*/
TALER_MCOT_TOKEN = 1,
/**
* Output type tax-receipt
*/
TALER_MCOT_TAX_RECEIPT = 2
};
/**
* Contract output (part of the v1 contract terms).
*/
struct TALER_MerchantContractOutput
{
/**
* Type of the output.
*/
enum TALER_MerchantContractOutputType type;
union
{
/**
* Coin-based output.
*/
struct {
/**
* Coins that will be yielded. This excludes any applicable withdraw fees.
*/
struct TALER_Amount brutto_yield;
/**
* Base URL of the exchange that will issue the coins.
*/
const char *exchange_url;
} coin;
/**
* Tax-receipt output.
*/
struct
{
/**
* Base URL of the donation authority that will issue the tax receipt.
*/
const char *donau_url;
} tax_receipt;
/**
* Token-based output.
*/
struct
{
/**
* Label of the token authority in the 'token_authorities'
* array on the top-level.
*/
const char *token_authority_label;
/**
* Number of tokens of this type required. Defaults to one if the
* field is not provided.
*/
unsigned int number;
} token;
} details;
};
/**
* Contract choice (part of the v1 contract terms).
*/
struct TALER_MerchantContractChoice
{
/**
* Summary of the order.
*/
const char *summary;
/**
* Internationalized summary.
*/
json_t *summary_i18n;
/**
* URL that will show that the order was successful
* after it has been paid for.
*/
const char *fulfillment_url;
/**
* Message shown to the customer after paying for the order.
* Either fulfillment_url or fulfillment_message must be specified.
*/
const char *fulfillment_message;
/**
* Map from IETF BCP 47 language tags to localized fulfillment messages.
*/
json_t *fulfillment_message_i18n;
/**
* Array of products that are part of the purchase.
*/
json_t *products;
/**
* Price to be paid for the transaction. Could be 0. The price is in addition
* to other instruments, such as rations and tokens.
* The exchange will subtract deposit fees from that amount
* before transferring it to the merchant.
*/
struct TALER_Amount price;
/**
* List of inputs the wallet must provision (all of them) to satisfy the
* conditions for the contract.
*/
struct TALER_MerchantContractInput *inputs;
/**
* Length of the @e inputs array.
*/
unsigned int inputs_len;
/**
* List of outputs the merchant promises to yield (all of them) once
* the contract is paid.
*/
struct TALER_MerchantContractOutput *ouputs;
/**
* Length of the @e outputs array.
*/
unsigned int outputs_len;
};
/**
* Struct to hold contract terms in v0 and v1 format. v0 contracts are mdoelled
* as a v1 contract with a single choice and no inputs and outputs. Use the
* version field to explicitly differentiate between v0 and v1 contracts.
*/
struct TALER_MerchantContract
{
/**
* URL where the same contract could be ordered again (if available).
*/
const char *public_reorder_url;
/**
* Our order ID.
*/
const char *order_id;
/**
* Merchant base URL.
*/
char *merchant_base_url;
/**
* Timestamp of the order.
*/
struct GNUNET_TIME_Timestamp timestamp;
/**
* Deadline for refunds.
*/
struct GNUNET_TIME_Timestamp refund_deadline;
/**
* Specifies for how long the wallet should try to get an
* automatic refund for the purchase.
*/
struct GNUNET_TIME_Relative auto_refund;
/**
* Payment deadline.
*/
struct GNUNET_TIME_Timestamp pay_deadline;
/**
* Wire transfer deadline.
*/
struct GNUNET_TIME_Timestamp wire_deadline;
/**
* Delivery date.
*/
struct GNUNET_TIME_Timestamp delivery_date;
/**
* Delivery location.
*/
json_t *delivery_location;
/**
* Nonce generated by the wallet and echoed by the merchant
* in this field when the proposal is generated.
*/
const char *nonce;
/**
* Extra data that is only interpreted by the merchant frontend.
*/
const json_t *extra;
/**
* Specified version of the contract.
*/
enum TALER_MerchantContractVersion version;
/**
* Array of possible specific contracts the wallet/customer may choose
* from by selecting the respective index when signing the deposit
* confirmation.
*/
struct TALER_MerchantContractChoice *choices;
/**
* Length of the @e choices array.
*/
unsigned int choices_len;
/**
* Array of token authorities.
*/
struct
{
/**
* Label of the token authority.
*/
const char *label;
/**
* Human-readable description of the semantics of the tokens issued by
* this authority.
*/
const char *summary;
/**
* Map from IETF BCP 47 language tags to localized summaries.
*/
json_t *summary_i18n;
/**
* Public key used to validate tokens signed by this authority.
*/
struct TALER_TokenFamilyPublicKey key;
/**
* When will tokens signed by this key expire?
*/
struct GNUNET_TIME_Timestamp token_expiration;
/**
* Must a wallet understand this token type to process contracts that
* consume or yield it?
*/
bool critical;
/**
* Class of token the token.
*/
enum TALER_MerchantContractTokenClass token_class;
/**
* Class-specific information about the token.
*/
union
{
/**
* Subscription token.
*/
struct
{
/**
* When does the subscription period start?
*/
struct GNUNET_TIME_Absolute start_date;
/**
* When does the subscription period end?
*/
struct GNUNET_TIME_Absolute end_date;
/**
* Array of domain names where this subscription can be safely used
* (e.g. the issuer warrants that these sites will re-issue tokens of
* this type if the respective contract says so). May contain "*" for
* any domain or subdomain.
*/
const char **trusted_domains;
/**
* Length of the @e trusted_domains array.
*/
unsigned int trusted_domains_len;
} subscription;
/**
* Discount token.
*/
struct
{
/**
* Array of domain names where this discount token is intended to be
* used. May contain "*" for any domain or subdomain. Users should be
* warned about sites proposing to consume discount tokens of this
* type that are not in this list that the merchant is accepting a
* coupon from a competitor and thus may be attaching different
* semantics (like get 20% discount for my competitors 30% discount
* token).
*/
const char **expected_domains;
/**
* Length of the @e expected_domains array.
*/
unsigned int expected_domains_len;
} discount;
} details;
} *token_authorities;
/**
* Length of the @e token_authorities array.
*/
unsigned int token_authorities_len;
/**
* Fee limits and wire account details by currency.
*/
struct
{
/**
* Currency these limits are for.
*/
char currency[TALER_CURRENCY_LEN];
/**
* The hash of the merchant instance's wire details.
*/
struct TALER_MerchantWireHashP h_wire;
/**
* Wire transfer method identifier for the wire method associated with ``h_wire``.
* The wallet may only select exchanges via a matching auditor if the
* exchange also supports this wire method.
* The wire transfer fees must be added based on this wire transfer method.
*/
char *wire_method;
/**
* Maximum total deposit fee accepted by the merchant for this contract.
*/
struct TALER_Amount max_fee;
} *limits;
/**
* Length of the @e limits array;
*/
unsigned int limits_len;
};
/**
* Serialize @a contract to a JSON object, ready to be stored in the database.
* The @a contract can be of v0 or v1.
*
* @param[in] contract contract struct to serialize
* @param[out] out serialized contract as JSON object
* @return #GNUNET_OK on success
* #GNUNET_NO if @a contract was not valid
* #GNUNET_SYSERR on failure
*/
enum GNUNET_GenericReturnValue
TMH_serialize_contract (const struct TALER_MerchantContract *contract,
json_t **out);
enum GNUNET_GenericReturnValue
TMH_serialize_contract_v0 (const struct TALER_MerchantContract *contract,
const struct TMH_MerchantInstance *instance,
json_t *exchanges,
json_t **out);
enum GNUNET_GenericReturnValue
TMH_serialize_contract_v1 (const struct TALER_MerchantContract *contract,
json_t **out);