diff options
-rw-r--r-- | src/backend/taler-merchant-httpd_contract.c | 0 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_contract.h | 319 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-orders.c | 461 |
3 files changed, 431 insertions, 349 deletions
diff --git a/src/backend/taler-merchant-httpd_contract.c b/src/backend/taler-merchant-httpd_contract.c new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/backend/taler-merchant-httpd_contract.c diff --git a/src/backend/taler-merchant-httpd_contract.h b/src/backend/taler-merchant-httpd_contract.h new file mode 100644 index 00000000..ed5fe4ad --- /dev/null +++ b/src/backend/taler-merchant-httpd_contract.h @@ -0,0 +1,319 @@ +/* + This file is part of TALER + (C) 2023 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 <http://www.gnu.org/licenses/> +*/ +/** + * @file taler-merchant-httpd_contract.h + * @brief shared logic for contract terms handling + * @author Christian Blättler + */ +#include "taler-merchant-httpd.h" + + +/** + * Possible versions of the contract terms. + */ +enum TALER_MerchantContractVersion +{ + + /** + * Version 0 + */ + TALER_MCV_V0 = 0, + + /** + * Version 1 + */ + TALER_MCV_V1 = 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. + */ + struct + { + /** + * Price to be paid. + */ + struct TALER_Amount price; + } coin; + + /** + * Token-based input. + */ + struct + { + /** + * Hash over the public key used to sign the type of subscription + * token required. + */ + struct TALER_TokenFamilyPublicKeyHash h_issuer; + + /** + * 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 + +}; + +/** +* Possible token output classes. +*/ +enum TALER_MerchantContractOutputTokenClass +{ + + /** + * Token class subscription + */ + TALER_MCOTC_SUBSCRIPTION = 0, + + /** + * Token class discount + */ + TALER_MCOTC_DISCOUNT = 1 +}; + +/** +* 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; + + /** + * Must a wallet understand this token type to process contracts that + * consume or yield it? + */ + bool critical; + + /** + * Class of token that will be yielded. + */ + enum TALER_MerchantContractOutputTokenClass token_class; + + /** + * Information about the class of token that will be yielded. + */ + 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; + } 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. + */ + const json_t *products; + + /** + * 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; +}
\ No newline at end of file diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c index 776d8c62..f886d9f2 100644 --- a/src/backend/taler-merchant-httpd_private-post-orders.c +++ b/src/backend/taler-merchant-httpd_private-post-orders.c @@ -33,6 +33,7 @@ #include <taler/taler_json_lib.h> #include "taler-merchant-httpd_private-post-orders.h" #include "taler-merchant-httpd_exchanges.h" +#include "taler-merchant-httpd_contract.h" #include "taler-merchant-httpd_helper.h" #include "taler-merchant-httpd_private-get-orders.h" @@ -228,19 +229,92 @@ struct OrderContext /** * Specified version of the order. */ - const char *version; + enum TALER_MerchantContractVersion version; /** - * Order information passed in in v0 format. + * 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; + + /** + * TODO: Maybe remove this and set it from settings where we serialize + * the order to JSON? + * + * Merchant's public key + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * TODO: Maybe remove this and set it from settings where we serialize + * the order to JSON? + * + * Information like name, website, email, etc. about the merchant. + */ + json_t *merchant; + + /** + * 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; + + /** + * Order information in v0 format. */ struct { /** - * Our order ID. - */ - const char *order_id; - - /** * Summary of the order. */ const char *summary; @@ -251,11 +325,6 @@ struct OrderContext json_t *summary_i18n; /** - * URL where the same contract could be ordered again (if available). - */ - const char *public_reorder_url; - - /** * URL that will show that the order was successful * after it has been paid for. */ @@ -273,62 +342,11 @@ struct OrderContext json_t *fulfillment_message_i18n; /** - * 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; - - /** - * 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; - - /** * Array of products that are part of the purchase. */ const json_t *products; /** - * TODO: Maybe remove this and set it from settings where we serialize - * the order to JSON? - * - * Information like name, website, email, etc. about the merchant. - */ - json_t *merchant; - - /** - * TODO: Maybe remove this and set it from settings where we serialize - * the order to JSON? - * - * Merchant's public key - */ - struct TALER_MerchantPublicKeyP merchant_pub; - - /** * Gross amount value of the contract. Used to * compute @e max_stefan_fee. */ @@ -338,23 +356,6 @@ struct OrderContext * Maximum fee as given by the client request. */ struct TALER_Amount max_fee; - - /** - * Specifies for how long the wallet should try to get an - * automatic refund for the purchase. - */ - struct GNUNET_TIME_Relative auto_refund; - - /** - * 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; } v0; /** @@ -363,299 +364,61 @@ struct OrderContext struct { /** - * Our order ID. + * Array of possible specific contracts the wallet/customer may choose + * from by selecting the respective index when signing the deposit + * confirmation. */ - const char *order_id; + struct TALER_MerchantContractChoice *choices; + /** + * Length of the @e choices array. + */ + unsigned int choices_len; + + /** + * TODO: This was moved out a level: Change design document according to this. + * Array of token authorities. + */ struct { /** - * 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. + * Label of the token authority. */ - const char *fulfillment_message; + const char *label; /** - * Map from IETF BCP 47 language tags to localized fulfillment messages. + * Human-readable description of the semantics of the tokens issued by + * this authority. */ - json_t *fulfillment_message_i18n; + const char *summary; /** - * Array of products that are part of the purchase. + * Map from IETF BCP 47 language tags to localized summaries. */ - const json_t *products; + json_t *summary_i18n; /** - * List of inputs the wallet must provision (all of them) to - * satisfy the conditions for the contract. + * Public key used to validate tokens signed by this authority. */ - union - { - /** - * Coin-based input. - */ - struct - { - /** - * Input type. Is "coin" for coin-based inputs. - */ - const char *type; - - /** - * Price to be paid. - */ - struct TALER_Amount price; - } coin; - - /** - * Token-based input. - */ - struct { - /** - * Input type. Is "token" for token-based inputs. - */ - const char *type; - - /** - * Hash over the public key used to sign the type of subscription - * token required. - */ - struct TALER_TokenFamilyPublicKeyHash h_issuer; - - /** - * Number of tokens of this type required. Defaults to one if the - * field is not provided. - */ - unsigned int number; - } token; - } *inputs; - - union - { - /** - * Currency-based output. - */ - struct { - /** - * Output type. Is "currency" for currency-based outputs. - */ - const char *type; - - /** - * Amount of currency 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; - } currency; - - /** - * Tax-receipt output. - */ - struct - { - /** - * Output type. Is "tax-receipt" for tax-receipt outputs. - */ - const char *type; - - /** - * ase URL of the donation authority that will issue the tax - * receipt. - */ - const char *donau_url; - } tax_receipt; - - /** - * Token-based output. - */ - struct - { - /** - * Output type. Is "token" for token-based outputs. - */ - const char *type; - - /** - * Label of the token authority in the 'token_types' map on the - * top-level. - */ - const char *authority_label; - - /** - * Must a wallet understand this token type to process contracts - * that consume or yield it? - */ - bool critical; - - /** - * Information about the class of token that will be yielded. - */ - union - { - /** - * Subscription token. - */ - struct - { - /** - * Token class. Is "subscription" for subscription tokens. - */ - const char *class; - - /** - * 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; - } subscription; - - /** - * Discount token. - */ - struct - { - /** - * Token class. Is "discount" for discount tokens. - */ - const char *class; - - /** - * 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 *trusted_domains; - } discount; - } details; - - } token; - } *ouputs; + struct TALER_TokenFamilyPublicKey key; /** - * Map from authority labels to metadata about the respective token - * authority. + * When will tokens signed by this key expire? */ - json_t *token_types; - - } *choices; - - /** - * TODO: Maybe remove this and set it from settings where we serialize - * the order to JSON? - * - * Information like name, website, email, etc. about the merchant. - */ - json_t *merchant; + struct GNUNET_TIME_Timestamp token_expiration; - /** - * TODO: Maybe remove this and set it from settings where we serialize - * the order to JSON? - * - * Merchant's public key - */ - struct TALER_MerchantPublicKeyP merchant_pub; - - /** - * Gross amount value of the contract. Used to - * compute @e max_stefan_fee. - */ - struct TALER_Amount brutto; - - /** - * URL where the same contract could be ordered again (if available). - */ - const char *public_reorder_url; - - /** - * 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; - - /** - * 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; - - /** - * Specifies for how long the wallet should try to get an - * automatic refund for the purchase. - */ - struct GNUNET_TIME_Relative auto_refund; + } *token_authorities; /** - * Nonce generated by the wallet and echoed by the merchant - * in this field when the proposal is generated. + * Length of the @e token_authorities array. */ - const char *nonce; + unsigned int token_authorities_len; /** - * Extra data that is only interpreted by the merchant frontend. + * TODO: Model this + * Fee limits and wire account details by currency. + * limits: { [currency:string] : CurrencyLimit }; */ - const json_t *extra; } v1; } parse_order; @@ -981,7 +744,7 @@ execute_transaction (struct OrderContext *oc) &oc->parse_request.h_post_data, oc->parse_order.pay_deadline, &oc->parse_request.claim_token, - oc->serialize_order.contract, /* called 'contract terms' at database. */ + oc->serialize_order.contract, /* called 'contract terms' in database. */ oc->parse_request.pos_key, oc->parse_request.pos_algorithm); if (qs <= 0) |