summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/taler-merchant-httpd_contract.c0
-rw-r--r--src/backend/taler-merchant-httpd_contract.h319
-rw-r--r--src/backend/taler-merchant-httpd_private-post-orders.c461
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)