/* 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);