merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

taler-merchant-httpd_post-orders-ORDER_ID-pay.c (167936B)


      1 /*
      2    This file is part of TALER
      3    (C) 2014-2026 Taler Systems SA
      4 
      5    TALER is free software; you can redistribute it and/or modify
      6    it under the terms of the GNU Affero General Public License as
      7    published by the Free Software Foundation; either version 3,
      8    or (at your option) any later version.
      9 
     10    TALER is distributed in the hope that it will be useful, but
     11    WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13    GNU General Public License for more details.
     14 
     15    You should have received a copy of the GNU General Public
     16    License along with TALER; see the file COPYING.  If not,
     17    see <http://www.gnu.org/licenses/>
     18  */
     19 
     20 /**
     21  * @file src/backend/taler-merchant-httpd_post-orders-ORDER_ID-pay.c
     22  * @brief handling of POST /orders/$ID/pay requests
     23  * @author Marcello Stanisci
     24  * @author Christian Grothoff
     25  * @author Florian Dold
     26  */
     27 #include "platform.h"
     28 struct ExchangeGroup;
     29 #define TALER_EXCHANGE_POST_BATCH_DEPOSIT_RESULT_CLOSURE struct ExchangeGroup
     30 #include <gnunet/gnunet_common.h>
     31 #include <gnunet/gnunet_db_lib.h>
     32 #include <gnunet/gnunet_json_lib.h>
     33 #include <gnunet/gnunet_time_lib.h>
     34 #include <jansson.h>
     35 #include <microhttpd.h>
     36 #include <stddef.h>
     37 #include <stdint.h>
     38 #include <string.h>
     39 #include <taler/taler_dbevents.h>
     40 #include <taler/taler_error_codes.h>
     41 #include <taler/taler_signatures.h>
     42 #include <taler/taler_json_lib.h>
     43 #include <taler/taler_exchange_service.h>
     44 #include "taler-merchant-httpd.h"
     45 #include "taler-merchant-httpd_exchanges.h"
     46 #include "taler-merchant-httpd_get-exchanges.h"
     47 #include "taler-merchant-httpd_helper.h"
     48 #include "taler-merchant-httpd_post-orders-ORDER_ID-pay.h"
     49 #include "taler-merchant-httpd_get-private-orders.h"
     50 #include "taler/taler_merchant_util.h"
     51 #include "merchantdb_lib.h"
     52 #include <donau/donau_service.h>
     53 #include <donau/donau_util.h>
     54 #include <donau/donau_json_lib.h>
     55 #include "merchant-database/increment_money_pots.h"
     56 #include "merchant-database/insert_deposit.h"
     57 #include "merchant-database/insert_deposit_confirmation.h"
     58 #include "merchant-database/insert_issued_token.h"
     59 #include "merchant-database/insert_order_blinded_sigs.h"
     60 #include "merchant-database/insert_spent_token.h"
     61 #include "merchant-database/lookup_contract_terms2.h"
     62 #include "merchant-database/lookup_deposits.h"
     63 #include "merchant-database/lookup_deposits_by_order.h"
     64 #include "merchant-database/lookup_order_charity.h"
     65 #include "merchant-database/lookup_refunds.h"
     66 #include "merchant-database/set_instance.h"
     67 #include "merchant-database/lookup_spent_tokens_by_order.h"
     68 #include "merchant-database/lookup_token_family_key.h"
     69 #include "merchant-database/mark_contract_paid.h"
     70 #include "merchant-database/select_order_blinded_sigs.h"
     71 #include "merchant-database/start.h"
     72 #include "merchant-database/preflight.h"
     73 #include "merchant-database/event_notify.h"
     74 #include "merchant-database/update_donau_instance_receipts_amount.h"
     75 
     76 /**
     77  * How often do we retry the (complex!) database transaction?
     78  */
     79 #define MAX_RETRIES 5
     80 
     81 /**
     82  * Maximum number of coins that we allow per transaction.
     83  * Note that the limit for each batch deposit request to
     84  * the exchange is lower, so we may break a very large
     85  * number of coins up into multiple smaller requests to
     86  * the exchange.
     87  */
     88 #define MAX_COIN_ALLOWED_COINS 1024
     89 
     90 /**
     91  * Maximum number of tokens that we allow as inputs per transaction
     92  */
     93 #define MAX_TOKEN_ALLOWED_INPUTS 64
     94 
     95 /**
     96  * Maximum number of tokens that we allow as outputs per transaction
     97  */
     98 #define MAX_TOKEN_ALLOWED_OUTPUTS 64
     99 
    100 /**
    101  * How often do we ask the exchange again about our
    102  * KYC status? Very rarely, as if the user actively
    103  * changes it, we should usually notice anyway.
    104  */
    105 #define KYC_RETRY_FREQUENCY GNUNET_TIME_UNIT_WEEKS
    106 
    107 /**
    108  * Information we keep for an individual call to the pay handler.
    109  */
    110 struct PayContext;
    111 
    112 
    113 /**
    114  * Different phases of processing the /pay request.
    115  */
    116 enum PayPhase
    117 {
    118   /**
    119    * Initial phase where the request is parsed.
    120    */
    121   PP_PARSE_PAY = 0,
    122 
    123   /**
    124    * Parse wallet data object from the pay request.
    125    */
    126   PP_PARSE_WALLET_DATA,
    127 
    128   /**
    129    * Check database state for the given order.
    130    */
    131   PP_CHECK_CONTRACT,
    132 
    133   /**
    134    * Validate provided tokens and token envelopes.
    135    */
    136   PP_VALIDATE_TOKENS,
    137 
    138   /**
    139    * Check if contract has been paid.
    140    */
    141   PP_CONTRACT_PAID,
    142 
    143   /**
    144    * Compute money pot changes.
    145    */
    146   PP_COMPUTE_MONEY_POTS,
    147 
    148   /**
    149    * Execute payment transaction.
    150    */
    151   PP_PAY_TRANSACTION,
    152 
    153   /**
    154    * Communicate with DONAU to generate a donation receipt from the donor BUDIs.
    155    */
    156   PP_REQUEST_DONATION_RECEIPT,
    157 
    158   /**
    159    * Process the donation receipt response from DONAU (save the donau_sigs to the db).
    160    */
    161   PP_FINAL_OUTPUT_TOKEN_PROCESSING,
    162 
    163   /**
    164    * Notify other processes about successful payment.
    165    */
    166   PP_PAYMENT_NOTIFICATION,
    167 
    168   /**
    169    * Create final success response.
    170    */
    171   PP_SUCCESS_RESPONSE,
    172 
    173   /**
    174    * Perform batch deposits with exchange(s).
    175    */
    176   PP_BATCH_DEPOSITS,
    177 
    178   /**
    179    * Return response in payment context.
    180    */
    181   PP_RETURN_RESPONSE,
    182 
    183   /**
    184    * An exchange denied a deposit, fail for
    185    * legal reasons.
    186    */
    187   PP_FAIL_LEGAL_REASONS,
    188 
    189   /**
    190    * Return #MHD_YES to end processing.
    191    */
    192   PP_END_YES,
    193 
    194   /**
    195    * Return #MHD_NO to end processing.
    196    */
    197   PP_END_NO
    198 };
    199 
    200 
    201 /**
    202  * Information kept during a pay request for each coin.
    203  */
    204 struct DepositConfirmation
    205 {
    206 
    207   /**
    208    * Reference to the main PayContext
    209    */
    210   struct PayContext *pc;
    211 
    212   /**
    213    * URL of the exchange that issued this coin.
    214    */
    215   char *exchange_url;
    216 
    217   /**
    218    * Details about the coin being deposited.
    219    */
    220   struct TALER_EXCHANGE_CoinDepositDetail cdd;
    221 
    222   /**
    223    * Fee charged by the exchange for the deposit operation of this coin.
    224    */
    225   struct TALER_Amount deposit_fee;
    226 
    227   /**
    228    * Fee charged by the exchange for the refund operation of this coin.
    229    */
    230   struct TALER_Amount refund_fee;
    231 
    232   /**
    233    * If a minimum age was required (i. e. pc->minimum_age is large enough),
    234    * this is the signature of the minimum age (as a single uint8_t), using the
    235    * private key to the corresponding age group.  Might be all zeroes for no
    236    * age attestation.
    237    */
    238   struct TALER_AgeAttestationP minimum_age_sig;
    239 
    240   /**
    241    * If a minimum age was required (i. e. pc->minimum_age is large enough),
    242    * this is the age commitment (i. e. age mask and vector of EdDSA public
    243    * keys, one per age group) that went into the mining of the coin.  The
    244    * SHA256 hash of the mask and the vector of public keys was bound to the
    245    * key.
    246    */
    247   struct TALER_AgeCommitment age_commitment;
    248 
    249   /**
    250    * Age mask in the denomination that defines the age groups.  Only
    251    * applicable, if minimum age was required.
    252    */
    253   struct TALER_AgeMask age_mask;
    254 
    255   /**
    256    * Offset of this coin into the `dc` array of all coins in the
    257    * @e pc.
    258    */
    259   unsigned int index;
    260 
    261   /**
    262    * true, if no field "age_commitment" was found in the JSON blob
    263    */
    264   bool no_age_commitment;
    265 
    266   /**
    267    * True, if no field "minimum_age_sig" was found in the JSON blob
    268    */
    269   bool no_minimum_age_sig;
    270 
    271   /**
    272    * true, if no field "h_age_commitment" was found in the JSON blob
    273    */
    274   bool no_h_age_commitment;
    275 
    276   /**
    277    * true if we found this coin in the database.
    278    */
    279   bool found_in_db;
    280 
    281   /**
    282    * true if we #deposit_paid_check() matched this coin in the database.
    283    */
    284   bool matched_in_db;
    285 
    286   /**
    287    * True if this coin is in the current batch.
    288    */
    289   bool in_batch;
    290 
    291 };
    292 
    293 struct TokenUseConfirmation
    294 {
    295 
    296   /**
    297    * Signature on the deposit request made using the token use private key.
    298    */
    299   struct TALER_TokenUseSignatureP sig;
    300 
    301   /**
    302    * Token use public key. This key was blindly signed by the merchant during
    303    * the token issuance process.
    304    */
    305   struct TALER_TokenUsePublicKeyP pub;
    306 
    307   /**
    308    * Unblinded signature on the token use public key done by the merchant.
    309    */
    310   struct TALER_TokenIssueSignature unblinded_sig;
    311 
    312   /**
    313    * Hash of the token issue public key associated with this token.
    314    * Note this is set in the validate_tokens phase.
    315    */
    316   struct TALER_TokenIssuePublicKeyHashP h_issue;
    317 
    318   /**
    319    * true if we found this token in the database.
    320    */
    321   bool found_in_db;
    322 
    323 };
    324 
    325 
    326 /**
    327  * Information about a token envelope.
    328  */
    329 struct TokenEnvelope
    330 {
    331 
    332   /**
    333    * Blinded token use public keys waiting to be signed.
    334    */
    335   struct TALER_TokenEnvelope blinded_token;
    336 
    337 };
    338 
    339 
    340 /**
    341  * (Blindly) signed token to be returned to the wallet.
    342  */
    343 struct SignedOutputToken
    344 {
    345 
    346   /**
    347    * Index of the output token that produced this blindly signed token.
    348    */
    349   unsigned int output_index;
    350 
    351   /**
    352    * Blinded token use public keys waiting to be signed.
    353    */
    354   struct TALER_BlindedTokenIssueSignature sig;
    355 
    356   /**
    357    * Hash of token issue public key.
    358    */
    359   struct TALER_TokenIssuePublicKeyHashP h_issue;
    360 
    361 };
    362 
    363 
    364 /**
    365  * Information kept during a pay request for each exchange.
    366  */
    367 struct ExchangeGroup
    368 {
    369 
    370   /**
    371    * Payment context this group is part of.
    372    */
    373   struct PayContext *pc;
    374 
    375   /**
    376    * Handle to the batch deposit operation currently in flight for this
    377    * exchange, NULL when no operation is pending.
    378    */
    379   struct TALER_EXCHANGE_PostBatchDepositHandle *bdh;
    380 
    381   /**
    382    * Handle for operation to lookup /keys (and auditors) from
    383    * the exchange used for this transaction; NULL if no operation is
    384    * pending.
    385    */
    386   struct TMH_EXCHANGES_KeysOperation *fo;
    387 
    388   /**
    389    * URL of the exchange that issued this coin. Aliases
    390    * the exchange URL of one of the coins, do not free!
    391    */
    392   const char *exchange_url;
    393 
    394   /**
    395    * The keys of the exchange.
    396    */
    397   struct TALER_EXCHANGE_Keys *keys;
    398 
    399   /**
    400    * Total deposit amount in this exchange group.
    401    */
    402   struct TALER_Amount total;
    403 
    404   /**
    405    * Wire fee that applies to this exchange for the
    406    * given payment context's wire method.
    407    */
    408   struct TALER_Amount wire_fee;
    409 
    410   /**
    411    * true if we already tried a forced /keys download.
    412    */
    413   bool tried_force_keys;
    414 
    415   /**
    416    * Did this exchange deny the transaction for legal reasons?
    417    */
    418   bool got_451;
    419 };
    420 
    421 
    422 /**
    423  * Information about donau, that can be fetched even
    424  * if the merhchant doesn't support donau
    425  */
    426 struct DonauData
    427 {
    428   /**
    429    * The user-selected Donau URL.
    430    */
    431   char *donau_url;
    432 
    433   /**
    434    * The donation year, as parsed from "year".
    435    */
    436   uint64_t donation_year;
    437 
    438   /**
    439    * The original BUDI key-pairs array from the donor
    440    * to be used for the receipt creation.
    441    */
    442   const json_t *budikeypairs;
    443 };
    444 
    445 /**
    446  * Information we keep for an individual call to the /pay handler.
    447  */
    448 struct PayContext
    449 {
    450 
    451   /**
    452    * Stored in a DLL.
    453    */
    454   struct PayContext *next;
    455 
    456   /**
    457    * Stored in a DLL.
    458    */
    459   struct PayContext *prev;
    460 
    461   /**
    462    * MHD connection to return to
    463    */
    464   struct MHD_Connection *connection;
    465 
    466   /**
    467    * Details about the client's request.
    468    */
    469   struct TMH_HandlerContext *hc;
    470 
    471   /**
    472    * Transaction ID given in @e root.
    473    */
    474   const char *order_id;
    475 
    476   /**
    477    * Response to return, NULL if we don't have one yet.
    478    */
    479   struct MHD_Response *response;
    480 
    481   /**
    482    * Array with @e output_tokens_len signed tokens returned in
    483    * the response to the wallet. This array combines both the
    484    * token family-signed outputs and the donation authority
    485    * outputs.  Each output has a field ``output_index``
    486    * which matches the index into the choice's outputs array.
    487    * The Donau outputs are those where the `output_index` matches
    488    * the @e validate_tokens.donau_output_index.
    489    */
    490   struct SignedOutputToken *output_tokens;
    491 
    492   /**
    493    * Number of output tokens to return in the response.
    494    * Length of the @e output_tokens array.
    495    */
    496   unsigned int output_tokens_len;
    497 
    498   /**
    499    * Counter used to generate the output index in append_output_token_sig().
    500    */
    501   unsigned int output_index_gen;
    502 
    503   /**
    504    * Counter used to generate the output index in append_output_token_sig().
    505    *
    506    * Counts the generated tokens _within_ the current output_index_gen.
    507    */
    508   unsigned int output_token_cnt;
    509 
    510   /**
    511    * HTTP status code to use for the reply, i.e 200 for "OK".
    512    * Special value UINT_MAX is used to indicate hard errors
    513    * (no reply, return #MHD_NO).
    514    */
    515   unsigned int response_code;
    516 
    517   /**
    518    * Payment processing phase we are in.
    519    */
    520   enum PayPhase phase;
    521 
    522   /**
    523    * #GNUNET_NO if the @e connection was not suspended,
    524    * #GNUNET_YES if the @e connection was suspended,
    525    * #GNUNET_SYSERR if @e connection was resumed to as
    526    * part of #MH_force_pc_resume during shutdown.
    527    */
    528   enum GNUNET_GenericReturnValue suspended;
    529 
    530   /**
    531    * Results from the phase_parse_pay()
    532    */
    533   struct
    534   {
    535 
    536     /**
    537      * Array with @e num_exchanges exchanges we are depositing
    538      * coins into.
    539      */
    540     struct ExchangeGroup **egs;
    541 
    542     /**
    543      * Array with @e coins_cnt coins we are despositing.
    544      */
    545     struct DepositConfirmation *dc;
    546 
    547     /**
    548      * Array with @e tokens_cnt input tokens passed to this request.
    549      */
    550     struct TokenUseConfirmation *tokens;
    551 
    552     /**
    553      * Optional session id given in @e root.
    554      * NULL if not given.
    555      */
    556     char *session_id;
    557 
    558     /**
    559      * Wallet data json object from the request. Containing additional
    560      * wallet data such as the selected choice_index.
    561      */
    562     const json_t *wallet_data;
    563 
    564     /**
    565      * Number of coins this payment is made of.  Length
    566      * of the @e dc array.
    567      */
    568     size_t coins_cnt;
    569 
    570     /**
    571      * Number of input tokens passed to this request.  Length
    572      * of the @e tokens array.
    573      */
    574     size_t tokens_cnt;
    575 
    576     /**
    577      * Number of exchanges involved in the payment. Length
    578      * of the @e eg array.
    579      */
    580     unsigned int num_exchanges;
    581 
    582   } parse_pay;
    583 
    584   /**
    585    * Results from the phase_wallet_data()
    586    */
    587   struct
    588   {
    589 
    590     /**
    591      * Array with @e token_envelopes_cnt (blinded) token envelopes.
    592      */
    593     struct TokenEnvelope *token_envelopes;
    594 
    595     /**
    596      * Index of selected choice in the @e contract_terms choices array.
    597      */
    598     int16_t choice_index;
    599 
    600     /**
    601      * Number of token envelopes passed to this request.
    602      * Length of the @e token_envelopes array.
    603      */
    604     size_t token_envelopes_cnt;
    605 
    606     /**
    607      * Hash of the canonicalized wallet data json object.
    608      */
    609     struct GNUNET_HashCode h_wallet_data;
    610 
    611     /**
    612      * Donau related information
    613      */
    614     struct DonauData donau;
    615 
    616     /**
    617      * Serial from the DB of the donau instance that we are using
    618      */
    619     uint64_t donau_instance_serial;
    620 
    621     /**
    622      * Number of the blinded key pairs @e bkps
    623      */
    624     unsigned int num_bkps;
    625 
    626     /**
    627      * Blinded key pairs received from the wallet
    628      */
    629     struct DONAU_BlindedUniqueDonorIdentifierKeyPair *bkps;
    630 
    631     /**
    632      * The id of the charity as saved on the donau.
    633      */
    634     uint64_t charity_id;
    635 
    636     /**
    637      * Private key of the charity(related to the private key of the merchant).
    638      */
    639     struct DONAU_CharityPrivateKeyP charity_priv;
    640 
    641     /**
    642      * Maximum amount of donations that the charity can receive per year.
    643      */
    644     struct TALER_Amount charity_max_per_year;
    645 
    646     /**
    647      * Amount of donations that the charity has received so far this year.
    648      */
    649     struct TALER_Amount charity_receipts_to_date;
    650 
    651     /**
    652      * Donau keys, that we are using to get the information about the bkps.
    653      */
    654     struct DONAU_Keys *donau_keys;
    655 
    656     /**
    657      * Amount from BKPS
    658      */
    659     struct TALER_Amount donation_amount;
    660 
    661   } parse_wallet_data;
    662 
    663   /**
    664    * Results from the phase_check_contract()
    665    */
    666   struct
    667   {
    668 
    669     /**
    670      * Hashed @e contract_terms.
    671      */
    672     struct TALER_PrivateContractHashP h_contract_terms;
    673 
    674     /**
    675      * Our contract (or NULL if not available).
    676      */
    677     json_t *contract_terms_json;
    678 
    679     /**
    680      * Parsed contract terms, NULL when parsing failed.
    681      */
    682     struct TALER_MERCHANT_Contract *contract_terms;
    683 
    684     /**
    685      * What wire method (of the @e mi) was selected by the wallet?
    686      * Set in #phase_parse_pay().
    687      */
    688     struct TMH_WireMethod *wm;
    689 
    690     /**
    691      * Set to the POS key, if applicable for this order.
    692      */
    693     char *pos_key;
    694 
    695     /**
    696      * Serial number of this order in the database (set once we did the lookup).
    697      */
    698     uint64_t order_serial;
    699 
    700     /**
    701      * Algorithm chosen for generating the confirmation code.
    702      */
    703     enum TALER_MerchantConfirmationAlgorithm pos_alg;
    704 
    705   } check_contract;
    706 
    707   /**
    708    * Results from the phase_validate_tokens()
    709    */
    710   struct
    711   {
    712 
    713     /**
    714      * Maximum fee the merchant is willing to pay, from @e root.
    715      * Note that IF the total fee of the exchange is higher, that is
    716      * acceptable to the merchant if the customer is willing to
    717      * pay the difference
    718      * (i.e. amount - max_fee <= actual_amount - actual_fee).
    719      */
    720     struct TALER_Amount max_fee;
    721 
    722     /**
    723      * Amount from @e root.  This is the amount the merchant expects
    724      * to make, minus @e max_fee.
    725      */
    726     struct TALER_Amount brutto;
    727 
    728     /**
    729      * Index of the donau output in the list of tokens.
    730      * Set to -1 if no donau output exists.
    731      */
    732     int donau_output_index;
    733 
    734   } validate_tokens;
    735 
    736 
    737   struct
    738   {
    739     /**
    740      * Length of the @a pots and @a increments arrays.
    741      */
    742     unsigned int num_pots;
    743 
    744     /**
    745      * Serial IDs of money pots to increment.
    746      */
    747     uint64_t *pots;
    748 
    749     /**
    750      * Increment for the respective money pot.
    751      */
    752     struct TALER_Amount *increments;
    753 
    754     /**
    755      * True if the money pots have already been computed.
    756      */
    757     bool pots_computed;
    758 
    759   } compute_money_pots;
    760 
    761   /**
    762    * Results from the phase_execute_pay_transaction()
    763    */
    764   struct
    765   {
    766 
    767     /**
    768      * Considering all the coins with the "found_in_db" flag
    769      * set, what is the total amount we were so far paid on
    770      * this contract?
    771      */
    772     struct TALER_Amount total_paid;
    773 
    774     /**
    775      * Considering all the coins with the "found_in_db" flag
    776      * set, what is the total amount we had to pay in deposit
    777      * fees so far on this contract?
    778      */
    779     struct TALER_Amount total_fees_paid;
    780 
    781     /**
    782      * Considering all the coins with the "found_in_db" flag
    783      * set, what is the total amount we already refunded?
    784      */
    785     struct TALER_Amount total_refunded;
    786 
    787     /**
    788      * Number of coin deposits pending.
    789      */
    790     unsigned int pending;
    791 
    792     /**
    793      * How often have we retried the 'main' transaction?
    794      */
    795     unsigned int retry_counter;
    796 
    797     /**
    798      * Set to true if the deposit currency of a coin
    799      * does not match the contract currency.
    800      */
    801     bool deposit_currency_mismatch;
    802 
    803     /**
    804      * Set to true if the database contains a (bogus)
    805      * refund for a different currency.
    806      */
    807     bool refund_currency_mismatch;
    808 
    809   } pay_transaction;
    810 
    811   /**
    812    * Results from the phase_batch_deposits()
    813    */
    814   struct
    815   {
    816 
    817     /**
    818      * Task called when the (suspended) processing for
    819      * the /pay request times out.
    820      * Happens when we don't get a response from the exchange.
    821      */
    822     struct GNUNET_SCHEDULER_Task *timeout_task;
    823 
    824     /**
    825      * Number of batch transactions pending.
    826      */
    827     unsigned int pending_at_eg;
    828 
    829     /**
    830      * Did any exchange deny a deposit for legal reasons?
    831      */
    832     bool got_451;
    833 
    834   } batch_deposits;
    835 
    836   /**
    837    * Struct for #phase_request_donation_receipt()
    838    */
    839   struct
    840   {
    841     /**
    842      * Handler of the donau request
    843      */
    844     struct DONAU_BatchIssueReceiptHandle *birh;
    845 
    846   } donau_receipt;
    847 };
    848 
    849 
    850 /**
    851  * Head of active pay context DLL.
    852  */
    853 static struct PayContext *pc_head;
    854 
    855 /**
    856  * Tail of active pay context DLL.
    857  */
    858 static struct PayContext *pc_tail;
    859 
    860 
    861 void
    862 TMH_force_pc_resume ()
    863 {
    864   for (struct PayContext *pc = pc_head;
    865        NULL != pc;
    866        pc = pc->next)
    867   {
    868     if (NULL != pc->batch_deposits.timeout_task)
    869     {
    870       GNUNET_SCHEDULER_cancel (pc->batch_deposits.timeout_task);
    871       pc->batch_deposits.timeout_task = NULL;
    872     }
    873     if (GNUNET_YES == pc->suspended)
    874     {
    875       pc->suspended = GNUNET_SYSERR;
    876       MHD_resume_connection (pc->connection);
    877     }
    878   }
    879 }
    880 
    881 
    882 /**
    883  * Resume payment processing.
    884  *
    885  * @param[in,out] pc payment process to resume
    886  */
    887 static void
    888 pay_resume (struct PayContext *pc)
    889 {
    890   GNUNET_assert (GNUNET_YES == pc->suspended);
    891   pc->suspended = GNUNET_NO;
    892   MHD_resume_connection (pc->connection);
    893   TALER_MHD_daemon_trigger (); /* we resumed, kick MHD */
    894 }
    895 
    896 
    897 /**
    898  * Resume the given pay context and send the given response.
    899  * Stores the response in the @a pc and signals MHD to resume
    900  * the connection.  Also ensures MHD runs immediately.
    901  *
    902  * @param pc payment context
    903  * @param response_code response code to use
    904  * @param response response data to send back
    905  */
    906 static void
    907 resume_pay_with_response (struct PayContext *pc,
    908                           unsigned int response_code,
    909                           struct MHD_Response *response)
    910 {
    911   pc->response_code = response_code;
    912   pc->response = response;
    913   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    914               "Resuming /pay handling. HTTP status for our reply is %u.\n",
    915               response_code);
    916   for (unsigned int i = 0; i<pc->parse_pay.num_exchanges; i++)
    917   {
    918     struct ExchangeGroup *eg = pc->parse_pay.egs[i];
    919 
    920     if (NULL != eg->fo)
    921     {
    922       TMH_EXCHANGES_keys4exchange_cancel (eg->fo);
    923       eg->fo = NULL;
    924       pc->batch_deposits.pending_at_eg--;
    925     }
    926     if (NULL != eg->bdh)
    927     {
    928       TALER_EXCHANGE_post_batch_deposit_cancel (eg->bdh);
    929       eg->bdh = NULL;
    930       pc->batch_deposits.pending_at_eg--;
    931     }
    932   }
    933   GNUNET_assert (0 == pc->batch_deposits.pending_at_eg);
    934   if (NULL != pc->batch_deposits.timeout_task)
    935   {
    936     GNUNET_SCHEDULER_cancel (pc->batch_deposits.timeout_task);
    937     pc->batch_deposits.timeout_task = NULL;
    938   }
    939   pc->phase = PP_RETURN_RESPONSE;
    940   pay_resume (pc);
    941 }
    942 
    943 
    944 /**
    945  * Resume payment processing with an error.
    946  *
    947  * @param pc operation to resume
    948  * @param ec taler error code to return
    949  * @param msg human readable error message
    950  */
    951 static void
    952 resume_pay_with_error (struct PayContext *pc,
    953                        enum TALER_ErrorCode ec,
    954                        const char *msg)
    955 {
    956   resume_pay_with_response (
    957     pc,
    958     TALER_ErrorCode_get_http_status_safe (ec),
    959     TALER_MHD_make_error (ec,
    960                           msg));
    961 }
    962 
    963 
    964 /**
    965  * Conclude payment processing for @a pc with the
    966  * given @a res MHD status code.
    967  *
    968  * @param[in,out] pc payment context for final state transition
    969  * @param res MHD return code to end with
    970  */
    971 static void
    972 pay_end (struct PayContext *pc,
    973          enum MHD_Result res)
    974 {
    975   pc->phase = (MHD_YES == res)
    976     ? PP_END_YES
    977     : PP_END_NO;
    978 }
    979 
    980 
    981 /**
    982  * Return response stored in @a pc.
    983  *
    984  * @param[in,out] pc payment context we are processing
    985  */
    986 static void
    987 phase_return_response (struct PayContext *pc)
    988 {
    989   GNUNET_assert (0 != pc->response_code);
    990   /* We are *done* processing the request, just queue the response (!) */
    991   if (UINT_MAX == pc->response_code)
    992   {
    993     GNUNET_break (0);
    994     pay_end (pc,
    995              MHD_NO); /* hard error */
    996     return;
    997   }
    998   pay_end (pc,
    999            MHD_queue_response (pc->connection,
   1000                                pc->response_code,
   1001                                pc->response));
   1002 }
   1003 
   1004 
   1005 /**
   1006  * Return a response indicating failure for legal reasons.
   1007  *
   1008  * @param[in,out] pc payment context we are processing
   1009  */
   1010 static void
   1011 phase_fail_for_legal_reasons (struct PayContext *pc)
   1012 {
   1013   json_t *exchanges;
   1014 
   1015   GNUNET_assert (0 == pc->pay_transaction.pending);
   1016   GNUNET_assert (pc->batch_deposits.got_451);
   1017   exchanges = json_array ();
   1018   GNUNET_assert (NULL != exchanges);
   1019   for (unsigned int i = 0; i<pc->parse_pay.num_exchanges; i++)
   1020   {
   1021     struct ExchangeGroup *eg = pc->parse_pay.egs[i];
   1022 
   1023     GNUNET_assert (NULL == eg->fo);
   1024     GNUNET_assert (NULL == eg->bdh);
   1025     if (! eg->got_451)
   1026       continue;
   1027     GNUNET_assert (
   1028       0 ==
   1029       json_array_append_new (
   1030         exchanges,
   1031         json_string (eg->exchange_url)));
   1032   }
   1033   pay_end (pc,
   1034            TALER_MHD_REPLY_JSON_PACK (
   1035              pc->connection,
   1036              MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS,
   1037              TALER_JSON_pack_ec (
   1038                TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LEGALLY_REFUSED),
   1039              GNUNET_JSON_pack_array_steal ("exchange_base_urls",
   1040                                            exchanges)));
   1041 }
   1042 
   1043 
   1044 /**
   1045  * Do database transaction for a completed batch deposit.
   1046  *
   1047  * @param eg group that completed
   1048  * @param dr response from the server
   1049  * @return transaction status
   1050  */
   1051 static enum GNUNET_DB_QueryStatus
   1052 batch_deposit_transaction (
   1053   const struct ExchangeGroup *eg,
   1054   const struct TALER_EXCHANGE_PostBatchDepositResponse *dr)
   1055 {
   1056   const struct PayContext *pc = eg->pc;
   1057   enum GNUNET_DB_QueryStatus qs;
   1058   uint64_t b_dep_serial;
   1059   uint32_t off = 0;
   1060 
   1061   qs = TALER_MERCHANTDB_set_instance (
   1062     TMH_db,
   1063     pc->hc->instance->settings.id);
   1064   if (qs <= 0)
   1065     return qs; /* failure, we're done */
   1066   qs = TALER_MERCHANTDB_insert_deposit_confirmation (
   1067     TMH_db,
   1068     pc->hc->instance->settings.id,
   1069     dr->details.ok.deposit_timestamp,
   1070     &pc->check_contract.h_contract_terms,
   1071     eg->exchange_url,
   1072     pc->check_contract.contract_terms->pc->wire_deadline,
   1073     &dr->details.ok.accumulated_total_without_fee,
   1074     &eg->wire_fee,
   1075     &pc->check_contract.wm->h_wire,
   1076     dr->details.ok.exchange_sig,
   1077     dr->details.ok.exchange_pub,
   1078     &b_dep_serial);
   1079   if (qs <= 0)
   1080     goto cleanup; /* Entire batch already known or failure, we're done */
   1081 
   1082   for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   1083   {
   1084     struct DepositConfirmation *dc = &pc->parse_pay.dc[i];
   1085 
   1086     /* might want to group deposits by batch more explicitly ... */
   1087     if (0 != strcmp (eg->exchange_url,
   1088                      dc->exchange_url))
   1089       continue;
   1090     if (dc->found_in_db)
   1091       continue;
   1092     if (! dc->in_batch)
   1093       continue;
   1094     /* FIXME-#9457: We might want to check if the order was fully paid concurrently
   1095        by some other wallet here, and if so, issue an auto-refund. Right now,
   1096        it is possible to over-pay if two wallets literally make a concurrent
   1097        payment, as the earlier check for 'paid' is not in the same transaction
   1098        scope as this 'insert' operation. */
   1099     qs = TALER_MERCHANTDB_insert_deposit (
   1100       TMH_db,
   1101       off++, /* might want to group deposits by batch more explicitly ... */
   1102       b_dep_serial,
   1103       &dc->cdd.coin_pub,
   1104       &dc->cdd.coin_sig,
   1105       &dc->cdd.amount,
   1106       &dc->deposit_fee,
   1107       &dc->refund_fee,
   1108       GNUNET_TIME_absolute_add (
   1109         pc->check_contract.contract_terms->pc->wire_deadline.abs_time,
   1110         GNUNET_TIME_randomize (GNUNET_TIME_UNIT_MINUTES)));
   1111     if (qs < 0)
   1112       goto cleanup;
   1113     GNUNET_break (qs > 0);
   1114   }
   1115 cleanup:
   1116   GNUNET_break (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT ==
   1117                 TALER_MERCHANTDB_set_instance (
   1118                   TMH_db,
   1119                   NULL));
   1120   return qs;
   1121 }
   1122 
   1123 
   1124 /**
   1125  * Handle case where the batch deposit completed
   1126  * with a status of #MHD_HTTP_OK.
   1127  *
   1128  * @param eg group that completed
   1129  * @param dr response from the server
   1130  */
   1131 static void
   1132 handle_batch_deposit_ok (
   1133   struct ExchangeGroup *eg,
   1134   const struct TALER_EXCHANGE_PostBatchDepositResponse *dr)
   1135 {
   1136   struct PayContext *pc = eg->pc;
   1137   enum GNUNET_DB_QueryStatus qs
   1138     = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
   1139 
   1140   /* store result to DB */
   1141   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
   1142               "Storing successful payment %s (%s) at instance `%s'\n",
   1143               pc->hc->infix,
   1144               GNUNET_h2s (&pc->check_contract.h_contract_terms.hash),
   1145               pc->hc->instance->settings.id);
   1146   for (unsigned int r = 0; r<MAX_RETRIES; r++)
   1147   {
   1148     TALER_MERCHANTDB_preflight (TMH_db);
   1149     if (GNUNET_OK !=
   1150         TALER_MERCHANTDB_start (TMH_db,
   1151                                 "batch-deposit-insert-confirmation"))
   1152     {
   1153       resume_pay_with_response (
   1154         pc,
   1155         MHD_HTTP_INTERNAL_SERVER_ERROR,
   1156         TALER_MHD_MAKE_JSON_PACK (
   1157           TALER_JSON_pack_ec (
   1158             TALER_EC_GENERIC_DB_START_FAILED),
   1159           TMH_pack_exchange_reply (&dr->hr)));
   1160       return;
   1161     }
   1162     qs = batch_deposit_transaction (eg,
   1163                                     dr);
   1164     if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
   1165     {
   1166       TALER_MERCHANTDB_rollback (TMH_db);
   1167       continue;
   1168     }
   1169     if (GNUNET_DB_STATUS_HARD_ERROR == qs)
   1170     {
   1171       GNUNET_break (0);
   1172       resume_pay_with_error (pc,
   1173                              TALER_EC_GENERIC_DB_COMMIT_FAILED,
   1174                              "batch_deposit_transaction");
   1175       TALER_MERCHANTDB_rollback (TMH_db);
   1176       return;
   1177     }
   1178     qs = TALER_MERCHANTDB_commit (TMH_db);
   1179     if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
   1180     {
   1181       TALER_MERCHANTDB_rollback (TMH_db);
   1182       continue;
   1183     }
   1184     if (GNUNET_DB_STATUS_HARD_ERROR == qs)
   1185     {
   1186       GNUNET_break (0);
   1187       resume_pay_with_error (pc,
   1188                              TALER_EC_GENERIC_DB_COMMIT_FAILED,
   1189                              "insert_deposit");
   1190     }
   1191     break; /* DB transaction succeeded */
   1192   }
   1193   if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
   1194   {
   1195     resume_pay_with_error (pc,
   1196                            TALER_EC_GENERIC_DB_SOFT_FAILURE,
   1197                            "insert_deposit");
   1198     return;
   1199   }
   1200 
   1201   /* Transaction is done, mark affected coins as complete as well. */
   1202   for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   1203   {
   1204     struct DepositConfirmation *dc = &pc->parse_pay.dc[i];
   1205 
   1206     if (0 != strcmp (eg->exchange_url,
   1207                      dc->exchange_url))
   1208       continue;
   1209     if (dc->found_in_db)
   1210       continue;
   1211     if (! dc->in_batch)
   1212       continue;
   1213     dc->found_in_db = true;     /* well, at least NOW it'd be true ;-) */
   1214     dc->in_batch = false;
   1215     pc->pay_transaction.pending--;
   1216   }
   1217 }
   1218 
   1219 
   1220 /**
   1221  * Notify taler-merchant-kyccheck that we got a KYC
   1222  * rule violation notification and should start to
   1223  * check our KYC status.
   1224  *
   1225  * @param eg exchange group we were notified for
   1226  */
   1227 static void
   1228 notify_kyc_required (const struct ExchangeGroup *eg)
   1229 {
   1230   struct GNUNET_DB_EventHeaderP es = {
   1231     .size = htons (sizeof (es)),
   1232     .type = htons (TALER_DBEVENT_MERCHANT_EXCHANGE_KYC_RULE_TRIGGERED)
   1233   };
   1234   char *hws;
   1235   char *extra;
   1236 
   1237   hws = GNUNET_STRINGS_data_to_string_alloc (
   1238     &eg->pc->check_contract.contract_terms->pc->h_wire,
   1239     sizeof (eg->pc->check_contract.contract_terms->pc->h_wire));
   1240   GNUNET_asprintf (&extra,
   1241                    "%s %s",
   1242                    hws,
   1243                    eg->exchange_url);
   1244   GNUNET_free (hws);
   1245   TALER_MERCHANTDB_event_notify (TMH_db,
   1246                                  &es,
   1247                                  extra,
   1248                                  strlen (extra) + 1);
   1249   GNUNET_free (extra);
   1250 }
   1251 
   1252 
   1253 /**
   1254  * Run batch deposits for @a eg.
   1255  *
   1256  * @param[in,out] eg group to do batch deposits for
   1257  */
   1258 static void
   1259 do_batch_deposits (struct ExchangeGroup *eg);
   1260 
   1261 
   1262 /**
   1263  * Callback to handle a batch deposit permission's response.
   1264  *
   1265  * @param cls a `struct ExchangeGroup`
   1266  * @param dr HTTP response code details
   1267  */
   1268 static void
   1269 batch_deposit_cb (
   1270   struct ExchangeGroup *eg,
   1271   const struct TALER_EXCHANGE_PostBatchDepositResponse *dr)
   1272 {
   1273   struct PayContext *pc = eg->pc;
   1274 
   1275   eg->bdh = NULL;
   1276   pc->batch_deposits.pending_at_eg--;
   1277   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1278               "Batch deposit completed with status %u\n",
   1279               dr->hr.http_status);
   1280   GNUNET_assert (GNUNET_YES == pc->suspended);
   1281   switch (dr->hr.http_status)
   1282   {
   1283   case MHD_HTTP_OK:
   1284     handle_batch_deposit_ok (eg,
   1285                              dr);
   1286     if (GNUNET_YES != pc->suspended)
   1287       return; /* handle_batch_deposit_ok already resumed with an error */
   1288     do_batch_deposits (eg);
   1289     return;
   1290   case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
   1291     for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   1292     {
   1293       struct DepositConfirmation *dc = &pc->parse_pay.dc[i];
   1294 
   1295       if (0 != strcmp (eg->exchange_url,
   1296                        dc->exchange_url))
   1297         continue;
   1298       dc->in_batch = false;
   1299     }
   1300     notify_kyc_required (eg);
   1301     eg->got_451 = true;
   1302     pc->batch_deposits.got_451 = true;
   1303     /* update pc->pay_transaction.pending */
   1304     for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   1305     {
   1306       struct DepositConfirmation *dc = &pc->parse_pay.dc[i];
   1307 
   1308       if (0 != strcmp (eg->exchange_url,
   1309                        pc->parse_pay.dc[i].exchange_url))
   1310         continue;
   1311       if (dc->found_in_db)
   1312         continue;
   1313       pc->pay_transaction.pending--;
   1314     }
   1315     if (0 == pc->batch_deposits.pending_at_eg)
   1316     {
   1317       pc->phase = PP_COMPUTE_MONEY_POTS;
   1318       pay_resume (pc);
   1319     }
   1320     return;
   1321   default:
   1322     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   1323                 "Deposit operation failed with HTTP code %u/%d\n",
   1324                 dr->hr.http_status,
   1325                 (int) dr->hr.ec);
   1326     for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   1327     {
   1328       struct DepositConfirmation *dc = &pc->parse_pay.dc[i];
   1329 
   1330       if (0 != strcmp (eg->exchange_url,
   1331                        dc->exchange_url))
   1332         continue;
   1333       dc->in_batch = false;
   1334     }
   1335     /* Transaction failed */
   1336     if (5 == dr->hr.http_status / 100)
   1337     {
   1338       /* internal server error at exchange */
   1339       resume_pay_with_response (pc,
   1340                                 MHD_HTTP_BAD_GATEWAY,
   1341                                 TALER_MHD_MAKE_JSON_PACK (
   1342                                   TALER_JSON_pack_ec (
   1343                                     TALER_EC_MERCHANT_GENERIC_EXCHANGE_UNEXPECTED_STATUS),
   1344                                   TMH_pack_exchange_reply (&dr->hr)));
   1345       return;
   1346     }
   1347     if (NULL == dr->hr.reply)
   1348     {
   1349       /* We can't do anything meaningful here, the exchange did something wrong */
   1350       resume_pay_with_response (
   1351         pc,
   1352         MHD_HTTP_BAD_GATEWAY,
   1353         TALER_MHD_MAKE_JSON_PACK (
   1354           TALER_JSON_pack_ec (
   1355             TALER_EC_MERCHANT_GENERIC_EXCHANGE_REPLY_MALFORMED),
   1356           TMH_pack_exchange_reply (&dr->hr)));
   1357       return;
   1358     }
   1359 
   1360     /* Forward error, adding the "exchange_url" for which the
   1361        error was being generated */
   1362     if (TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS == dr->hr.ec)
   1363     {
   1364       resume_pay_with_response (
   1365         pc,
   1366         MHD_HTTP_CONFLICT,
   1367         TALER_MHD_MAKE_JSON_PACK (
   1368           TALER_JSON_pack_ec (
   1369             TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_FUNDS),
   1370           TMH_pack_exchange_reply (&dr->hr),
   1371           GNUNET_JSON_pack_string ("exchange_url",
   1372                                    eg->exchange_url)));
   1373       return;
   1374     }
   1375     resume_pay_with_response (
   1376       pc,
   1377       MHD_HTTP_BAD_GATEWAY,
   1378       TALER_MHD_MAKE_JSON_PACK (
   1379         TALER_JSON_pack_ec (
   1380           TALER_EC_MERCHANT_GENERIC_EXCHANGE_UNEXPECTED_STATUS),
   1381         TMH_pack_exchange_reply (&dr->hr),
   1382         GNUNET_JSON_pack_string ("exchange_url",
   1383                                  eg->exchange_url)));
   1384     return;
   1385   } /* end switch */
   1386 }
   1387 
   1388 
   1389 static void
   1390 do_batch_deposits (struct ExchangeGroup *eg)
   1391 {
   1392   struct PayContext *pc = eg->pc;
   1393   struct TMH_HandlerContext *hc = pc->hc;
   1394   unsigned int group_size = 0;
   1395   /* Initiate /batch-deposit operation for all coins of
   1396      the current exchange (!) */
   1397 
   1398   GNUNET_assert (NULL != eg->keys);
   1399   for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   1400   {
   1401     struct DepositConfirmation *dc = &pc->parse_pay.dc[i];
   1402 
   1403     if (0 != strcmp (eg->exchange_url,
   1404                      pc->parse_pay.dc[i].exchange_url))
   1405       continue;
   1406     if (dc->found_in_db)
   1407       continue;
   1408     group_size++;
   1409     if (group_size >= TALER_MAX_COINS)
   1410       break;
   1411   }
   1412   if (0 == group_size)
   1413   {
   1414     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1415                 "Group size zero, %u batch transactions remain pending\n",
   1416                 pc->batch_deposits.pending_at_eg);
   1417     if (0 == pc->batch_deposits.pending_at_eg)
   1418     {
   1419       pc->phase = PP_COMPUTE_MONEY_POTS;
   1420       pay_resume (pc);
   1421       return;
   1422     }
   1423     return;
   1424   }
   1425   /* Dispatch the next batch of up to TALER_MAX_COINS coins.
   1426      On success, batch_deposit_cb() will re-invoke
   1427      do_batch_deposits() to send further batches until
   1428      all coins are done. */
   1429   {
   1430     struct TALER_EXCHANGE_DepositContractDetail dcd = {
   1431       .wire_deadline
   1432         = pc->check_contract.contract_terms->pc->wire_deadline,
   1433       .merchant_payto_uri
   1434         = pc->check_contract.wm->payto_uri,
   1435       .extra_wire_subject_metadata
   1436         = pc->check_contract.wm->extra_wire_subject_metadata,
   1437       .wire_salt
   1438         = pc->check_contract.wm->wire_salt,
   1439       .h_contract_terms
   1440         = pc->check_contract.h_contract_terms,
   1441       .wallet_data_hash
   1442         = pc->parse_wallet_data.h_wallet_data,
   1443       .wallet_timestamp
   1444         = pc->check_contract.contract_terms->pc->timestamp,
   1445       .merchant_pub
   1446         = hc->instance->merchant_pub,
   1447       .refund_deadline
   1448         = pc->check_contract.contract_terms->pc->refund_deadline
   1449     };
   1450     /* Collect up to TALER_MAX_COINS eligible coins for this batch */
   1451     struct TALER_EXCHANGE_CoinDepositDetail cdds[group_size];
   1452     unsigned int batch_size = 0;
   1453     enum TALER_ErrorCode ec;
   1454 
   1455     /* FIXME-optimization: move signing outside of this 'loop'
   1456        and into the code that runs long before we look at a
   1457        specific exchange, otherwise we sign repeatedly! */
   1458     TALER_merchant_contract_sign (&pc->check_contract.h_contract_terms,
   1459                                   &pc->hc->instance->merchant_priv,
   1460                                   &dcd.merchant_sig);
   1461     for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   1462     {
   1463       struct DepositConfirmation *dc = &pc->parse_pay.dc[i];
   1464 
   1465       if (dc->found_in_db)
   1466         continue;
   1467       if (0 != strcmp (dc->exchange_url,
   1468                        eg->exchange_url))
   1469         continue;
   1470       dc->in_batch = true;
   1471       cdds[batch_size++] = dc->cdd;
   1472       if (batch_size == group_size)
   1473         break;
   1474     }
   1475     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1476                 "Initiating batch deposit with %u coins\n",
   1477                 batch_size);
   1478     /* Note: the coin signatures over the wallet_data_hash are
   1479        checked inside of this call */
   1480     eg->bdh = TALER_EXCHANGE_post_batch_deposit_create (
   1481       TMH_curl_ctx,
   1482       eg->exchange_url,
   1483       eg->keys,
   1484       &dcd,
   1485       batch_size,
   1486       cdds,
   1487       &ec);
   1488     if (NULL == eg->bdh)
   1489     {
   1490       /* Signature was invalid or some other constraint was not satisfied.  If
   1491          the exchange was unavailable, we'd get that information in the
   1492          callback. */
   1493       GNUNET_break_op (0);
   1494       resume_pay_with_response (
   1495         pc,
   1496         TALER_ErrorCode_get_http_status_safe (ec),
   1497         TALER_MHD_MAKE_JSON_PACK (
   1498           TALER_JSON_pack_ec (ec),
   1499           GNUNET_JSON_pack_string ("exchange_url",
   1500                                    eg->exchange_url)));
   1501       return;
   1502     }
   1503     pc->batch_deposits.pending_at_eg++;
   1504     if (TMH_force_audit)
   1505     {
   1506       GNUNET_assert (
   1507         GNUNET_OK ==
   1508         TALER_EXCHANGE_post_batch_deposit_set_options (
   1509           eg->bdh,
   1510           TALER_EXCHANGE_post_batch_deposit_option_force_dc ()));
   1511     }
   1512     TALER_EXCHANGE_post_batch_deposit_start (eg->bdh,
   1513                                              &batch_deposit_cb,
   1514                                              eg);
   1515   }
   1516 }
   1517 
   1518 
   1519 /**
   1520  * Force re-downloading keys for @a eg.
   1521  *
   1522  * @param[in,out] eg group to re-download keys for
   1523  */
   1524 static void
   1525 force_keys (struct ExchangeGroup *eg);
   1526 
   1527 
   1528 /**
   1529  * Function called with the result of our exchange keys lookup.
   1530  *
   1531  * @param cls the `struct ExchangeGroup`
   1532  * @param keys the keys of the exchange
   1533  * @param exchange representation of the exchange
   1534  */
   1535 static void
   1536 process_pay_with_keys (
   1537   void *cls,
   1538   struct TALER_EXCHANGE_Keys *keys,
   1539   struct TMH_Exchange *exchange)
   1540 {
   1541   struct ExchangeGroup *eg = cls;
   1542   struct PayContext *pc = eg->pc;
   1543   struct TMH_HandlerContext *hc = pc->hc;
   1544   struct TALER_Amount max_amount;
   1545   enum TMH_ExchangeStatus es;
   1546 
   1547   eg->fo = NULL;
   1548   pc->batch_deposits.pending_at_eg--;
   1549   GNUNET_SCHEDULER_begin_async_scope (&hc->async_scope_id);
   1550   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1551               "Processing payment with keys from exchange %s\n",
   1552               eg->exchange_url);
   1553   GNUNET_assert (GNUNET_YES == pc->suspended);
   1554   if (NULL == keys)
   1555   {
   1556     GNUNET_break_op (0);
   1557     resume_pay_with_error (
   1558       pc,
   1559       TALER_EC_MERCHANT_GENERIC_EXCHANGE_TIMEOUT,
   1560       NULL);
   1561     return;
   1562   }
   1563   if (NULL != eg->keys)
   1564     TALER_EXCHANGE_keys_decref (eg->keys);
   1565   eg->keys = TALER_EXCHANGE_keys_incref (keys);
   1566   if (! TMH_EXCHANGES_is_below_limit (keys,
   1567                                       TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION,
   1568                                       &eg->total))
   1569   {
   1570     GNUNET_break_op (0);
   1571     resume_pay_with_error (
   1572       pc,
   1573       TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_TRANSACTION_LIMIT_VIOLATION,
   1574       eg->exchange_url);
   1575     return;
   1576   }
   1577 
   1578   max_amount = eg->total;
   1579   es = TMH_exchange_check_debit (
   1580     pc->hc->instance->settings.id,
   1581     exchange,
   1582     pc->check_contract.wm,
   1583     &max_amount);
   1584   if ( (TMH_ES_OK != es) &&
   1585        (TMH_ES_RETRY_OK != es) )
   1586   {
   1587     if (eg->tried_force_keys ||
   1588         (0 == (TMH_ES_RETRY_OK & es)) )
   1589     {
   1590       GNUNET_break_op (0);
   1591       resume_pay_with_error (
   1592         pc,
   1593         TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_WIRE_METHOD_UNSUPPORTED,
   1594         NULL);
   1595       return;
   1596     }
   1597     force_keys (eg);
   1598     return;
   1599   }
   1600   if (-1 ==
   1601       TALER_amount_cmp (&max_amount,
   1602                         &eg->total))
   1603   {
   1604     /* max_amount < eg->total */
   1605     GNUNET_break_op (0);
   1606     resume_pay_with_error (
   1607       pc,
   1608       TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_TRANSACTION_LIMIT_VIOLATION,
   1609       eg->exchange_url);
   1610     return;
   1611   }
   1612 
   1613   if (GNUNET_OK !=
   1614       TMH_EXCHANGES_lookup_wire_fee (exchange,
   1615                                      pc->check_contract.wm->wire_method,
   1616                                      &eg->wire_fee))
   1617   {
   1618     if (eg->tried_force_keys)
   1619     {
   1620       GNUNET_break_op (0);
   1621       resume_pay_with_error (
   1622         pc,
   1623         TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_WIRE_METHOD_UNSUPPORTED,
   1624         pc->check_contract.wm->wire_method);
   1625       return;
   1626     }
   1627     force_keys (eg);
   1628     return;
   1629   }
   1630   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1631               "Got wire data for %s\n",
   1632               eg->exchange_url);
   1633 
   1634   /* Check all coins satisfy constraints like deposit deadlines
   1635      and age restrictions */
   1636   for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   1637   {
   1638     struct DepositConfirmation *dc = &pc->parse_pay.dc[i];
   1639     const struct TALER_EXCHANGE_DenomPublicKey *denom_details;
   1640     bool is_age_restricted_denom = false;
   1641 
   1642     if (0 != strcmp (eg->exchange_url,
   1643                      pc->parse_pay.dc[i].exchange_url))
   1644       continue;
   1645     if (dc->found_in_db)
   1646       continue;
   1647 
   1648     denom_details
   1649       = TALER_EXCHANGE_get_denomination_key_by_hash (keys,
   1650                                                      &dc->cdd.h_denom_pub);
   1651     if (NULL == denom_details)
   1652     {
   1653       if (eg->tried_force_keys)
   1654       {
   1655         GNUNET_break_op (0);
   1656         resume_pay_with_response (
   1657           pc,
   1658           MHD_HTTP_BAD_REQUEST,
   1659           TALER_MHD_MAKE_JSON_PACK (
   1660             TALER_JSON_pack_ec (
   1661               TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND),
   1662             GNUNET_JSON_pack_data_auto ("h_denom_pub",
   1663                                         &dc->cdd.h_denom_pub),
   1664             GNUNET_JSON_pack_allow_null (
   1665               GNUNET_JSON_pack_object_steal (
   1666                 "exchange_keys",
   1667                 TALER_EXCHANGE_keys_to_json (keys)))));
   1668         return;
   1669       }
   1670       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1671                   "Missing denomination %s from exchange %s, updating keys\n",
   1672                   GNUNET_h2s (&dc->cdd.h_denom_pub.hash),
   1673                   eg->exchange_url);
   1674       force_keys (eg);
   1675       return;
   1676     }
   1677     dc->deposit_fee = denom_details->fees.deposit;
   1678     dc->refund_fee = denom_details->fees.refund;
   1679 
   1680     if (GNUNET_TIME_absolute_is_past (
   1681           denom_details->expire_deposit.abs_time))
   1682     {
   1683       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
   1684                   "Denomination key offered by client has expired for deposits\n");
   1685       resume_pay_with_response (
   1686         pc,
   1687         MHD_HTTP_GONE,
   1688         TALER_MHD_MAKE_JSON_PACK (
   1689           TALER_JSON_pack_ec (
   1690             TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_DEPOSIT_EXPIRED),
   1691           GNUNET_JSON_pack_data_auto ("h_denom_pub",
   1692                                       &denom_details->h_key)));
   1693       return;
   1694     }
   1695 
   1696     /* Now that we have the details about the denomination, we can verify age
   1697      * restriction requirements, if applicable. Note that denominations with an
   1698      * age_mask equal to zero always pass the age verification.  */
   1699     is_age_restricted_denom = (0 != denom_details->key.age_mask.bits);
   1700 
   1701     if (is_age_restricted_denom &&
   1702         (0 < pc->check_contract.contract_terms->pc->base->minimum_age))
   1703     {
   1704       /* Minimum age given and restricted coin provided: We need to verify the
   1705        * minimum age */
   1706       unsigned int code = 0;
   1707 
   1708       if (dc->no_age_commitment)
   1709       {
   1710         GNUNET_break_op (0);
   1711         code = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_MISSING;
   1712         goto AGE_FAIL;
   1713       }
   1714       dc->age_commitment.mask = denom_details->key.age_mask;
   1715       if (((int) (dc->age_commitment.num + 1)) !=
   1716           __builtin_popcount (dc->age_commitment.mask.bits))
   1717       {
   1718         GNUNET_break_op (0);
   1719         code =
   1720           TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_SIZE_MISMATCH;
   1721         goto AGE_FAIL;
   1722       }
   1723       if (GNUNET_OK !=
   1724           TALER_age_commitment_verify (
   1725             &dc->age_commitment,
   1726             pc->check_contract.contract_terms->pc->base->minimum_age,
   1727             &dc->minimum_age_sig))
   1728         code = TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AGE_VERIFICATION_FAILED;
   1729 AGE_FAIL:
   1730       if (0 < code)
   1731       {
   1732         GNUNET_break_op (0);
   1733         TALER_age_commitment_free (&dc->age_commitment);
   1734         resume_pay_with_response (
   1735           pc,
   1736           MHD_HTTP_BAD_REQUEST,
   1737           TALER_MHD_MAKE_JSON_PACK (
   1738             TALER_JSON_pack_ec (code),
   1739             GNUNET_JSON_pack_data_auto ("h_denom_pub",
   1740                                         &denom_details->h_key)));
   1741         return;
   1742       }
   1743 
   1744       /* Age restriction successfully verified!
   1745        * Calculate the hash of the age commitment. */
   1746       TALER_age_commitment_hash (&dc->age_commitment,
   1747                                  &dc->cdd.h_age_commitment);
   1748       TALER_age_commitment_free (&dc->age_commitment);
   1749     }
   1750     else if (is_age_restricted_denom &&
   1751              dc->no_h_age_commitment)
   1752     {
   1753       /* The contract did not ask for a minimum_age but the client paid
   1754        * with a coin that has age restriction enabled.  We lack the hash
   1755        * of the age commitment in this case in order to verify the coin
   1756        * and to deposit it with the exchange. */
   1757       GNUNET_break_op (0);
   1758       resume_pay_with_response (
   1759         pc,
   1760         MHD_HTTP_BAD_REQUEST,
   1761         TALER_MHD_MAKE_JSON_PACK (
   1762           TALER_JSON_pack_ec (
   1763             TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_HASH_MISSING),
   1764           GNUNET_JSON_pack_data_auto ("h_denom_pub",
   1765                                       &denom_details->h_key)));
   1766       return;
   1767     }
   1768   }
   1769 
   1770   do_batch_deposits (eg);
   1771 }
   1772 
   1773 
   1774 static void
   1775 force_keys (struct ExchangeGroup *eg)
   1776 {
   1777   struct PayContext *pc = eg->pc;
   1778 
   1779   eg->tried_force_keys = true;
   1780   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1781               "Forcing /keys download (once)\n");
   1782   eg->fo = TMH_EXCHANGES_keys4exchange (
   1783     eg->exchange_url,
   1784     true,
   1785     &process_pay_with_keys,
   1786     eg);
   1787   if (NULL == eg->fo)
   1788   {
   1789     GNUNET_break_op (0);
   1790     resume_pay_with_error (pc,
   1791                            TALER_EC_MERCHANT_GENERIC_EXCHANGE_UNTRUSTED,
   1792                            eg->exchange_url);
   1793     return;
   1794   }
   1795   pc->batch_deposits.pending_at_eg++;
   1796 }
   1797 
   1798 
   1799 /**
   1800  * Handle a timeout for the processing of the pay request.
   1801  *
   1802  * @param cls our `struct PayContext`
   1803  */
   1804 static void
   1805 handle_pay_timeout (void *cls)
   1806 {
   1807   struct PayContext *pc = cls;
   1808 
   1809   pc->batch_deposits.timeout_task = NULL;
   1810   GNUNET_assert (GNUNET_YES == pc->suspended);
   1811   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1812               "Resuming pay with error after timeout\n");
   1813   resume_pay_with_error (pc,
   1814                          TALER_EC_MERCHANT_GENERIC_EXCHANGE_TIMEOUT,
   1815                          NULL);
   1816 }
   1817 
   1818 
   1819 /**
   1820  * Compute the timeout for a /pay request based on the number of coins
   1821  * involved.
   1822  *
   1823  * @param num_coins number of coins
   1824  * @returns timeout for the /pay request
   1825  */
   1826 static struct GNUNET_TIME_Relative
   1827 get_pay_timeout (unsigned int num_coins)
   1828 {
   1829   struct GNUNET_TIME_Relative t;
   1830 
   1831   /* FIXME-Performance-Optimization: Do some benchmarking to come up with a
   1832    * better timeout.  We've increased this value so the wallet integration
   1833    * test passes again on my (Florian) machine.
   1834    */
   1835   t = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
   1836                                      15 * (1 + (num_coins / 5)));
   1837 
   1838   return t;
   1839 }
   1840 
   1841 
   1842 /**
   1843  * Start batch deposits for all exchanges involved
   1844  * in this payment.
   1845  *
   1846  * @param[in,out] pc payment context we are processing
   1847  */
   1848 static void
   1849 phase_batch_deposits (struct PayContext *pc)
   1850 {
   1851   for (unsigned int i = 0; i<pc->parse_pay.num_exchanges; i++)
   1852   {
   1853     struct ExchangeGroup *eg = pc->parse_pay.egs[i];
   1854     bool have_coins = false;
   1855 
   1856     for (size_t j = 0; j<pc->parse_pay.coins_cnt; j++)
   1857     {
   1858       struct DepositConfirmation *dc = &pc->parse_pay.dc[j];
   1859 
   1860       if (0 != strcmp (eg->exchange_url,
   1861                        dc->exchange_url))
   1862         continue;
   1863       if (dc->found_in_db)
   1864         continue;
   1865       have_coins = true;
   1866       break;
   1867     }
   1868     if (! have_coins)
   1869       continue; /* no coins left to deposit at this exchange */
   1870     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1871                 "Getting /keys for %s\n",
   1872                 eg->exchange_url);
   1873     eg->fo = TMH_EXCHANGES_keys4exchange (
   1874       eg->exchange_url,
   1875       false,
   1876       &process_pay_with_keys,
   1877       eg);
   1878     if (NULL == eg->fo)
   1879     {
   1880       GNUNET_break_op (0);
   1881       pay_end (pc,
   1882                TALER_MHD_reply_with_error (
   1883                  pc->connection,
   1884                  MHD_HTTP_BAD_REQUEST,
   1885                  TALER_EC_MERCHANT_GENERIC_EXCHANGE_UNTRUSTED,
   1886                  eg->exchange_url));
   1887       return;
   1888     }
   1889     pc->batch_deposits.pending_at_eg++;
   1890   }
   1891   if (0 == pc->batch_deposits.pending_at_eg)
   1892   {
   1893     pc->phase = PP_COMPUTE_MONEY_POTS;
   1894     pay_resume (pc);
   1895     return;
   1896   }
   1897   /* Suspend while we interact with the exchange */
   1898   MHD_suspend_connection (pc->connection);
   1899   pc->suspended = GNUNET_YES;
   1900   GNUNET_assert (NULL == pc->batch_deposits.timeout_task);
   1901   pc->batch_deposits.timeout_task
   1902     = GNUNET_SCHEDULER_add_delayed (get_pay_timeout (pc->parse_pay.coins_cnt),
   1903                                     &handle_pay_timeout,
   1904                                     pc);
   1905 }
   1906 
   1907 
   1908 /**
   1909  * Build JSON array of blindly signed token envelopes,
   1910  * to be used in the response to the wallet.
   1911  *
   1912  * @param[in,out] pc payment context to use
   1913  */
   1914 static json_t *
   1915 build_token_sigs (struct PayContext *pc)
   1916 {
   1917   json_t *token_sigs;
   1918 
   1919   if (0 == pc->output_tokens_len)
   1920     return NULL;
   1921   token_sigs = json_array ();
   1922   GNUNET_assert (NULL != token_sigs);
   1923   for (unsigned int i = 0; i < pc->output_tokens_len; i++)
   1924   {
   1925     if (NULL == pc->output_tokens[i].sig.signature)
   1926       continue; /* must be optional TF and wallet did not provide it */
   1927     GNUNET_assert (0 ==
   1928                    json_array_append_new (
   1929                      token_sigs,
   1930                      GNUNET_JSON_PACK (
   1931                        GNUNET_JSON_pack_blinded_sig (
   1932                          "blind_sig",
   1933                          pc->output_tokens[i].sig.signature)
   1934                        )));
   1935   }
   1936   return token_sigs;
   1937 }
   1938 
   1939 
   1940 /**
   1941  * Generate response (payment successful)
   1942  *
   1943  * @param[in,out] pc payment context where the payment was successful
   1944  */
   1945 static void
   1946 phase_success_response (struct PayContext *pc)
   1947 {
   1948   struct TALER_MerchantSignatureP sig;
   1949   char *pos_confirmation;
   1950 
   1951   /* Sign on our end (as the payment did go through, even if it may
   1952      have been refunded already) */
   1953   TALER_merchant_pay_sign (&pc->check_contract.h_contract_terms,
   1954                            &pc->hc->instance->merchant_priv,
   1955                            &sig);
   1956   /* Build the response */
   1957   pos_confirmation = (NULL == pc->check_contract.pos_key)
   1958     ? NULL
   1959     : TALER_build_pos_confirmation (
   1960     pc->check_contract.pos_key,
   1961     pc->check_contract.pos_alg,
   1962     &pc->validate_tokens.brutto,
   1963     pc->check_contract.contract_terms->pc->timestamp);
   1964   pay_end (pc,
   1965            TALER_MHD_REPLY_JSON_PACK (
   1966              pc->connection,
   1967              MHD_HTTP_OK,
   1968              GNUNET_JSON_pack_allow_null (
   1969                GNUNET_JSON_pack_string ("pos_confirmation",
   1970                                         pos_confirmation)),
   1971              GNUNET_JSON_pack_allow_null (
   1972                GNUNET_JSON_pack_array_steal ("token_sigs",
   1973                                              build_token_sigs (pc))),
   1974              GNUNET_JSON_pack_data_auto ("sig",
   1975                                          &sig)));
   1976   GNUNET_free (pos_confirmation);
   1977 }
   1978 
   1979 
   1980 /**
   1981  * Use database to notify other clients about the
   1982  * payment being completed.
   1983  *
   1984  * @param[in,out] pc context to trigger notification for
   1985  */
   1986 static void
   1987 phase_payment_notification (struct PayContext *pc)
   1988 {
   1989   {
   1990     struct TMH_OrderPayEventP pay_eh = {
   1991       .header.size = htons (sizeof (pay_eh)),
   1992       .header.type = htons (TALER_DBEVENT_MERCHANT_ORDER_PAID),
   1993       .merchant_pub = pc->hc->instance->merchant_pub
   1994     };
   1995 
   1996     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   1997                 "Notifying clients about payment of order %s\n",
   1998                 pc->order_id);
   1999     GNUNET_CRYPTO_hash (pc->order_id,
   2000                         strlen (pc->order_id),
   2001                         &pay_eh.h_order_id);
   2002     TALER_MERCHANTDB_event_notify (TMH_db,
   2003                                    &pay_eh.header,
   2004                                    NULL,
   2005                                    0);
   2006   }
   2007   {
   2008     struct TMH_OrderPayEventP pay_eh = {
   2009       .header.size = htons (sizeof (pay_eh)),
   2010       .header.type = htons (TALER_DBEVENT_MERCHANT_ORDER_STATUS_CHANGED),
   2011       .merchant_pub = pc->hc->instance->merchant_pub
   2012     };
   2013 
   2014     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   2015                 "Notifying clients about status change of order %s\n",
   2016                 pc->order_id);
   2017     GNUNET_CRYPTO_hash (pc->order_id,
   2018                         strlen (pc->order_id),
   2019                         &pay_eh.h_order_id);
   2020     TALER_MERCHANTDB_event_notify (TMH_db,
   2021                                    &pay_eh.header,
   2022                                    NULL,
   2023                                    0);
   2024   }
   2025   if ( (NULL != pc->parse_pay.session_id) &&
   2026        (NULL != pc->check_contract.contract_terms->pc->base->fulfillment_url) )
   2027   {
   2028     struct TMH_SessionEventP session_eh = {
   2029       .header.size = htons (sizeof (session_eh)),
   2030       .header.type = htons (TALER_DBEVENT_MERCHANT_SESSION_CAPTURED),
   2031       .merchant_pub = pc->hc->instance->merchant_pub
   2032     };
   2033 
   2034     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   2035                 "Notifying clients about session change to %s for %s\n",
   2036                 pc->parse_pay.session_id,
   2037                 pc->check_contract.contract_terms->pc->base->fulfillment_url);
   2038     GNUNET_CRYPTO_hash (pc->parse_pay.session_id,
   2039                         strlen (pc->parse_pay.session_id),
   2040                         &session_eh.h_session_id);
   2041     GNUNET_CRYPTO_hash (
   2042       pc->check_contract.contract_terms->pc->base->fulfillment_url,
   2043       strlen (pc->check_contract.contract_terms->pc->base->fulfillment_url),
   2044       &session_eh.h_fulfillment_url);
   2045     TALER_MERCHANTDB_event_notify (TMH_db,
   2046                                    &session_eh.header,
   2047                                    NULL,
   2048                                    0);
   2049   }
   2050   pc->phase = PP_SUCCESS_RESPONSE;
   2051 }
   2052 
   2053 
   2054 /**
   2055  * Phase to write all outputs to our database so we do
   2056  * not re-request them in case the client re-plays the
   2057  * request.
   2058  *
   2059  * @param[in,out] pc payment context
   2060  */
   2061 static void
   2062 phase_final_output_token_processing (struct PayContext *pc)
   2063 {
   2064   if (0 == pc->output_tokens_len)
   2065   {
   2066     pc->phase++;
   2067     return;
   2068   }
   2069   for (unsigned int retry = 0; retry < MAX_RETRIES; retry++)
   2070   {
   2071     enum GNUNET_DB_QueryStatus qs;
   2072 
   2073     TALER_MERCHANTDB_preflight (TMH_db);
   2074     if (GNUNET_OK !=
   2075         TALER_MERCHANTDB_start (TMH_db,
   2076                                 "insert_order_blinded_sigs"))
   2077     {
   2078       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   2079                   "start insert_order_blinded_sigs_failed");
   2080       pc->phase++;
   2081       return;
   2082     }
   2083     if (pc->parse_wallet_data.num_bkps > 0)
   2084     {
   2085       qs = TALER_MERCHANTDB_update_donau_instance_receipts_amount (
   2086         TMH_db,
   2087         &pc->parse_wallet_data.donau_instance_serial,
   2088         &pc->parse_wallet_data.charity_receipts_to_date);
   2089       switch (qs)
   2090       {
   2091       case GNUNET_DB_STATUS_HARD_ERROR:
   2092         TALER_MERCHANTDB_rollback (TMH_db);
   2093         GNUNET_break (0);
   2094         pc->phase++;
   2095         return;
   2096       case GNUNET_DB_STATUS_SOFT_ERROR:
   2097         TALER_MERCHANTDB_rollback (TMH_db);
   2098         continue;
   2099       case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
   2100         /* weird for an update */
   2101         GNUNET_break (0);
   2102         break;
   2103       case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
   2104         break;
   2105       }
   2106     }
   2107     for (unsigned int i = 0;
   2108          i < pc->output_tokens_len;
   2109          i++)
   2110     {
   2111       if (NULL == pc->output_tokens[i].sig.signature)
   2112         continue; /* must have been optional and not provided by wallet */
   2113       qs = TALER_MERCHANTDB_insert_order_blinded_sigs (
   2114         TMH_db,
   2115         pc->order_id,
   2116         i,
   2117         &pc->output_tokens[i].h_issue.hash,
   2118         pc->output_tokens[i].sig.signature);
   2119 
   2120       switch (qs)
   2121       {
   2122       case GNUNET_DB_STATUS_HARD_ERROR:
   2123         TALER_MERCHANTDB_rollback (TMH_db);
   2124         pc->phase++;
   2125         return;
   2126       case GNUNET_DB_STATUS_SOFT_ERROR:
   2127         TALER_MERCHANTDB_rollback (TMH_db);
   2128         goto OUTER;
   2129       case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
   2130         /* weird for an update */
   2131         GNUNET_break (0);
   2132         break;
   2133       case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
   2134         break;
   2135       }
   2136     } /* for i */
   2137     qs = TALER_MERCHANTDB_commit (TMH_db);
   2138     switch (qs)
   2139     {
   2140     case GNUNET_DB_STATUS_HARD_ERROR:
   2141       TALER_MERCHANTDB_rollback (TMH_db);
   2142       pc->phase++;
   2143       return;
   2144     case GNUNET_DB_STATUS_SOFT_ERROR:
   2145       TALER_MERCHANTDB_rollback (TMH_db);
   2146       continue;
   2147     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
   2148       pc->phase++;
   2149       return; /* success */
   2150     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
   2151       pc->phase++;
   2152       return; /* success */
   2153     }
   2154     GNUNET_break (0);
   2155     pc->phase++;
   2156     return; /* strange */
   2157 OUTER:
   2158   } /* for retry */
   2159   TALER_MERCHANTDB_rollback (TMH_db);
   2160   pc->phase++;
   2161   /* We continue anyway, as there is not much we can
   2162      do here: the Donau *did* issue us the receipts;
   2163      also, we'll eventually ask the Donau for the
   2164      balance and get the correct one. Plus, we were
   2165      paid by the client, so it's technically all still
   2166      OK. If the request fails anyway, the wallet will
   2167      most likely replay the request and then hopefully
   2168      we will succeed the next time */
   2169 }
   2170 
   2171 
   2172 /**
   2173  * Add donation receipt outputs to the output_tokens.
   2174  *
   2175  * Note that under the current (odd, bad) libdonau
   2176  * API *we* are responsible for freeing blinded_sigs,
   2177  * so we truly own that array!
   2178  *
   2179  * @param[in,out] pc payment context
   2180  * @param num_blinded_sigs number of signatures received
   2181  * @param blinded_sigs blinded signatures from Donau
   2182  * @return #GNUNET_OK on success,
   2183  *         #GNUNET_SYSERR on failure (state machine was
   2184  *          in that case already advanced)
   2185  */
   2186 static enum GNUNET_GenericReturnValue
   2187 add_donation_receipt_outputs (
   2188   struct PayContext *pc,
   2189   size_t num_blinded_sigs,
   2190   struct DONAU_BlindedDonationUnitSignature *blinded_sigs)
   2191 {
   2192   unsigned int i;
   2193   int donau_output_index = pc->validate_tokens.donau_output_index;
   2194 
   2195   GNUNET_assert (pc->parse_wallet_data.num_bkps ==
   2196                  num_blinded_sigs);
   2197   GNUNET_assert (donau_output_index >= 0);
   2198 
   2199   /* Find position where donau tokens start in output_tokens */
   2200   for (i = 0; i<pc->output_tokens_len; i++)
   2201   {
   2202     const struct SignedOutputToken *sot
   2203       = &pc->output_tokens[i];
   2204 
   2205     /* Only look at actual donau tokens. */
   2206     if (sot->output_index == donau_output_index)
   2207       break;
   2208   }
   2209 
   2210   /* copy donau signatures into output array */
   2211   for (unsigned int j=0; j<pc->parse_wallet_data.num_bkps; j++)
   2212   {
   2213     struct SignedOutputToken *sot;
   2214 
   2215     GNUNET_assert (i + j < pc->output_tokens_len);
   2216     sot = &pc->output_tokens[i + j];
   2217     GNUNET_assert (sot->output_index == donau_output_index);
   2218     sot->sig.signature = GNUNET_CRYPTO_blind_sig_incref (
   2219       blinded_sigs[j].blinded_sig);
   2220     sot->h_issue.hash
   2221       = pc->parse_wallet_data.bkps[j].h_donation_unit_pub.hash;
   2222   }
   2223   return GNUNET_OK;
   2224 }
   2225 
   2226 
   2227 /**
   2228  * Callback to handle the result of a batch issue request.
   2229  *
   2230  * @param cls our `struct PayContext`
   2231  * @param resp the response from Donau
   2232  */
   2233 static void
   2234 merchant_donau_issue_receipt_cb (
   2235   void *cls,
   2236   const struct DONAU_BatchIssueResponse *resp)
   2237 {
   2238   struct PayContext *pc = cls;
   2239   /* Donau replies asynchronously, so we expect the PayContext
   2240    * to be suspended. */
   2241   GNUNET_assert (GNUNET_YES == pc->suspended);
   2242   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
   2243               "Donau responded with status=%u, ec=%u",
   2244               resp->hr.http_status,
   2245               resp->hr.ec);
   2246   switch (resp->hr.http_status)
   2247   {
   2248   case 0:
   2249     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
   2250                 "Donau batch issue request from merchant-httpd failed (http_status==0)");
   2251     resume_pay_with_error (pc,
   2252                            TALER_EC_MERCHANT_GENERIC_DONAU_INVALID_RESPONSE,
   2253                            resp->hr.hint);
   2254     return;
   2255   case MHD_HTTP_OK:
   2256   case MHD_HTTP_CREATED:
   2257     if (TALER_EC_NONE != resp->hr.ec)
   2258     {
   2259       /* Most probably, it is just some small flaw from
   2260        * donau so no point in failing, yet we have to display it */
   2261       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
   2262                   "Donau signalled error %u despite HTTP %u",
   2263                   resp->hr.ec,
   2264                   resp->hr.http_status);
   2265     }
   2266     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   2267                 "Donau accepted donation receipts with total_issued=%s",
   2268                 TALER_amount2s (&resp->details.ok.issued_amount));
   2269     if (GNUNET_OK !=
   2270         add_donation_receipt_outputs (pc,
   2271                                       resp->details.ok.num_blinded_sigs,
   2272                                       resp->details.ok.blinded_sigs))
   2273       return; /* state machine was already advanced */
   2274     pc->phase = PP_FINAL_OUTPUT_TOKEN_PROCESSING;
   2275     pay_resume (pc);
   2276     return;
   2277 
   2278   case MHD_HTTP_BAD_REQUEST:
   2279   case MHD_HTTP_FORBIDDEN:
   2280   case MHD_HTTP_NOT_FOUND:
   2281   case MHD_HTTP_INTERNAL_SERVER_ERROR:
   2282   default: /* make sure that everything except 200/201 will end up here*/
   2283     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
   2284                 "Donau replied with HTTP %u (ec=%u)",
   2285                 resp->hr.http_status,
   2286                 resp->hr.ec);
   2287     resume_pay_with_error (pc,
   2288                            TALER_EC_MERCHANT_GENERIC_DONAU_INVALID_RESPONSE,
   2289                            resp->hr.hint);
   2290     return;
   2291   }
   2292 }
   2293 
   2294 
   2295 /**
   2296  * Parse a bkp encoded in JSON.
   2297  *
   2298  * @param[out] bkp where to return the result
   2299  * @param bkp_key_obj json to parse
   2300  * @return #GNUNET_OK if all is fine, #GNUNET_SYSERR if @a bkp_key_obj
   2301  * is malformed.
   2302  */
   2303 static enum GNUNET_GenericReturnValue
   2304 merchant_parse_json_bkp (struct DONAU_BlindedUniqueDonorIdentifierKeyPair *bkp,
   2305                          const json_t *bkp_key_obj)
   2306 {
   2307   struct GNUNET_JSON_Specification spec[] = {
   2308     GNUNET_JSON_spec_fixed_auto ("h_donation_unit_pub",
   2309                                  &bkp->h_donation_unit_pub),
   2310     DONAU_JSON_spec_blinded_donation_identifier ("blinded_udi",
   2311                                                  &bkp->blinded_udi),
   2312     GNUNET_JSON_spec_end ()
   2313   };
   2314 
   2315   if (GNUNET_OK !=
   2316       GNUNET_JSON_parse (bkp_key_obj,
   2317                          spec,
   2318                          NULL,
   2319                          NULL))
   2320   {
   2321     GNUNET_break_op (0);
   2322     return GNUNET_SYSERR;
   2323   }
   2324   return GNUNET_OK;
   2325 }
   2326 
   2327 
   2328 /**
   2329  * Generate a donation signature for the bkp and charity.
   2330  *
   2331  * @param[in,out] pc payment context containing the charity and bkps
   2332  */
   2333 static void
   2334 phase_request_donation_receipt (struct PayContext *pc)
   2335 {
   2336   if ( (NULL == pc->parse_wallet_data.donau.donau_url) ||
   2337        (0 == pc->parse_wallet_data.num_bkps) )
   2338   {
   2339     pc->phase++;
   2340     return;
   2341   }
   2342   pc->donau_receipt.birh =
   2343     DONAU_charity_issue_receipt (
   2344       TMH_curl_ctx,
   2345       pc->parse_wallet_data.donau.donau_url,
   2346       &pc->parse_wallet_data.charity_priv,
   2347       pc->parse_wallet_data.charity_id,
   2348       pc->parse_wallet_data.donau.donation_year,
   2349       pc->parse_wallet_data.num_bkps,
   2350       pc->parse_wallet_data.bkps,
   2351       &merchant_donau_issue_receipt_cb,
   2352       pc);
   2353   if (NULL == pc->donau_receipt.birh)
   2354   {
   2355     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
   2356                 "Failed to create Donau receipt request");
   2357     pay_end (pc,
   2358              TALER_MHD_reply_with_error (pc->connection,
   2359                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
   2360                                          TALER_EC_GENERIC_CLIENT_INTERNAL_ERROR,
   2361                                          "Donau request creation error"));
   2362     return;
   2363   }
   2364   MHD_suspend_connection (pc->connection);
   2365   pc->suspended = GNUNET_YES;
   2366 }
   2367 
   2368 
   2369 /**
   2370  * Increment the money pot @a pot_id in @a pc by @a increment.
   2371  *
   2372  * @param[in,out] pc context to update
   2373  * @param pot_id money pot to increment
   2374  * @param increment amount to add
   2375  */
   2376 static void
   2377 increment_pot (struct PayContext *pc,
   2378                uint64_t pot_id,
   2379                const struct TALER_Amount *increment)
   2380 {
   2381   for (unsigned int i = 0; i<pc->compute_money_pots.num_pots; i++)
   2382   {
   2383     if (pot_id == pc->compute_money_pots.pots[i])
   2384     {
   2385       struct TALER_Amount *p;
   2386 
   2387       p = &pc->compute_money_pots.increments[i];
   2388       GNUNET_assert (0 <=
   2389                      TALER_amount_add (p,
   2390                                        p,
   2391                                        increment));
   2392       return;
   2393     }
   2394   }
   2395   GNUNET_array_append (pc->compute_money_pots.pots,
   2396                        pc->compute_money_pots.num_pots,
   2397                        pot_id);
   2398   pc->compute_money_pots.num_pots--; /* do not increment twice... */
   2399   GNUNET_array_append (pc->compute_money_pots.increments,
   2400                        pc->compute_money_pots.num_pots,
   2401                        *increment);
   2402 }
   2403 
   2404 
   2405 /**
   2406  * Compute the total changes to money pots in preparation
   2407  * for the #PP_PAY_TRANSACTION phase.
   2408  *
   2409  * @param[in,out] pc payment context to transact
   2410  */
   2411 static void
   2412 phase_compute_money_pots (struct PayContext *pc)
   2413 {
   2414   const struct TALER_MERCHANT_Contract *contract
   2415     = pc->check_contract.contract_terms;
   2416   struct TALER_Amount assigned;
   2417 
   2418   if (0 == pc->parse_pay.coins_cnt)
   2419   {
   2420     /* Did not pay with any coins, so no currency/amount involved,
   2421        hence no money pot update possible. */
   2422     pc->phase++;
   2423     return;
   2424   }
   2425 
   2426   if (pc->compute_money_pots.pots_computed)
   2427   {
   2428     pc->phase++;
   2429     return;
   2430   }
   2431   /* reset, in case this phase is run a 2nd time */
   2432   GNUNET_free (pc->compute_money_pots.pots);
   2433   GNUNET_free (pc->compute_money_pots.increments);
   2434   pc->compute_money_pots.num_pots = 0;
   2435 
   2436   GNUNET_assert (GNUNET_OK ==
   2437                  TALER_amount_set_zero (pc->parse_pay.dc[0].cdd.amount.currency,
   2438                                         &assigned));
   2439   GNUNET_assert (NULL != contract);
   2440   for (size_t i = 0; i<contract->pc->products_len; i++)
   2441   {
   2442     const struct TALER_MERCHANT_ProductSold *product
   2443       = &contract->pc->products[i];
   2444     const struct TALER_Amount *price = NULL;
   2445 
   2446     /* find price in the right currency */
   2447     for (unsigned int j = 0; j<product->prices_length; j++)
   2448     {
   2449       if (GNUNET_OK ==
   2450           TALER_amount_cmp_currency (&assigned,
   2451                                      &product->prices[j]))
   2452       {
   2453         price = &product->prices[j];
   2454         break;
   2455       }
   2456     }
   2457     if (NULL == price)
   2458     {
   2459       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   2460                   "Product `%s' has no price given in `%s'.\n",
   2461                   product->product_id,
   2462                   assigned.currency);
   2463       continue;
   2464     }
   2465     if (0 != product->product_money_pot)
   2466     {
   2467       GNUNET_assert (0 <=
   2468                      TALER_amount_add (&assigned,
   2469                                        &assigned,
   2470                                        price));
   2471       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   2472                   "Contributing to product money pot %llu increment of %s\n",
   2473                   (unsigned long long) product->product_money_pot,
   2474                   TALER_amount2s (price));
   2475       increment_pot (pc,
   2476                      product->product_money_pot,
   2477                      price);
   2478     }
   2479   }
   2480 
   2481   {
   2482     /* Compute what is left from the order total and account for that.
   2483        Also sanity-check and handle the case where the overall order
   2484        is below that of the sum of the products. */
   2485     struct TALER_Amount left;
   2486 
   2487     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   2488                 "Order brutto is %s\n",
   2489                 TALER_amount2s (&pc->validate_tokens.brutto));
   2490     if (0 >
   2491         TALER_amount_subtract (&left,
   2492                                &pc->validate_tokens.brutto,
   2493                                &assigned))
   2494     {
   2495       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   2496                   "Total order brutto amount below sum from products, skipping per-product money pots\n");
   2497       GNUNET_free (pc->compute_money_pots.pots);
   2498       GNUNET_free (pc->compute_money_pots.increments);
   2499       pc->compute_money_pots.num_pots = 0;
   2500       left = pc->validate_tokens.brutto;
   2501     }
   2502 
   2503     if ( (! TALER_amount_is_zero (&left)) &&
   2504          (0 != contract->pc->base->default_money_pot) )
   2505     {
   2506       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   2507                   "Computing money pot %llu increment as %s\n",
   2508                   (unsigned long long) contract->pc->base->default_money_pot,
   2509                   TALER_amount2s (&left));
   2510       increment_pot (pc,
   2511                      contract->pc->base->default_money_pot,
   2512                      &left);
   2513     }
   2514   }
   2515   pc->compute_money_pots.pots_computed = true;
   2516   pc->phase++;
   2517 }
   2518 
   2519 
   2520 /**
   2521  * Function called with information about a coin that was deposited.
   2522  *
   2523  * @param cls closure
   2524  * @param exchange_url exchange where @a coin_pub was deposited
   2525  * @param coin_pub public key of the coin
   2526  * @param amount_with_fee amount the exchange will deposit for this coin
   2527  * @param deposit_fee fee the exchange will charge for this coin
   2528  * @param refund_fee fee the exchange will charge for refunding this coin
   2529  */
   2530 static void
   2531 check_coin_paid (void *cls,
   2532                  const char *exchange_url,
   2533                  const struct TALER_CoinSpendPublicKeyP *coin_pub,
   2534                  const struct TALER_Amount *amount_with_fee,
   2535                  const struct TALER_Amount *deposit_fee,
   2536                  const struct TALER_Amount *refund_fee)
   2537 {
   2538   struct PayContext *pc = cls;
   2539 
   2540   for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   2541   {
   2542     struct DepositConfirmation *dc = &pc->parse_pay.dc[i];
   2543 
   2544     if (dc->found_in_db)
   2545       continue; /* processed earlier, skip "expensive" memcmp() */
   2546     /* Get matching coin from results*/
   2547     if ( (0 != GNUNET_memcmp (coin_pub,
   2548                               &dc->cdd.coin_pub)) ||
   2549          (0 !=
   2550           strcmp (exchange_url,
   2551                   dc->exchange_url)) ||
   2552          (GNUNET_OK !=
   2553           TALER_amount_cmp_currency (amount_with_fee,
   2554                                      &dc->cdd.amount)) ||
   2555          (0 != TALER_amount_cmp (amount_with_fee,
   2556                                  &dc->cdd.amount)) )
   2557       continue; /* does not match, skip */
   2558     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
   2559                 "Deposit of coin `%s' already in our DB.\n",
   2560                 TALER_B2S (coin_pub));
   2561     if ( (GNUNET_OK !=
   2562           TALER_amount_cmp_currency (&pc->pay_transaction.total_paid,
   2563                                      amount_with_fee)) ||
   2564          (GNUNET_OK !=
   2565           TALER_amount_cmp_currency (&pc->pay_transaction.total_fees_paid,
   2566                                      deposit_fee)) )
   2567     {
   2568       GNUNET_break_op (0);
   2569       pc->pay_transaction.deposit_currency_mismatch = true;
   2570       break;
   2571     }
   2572     GNUNET_assert (0 <=
   2573                    TALER_amount_add (&pc->pay_transaction.total_paid,
   2574                                      &pc->pay_transaction.total_paid,
   2575                                      amount_with_fee));
   2576     GNUNET_assert (0 <=
   2577                    TALER_amount_add (&pc->pay_transaction.total_fees_paid,
   2578                                      &pc->pay_transaction.total_fees_paid,
   2579                                      deposit_fee));
   2580     dc->deposit_fee = *deposit_fee;
   2581     dc->refund_fee = *refund_fee;
   2582     dc->cdd.amount = *amount_with_fee;
   2583     dc->found_in_db = true;
   2584     pc->pay_transaction.pending--;
   2585   }
   2586 }
   2587 
   2588 
   2589 /**
   2590  * Function called with information about a refund.  Check if this coin was
   2591  * claimed by the wallet for the transaction, and if so add the refunded
   2592  * amount to the pc's "total_refunded" amount.
   2593  *
   2594  * @param cls closure with a `struct PayContext`
   2595  * @param coin_pub public coin from which the refund comes from
   2596  * @param refund_amount refund amount which is being taken from @a coin_pub
   2597  */
   2598 static void
   2599 check_coin_refunded (void *cls,
   2600                      const struct TALER_CoinSpendPublicKeyP *coin_pub,
   2601                      const struct TALER_Amount *refund_amount)
   2602 {
   2603   struct PayContext *pc = cls;
   2604 
   2605   /* We look at refunds here that apply to the coins
   2606      that the customer is currently trying to pay us with.
   2607 
   2608      Such refunds are not "normal" refunds, but abort-pay refunds, which are
   2609      given in the case that the wallet aborts the payment.
   2610      In the case the wallet then decides to complete the payment *after* doing
   2611      an abort-pay refund (an unusual but possible case), we need
   2612      to make sure that existing refunds are accounted for. */
   2613 
   2614   for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   2615   {
   2616     struct DepositConfirmation *dc = &pc->parse_pay.dc[i];
   2617 
   2618     /* Get matching coins from results.  */
   2619     if (0 != GNUNET_memcmp (coin_pub,
   2620                             &dc->cdd.coin_pub))
   2621       continue;
   2622     if (GNUNET_OK !=
   2623         TALER_amount_cmp_currency (&pc->pay_transaction.total_refunded,
   2624                                    refund_amount))
   2625     {
   2626       GNUNET_break (0);
   2627       pc->pay_transaction.refund_currency_mismatch = true;
   2628       break;
   2629     }
   2630     GNUNET_assert (0 <=
   2631                    TALER_amount_add (&pc->pay_transaction.total_refunded,
   2632                                      &pc->pay_transaction.total_refunded,
   2633                                      refund_amount));
   2634     break;
   2635   }
   2636 }
   2637 
   2638 
   2639 /**
   2640  * Check whether the amount paid is sufficient to cover the price.
   2641  *
   2642  * @param pc payment context to check
   2643  * @return true if the payment is sufficient, false if it is
   2644  *         insufficient
   2645  */
   2646 static bool
   2647 check_payment_sufficient (struct PayContext *pc)
   2648 {
   2649   struct TALER_Amount acc_fee;
   2650   struct TALER_Amount acc_amount;
   2651   struct TALER_Amount final_amount;
   2652   struct TALER_Amount total_wire_fee;
   2653   struct TALER_Amount total_needed;
   2654 
   2655   if (0 == pc->parse_pay.coins_cnt)
   2656     return TALER_amount_is_zero (&pc->validate_tokens.brutto);
   2657   GNUNET_assert (GNUNET_OK ==
   2658                  TALER_amount_set_zero (pc->validate_tokens.brutto.currency,
   2659                                         &total_wire_fee));
   2660   for (unsigned int i = 0; i < pc->parse_pay.num_exchanges; i++)
   2661   {
   2662     if (GNUNET_OK !=
   2663         TALER_amount_cmp_currency (&total_wire_fee,
   2664                                    &pc->parse_pay.egs[i]->wire_fee))
   2665     {
   2666       GNUNET_break_op (0);
   2667       pay_end (pc,
   2668                TALER_MHD_reply_with_error (pc->connection,
   2669                                            MHD_HTTP_BAD_REQUEST,
   2670                                            TALER_EC_GENERIC_CURRENCY_MISMATCH,
   2671                                            total_wire_fee.currency));
   2672       return false;
   2673     }
   2674     if (0 >
   2675         TALER_amount_add (&total_wire_fee,
   2676                           &total_wire_fee,
   2677                           &pc->parse_pay.egs[i]->wire_fee))
   2678     {
   2679       GNUNET_break (0);
   2680       pay_end (pc,
   2681                TALER_MHD_reply_with_error (
   2682                  pc->connection,
   2683                  MHD_HTTP_INTERNAL_SERVER_ERROR,
   2684                  TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED,
   2685                  "could not add exchange wire fee to total"));
   2686       return false;
   2687     }
   2688   }
   2689 
   2690   /**
   2691    * This loops calculates what are the deposit fee / total
   2692    * amount with fee / and wire fee, for all the coins.
   2693    */
   2694   GNUNET_assert (GNUNET_OK ==
   2695                  TALER_amount_set_zero (pc->validate_tokens.brutto.currency,
   2696                                         &acc_fee));
   2697   GNUNET_assert (GNUNET_OK ==
   2698                  TALER_amount_set_zero (pc->validate_tokens.brutto.currency,
   2699                                         &acc_amount));
   2700   for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   2701   {
   2702     struct DepositConfirmation *dc = &pc->parse_pay.dc[i];
   2703 
   2704     GNUNET_assert (dc->found_in_db);
   2705     if ( (GNUNET_OK !=
   2706           TALER_amount_cmp_currency (&acc_fee,
   2707                                      &dc->deposit_fee)) ||
   2708          (GNUNET_OK !=
   2709           TALER_amount_cmp_currency (&acc_amount,
   2710                                      &dc->cdd.amount)) )
   2711     {
   2712       GNUNET_break_op (0);
   2713       pay_end (pc,
   2714                TALER_MHD_reply_with_error (
   2715                  pc->connection,
   2716                  MHD_HTTP_BAD_REQUEST,
   2717                  TALER_EC_GENERIC_CURRENCY_MISMATCH,
   2718                  dc->deposit_fee.currency));
   2719       return false;
   2720     }
   2721     if ( (0 >
   2722           TALER_amount_add (&acc_fee,
   2723                             &dc->deposit_fee,
   2724                             &acc_fee)) ||
   2725          (0 >
   2726           TALER_amount_add (&acc_amount,
   2727                             &dc->cdd.amount,
   2728                             &acc_amount)) )
   2729     {
   2730       GNUNET_break (0);
   2731       /* Overflow in these amounts? Very strange. */
   2732       pay_end (pc,
   2733                TALER_MHD_reply_with_error (
   2734                  pc->connection,
   2735                  MHD_HTTP_INTERNAL_SERVER_ERROR,
   2736                  TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AMOUNT_OVERFLOW,
   2737                  "Overflow adding up amounts"));
   2738       return false;
   2739     }
   2740     if (1 ==
   2741         TALER_amount_cmp (&dc->deposit_fee,
   2742                           &dc->cdd.amount))
   2743     {
   2744       GNUNET_break_op (0);
   2745       pay_end (pc,
   2746                TALER_MHD_reply_with_error (
   2747                  pc->connection,
   2748                  MHD_HTTP_BAD_REQUEST,
   2749                  TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_FEES_EXCEED_PAYMENT,
   2750                  "Deposit fees exceed coin's contribution"));
   2751       return false;
   2752     }
   2753   } /* end deposit loop */
   2754 
   2755   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
   2756               "Amount received from wallet: %s\n",
   2757               TALER_amount2s (&acc_amount));
   2758   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
   2759               "Deposit fee for all coins: %s\n",
   2760               TALER_amount2s (&acc_fee));
   2761   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
   2762               "Total wire fee: %s\n",
   2763               TALER_amount2s (&total_wire_fee));
   2764   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
   2765               "Deposit fee limit for merchant: %s\n",
   2766               TALER_amount2s (&pc->validate_tokens.max_fee));
   2767   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
   2768               "Total refunded amount: %s\n",
   2769               TALER_amount2s (&pc->pay_transaction.total_refunded));
   2770 
   2771   /* Now compare exchange wire fee compared to what we are willing to pay */
   2772   if (GNUNET_YES !=
   2773       TALER_amount_cmp_currency (&total_wire_fee,
   2774                                  &acc_fee))
   2775   {
   2776     GNUNET_break (0);
   2777     pay_end (pc,
   2778              TALER_MHD_reply_with_error (
   2779                pc->connection,
   2780                MHD_HTTP_BAD_REQUEST,
   2781                TALER_EC_GENERIC_CURRENCY_MISMATCH,
   2782                total_wire_fee.currency));
   2783     return false;
   2784   }
   2785 
   2786   /* add wire fee to the total fees */
   2787   if (0 >
   2788       TALER_amount_add (&acc_fee,
   2789                         &acc_fee,
   2790                         &total_wire_fee))
   2791   {
   2792     GNUNET_break (0);
   2793     pay_end (pc,
   2794              TALER_MHD_reply_with_error (
   2795                pc->connection,
   2796                MHD_HTTP_INTERNAL_SERVER_ERROR,
   2797                TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AMOUNT_OVERFLOW,
   2798                "Overflow adding up amounts"));
   2799     return false;
   2800   }
   2801   if (-1 == TALER_amount_cmp (&pc->validate_tokens.max_fee,
   2802                               &acc_fee))
   2803   {
   2804     /**
   2805      * Sum of fees of *all* the different exchanges of all the coins are
   2806      * higher than the fixed limit that the merchant is willing to pay.  The
   2807      * difference must be paid by the customer.
   2808      */
   2809     struct TALER_Amount excess_fee;
   2810 
   2811     /* compute fee amount to be covered by customer */
   2812     GNUNET_assert (TALER_AAR_RESULT_POSITIVE ==
   2813                    TALER_amount_subtract (&excess_fee,
   2814                                           &acc_fee,
   2815                                           &pc->validate_tokens.max_fee));
   2816     /* add that to the total */
   2817     if (0 >
   2818         TALER_amount_add (&total_needed,
   2819                           &excess_fee,
   2820                           &pc->validate_tokens.brutto))
   2821     {
   2822       GNUNET_break (0);
   2823       pay_end (pc,
   2824                TALER_MHD_reply_with_error (
   2825                  pc->connection,
   2826                  MHD_HTTP_INTERNAL_SERVER_ERROR,
   2827                  TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AMOUNT_OVERFLOW,
   2828                  "Overflow adding up amounts"));
   2829       return false;
   2830     }
   2831   }
   2832   else
   2833   {
   2834     /* Fees are fully covered by the merchant, all we require
   2835        is that the total payment is not below the contract's amount */
   2836     total_needed = pc->validate_tokens.brutto;
   2837   }
   2838 
   2839   /* Do not count refunds towards the payment */
   2840   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   2841               "Subtracting total refunds from paid amount: %s\n",
   2842               TALER_amount2s (&pc->pay_transaction.total_refunded));
   2843   if (0 >
   2844       TALER_amount_subtract (&final_amount,
   2845                              &acc_amount,
   2846                              &pc->pay_transaction.total_refunded))
   2847   {
   2848     GNUNET_break (0);
   2849     pay_end (pc,
   2850              TALER_MHD_reply_with_error (
   2851                pc->connection,
   2852                MHD_HTTP_INTERNAL_SERVER_ERROR,
   2853                TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_REFUNDS_EXCEED_PAYMENTS,
   2854                "refunded amount exceeds total payments"));
   2855     return false;
   2856   }
   2857 
   2858   if (-1 == TALER_amount_cmp (&final_amount,
   2859                               &total_needed))
   2860   {
   2861     /* acc_amount < total_needed */
   2862     if (-1 < TALER_amount_cmp (&acc_amount,
   2863                                &total_needed))
   2864     {
   2865       GNUNET_break_op (0);
   2866       pay_end (pc,
   2867                TALER_MHD_reply_with_error (
   2868                  pc->connection,
   2869                  MHD_HTTP_PAYMENT_REQUIRED,
   2870                  TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_REFUNDED,
   2871                  "contract not paid up due to refunds"));
   2872       return false;
   2873     }
   2874     if (-1 < TALER_amount_cmp (&acc_amount,
   2875                                &pc->validate_tokens.brutto))
   2876     {
   2877       GNUNET_break_op (0);
   2878       pay_end (pc,
   2879                TALER_MHD_reply_with_error (
   2880                  pc->connection,
   2881                  MHD_HTTP_BAD_REQUEST,
   2882                  TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_DUE_TO_FEES,
   2883                  "contract not paid up due to fees (client may have calculated them badly)"));
   2884       return false;
   2885     }
   2886     GNUNET_break_op (0);
   2887     pay_end (pc,
   2888              TALER_MHD_reply_with_error (
   2889                pc->connection,
   2890                MHD_HTTP_BAD_REQUEST,
   2891                TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_PAYMENT_INSUFFICIENT,
   2892                "payment insufficient"));
   2893     return false;
   2894   }
   2895   return true;
   2896 }
   2897 
   2898 
   2899 /**
   2900  * Execute the DB transaction.  If required (from
   2901  * soft/serialization errors), the transaction can be
   2902  * restarted here.
   2903  *
   2904  * @param[in,out] pc payment context to transact
   2905  */
   2906 static void
   2907 phase_execute_pay_transaction (struct PayContext *pc)
   2908 {
   2909   struct TMH_HandlerContext *hc = pc->hc;
   2910   const char *instance_id = hc->instance->settings.id;
   2911 
   2912   if (pc->batch_deposits.got_451)
   2913   {
   2914     pc->phase = PP_FAIL_LEGAL_REASONS;
   2915     return;
   2916   }
   2917   /* Avoid re-trying transactions on soft errors forever! */
   2918   if (pc->pay_transaction.retry_counter++ > MAX_RETRIES)
   2919   {
   2920     GNUNET_break (0);
   2921     pay_end (pc,
   2922              TALER_MHD_reply_with_error (pc->connection,
   2923                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
   2924                                          TALER_EC_GENERIC_DB_SOFT_FAILURE,
   2925                                          NULL));
   2926     return;
   2927   }
   2928 
   2929   /* Initialize some amount accumulators
   2930      (used in check_coin_paid(), check_coin_refunded()
   2931      and check_payment_sufficient()). */
   2932   GNUNET_break (GNUNET_OK ==
   2933                 TALER_amount_set_zero (pc->validate_tokens.brutto.currency,
   2934                                        &pc->pay_transaction.total_paid));
   2935   GNUNET_break (GNUNET_OK ==
   2936                 TALER_amount_set_zero (pc->validate_tokens.brutto.currency,
   2937                                        &pc->pay_transaction.total_fees_paid));
   2938   GNUNET_break (GNUNET_OK ==
   2939                 TALER_amount_set_zero (pc->validate_tokens.brutto.currency,
   2940                                        &pc->pay_transaction.total_refunded));
   2941   for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   2942     pc->parse_pay.dc[i].found_in_db = false;
   2943   pc->pay_transaction.pending = pc->parse_pay.coins_cnt;
   2944 
   2945   /* First, try to see if we have all we need already done */
   2946   TALER_MERCHANTDB_preflight (TMH_db);
   2947   if (GNUNET_OK !=
   2948       TALER_MERCHANTDB_start (TMH_db,
   2949                               "run pay"))
   2950   {
   2951     GNUNET_break (0);
   2952     pay_end (pc,
   2953              TALER_MHD_reply_with_error (pc->connection,
   2954                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
   2955                                          TALER_EC_GENERIC_DB_START_FAILED,
   2956                                          NULL));
   2957     return;
   2958   }
   2959 
   2960   for (size_t i = 0; i<pc->parse_pay.tokens_cnt; i++)
   2961   {
   2962     struct TokenUseConfirmation *tuc = &pc->parse_pay.tokens[i];
   2963     enum GNUNET_DB_QueryStatus qs;
   2964 
   2965     /* Insert used token into database, the unique constraint will
   2966        case an error if this token was used before. */
   2967     qs = TALER_MERCHANTDB_insert_spent_token (TMH_db,
   2968                                               &pc->check_contract.h_contract_terms,
   2969                                               &tuc->h_issue,
   2970                                               &tuc->pub,
   2971                                               &tuc->sig,
   2972                                               &tuc->unblinded_sig);
   2973 
   2974     switch (qs)
   2975     {
   2976     case GNUNET_DB_STATUS_SOFT_ERROR:
   2977       TALER_MERCHANTDB_rollback (TMH_db);
   2978       return; /* do it again */
   2979     case GNUNET_DB_STATUS_HARD_ERROR:
   2980       /* Always report on hard error as well to enable diagnostics */
   2981       TALER_MERCHANTDB_rollback (TMH_db);
   2982       pay_end (pc,
   2983                TALER_MHD_reply_with_error (pc->connection,
   2984                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
   2985                                            TALER_EC_GENERIC_DB_STORE_FAILED,
   2986                                            "insert used token"));
   2987       return;
   2988     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
   2989       /* UNIQUE constraint violation, meaning this token was already used. */
   2990       TALER_MERCHANTDB_rollback (TMH_db);
   2991       pay_end (pc,
   2992                TALER_MHD_reply_with_error (pc->connection,
   2993                                            MHD_HTTP_CONFLICT,
   2994                                            TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_INVALID,
   2995                                            NULL));
   2996       return;
   2997     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
   2998       /* Good, proceed! */
   2999       break;
   3000     }
   3001   } /* for all tokens */
   3002 
   3003   {
   3004     enum GNUNET_DB_QueryStatus qs;
   3005 
   3006     /* Check if some of these coins already succeeded for _this_ contract.  */
   3007     qs = TALER_MERCHANTDB_lookup_deposits (TMH_db,
   3008                                            instance_id,
   3009                                            &pc->check_contract.h_contract_terms,
   3010                                            &check_coin_paid,
   3011                                            pc);
   3012     if (0 > qs)
   3013     {
   3014       TALER_MERCHANTDB_rollback (TMH_db);
   3015       if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
   3016         return; /* do it again */
   3017       /* Always report on hard error as well to enable diagnostics */
   3018       GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
   3019       pay_end (pc,
   3020                TALER_MHD_reply_with_error (pc->connection,
   3021                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
   3022                                            TALER_EC_GENERIC_DB_FETCH_FAILED,
   3023                                            "lookup deposits"));
   3024       return;
   3025     }
   3026     if (pc->pay_transaction.deposit_currency_mismatch)
   3027     {
   3028       TALER_MERCHANTDB_rollback (TMH_db);
   3029       GNUNET_break_op (0);
   3030       pay_end (pc,
   3031                TALER_MHD_reply_with_error (
   3032                  pc->connection,
   3033                  MHD_HTTP_BAD_REQUEST,
   3034                  TALER_EC_MERCHANT_GENERIC_CURRENCY_MISMATCH,
   3035                  pc->validate_tokens.brutto.currency));
   3036       return;
   3037     }
   3038   }
   3039 
   3040   {
   3041     enum GNUNET_DB_QueryStatus qs;
   3042 
   3043     /* Check if we refunded some of the coins */
   3044     qs = TALER_MERCHANTDB_lookup_refunds (TMH_db,
   3045                                           instance_id,
   3046                                           &pc->check_contract.h_contract_terms,
   3047                                           &check_coin_refunded,
   3048                                           pc);
   3049     if (0 > qs)
   3050     {
   3051       TALER_MERCHANTDB_rollback (TMH_db);
   3052       if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
   3053         return; /* do it again */
   3054       /* Always report on hard error as well to enable diagnostics */
   3055       GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
   3056       pay_end (pc,
   3057                TALER_MHD_reply_with_error (pc->connection,
   3058                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
   3059                                            TALER_EC_GENERIC_DB_FETCH_FAILED,
   3060                                            "lookup refunds"));
   3061       return;
   3062     }
   3063     if (pc->pay_transaction.refund_currency_mismatch)
   3064     {
   3065       TALER_MERCHANTDB_rollback (TMH_db);
   3066       pay_end (pc,
   3067                TALER_MHD_reply_with_error (pc->connection,
   3068                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
   3069                                            TALER_EC_GENERIC_DB_FETCH_FAILED,
   3070                                            "refund currency in database does not match order currency"));
   3071       return;
   3072     }
   3073   }
   3074 
   3075   /* Check if there are coins that still need to be processed */
   3076   if (0 != pc->pay_transaction.pending)
   3077   {
   3078     /* we made no DB changes, so we can just rollback */
   3079     TALER_MERCHANTDB_rollback (TMH_db);
   3080     /* Ok, we need to first go to the network to process more coins.
   3081        We that interaction in *tiny* transactions (hence the rollback
   3082        above). */
   3083     pc->phase = PP_BATCH_DEPOSITS;
   3084     return;
   3085   }
   3086 
   3087   /* 0 == pc->pay_transaction.pending: all coins processed, let's see if that was enough */
   3088   if (! check_payment_sufficient (pc))
   3089   {
   3090     /* check_payment_sufficient() will have queued an error already.
   3091        We need to still abort the transaction. */
   3092     TALER_MERCHANTDB_rollback (TMH_db);
   3093     return;
   3094   }
   3095   /* Payment succeeded, save in database */
   3096   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   3097               "Order `%s' (%s) was fully paid\n",
   3098               pc->order_id,
   3099               GNUNET_h2s (&pc->check_contract.h_contract_terms.hash));
   3100   {
   3101     enum GNUNET_DB_QueryStatus qs;
   3102 
   3103     qs = TALER_MERCHANTDB_mark_contract_paid (TMH_db,
   3104                                               instance_id,
   3105                                               &pc->check_contract.h_contract_terms,
   3106                                               pc->parse_pay.session_id,
   3107                                               pc->parse_wallet_data.choice_index);
   3108     if (qs < 0)
   3109     {
   3110       TALER_MERCHANTDB_rollback (TMH_db);
   3111       if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
   3112         return; /* do it again */
   3113       GNUNET_break (0);
   3114       pay_end (pc,
   3115                TALER_MHD_reply_with_error (pc->connection,
   3116                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
   3117                                            TALER_EC_GENERIC_DB_STORE_FAILED,
   3118                                            "mark contract paid"));
   3119       return;
   3120     }
   3121     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   3122                 "Marked contract paid returned %d\n",
   3123                 (int) qs);
   3124 
   3125     if ( (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) &&
   3126          (0 < pc->compute_money_pots.num_pots) )
   3127     {
   3128       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   3129                   "Incrementing %u money pots by %s\n",
   3130                   pc->compute_money_pots.num_pots,
   3131                   TALER_amount2s (&pc->compute_money_pots.increments[0]));
   3132       qs = TALER_MERCHANTDB_increment_money_pots (
   3133         TMH_db,
   3134         instance_id,
   3135         pc->compute_money_pots.num_pots,
   3136         pc->compute_money_pots.pots,
   3137         pc->compute_money_pots.increments);
   3138       switch (qs)
   3139       {
   3140       case GNUNET_DB_STATUS_SOFT_ERROR:
   3141         TALER_MERCHANTDB_rollback (TMH_db);
   3142         return; /* do it again */
   3143       case GNUNET_DB_STATUS_HARD_ERROR:
   3144         /* Always report on hard error as well to enable diagnostics */
   3145         TALER_MERCHANTDB_rollback (TMH_db);
   3146         pay_end (pc,
   3147                  TALER_MHD_reply_with_error (
   3148                    pc->connection,
   3149                    MHD_HTTP_INTERNAL_SERVER_ERROR,
   3150                    TALER_EC_GENERIC_DB_STORE_FAILED,
   3151                    "increment_money_pots"));
   3152         return;
   3153       case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
   3154         /* strange */
   3155         GNUNET_break (0);
   3156         break;
   3157       case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
   3158         /* Good, proceed! */
   3159         break;
   3160       }
   3161     }
   3162   }
   3163 
   3164   {
   3165     const struct TALER_MERCHANT_ContractChoice *choice =
   3166       &pc->check_contract.contract_terms->pc->details.v1
   3167       .choices[pc->parse_wallet_data.choice_index];
   3168 
   3169     for (size_t i = 0; i<pc->output_tokens_len; i++)
   3170     {
   3171       unsigned int output_index;
   3172       enum TALER_MERCHANT_ContractOutputType type;
   3173 
   3174       output_index = pc->output_tokens[i].output_index;
   3175       GNUNET_assert (output_index < choice->outputs_len);
   3176       type = choice->outputs[output_index].type;
   3177       switch (type)
   3178       {
   3179       case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_INVALID:
   3180         /* Well, good luck getting here */
   3181         GNUNET_break (0);
   3182         pay_end (pc,
   3183                  TALER_MHD_reply_with_error (pc->connection,
   3184                                              MHD_HTTP_INTERNAL_SERVER_ERROR,
   3185                                              TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
   3186                                              "invalid output type"));
   3187         break;
   3188       case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_DONATION_RECEIPT:
   3189         /* We skip output tokens of donation receipts here, as they are handled in the
   3190          * phase_final_output_token_processing() callback from donau */
   3191         break;
   3192       case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN:
   3193         struct SignedOutputToken *output =
   3194           &pc->output_tokens[i];
   3195         enum GNUNET_DB_QueryStatus qs;
   3196 
   3197         if (NULL == output->sig.signature)
   3198           continue; /* must have been optional and not provided by wallet */
   3199         qs = TALER_MERCHANTDB_insert_issued_token (
   3200           TMH_db,
   3201           &pc->check_contract.h_contract_terms,
   3202           &output->h_issue,
   3203           &output->sig);
   3204         switch (qs)
   3205         {
   3206         case GNUNET_DB_STATUS_HARD_ERROR:
   3207           TALER_MERCHANTDB_rollback (TMH_db);
   3208           GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
   3209           pay_end (pc,
   3210                    TALER_MHD_reply_with_error (
   3211                      pc->connection,
   3212                      MHD_HTTP_INTERNAL_SERVER_ERROR,
   3213                      TALER_EC_GENERIC_DB_STORE_FAILED,
   3214                      "insert output token"));
   3215           return;
   3216         case GNUNET_DB_STATUS_SOFT_ERROR:
   3217           /* Serialization failure, retry */
   3218           TALER_MERCHANTDB_rollback (TMH_db);
   3219           return;
   3220         case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
   3221           /* UNIQUE constraint violation, meaning this token was already used. */
   3222           TALER_MERCHANTDB_rollback (TMH_db);
   3223           pay_end (pc,
   3224                    TALER_MHD_reply_with_error (
   3225                      pc->connection,
   3226                      MHD_HTTP_INTERNAL_SERVER_ERROR,
   3227                      TALER_EC_GENERIC_DB_STORE_FAILED,
   3228                      "duplicate output token"));
   3229           return;
   3230         case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
   3231           break;
   3232         }
   3233         break;
   3234       }
   3235     }
   3236   }
   3237 
   3238   TMH_notify_order_change (
   3239     hc->instance,
   3240     TMH_OSF_CLAIMED | TMH_OSF_PAID,
   3241     pc->check_contract.contract_terms->pc->timestamp,
   3242     pc->check_contract.order_serial);
   3243   {
   3244     enum GNUNET_DB_QueryStatus qs;
   3245     json_t *jhook;
   3246 
   3247     jhook = GNUNET_JSON_PACK (
   3248       GNUNET_JSON_pack_object_incref ("contract_terms",
   3249                                       pc->check_contract.contract_terms_json),
   3250       GNUNET_JSON_pack_string ("order_id",
   3251                                pc->order_id)
   3252       );
   3253     GNUNET_assert (NULL != jhook);
   3254     qs = TMH_trigger_webhook (pc->hc->instance->settings.id,
   3255                               "pay",
   3256                               jhook);
   3257     json_decref (jhook);
   3258     if (qs < 0)
   3259     {
   3260       TALER_MERCHANTDB_rollback (TMH_db);
   3261       if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
   3262         return; /* do it again */
   3263       GNUNET_break (0);
   3264       pay_end (pc,
   3265                TALER_MHD_reply_with_error (pc->connection,
   3266                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
   3267                                            TALER_EC_GENERIC_DB_STORE_FAILED,
   3268                                            "failed to trigger webhooks"));
   3269       return;
   3270     }
   3271   }
   3272   {
   3273     enum GNUNET_DB_QueryStatus qs;
   3274 
   3275     /* Now commit! */
   3276     qs = TALER_MERCHANTDB_commit (TMH_db);
   3277     if (0 > qs)
   3278     {
   3279       /* commit failed */
   3280       TALER_MERCHANTDB_rollback (TMH_db);
   3281       if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
   3282         return; /* do it again */
   3283       GNUNET_break (0);
   3284       pay_end (pc,
   3285                TALER_MHD_reply_with_error (pc->connection,
   3286                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
   3287                                            TALER_EC_GENERIC_DB_COMMIT_FAILED,
   3288                                            NULL));
   3289       return;
   3290     }
   3291   }
   3292   pc->phase++;
   3293 }
   3294 
   3295 
   3296 /**
   3297  * Ensures that the expected number of tokens for a @e key
   3298  * are provided as inputs and have valid signatures.
   3299  *
   3300  * @param[in,out] pc payment context we are processing
   3301  * @param family family the tokens should be from
   3302  * @param index offset into parse_pay.tokens where the
   3303  *          input tokens for @a family should start
   3304  * @param expected_num number of tokens expected
   3305  * @return #GNUNET_YES on success
   3306  */
   3307 static enum GNUNET_GenericReturnValue
   3308 find_valid_input_tokens (
   3309   struct PayContext *pc,
   3310   const struct TALER_MERCHANT_ContractTokenFamily *family,
   3311   unsigned int index,
   3312   unsigned int expected_num)
   3313 {
   3314   unsigned int num_validated = 0;
   3315   struct GNUNET_TIME_Timestamp now
   3316     = GNUNET_TIME_timestamp_get ();
   3317   const struct TALER_MERCHANT_ContractTokenFamilyKey *kig = NULL;
   3318 
   3319   for (unsigned int j = 0; j < expected_num; j++)
   3320   {
   3321     struct TokenUseConfirmation *tuc;
   3322     const struct TALER_MERCHANT_ContractTokenFamilyKey *key = NULL;
   3323 
   3324     if (index + j >= pc->parse_pay.tokens_cnt)
   3325     {
   3326       /* There are not a sufficient number of input tokens left
   3327          to satisfy the request. Game over. */
   3328       GNUNET_break_op (0);
   3329       pay_end (pc,
   3330                TALER_MHD_reply_with_error (
   3331                  pc->connection,
   3332                  MHD_HTTP_BAD_REQUEST,
   3333                  TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_COUNT_MISMATCH,
   3334                  NULL));
   3335       return GNUNET_NO;
   3336     }
   3337     tuc = &pc->parse_pay.tokens[index + j];
   3338 
   3339     for (unsigned int i = 0; i<family->keys_len; i++)
   3340     {
   3341       const struct TALER_MERCHANT_ContractTokenFamilyKey *ki
   3342         = &family->keys[i];
   3343 
   3344       if (0 ==
   3345           GNUNET_memcmp (&ki->pub.public_key->pub_key_hash,
   3346                          &tuc->h_issue.hash))
   3347       {
   3348         if (GNUNET_TIME_timestamp_cmp (ki->valid_after,
   3349                                        >,
   3350                                        now) ||
   3351             GNUNET_TIME_timestamp_cmp (ki->valid_before,
   3352                                        <=,
   3353                                        now))
   3354         {
   3355           /* We have a match, but not in the current validity period */
   3356           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   3357                       "Public key %s currently not valid\n",
   3358                       GNUNET_h2s (&ki->pub.public_key->pub_key_hash));
   3359           kig = ki;
   3360           continue;
   3361         }
   3362         key = ki;
   3363         break;
   3364       }
   3365     }
   3366     if (NULL == key)
   3367     {
   3368       if (NULL != kig)
   3369       {
   3370         char start_str[128];
   3371         char end_str[128];
   3372         char emsg[350];
   3373 
   3374         GNUNET_snprintf (start_str,
   3375                          sizeof (start_str),
   3376                          "%s",
   3377                          GNUNET_STRINGS_timestamp_to_string (kig->valid_after));
   3378         GNUNET_snprintf (end_str,
   3379                          sizeof (end_str),
   3380                          "%s",
   3381                          GNUNET_STRINGS_timestamp_to_string (kig->valid_before));
   3382         /* FIXME: use more specific EC */
   3383         GNUNET_snprintf (emsg,
   3384                          sizeof (emsg),
   3385                          "Token is only valid from %s to %s",
   3386                          start_str,
   3387                          end_str);
   3388         pay_end (pc,
   3389                  TALER_MHD_reply_with_error (
   3390                    pc->connection,
   3391                    MHD_HTTP_GONE,
   3392                    TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_OFFER_EXPIRED,
   3393                    emsg));
   3394         return GNUNET_NO;
   3395       }
   3396       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   3397                   "Input token supplied for public key %s that is not acceptable\n",
   3398                   GNUNET_h2s (&tuc->h_issue.hash));
   3399       GNUNET_break_op (0);
   3400       pay_end (pc,
   3401                TALER_MHD_reply_with_error (
   3402                  pc->connection,
   3403                  MHD_HTTP_BAD_REQUEST,
   3404                  TALER_EC_MERCHANT_GENERIC_TOKEN_KEY_UNKNOWN,
   3405                  NULL));
   3406       return GNUNET_NO;
   3407     }
   3408     if (GNUNET_OK !=
   3409         TALER_token_issue_verify (&tuc->pub,
   3410                                   &key->pub,
   3411                                   &tuc->unblinded_sig))
   3412     {
   3413       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   3414                   "Input token for public key with valid_after "
   3415                   "`%s' has invalid issue signature\n",
   3416                   GNUNET_TIME_timestamp2s (key->valid_after));
   3417       GNUNET_break (0);
   3418       pay_end (pc,
   3419                TALER_MHD_reply_with_error (
   3420                  pc->connection,
   3421                  MHD_HTTP_BAD_REQUEST,
   3422                  TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_ISSUE_SIG_INVALID,
   3423                  NULL));
   3424       return GNUNET_NO;
   3425     }
   3426 
   3427     if (GNUNET_OK !=
   3428         TALER_wallet_token_use_verify (&pc->check_contract.h_contract_terms,
   3429                                        &pc->parse_wallet_data.h_wallet_data,
   3430                                        &tuc->pub,
   3431                                        &tuc->sig))
   3432     {
   3433       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   3434                   "Input token for public key with valid_before "
   3435                   "`%s' has invalid use signature\n",
   3436                   GNUNET_TIME_timestamp2s (key->valid_before));
   3437       GNUNET_break (0);
   3438       pay_end (pc,
   3439                TALER_MHD_reply_with_error (
   3440                  pc->connection,
   3441                  MHD_HTTP_BAD_REQUEST,
   3442                  TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_USE_SIG_INVALID,
   3443                  NULL));
   3444       return GNUNET_NO;
   3445     }
   3446     num_validated++;
   3447   }
   3448   GNUNET_assert (num_validated == expected_num);
   3449   return GNUNET_YES;
   3450 }
   3451 
   3452 
   3453 /**
   3454  * Check if an output token of the given @a tfk is mandatory, or if
   3455  * wallets are allowed to simply not support it and still proceed.
   3456  *
   3457  * @param tfk token family kind to check
   3458  * @return true if such outputs are mandatory and wallets must supply
   3459  *  the corresponding blinded input
   3460  */
   3461 /* FIXME: this function belongs into a lower-level lib! */
   3462 static bool
   3463 test_tfk_mandatory (enum TALER_MERCHANTDB_TokenFamilyKind tfk)
   3464 {
   3465   switch (tfk)
   3466   {
   3467   case TALER_MERCHANTDB_TFK_Discount:
   3468     return false;
   3469   case TALER_MERCHANTDB_TFK_Subscription:
   3470     return true;
   3471   }
   3472   GNUNET_break (0);
   3473   return false;
   3474 }
   3475 
   3476 
   3477 /**
   3478  * Sign the tokens provided by the wallet for a particular @a key.
   3479  *
   3480  * @param[in,out] pc reference for payment we are processing
   3481  * @param key token family data
   3482  * @param priv private key to use to sign with
   3483  * @param mandatory true if the token must exist, if false
   3484  *        and the client did not provide an envelope, that's OK and
   3485  *        we just also skimp on the signature
   3486  * @param wallet_index starting offset in the token envelopes array
   3487  * @param output_index starting offset into the output_tokens array
   3488  * @param expected_num number of tokens of this type that we should create
   3489  * @return #GNUNET_NO on failure
   3490  *         #GNUNET_OK on success
   3491  */
   3492 static enum GNUNET_GenericReturnValue
   3493 sign_token_envelopes (
   3494   struct PayContext *pc,
   3495   const struct TALER_MERCHANT_ContractTokenFamilyKey *key,
   3496   const struct TALER_TokenIssuePrivateKey *priv,
   3497   bool mandatory,
   3498   unsigned int wallet_index,
   3499   unsigned int output_index,
   3500   unsigned int expected_num)
   3501 {
   3502   unsigned int num_signed = 0;
   3503 
   3504   for (unsigned int j = 0; j<expected_num; j++)
   3505   {
   3506     unsigned int wallet_pos = wallet_index + j;
   3507     unsigned int output_pos = output_index + j;
   3508     const struct TokenEnvelope *env
   3509       = &pc->parse_wallet_data.token_envelopes[wallet_pos];
   3510     struct SignedOutputToken *output
   3511       = &pc->output_tokens[output_pos];
   3512 
   3513     if (wallet_pos >= pc->parse_wallet_data.token_envelopes_cnt)
   3514     {
   3515       if (! mandatory)
   3516         return GNUNET_OK; /* wallet input too short, we can live with it */
   3517 
   3518       /* mandatory token families require a token envelope, and
   3519          the wallet did not provide enough of them */
   3520       GNUNET_break_op (0);
   3521       pay_end (pc,
   3522                TALER_MHD_reply_with_error (
   3523                  pc->connection,
   3524                  MHD_HTTP_BAD_REQUEST,
   3525                  TALER_EC_GENERIC_PARAMETER_MALFORMED,
   3526                  "Token envelope for mandatory token family missing"));
   3527       return GNUNET_NO;
   3528     }
   3529     if (output_pos >= pc->output_tokens_len)
   3530     {
   3531       GNUNET_assert (0); /* this should not happen, we *computed*
   3532                             output_tokens_len to be big enough! */
   3533       return GNUNET_NO;
   3534     }
   3535     if (NULL == env->blinded_token.blinded_pub)
   3536     {
   3537       if (! mandatory)
   3538         continue;
   3539 
   3540       /* mandatory token families require a token envelope. */
   3541       GNUNET_break_op (0);
   3542       pay_end (pc,
   3543                TALER_MHD_reply_with_error (
   3544                  pc->connection,
   3545                  MHD_HTTP_BAD_REQUEST,
   3546                  TALER_EC_GENERIC_PARAMETER_MALFORMED,
   3547                  "Token envelope for mandatory token family missing"));
   3548       return GNUNET_NO;
   3549     }
   3550     TALER_token_issue_sign (priv,
   3551                             &env->blinded_token,
   3552                             &output->sig);
   3553     output->h_issue.hash
   3554       = key->pub.public_key->pub_key_hash;
   3555     num_signed++;
   3556   }
   3557 
   3558   if (mandatory &&
   3559       (num_signed != expected_num) )
   3560   {
   3561     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   3562                 "Expected %d token envelopes for public key with valid_after "
   3563                 "'%s', but found %d\n",
   3564                 expected_num,
   3565                 GNUNET_TIME_timestamp2s (key->valid_after),
   3566                 num_signed);
   3567     GNUNET_break (0);
   3568     pay_end (pc,
   3569              TALER_MHD_reply_with_error (
   3570                pc->connection,
   3571                MHD_HTTP_BAD_REQUEST,
   3572                TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_TOKEN_ENVELOPE_COUNT_MISMATCH,
   3573                NULL));
   3574     return GNUNET_NO;
   3575   }
   3576 
   3577   return GNUNET_OK;
   3578 }
   3579 
   3580 
   3581 /**
   3582  * Find the family entry for the family of the given @a slug
   3583  * in @a pc.
   3584  *
   3585  * @param[in] pc payment context to search
   3586  * @param slug slug to search for
   3587  * @return NULL if @a slug was not found
   3588  */
   3589 static const struct TALER_MERCHANT_ContractTokenFamily *
   3590 find_family (const struct PayContext *pc,
   3591              const char *slug)
   3592 {
   3593   for (unsigned int i = 0;
   3594        i < pc->check_contract.contract_terms->pc->details.v1.token_authorities_len;
   3595        i++)
   3596   {
   3597     const struct TALER_MERCHANT_ContractTokenFamily *tfi
   3598       = &pc->check_contract.contract_terms->pc->details.v1.token_authorities[i];
   3599 
   3600     if (0 == strcmp (tfi->slug,
   3601                      slug))
   3602     {
   3603       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   3604                   "Token family %s found with %u keys\n",
   3605                   slug,
   3606                   tfi->keys_len);
   3607       return tfi;
   3608     }
   3609   }
   3610   return NULL;
   3611 }
   3612 
   3613 
   3614 /**
   3615  * Handle contract output of type TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN.
   3616  * Looks up the token family, loads the matching private key,
   3617  * and signs the corresponding token envelopes from the wallet.
   3618  *
   3619  * @param[in,out] pc context for the pay request
   3620  * @param wallet_index start index of this output in the
   3621  *     ``parse_wallet_data.token_envelopes`` array
   3622  * @param output contract output we need to process
   3623  * @param output_index start index of this output in the
   3624  *     ``output_tokens`` array of @a pc
   3625  * @return #GNUNET_OK on success, #GNUNET_NO if an error was encountered
   3626  */
   3627 static enum GNUNET_GenericReturnValue
   3628 handle_output_token (struct PayContext *pc,
   3629                      unsigned int wallet_index,
   3630                      const struct TALER_MERCHANT_ContractOutput *output,
   3631                      unsigned int output_index)
   3632 {
   3633   const struct TALER_MERCHANT_ContractTokenFamily *family;
   3634   struct TALER_MERCHANT_ContractTokenFamilyKey *key;
   3635   struct TALER_MERCHANTDB_TokenFamilyKeyDetails details;
   3636   enum GNUNET_DB_QueryStatus qs;
   3637   bool mandatory;
   3638 
   3639   /* Locate token family in the contract.
   3640      This should ever fail as this invariant should
   3641      have been checked when the contract was created. */
   3642   family = find_family (pc,
   3643                         output->details.token.token_family_slug);
   3644   if (NULL == family)
   3645   {
   3646     /* This "should never happen", so treat it as an internal error */
   3647     GNUNET_break (0);
   3648     pay_end (pc,
   3649              TALER_MHD_reply_with_error (
   3650                pc->connection,
   3651                MHD_HTTP_INTERNAL_SERVER_ERROR,
   3652                TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
   3653                "token family not found in order"));
   3654     return GNUNET_SYSERR;
   3655   }
   3656 
   3657   /* Check the key_index field from the output. */
   3658   if (output->details.token.key_index >= family->keys_len)
   3659   {
   3660     /* Also "should never happen", contract was presumably validated on insert */
   3661     GNUNET_break (0);
   3662     pay_end (pc,
   3663              TALER_MHD_reply_with_error (
   3664                pc->connection,
   3665                MHD_HTTP_INTERNAL_SERVER_ERROR,
   3666                TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
   3667                "key index invalid for token family"));
   3668     return GNUNET_SYSERR;
   3669   }
   3670 
   3671   /* Pick the correct key inside that family. */
   3672   key = &family->keys[output->details.token.key_index];
   3673 
   3674   /* Fetch the private key from the DB for the merchant instance and
   3675    * this particular family/time interval. */
   3676   qs = TALER_MERCHANTDB_lookup_token_family_key (
   3677     TMH_db,
   3678     pc->hc->instance->settings.id,
   3679     family->slug,
   3680     pc->check_contract.contract_terms->pc->timestamp,
   3681     pc->check_contract.contract_terms->pc->pay_deadline,
   3682     &details);
   3683   switch (qs)
   3684   {
   3685   case GNUNET_DB_STATUS_HARD_ERROR:
   3686   case GNUNET_DB_STATUS_SOFT_ERROR:
   3687     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
   3688                 "Database error looking up token-family key for %s\n",
   3689                 family->slug);
   3690     GNUNET_break (0);
   3691     pay_end (pc,
   3692              TALER_MHD_reply_with_error (
   3693                pc->connection,
   3694                MHD_HTTP_INTERNAL_SERVER_ERROR,
   3695                TALER_EC_GENERIC_DB_FETCH_FAILED,
   3696                NULL));
   3697     return GNUNET_NO;
   3698   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
   3699     GNUNET_log (
   3700       GNUNET_ERROR_TYPE_ERROR,
   3701       "Token-family key for %s not found at [%llu,%llu]\n",
   3702       family->slug,
   3703       (unsigned long long)
   3704       pc->check_contract.contract_terms->pc->timestamp.abs_time.abs_value_us,
   3705       (unsigned long long)
   3706       pc->check_contract.contract_terms->pc->pay_deadline.abs_time.abs_value_us
   3707       );
   3708     GNUNET_break (0);
   3709     pay_end (pc,
   3710              TALER_MHD_reply_with_error (
   3711                pc->connection,
   3712                MHD_HTTP_NOT_FOUND,
   3713                TALER_EC_MERCHANT_GENERIC_TOKEN_KEY_UNKNOWN,
   3714                family->slug));
   3715     return GNUNET_NO;
   3716 
   3717   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
   3718     break;
   3719   }
   3720   GNUNET_free (details.token_family.slug);
   3721   GNUNET_free (details.token_family.name);
   3722   GNUNET_free (details.token_family.description);
   3723   json_decref (details.token_family.description_i18n);
   3724   if (NULL != details.pub.public_key)
   3725     GNUNET_CRYPTO_blind_sign_pub_decref (details.pub.public_key);
   3726   GNUNET_free (details.token_family.cipher_spec);
   3727   if (NULL == details.priv.private_key)
   3728   {
   3729     /* The key SHOULD have been created when we
   3730        created the order (after all, the client was able
   3731        to blind, and that requires us having had a public
   3732        key). So how did we loose it? Bad bug, this should
   3733        not be possible. */
   3734     GNUNET_break (0);
   3735     pay_end (pc,
   3736              TALER_MHD_reply_with_error (
   3737                pc->connection,
   3738                MHD_HTTP_INTERNAL_SERVER_ERROR,
   3739                TALER_EC_GENERIC_DB_INVARIANT_FAILURE,
   3740                "private token family key not found"));
   3741     return GNUNET_NO;
   3742 
   3743   }
   3744 
   3745   /* Depending on the token family, decide if the token envelope
   3746    * is mandatory or optional.  (Simplified logic here: adapt as needed.) */
   3747   mandatory = test_tfk_mandatory (details.token_family.kind);
   3748   /* Actually sign the number of token envelopes specified in 'count'.
   3749    * 'output_index' is the offset into the output_tokens while
   3750    * 'wallet_index' is the offset into parse_wallet_data.token_envelopes */
   3751   if (GNUNET_OK !=
   3752       sign_token_envelopes (pc,
   3753                             key,
   3754                             &details.priv,
   3755                             mandatory,
   3756                             wallet_index,
   3757                             output_index,
   3758                             output->details.token.count))
   3759   {
   3760     /* sign_token_envelopes() already queued up an error via pay_end() */
   3761     GNUNET_break_op (0);
   3762     return GNUNET_NO;
   3763   }
   3764   GNUNET_CRYPTO_blind_sign_priv_decref (details.priv.private_key);
   3765   return GNUNET_OK;
   3766 }
   3767 
   3768 
   3769 /**
   3770  * Handle checks for contract output of type
   3771  * #TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_DONATION_RECEIPT.
   3772  *
   3773  * @param pc context for the pay request
   3774  * @param output the contract output describing the donation receipt requirement
   3775  * @return #GNUNET_OK on success,
   3776  *         #GNUNET_NO if an error was already queued
   3777  */
   3778 static enum GNUNET_GenericReturnValue
   3779 handle_output_donation_receipt (
   3780   struct PayContext *pc,
   3781   const struct TALER_MERCHANT_ContractOutput *output)
   3782 {
   3783   enum GNUNET_GenericReturnValue ret;
   3784 
   3785   ret = DONAU_get_donation_amount_from_bkps (
   3786     pc->parse_wallet_data.donau_keys,
   3787     pc->parse_wallet_data.bkps,
   3788     pc->parse_wallet_data.num_bkps,
   3789     pc->parse_wallet_data.donau.donation_year,
   3790     &pc->parse_wallet_data.donation_amount);
   3791   switch (ret)
   3792   {
   3793   case GNUNET_SYSERR:
   3794     GNUNET_break (0);
   3795     pay_end (pc,
   3796              TALER_MHD_reply_with_error (
   3797                pc->connection,
   3798                MHD_HTTP_INTERNAL_SERVER_ERROR,
   3799                TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
   3800                NULL));
   3801     return GNUNET_NO;
   3802   case GNUNET_NO:
   3803     GNUNET_break_op (0);
   3804     pay_end (pc,
   3805              TALER_MHD_reply_with_error (
   3806                pc->connection,
   3807                MHD_HTTP_BAD_REQUEST,
   3808                TALER_EC_GENERIC_PARAMETER_MALFORMED,
   3809                "inconsistent bkps / donau keys"));
   3810     return GNUNET_NO;
   3811   case GNUNET_OK:
   3812     break;
   3813   }
   3814 
   3815   if (GNUNET_OK !=
   3816       TALER_amount_cmp_currency (&pc->parse_wallet_data.donation_amount,
   3817                                  &output->details.donation_receipt.amount))
   3818   {
   3819     GNUNET_break_op (0);
   3820     pay_end (pc,
   3821              TALER_MHD_reply_with_error (
   3822                pc->connection,
   3823                MHD_HTTP_BAD_REQUEST,
   3824                TALER_EC_GENERIC_CURRENCY_MISMATCH,
   3825                output->details.donation_receipt.amount.currency));
   3826     return GNUNET_NO;
   3827   }
   3828 
   3829   if (0 !=
   3830       TALER_amount_cmp (&pc->parse_wallet_data.donation_amount,
   3831                         &output->details.donation_receipt.amount))
   3832   {
   3833     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
   3834                 "Wallet amount: %s\n",
   3835                 TALER_amount2s (&pc->parse_wallet_data.donation_amount));
   3836     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
   3837                 "Donation receipt amount: %s\n",
   3838                 TALER_amount2s (&output->details.donation_receipt.amount));
   3839     GNUNET_break_op (0);
   3840     pay_end (pc,
   3841              TALER_MHD_reply_with_error (
   3842                pc->connection,
   3843                MHD_HTTP_CONFLICT,
   3844                TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_DONATION_AMOUNT_MISMATCH,
   3845                "donation amount mismatch"));
   3846     return GNUNET_NO;
   3847   }
   3848   {
   3849     struct TALER_Amount receipts_to_date;
   3850 
   3851     if (0 >
   3852         TALER_amount_add (&receipts_to_date,
   3853                           &pc->parse_wallet_data.charity_receipts_to_date,
   3854                           &pc->parse_wallet_data.donation_amount))
   3855     {
   3856       GNUNET_break (0);
   3857       pay_end (pc,
   3858                TALER_MHD_reply_with_error (pc->connection,
   3859                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
   3860                                            TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AMOUNT_OVERFLOW,
   3861                                            "adding donation amount"));
   3862       return GNUNET_NO;
   3863     }
   3864 
   3865     if (1 ==
   3866         TALER_amount_cmp (&receipts_to_date,
   3867                           &pc->parse_wallet_data.charity_max_per_year))
   3868     {
   3869       GNUNET_break_op (0);
   3870       pay_end (pc,
   3871                TALER_MHD_reply_with_error (pc->connection,
   3872                                            MHD_HTTP_CONFLICT,
   3873                                            TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_DONATION_AMOUNT_MISMATCH,
   3874                                            "donation limit exceeded"));
   3875       return GNUNET_NO;
   3876     }
   3877     pc->parse_wallet_data.charity_receipts_to_date = receipts_to_date;
   3878   }
   3879   return GNUNET_OK;
   3880 }
   3881 
   3882 
   3883 /**
   3884  * Count tokens produced by an output.
   3885  *
   3886  * @param pc pay context
   3887  * @param output output to consider
   3888  * @returns number of output tokens
   3889  */
   3890 static unsigned int
   3891 count_output_tokens (const struct PayContext *pc,
   3892                      const struct TALER_MERCHANT_ContractOutput *output)
   3893 {
   3894   switch (output->type)
   3895   {
   3896   case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_INVALID:
   3897     GNUNET_assert (0);
   3898     break;
   3899   case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN:
   3900     return output->details.token.count;
   3901   case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_DONATION_RECEIPT:
   3902     return pc->parse_wallet_data.num_bkps;
   3903   }
   3904   /* Not reached. */
   3905   GNUNET_assert (0);
   3906 }
   3907 
   3908 
   3909 /**
   3910  * Validate tokens and token envelopes. First, we check if all tokens listed
   3911  * in the 'inputs' array of the selected choice are present in the 'tokens'
   3912  * array of the request. Then, we validate the signatures of each provided
   3913  * token.
   3914  *
   3915  * @param[in,out] pc context we use to handle the payment
   3916  */
   3917 static void
   3918 phase_validate_tokens (struct PayContext *pc)
   3919 {
   3920   /* We haven't seen a donau output yet. */
   3921   pc->validate_tokens.donau_output_index = -1;
   3922 
   3923   switch (pc->check_contract.contract_terms->pc->base->version)
   3924   {
   3925   case TALER_MERCHANT_CONTRACT_VERSION_0:
   3926     /* No tokens to validate */
   3927     pc->phase = PP_COMPUTE_MONEY_POTS;
   3928     pc->validate_tokens.max_fee
   3929       = pc->check_contract.contract_terms->pc->details.v0.max_fee;
   3930     pc->validate_tokens.brutto
   3931       = pc->check_contract.contract_terms->pc->details.v0.brutto;
   3932     break;
   3933   case TALER_MERCHANT_CONTRACT_VERSION_1:
   3934     {
   3935       const struct TALER_MERCHANT_ContractChoice *selected
   3936         = &pc->check_contract.contract_terms->pc->details.v1.choices[
   3937             pc->parse_wallet_data.choice_index];
   3938       unsigned int output_off;
   3939       unsigned int wallet_off;
   3940       unsigned int cnt;
   3941 
   3942       pc->validate_tokens.max_fee = selected->max_fee;
   3943       pc->validate_tokens.brutto = selected->amount;
   3944       wallet_off = 0;
   3945       for (unsigned int i = 0; i<selected->inputs_len; i++)
   3946       {
   3947         const struct TALER_MERCHANT_ContractInput *input
   3948           = &selected->inputs[i];
   3949         const struct TALER_MERCHANT_ContractTokenFamily *family;
   3950 
   3951         switch (input->type)
   3952         {
   3953         case TALER_MERCHANT_CONTRACT_INPUT_TYPE_INVALID:
   3954           GNUNET_break (0);
   3955           pay_end (pc,
   3956                    TALER_MHD_reply_with_error (
   3957                      pc->connection,
   3958                      MHD_HTTP_BAD_REQUEST,
   3959                      TALER_EC_GENERIC_PARAMETER_MALFORMED,
   3960                      "input token type not valid"));
   3961           return;
   3962 #if FUTURE
   3963         case TALER_MERCHANT_CONTRACT_INPUT_TYPE_COIN:
   3964           GNUNET_break (0);
   3965           pay_end (pc,
   3966                    TALER_MHD_reply_with_error (
   3967                      pc->connection,
   3968                      MHD_HTTP_NOT_IMPLEMENTED,
   3969                      TALER_EC_MERCHANT_GENERIC_FEATURE_NOT_AVAILABLE,
   3970                      "token type not yet supported"));
   3971           return;
   3972 #endif
   3973         case TALER_MERCHANT_CONTRACT_INPUT_TYPE_TOKEN:
   3974           family = find_family (pc,
   3975                                 input->details.token.token_family_slug);
   3976           if (NULL == family)
   3977           {
   3978             /* this should never happen, since the choices and
   3979                token families are validated on insert. */
   3980             GNUNET_break (0);
   3981             pay_end (pc,
   3982                      TALER_MHD_reply_with_error (
   3983                        pc->connection,
   3984                        MHD_HTTP_INTERNAL_SERVER_ERROR,
   3985                        TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
   3986                        "token family not found in order"));
   3987             return;
   3988           }
   3989           if (GNUNET_NO ==
   3990               find_valid_input_tokens (pc,
   3991                                        family,
   3992                                        wallet_off,
   3993                                        input->details.token.count))
   3994           {
   3995             /* Error is already scheduled from find_valid_input_token. */
   3996             return;
   3997           }
   3998           wallet_off += input->details.token.count;
   3999         }
   4000       }
   4001 
   4002       /* calculate pc->output_tokens_len */
   4003       output_off = 0;
   4004       for (unsigned int i = 0; i<selected->outputs_len; i++)
   4005       {
   4006         const struct TALER_MERCHANT_ContractOutput *output
   4007           = &selected->outputs[i];
   4008 
   4009         switch (output->type)
   4010         {
   4011         case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_INVALID:
   4012           GNUNET_assert (0);
   4013           break;
   4014         case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN:
   4015           cnt = output->details.token.count;
   4016           if (output_off + cnt < output_off)
   4017           {
   4018             GNUNET_break_op (0);
   4019             pay_end (pc,
   4020                      TALER_MHD_reply_with_error (
   4021                        pc->connection,
   4022                        MHD_HTTP_BAD_REQUEST,
   4023                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
   4024                        "output token counter overflow"));
   4025             return;
   4026           }
   4027           output_off += cnt;
   4028           break;
   4029         case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_DONATION_RECEIPT:
   4030           /* check that this output type appears at most once */
   4031           if (pc->validate_tokens.donau_output_index >= 0)
   4032           {
   4033             /* This should have been prevented when the
   4034                contract was initially created */
   4035             GNUNET_break (0);
   4036             pay_end (pc,
   4037                      TALER_MHD_reply_with_error (
   4038                        pc->connection,
   4039                        MHD_HTTP_INTERNAL_SERVER_ERROR,
   4040                        TALER_EC_GENERIC_DB_INVARIANT_FAILURE,
   4041                        "two donau output sets in same contract"));
   4042             return;
   4043           }
   4044           pc->validate_tokens.donau_output_index = i;
   4045           if (output_off + pc->parse_wallet_data.num_bkps < output_off)
   4046           {
   4047             GNUNET_break_op (0);
   4048             pay_end (pc,
   4049                      TALER_MHD_reply_with_error (
   4050                        pc->connection,
   4051                        MHD_HTTP_BAD_REQUEST,
   4052                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
   4053                        "output token counter overflow"));
   4054             return;
   4055           }
   4056           output_off += pc->parse_wallet_data.num_bkps;
   4057           break;
   4058         }
   4059       }
   4060 
   4061 
   4062       pc->output_tokens_len = output_off;
   4063       pc->output_tokens
   4064         = GNUNET_new_array (pc->output_tokens_len,
   4065                             struct SignedOutputToken);
   4066 
   4067       /* calculate pc->output_tokens[].output_index */
   4068       output_off = 0; /* index into output_tokens */
   4069       for (unsigned int i = 0; i<selected->outputs_len; i++)
   4070       {
   4071         const struct TALER_MERCHANT_ContractOutput *output
   4072           = &selected->outputs[i];
   4073 
   4074         cnt = count_output_tokens (pc,
   4075                                    output);
   4076         for (unsigned int j = 0; j<cnt; j++)
   4077           pc->output_tokens[output_off + j].output_index = i;
   4078         output_off += cnt;
   4079       }
   4080 
   4081       /* compute non-donau outputs */
   4082       output_off = 0; /* index into output_tokens */
   4083       wallet_off = 0; /* index into parse_wallet_data.token_envelopes */
   4084       for (unsigned int i = 0; i<selected->outputs_len; i++)
   4085       {
   4086         const struct TALER_MERCHANT_ContractOutput *output
   4087           = &selected->outputs[i];
   4088 
   4089         switch (output->type)
   4090         {
   4091         case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_INVALID:
   4092           GNUNET_assert (0);
   4093           break;
   4094         case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN:
   4095           cnt = output->details.token.count;
   4096           GNUNET_assert (output_off + cnt
   4097                          <= pc->output_tokens_len);
   4098           if (GNUNET_OK !=
   4099               handle_output_token (pc,
   4100                                    wallet_off,
   4101                                    output,
   4102                                    output_off))
   4103           {
   4104             /* Error is already scheduled from handle_output_token. */
   4105             return;
   4106           }
   4107           output_off += cnt;
   4108           wallet_off += cnt;
   4109           break;
   4110         case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_DONATION_RECEIPT:
   4111           if ( (0 != pc->parse_wallet_data.num_bkps) &&
   4112                (GNUNET_OK !=
   4113                 handle_output_donation_receipt (pc,
   4114                                                 output)) )
   4115           {
   4116             /* Error is already scheduled from handle_output_donation_receipt. */
   4117             return;
   4118           }
   4119           output_off += pc->parse_wallet_data.num_bkps;
   4120           /* Note: wallet_off NOT increased, as bkps are
   4121              separate from parse_wallet_data.token_envelopes */
   4122           continue;
   4123         } /* switch on output token */
   4124       } /* for all output token types */
   4125     } /* case contract v1 */
   4126     break;
   4127   } /* switch on contract type */
   4128 
   4129   for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   4130   {
   4131     const struct DepositConfirmation *dc = &pc->parse_pay.dc[i];
   4132 
   4133     if (GNUNET_OK !=
   4134         TALER_amount_cmp_currency (&dc->cdd.amount,
   4135                                    &pc->validate_tokens.brutto))
   4136     {
   4137       GNUNET_break_op (0);
   4138       pay_end (pc,
   4139                TALER_MHD_reply_with_error (
   4140                  pc->connection,
   4141                  MHD_HTTP_CONFLICT,
   4142                  TALER_EC_MERCHANT_GENERIC_CURRENCY_MISMATCH,
   4143                  pc->validate_tokens.brutto.currency));
   4144       return;
   4145     }
   4146   }
   4147 
   4148   pc->phase = PP_COMPUTE_MONEY_POTS;
   4149 }
   4150 
   4151 
   4152 /**
   4153  * Function called with information about a coin that was deposited.
   4154  * Checks if this coin is in our list of deposits as well.
   4155  *
   4156  * @param cls closure with our `struct PayContext *`
   4157  * @param deposit_serial which deposit operation is this about
   4158  * @param exchange_url URL of the exchange that issued the coin
   4159  * @param h_wire hash of merchant's wire details
   4160  * @param deposit_timestamp when was the deposit made
   4161  * @param amount_with_fee amount the exchange will deposit for this coin
   4162  * @param deposit_fee fee the exchange will charge for this coin
   4163  * @param coin_pub public key of the coin
   4164  */
   4165 static void
   4166 deposit_paid_check (
   4167   void *cls,
   4168   uint64_t deposit_serial,
   4169   const char *exchange_url,
   4170   const struct TALER_MerchantWireHashP *h_wire,
   4171   struct GNUNET_TIME_Timestamp deposit_timestamp,
   4172   const struct TALER_Amount *amount_with_fee,
   4173   const struct TALER_Amount *deposit_fee,
   4174   const struct TALER_CoinSpendPublicKeyP *coin_pub)
   4175 {
   4176   struct PayContext *pc = cls;
   4177 
   4178   for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   4179   {
   4180     struct DepositConfirmation *dci = &pc->parse_pay.dc[i];
   4181 
   4182     if ( (0 ==
   4183           GNUNET_memcmp (&dci->cdd.coin_pub,
   4184                          coin_pub)) &&
   4185          (0 ==
   4186           strcmp (dci->exchange_url,
   4187                   exchange_url)) &&
   4188          (GNUNET_YES ==
   4189           TALER_amount_cmp_currency (&dci->cdd.amount,
   4190                                      amount_with_fee)) &&
   4191          (0 ==
   4192           TALER_amount_cmp (&dci->cdd.amount,
   4193                             amount_with_fee)) )
   4194     {
   4195       dci->matched_in_db = true;
   4196       break;
   4197     }
   4198   }
   4199 }
   4200 
   4201 
   4202 /**
   4203  * Function called with information about a token that was spent.
   4204  * FIXME: Replace this with a more specific function for this cb
   4205  *
   4206  * @param cls closure with `struct PayContext *`
   4207  * @param spent_token_serial "serial" of the spent token unused
   4208  * @param h_contract_terms hash of the contract terms unused
   4209  * @param h_issue_pub hash of the token issue public key unused
   4210  * @param use_pub public key of the token
   4211  * @param use_sig signature of the token
   4212  * @param issue_sig signature of the token issue
   4213  */
   4214 static void
   4215 input_tokens_paid_check (
   4216   void *cls,
   4217   uint64_t spent_token_serial,
   4218   const struct TALER_PrivateContractHashP *h_contract_terms,
   4219   const struct TALER_TokenIssuePublicKeyHashP *h_issue_pub,
   4220   const struct TALER_TokenUsePublicKeyP *use_pub,
   4221   const struct TALER_TokenUseSignatureP *use_sig,
   4222   const struct TALER_TokenIssueSignature *issue_sig)
   4223 {
   4224   struct PayContext *pc = cls;
   4225 
   4226   for (size_t i = 0; i<pc->parse_pay.tokens_cnt; i++)
   4227   {
   4228     struct TokenUseConfirmation *tuc = &pc->parse_pay.tokens[i];
   4229 
   4230     if ( (0 ==
   4231           GNUNET_memcmp (&tuc->pub,
   4232                          use_pub)) &&
   4233          (0 ==
   4234           GNUNET_memcmp (&tuc->sig,
   4235                          use_sig)) &&
   4236          (0 ==
   4237           GNUNET_memcmp (&tuc->unblinded_sig,
   4238                          issue_sig)) )
   4239     {
   4240       tuc->found_in_db = true;
   4241       break;
   4242     }
   4243   }
   4244 }
   4245 
   4246 
   4247 /**
   4248  * Small helper function to append an output token signature from db
   4249  *
   4250  * @param cls closure with `struct PayContext *`
   4251  * @param h_issue hash of the token
   4252  * @param sig signature of the token
   4253  */
   4254 static void
   4255 append_output_token_sig (void *cls,
   4256                          struct GNUNET_HashCode *h_issue,
   4257                          struct GNUNET_CRYPTO_BlindedSignature *sig)
   4258 {
   4259   struct PayContext *pc = cls;
   4260   struct TALER_MERCHANT_ContractChoice *choice;
   4261   const struct TALER_MERCHANT_ContractOutput *output;
   4262   struct SignedOutputToken out;
   4263   unsigned int cnt;
   4264 
   4265   memset (&out,
   4266           0,
   4267           sizeof (out));
   4268   GNUNET_assert (TALER_MERCHANT_CONTRACT_VERSION_1 ==
   4269                  pc->check_contract.contract_terms->pc->base->version);
   4270   choice = &pc->check_contract.contract_terms->pc->details.v1
   4271            .choices[pc->parse_wallet_data.choice_index];
   4272   output = &choice->outputs[pc->output_index_gen];
   4273   cnt = count_output_tokens (pc,
   4274                              output);
   4275   out.output_index = pc->output_index_gen;
   4276   out.h_issue.hash = *h_issue;
   4277   out.sig.signature = sig;
   4278   GNUNET_CRYPTO_blind_sig_incref (sig);
   4279   GNUNET_array_append (pc->output_tokens,
   4280                        pc->output_tokens_len,
   4281                        out);
   4282   /* Go to next output once we've output all tokens for the current one. */
   4283   pc->output_token_cnt++;
   4284   if (pc->output_token_cnt >= cnt)
   4285   {
   4286     pc->output_token_cnt = 0;
   4287     pc->output_index_gen++;
   4288   }
   4289 }
   4290 
   4291 
   4292 /**
   4293  * Handle case where contract was already paid. Either decides
   4294  * the payment is idempotent, or refunds the excess payment.
   4295  *
   4296  * @param[in,out] pc context we use to handle the payment
   4297  */
   4298 static void
   4299 phase_contract_paid (struct PayContext *pc)
   4300 {
   4301   json_t *refunds;
   4302   bool unmatched = false;
   4303 
   4304   {
   4305     enum GNUNET_DB_QueryStatus qs;
   4306 
   4307     qs = TALER_MERCHANTDB_lookup_deposits_by_order (TMH_db,
   4308                                                     pc->check_contract.order_serial,
   4309                                                     &deposit_paid_check,
   4310                                                     pc);
   4311     /* Since orders with choices can have a price of zero,
   4312        0 is also a valid query state */
   4313     if (qs < 0)
   4314     {
   4315       GNUNET_break (0);
   4316       pay_end (pc,
   4317                TALER_MHD_reply_with_error (
   4318                  pc->connection,
   4319                  MHD_HTTP_INTERNAL_SERVER_ERROR,
   4320                  TALER_EC_GENERIC_DB_FETCH_FAILED,
   4321                  "lookup_deposits_by_order"));
   4322       return;
   4323     }
   4324   }
   4325   for (size_t i = 0;
   4326        i<pc->parse_pay.coins_cnt && ! unmatched;
   4327        i++)
   4328   {
   4329     struct DepositConfirmation *dci = &pc->parse_pay.dc[i];
   4330 
   4331     if (! dci->matched_in_db)
   4332       unmatched = true;
   4333   }
   4334   /* Check if provided input tokens match token in the database */
   4335   {
   4336     enum GNUNET_DB_QueryStatus qs;
   4337 
   4338     /* FIXME-Optimization: Maybe use h_contract instead of order_serial here? */
   4339     qs = TALER_MERCHANTDB_lookup_spent_tokens_by_order (TMH_db,
   4340                                                         pc->check_contract.order_serial,
   4341                                                         &input_tokens_paid_check,
   4342                                                         pc);
   4343 
   4344     if (qs < 0)
   4345     {
   4346       GNUNET_break (0);
   4347       pay_end (pc,
   4348                TALER_MHD_reply_with_error (
   4349                  pc->connection,
   4350                  MHD_HTTP_INTERNAL_SERVER_ERROR,
   4351                  TALER_EC_GENERIC_DB_FETCH_FAILED,
   4352                  "lookup_spent_tokens_by_order"));
   4353       return;
   4354     }
   4355   }
   4356   for (size_t i = 0; i<pc->parse_pay.tokens_cnt && ! unmatched; i++)
   4357   {
   4358     struct TokenUseConfirmation *tuc = &pc->parse_pay.tokens[i];
   4359 
   4360     if (! tuc->found_in_db)
   4361       unmatched = true;
   4362   }
   4363 
   4364   /* In this part we are fetching token_sigs related output */
   4365   if (! unmatched)
   4366   {
   4367     /* Everything fine, idempotent request, generate response immediately */
   4368     enum GNUNET_DB_QueryStatus qs;
   4369 
   4370     pc->output_index_gen = 0;
   4371     qs = TALER_MERCHANTDB_select_order_blinded_sigs (
   4372       TMH_db,
   4373       pc->order_id,
   4374       &append_output_token_sig,
   4375       pc);
   4376     if (0 > qs)
   4377     {
   4378       GNUNET_break (0);
   4379       pay_end (pc,
   4380                TALER_MHD_reply_with_error (
   4381                  pc->connection,
   4382                  MHD_HTTP_INTERNAL_SERVER_ERROR,
   4383                  TALER_EC_GENERIC_DB_FETCH_FAILED,
   4384                  "select_order_blinded_sigs"));
   4385       return;
   4386     }
   4387 
   4388     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   4389                 "Idempotent pay request for order `%s', signing again\n",
   4390                 pc->order_id);
   4391     pc->phase = PP_SUCCESS_RESPONSE;
   4392     return;
   4393   }
   4394   /* Conflict, double-payment detected! */
   4395   /* FIXME-#8674: What should we do with input tokens?
   4396      Currently there is no refund for tokens. */
   4397   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   4398               "Client attempted to pay extra for already paid order `%s'\n",
   4399               pc->order_id);
   4400   refunds = json_array ();
   4401   GNUNET_assert (NULL != refunds);
   4402   for (size_t i = 0; i<pc->parse_pay.coins_cnt; i++)
   4403   {
   4404     struct DepositConfirmation *dci = &pc->parse_pay.dc[i];
   4405     struct TALER_MerchantSignatureP merchant_sig;
   4406 
   4407     if (dci->matched_in_db)
   4408       continue;
   4409     TALER_merchant_refund_sign (&dci->cdd.coin_pub,
   4410                                 &pc->check_contract.h_contract_terms,
   4411                                 0, /* rtransaction id */
   4412                                 &dci->cdd.amount,
   4413                                 &pc->hc->instance->merchant_priv,
   4414                                 &merchant_sig);
   4415     GNUNET_assert (
   4416       0 ==
   4417       json_array_append_new (
   4418         refunds,
   4419         GNUNET_JSON_PACK (
   4420           GNUNET_JSON_pack_data_auto (
   4421             "coin_pub",
   4422             &dci->cdd.coin_pub),
   4423           GNUNET_JSON_pack_data_auto (
   4424             "merchant_sig",
   4425             &merchant_sig),
   4426           TALER_JSON_pack_amount ("amount",
   4427                                   &dci->cdd.amount),
   4428           GNUNET_JSON_pack_uint64 ("rtransaction_id",
   4429                                    0))));
   4430   }
   4431   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   4432               "Generating JSON response with code %d\n",
   4433               (int) TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_ALREADY_PAID);
   4434   pay_end (pc,
   4435            TALER_MHD_REPLY_JSON_PACK (
   4436              pc->connection,
   4437              MHD_HTTP_CONFLICT,
   4438              TALER_MHD_PACK_EC (
   4439                TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_ALREADY_PAID),
   4440              GNUNET_JSON_pack_array_steal ("refunds",
   4441                                            refunds)));
   4442 }
   4443 
   4444 
   4445 /**
   4446  * Check the database state for the given order.
   4447  * Schedules an error response in the connection on failure.
   4448  *
   4449  * @param[in,out] pc context we use to handle the payment
   4450  */
   4451 static void
   4452 phase_check_contract (struct PayContext *pc)
   4453 {
   4454   /* obtain contract terms */
   4455   enum GNUNET_DB_QueryStatus qs;
   4456   bool paid = false;
   4457 
   4458   if (NULL != pc->check_contract.contract_terms_json)
   4459   {
   4460     json_decref (pc->check_contract.contract_terms_json);
   4461     pc->check_contract.contract_terms_json = NULL;
   4462   }
   4463   if (NULL != pc->check_contract.contract_terms)
   4464   {
   4465     TALER_MERCHANT_contract_free (pc->check_contract.contract_terms);
   4466     pc->check_contract.contract_terms = NULL;
   4467   }
   4468   qs = TALER_MERCHANTDB_lookup_contract_terms2 (
   4469     TMH_db,
   4470     pc->hc->instance->settings.id,
   4471     pc->order_id,
   4472     &pc->check_contract.contract_terms_json,
   4473     &pc->check_contract.order_serial,
   4474     &paid,
   4475     NULL,
   4476     &pc->check_contract.pos_key,
   4477     &pc->check_contract.pos_alg);
   4478   if (0 > qs)
   4479   {
   4480     /* single, read-only SQL statements should never cause
   4481        serialization problems */
   4482     GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
   4483     /* Always report on hard error to enable diagnostics */
   4484     GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
   4485     pay_end (pc,
   4486              TALER_MHD_reply_with_error (
   4487                pc->connection,
   4488                MHD_HTTP_INTERNAL_SERVER_ERROR,
   4489                TALER_EC_GENERIC_DB_FETCH_FAILED,
   4490                "contract terms"));
   4491     return;
   4492   }
   4493   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
   4494   {
   4495     pay_end (pc,
   4496              TALER_MHD_reply_with_error (
   4497                pc->connection,
   4498                MHD_HTTP_NOT_FOUND,
   4499                TALER_EC_MERCHANT_GENERIC_ORDER_UNKNOWN,
   4500                pc->order_id));
   4501     return;
   4502   }
   4503   /* hash contract (needed later) */
   4504 #if DEBUG
   4505   json_dumpf (pc->check_contract.contract_terms_json,
   4506               stderr,
   4507               JSON_INDENT (2));
   4508 #endif
   4509   if (GNUNET_OK !=
   4510       TALER_JSON_contract_hash (pc->check_contract.contract_terms_json,
   4511                                 &pc->check_contract.h_contract_terms))
   4512   {
   4513     GNUNET_break (0);
   4514     pay_end (pc,
   4515              TALER_MHD_reply_with_error (
   4516                pc->connection,
   4517                MHD_HTTP_INTERNAL_SERVER_ERROR,
   4518                TALER_EC_GENERIC_FAILED_COMPUTE_JSON_HASH,
   4519                NULL));
   4520     return;
   4521   }
   4522 
   4523   /* Parse the contract terms even for paid orders,
   4524      as later phases need it. */
   4525 
   4526   pc->check_contract.contract_terms = TALER_MERCHANT_contract_parse (
   4527     pc->check_contract.contract_terms_json);
   4528 
   4529   if (NULL == pc->check_contract.contract_terms)
   4530   {
   4531     /* invalid contract */
   4532     GNUNET_break (0);
   4533     pay_end (pc,
   4534              TALER_MHD_reply_with_error (
   4535                pc->connection,
   4536                MHD_HTTP_INTERNAL_SERVER_ERROR,
   4537                TALER_EC_MERCHANT_GENERIC_DB_CONTRACT_CONTENT_INVALID,
   4538                pc->order_id));
   4539     return;
   4540   }
   4541 
   4542   if (paid)
   4543   {
   4544     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   4545                 "Order `%s' paid, checking for double-payment\n",
   4546                 pc->order_id);
   4547     pc->phase = PP_CONTRACT_PAID;
   4548     return;
   4549   }
   4550   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   4551               "Handling payment for order `%s' with contract hash `%s'\n",
   4552               pc->order_id,
   4553               GNUNET_h2s (&pc->check_contract.h_contract_terms.hash));
   4554 
   4555   /* Check fundamentals */
   4556   {
   4557     switch (pc->check_contract.contract_terms->pc->base->version)
   4558     {
   4559     case TALER_MERCHANT_CONTRACT_VERSION_0:
   4560       {
   4561         if (pc->parse_wallet_data.choice_index > 0)
   4562         {
   4563           GNUNET_break (0);
   4564           pay_end (pc,
   4565                    TALER_MHD_reply_with_error (
   4566                      pc->connection,
   4567                      MHD_HTTP_BAD_REQUEST,
   4568                      TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_CHOICE_INDEX_OUT_OF_BOUNDS,
   4569                      "contract terms v0 has no choices"));
   4570           return;
   4571         }
   4572       }
   4573       break;
   4574     case TALER_MERCHANT_CONTRACT_VERSION_1:
   4575       {
   4576         if (pc->parse_wallet_data.choice_index < 0)
   4577         {
   4578           GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   4579                       "Order `%s' has non-empty choices array but"
   4580                       "request is missing 'choice_index' field\n",
   4581                       pc->order_id);
   4582           GNUNET_break (0);
   4583           pay_end (pc,
   4584                    TALER_MHD_reply_with_error (
   4585                      pc->connection,
   4586                      MHD_HTTP_BAD_REQUEST,
   4587                      TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_CHOICE_INDEX_MISSING,
   4588                      NULL));
   4589           return;
   4590         }
   4591         if (pc->parse_wallet_data.choice_index >=
   4592             pc->check_contract.contract_terms->pc->details.v1.choices_len)
   4593         {
   4594           GNUNET_log (
   4595             GNUNET_ERROR_TYPE_INFO,
   4596             "Order `%s' has choices array with %u elements but "
   4597             "request has 'choice_index' field with value %d\n",
   4598             pc->order_id,
   4599             pc->check_contract.contract_terms->pc->details.v1.choices_len,
   4600             pc->parse_wallet_data.choice_index);
   4601           GNUNET_break (0);
   4602           pay_end (pc,
   4603                    TALER_MHD_reply_with_error (
   4604                      pc->connection,
   4605                      MHD_HTTP_BAD_REQUEST,
   4606                      TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_CHOICE_INDEX_OUT_OF_BOUNDS,
   4607                      NULL));
   4608           return;
   4609         }
   4610       }
   4611       break;
   4612     default:
   4613       GNUNET_break (0);
   4614       pay_end (pc,
   4615                TALER_MHD_reply_with_error (
   4616                  pc->connection,
   4617                  MHD_HTTP_INTERNAL_SERVER_ERROR,
   4618                  TALER_EC_GENERIC_DB_FETCH_FAILED,
   4619                  "contract 'version' in database not supported by this backend")
   4620                );
   4621       return;
   4622     }
   4623   }
   4624 
   4625   if (GNUNET_TIME_timestamp_cmp (
   4626         pc->check_contract.contract_terms->pc->wire_deadline,
   4627         <,
   4628         pc->check_contract.contract_terms->pc->refund_deadline))
   4629   {
   4630     /* This should already have been checked when creating the order! */
   4631     GNUNET_break (0);
   4632     pay_end (pc,
   4633              TALER_MHD_reply_with_error (
   4634                pc->connection,
   4635                MHD_HTTP_INTERNAL_SERVER_ERROR,
   4636                TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE,
   4637                NULL));
   4638     return;
   4639   }
   4640   if (GNUNET_TIME_absolute_is_past (
   4641         pc->check_contract.contract_terms->pc->pay_deadline.abs_time))
   4642   {
   4643     /* too late */
   4644     pay_end (pc,
   4645              TALER_MHD_reply_with_error (
   4646                pc->connection,
   4647                MHD_HTTP_GONE,
   4648                TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_OFFER_EXPIRED,
   4649                NULL));
   4650     return;
   4651   }
   4652 
   4653 /* Make sure wire method (still) exists for this instance */
   4654   {
   4655     struct TMH_WireMethod *wm;
   4656 
   4657     wm = pc->hc->instance->wm_head;
   4658     while ( (NULL != wm) &&
   4659             (0 !=
   4660              GNUNET_memcmp (
   4661                &pc->check_contract.contract_terms->pc->h_wire,
   4662                &wm->h_wire)) )
   4663       wm = wm->next;
   4664     if (NULL == wm)
   4665     {
   4666       GNUNET_break (0);
   4667       pay_end (pc,
   4668                TALER_MHD_reply_with_error (
   4669                  pc->connection,
   4670                  MHD_HTTP_INTERNAL_SERVER_ERROR,
   4671                  TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_WIRE_HASH_UNKNOWN,
   4672                  NULL));
   4673       return;
   4674     }
   4675     pc->check_contract.wm = wm;
   4676   }
   4677   pc->phase = PP_VALIDATE_TOKENS;
   4678 }
   4679 
   4680 
   4681 /**
   4682  * Try to parse the wallet_data object of the pay request into
   4683  * the given context. Schedules an error response in the connection
   4684  * on failure.
   4685  *
   4686  * @param[in,out] pc context we use to handle the payment
   4687  */
   4688 static void
   4689 phase_parse_wallet_data (struct PayContext *pc)
   4690 {
   4691   const json_t *tokens_evs;
   4692   const json_t *donau_obj;
   4693 
   4694   struct GNUNET_JSON_Specification spec[] = {
   4695     GNUNET_JSON_spec_mark_optional (
   4696       GNUNET_JSON_spec_int16 ("choice_index",
   4697                               &pc->parse_wallet_data.choice_index),
   4698       NULL),
   4699     GNUNET_JSON_spec_mark_optional (
   4700       GNUNET_JSON_spec_array_const ("tokens_evs",
   4701                                     &tokens_evs),
   4702       NULL),
   4703     GNUNET_JSON_spec_mark_optional (
   4704       GNUNET_JSON_spec_object_const ("donau",
   4705                                      &donau_obj),
   4706       NULL),
   4707     GNUNET_JSON_spec_end ()
   4708   };
   4709 
   4710   pc->parse_wallet_data.choice_index = -1;
   4711   if (NULL == pc->parse_pay.wallet_data)
   4712   {
   4713     pc->phase = PP_CHECK_CONTRACT;
   4714     return;
   4715   }
   4716   {
   4717     enum GNUNET_GenericReturnValue res;
   4718 
   4719     res = TALER_MHD_parse_json_data (pc->connection,
   4720                                      pc->parse_pay.wallet_data,
   4721                                      spec);
   4722     if (GNUNET_YES != res)
   4723     {
   4724       GNUNET_break_op (0);
   4725       pay_end (pc,
   4726                (GNUNET_NO == res)
   4727              ? MHD_YES
   4728              : MHD_NO);
   4729       return;
   4730     }
   4731   }
   4732 
   4733   pc->parse_wallet_data.token_envelopes_cnt
   4734     = json_array_size (tokens_evs);
   4735   if (pc->parse_wallet_data.token_envelopes_cnt >
   4736       MAX_TOKEN_ALLOWED_OUTPUTS)
   4737   {
   4738     GNUNET_break_op (0);
   4739     pay_end (pc,
   4740              TALER_MHD_reply_with_error (
   4741                pc->connection,
   4742                MHD_HTTP_BAD_REQUEST,
   4743                TALER_EC_GENERIC_PARAMETER_MALFORMED,
   4744                "'tokens_evs' array too long"));
   4745     return;
   4746   }
   4747   pc->parse_wallet_data.token_envelopes
   4748     = GNUNET_new_array (pc->parse_wallet_data.token_envelopes_cnt,
   4749                         struct TokenEnvelope);
   4750 
   4751   {
   4752     unsigned int tokens_ev_index;
   4753     json_t *token_ev;
   4754 
   4755     json_array_foreach (tokens_evs,
   4756                         tokens_ev_index,
   4757                         token_ev)
   4758     {
   4759       struct TokenEnvelope *ev
   4760         = &pc->parse_wallet_data.token_envelopes[tokens_ev_index];
   4761       struct GNUNET_JSON_Specification ispec[] = {
   4762         TALER_JSON_spec_token_envelope (NULL,
   4763                                         &ev->blinded_token),
   4764         GNUNET_JSON_spec_end ()
   4765       };
   4766       enum GNUNET_GenericReturnValue res;
   4767 
   4768       if (json_is_null (token_ev))
   4769         continue;
   4770       res = TALER_MHD_parse_json_data (pc->connection,
   4771                                        token_ev,
   4772                                        ispec);
   4773       if (GNUNET_YES != res)
   4774       {
   4775         GNUNET_break_op (0);
   4776         pay_end (pc,
   4777                  (GNUNET_NO == res)
   4778                  ? MHD_YES
   4779                  : MHD_NO);
   4780         return;
   4781       }
   4782 
   4783       for (unsigned int j = 0; j<tokens_ev_index; j++)
   4784       {
   4785         if (0 ==
   4786             GNUNET_memcmp (ev->blinded_token.blinded_pub,
   4787                            pc->parse_wallet_data.token_envelopes[j].
   4788                            blinded_token.blinded_pub))
   4789         {
   4790           GNUNET_break_op (0);
   4791           pay_end (pc,
   4792                    TALER_MHD_reply_with_error (
   4793                      pc->connection,
   4794                      MHD_HTTP_BAD_REQUEST,
   4795                      TALER_EC_GENERIC_PARAMETER_MALFORMED,
   4796                      "duplicate token envelope in list"));
   4797           return;
   4798         }
   4799       }
   4800     }
   4801   }
   4802 
   4803   if (NULL != donau_obj)
   4804   {
   4805     const char *donau_url_tmp;
   4806     const json_t *budikeypairs;
   4807     json_t *donau_keys_json;
   4808 
   4809     /* Fetching and checking that all 3 are present in some way */
   4810     struct GNUNET_JSON_Specification dspec[] = {
   4811       GNUNET_JSON_spec_string      ("url",
   4812                                     &donau_url_tmp),
   4813       GNUNET_JSON_spec_uint64      ("year",
   4814                                     &pc->parse_wallet_data.donau.donation_year),
   4815       GNUNET_JSON_spec_array_const ("budikeypairs",
   4816                                     &budikeypairs),
   4817       GNUNET_JSON_spec_end ()
   4818     };
   4819     enum GNUNET_GenericReturnValue res;
   4820 
   4821     res = TALER_MHD_parse_json_data (pc->connection,
   4822                                      donau_obj,
   4823                                      dspec);
   4824     if (GNUNET_YES != res)
   4825     {
   4826       GNUNET_break_op (0);
   4827       pay_end (pc,
   4828                (GNUNET_NO == res)
   4829                ? MHD_YES
   4830                : MHD_NO);
   4831       return;
   4832     }
   4833 
   4834     /* Check if the needed data is present for the given donau URL */
   4835     {
   4836       enum GNUNET_DB_QueryStatus qs;
   4837 
   4838       qs = TALER_MERCHANTDB_lookup_order_charity (
   4839         TMH_db,
   4840         pc->hc->instance->settings.id,
   4841         donau_url_tmp,
   4842         &pc->parse_wallet_data.charity_id,
   4843         &pc->parse_wallet_data.charity_max_per_year,
   4844         &pc->parse_wallet_data.charity_receipts_to_date,
   4845         &donau_keys_json,
   4846         &pc->parse_wallet_data.donau_instance_serial);
   4847 
   4848       switch (qs)
   4849       {
   4850       case GNUNET_DB_STATUS_HARD_ERROR:
   4851       case GNUNET_DB_STATUS_SOFT_ERROR:
   4852         TALER_MERCHANTDB_rollback (TMH_db);
   4853         pay_end (pc,
   4854                  TALER_MHD_reply_with_error (
   4855                    pc->connection,
   4856                    MHD_HTTP_INTERNAL_SERVER_ERROR,
   4857                    TALER_EC_GENERIC_DB_FETCH_FAILED,
   4858                    "lookup_order_charity"));
   4859         return;
   4860       case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
   4861         TALER_MERCHANTDB_rollback (TMH_db);
   4862         pay_end (pc,
   4863                  TALER_MHD_reply_with_error (
   4864                    pc->connection,
   4865                    MHD_HTTP_NOT_FOUND,
   4866                    TALER_EC_MERCHANT_GENERIC_DONAU_CHARITY_UNKNOWN,
   4867                    donau_url_tmp));
   4868         return;
   4869       case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
   4870         GNUNET_static_assert (sizeof (pc->parse_wallet_data.charity_priv) ==
   4871                               sizeof (pc->hc->instance->merchant_priv));
   4872         memcpy (&pc->parse_wallet_data.charity_priv,
   4873                 &pc->hc->instance->merchant_priv,
   4874                 sizeof (pc->hc->instance->merchant_priv));
   4875         pc->parse_wallet_data.donau.donau_url =
   4876           GNUNET_strdup (donau_url_tmp);
   4877         break;
   4878       }
   4879     }
   4880 
   4881     {
   4882       pc->parse_wallet_data.donau_keys =
   4883         DONAU_keys_from_json (donau_keys_json);
   4884       json_decref (donau_keys_json);
   4885       if (NULL == pc->parse_wallet_data.donau_keys)
   4886       {
   4887         GNUNET_break_op (0);
   4888         pay_end (pc,
   4889                  TALER_MHD_reply_with_error (pc->connection,
   4890                                              MHD_HTTP_BAD_REQUEST,
   4891                                              TALER_EC_GENERIC_PARAMETER_MALFORMED,
   4892                                              "Invalid donau_keys"));
   4893         return;
   4894       }
   4895     }
   4896 
   4897     /* Stage to parse the budikeypairs from json to struct */
   4898     if (0 != json_array_size (budikeypairs))
   4899     {
   4900       size_t num_bkps = json_array_size (budikeypairs);
   4901       struct DONAU_BlindedUniqueDonorIdentifierKeyPair *bkps =
   4902         GNUNET_new_array (num_bkps,
   4903                           struct DONAU_BlindedUniqueDonorIdentifierKeyPair);
   4904 
   4905       /* Change to json for each */
   4906       for (size_t i = 0; i < num_bkps; i++)
   4907       {
   4908         const json_t *bkp_obj = json_array_get (budikeypairs,
   4909                                                 i);
   4910         if (GNUNET_SYSERR ==
   4911             merchant_parse_json_bkp (&bkps[i],
   4912                                      bkp_obj))
   4913         {
   4914           GNUNET_break_op (0);
   4915           for (size_t j = 0; j < i; j++)
   4916             GNUNET_CRYPTO_blinded_message_decref (
   4917               bkps[j].blinded_udi.blinded_message);
   4918           GNUNET_free (bkps);
   4919           pay_end (pc,
   4920                    TALER_MHD_reply_with_error (pc->connection,
   4921                                                MHD_HTTP_BAD_REQUEST,
   4922                                                TALER_EC_GENERIC_PARAMETER_MALFORMED,
   4923                                                "Failed to parse budikeypairs"));
   4924           return;
   4925         }
   4926       }
   4927 
   4928       pc->parse_wallet_data.num_bkps = num_bkps;
   4929       pc->parse_wallet_data.bkps = bkps;
   4930     }
   4931   }
   4932   TALER_json_hash (pc->parse_pay.wallet_data,
   4933                    &pc->parse_wallet_data.h_wallet_data);
   4934 
   4935   pc->phase = PP_CHECK_CONTRACT;
   4936 }
   4937 
   4938 
   4939 /**
   4940  * Try to parse the pay request into the given pay context.
   4941  * Schedules an error response in the connection on failure.
   4942  *
   4943  * @param[in,out] pc context we use to handle the payment
   4944  */
   4945 static void
   4946 phase_parse_pay (struct PayContext *pc)
   4947 {
   4948   const char *session_id = NULL;
   4949   const json_t *coins;
   4950   const json_t *tokens;
   4951   struct GNUNET_JSON_Specification spec[] = {
   4952     GNUNET_JSON_spec_array_const ("coins",
   4953                                   &coins),
   4954     GNUNET_JSON_spec_mark_optional (
   4955       GNUNET_JSON_spec_string ("session_id",
   4956                                &session_id),
   4957       NULL),
   4958     GNUNET_JSON_spec_mark_optional (
   4959       GNUNET_JSON_spec_object_const ("wallet_data",
   4960                                      &pc->parse_pay.wallet_data),
   4961       NULL),
   4962     GNUNET_JSON_spec_mark_optional (
   4963       GNUNET_JSON_spec_array_const ("tokens",
   4964                                     &tokens),
   4965       NULL),
   4966     GNUNET_JSON_spec_end ()
   4967   };
   4968 
   4969 #if DEBUG
   4970   {
   4971     char *dump = json_dumps (pc->hc->request_body,
   4972                              JSON_INDENT (2)
   4973                              | JSON_ENCODE_ANY
   4974                              | JSON_SORT_KEYS);
   4975 
   4976     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   4977                 "POST /orders/%s/pay – request body follows:\n%s\n",
   4978                 pc->order_id,
   4979                 dump);
   4980 
   4981     free (dump);
   4982 
   4983   }
   4984 #endif /* DEBUG */
   4985 
   4986   GNUNET_assert (PP_PARSE_PAY == pc->phase);
   4987   {
   4988     enum GNUNET_GenericReturnValue res;
   4989 
   4990     res = TALER_MHD_parse_json_data (pc->connection,
   4991                                      pc->hc->request_body,
   4992                                      spec);
   4993     if (GNUNET_YES != res)
   4994     {
   4995       GNUNET_break_op (0);
   4996       pay_end (pc,
   4997                (GNUNET_NO == res)
   4998                ? MHD_YES
   4999                : MHD_NO);
   5000       return;
   5001     }
   5002   }
   5003 
   5004   /* copy session ID (if set) */
   5005   if (NULL != session_id)
   5006   {
   5007     pc->parse_pay.session_id = GNUNET_strdup (session_id);
   5008   }
   5009   else
   5010   {
   5011     /* use empty string as default if client didn't specify it */
   5012     pc->parse_pay.session_id = GNUNET_strdup ("");
   5013   }
   5014 
   5015   pc->parse_pay.coins_cnt = json_array_size (coins);
   5016   if (pc->parse_pay.coins_cnt > MAX_COIN_ALLOWED_COINS)
   5017   {
   5018     GNUNET_break_op (0);
   5019     pay_end (pc,
   5020              TALER_MHD_reply_with_error (
   5021                pc->connection,
   5022                MHD_HTTP_BAD_REQUEST,
   5023                TALER_EC_GENERIC_PARAMETER_MALFORMED,
   5024                "'coins' array too long"));
   5025     return;
   5026   }
   5027   /* note: 1 coin = 1 deposit confirmation expected */
   5028   pc->parse_pay.dc = GNUNET_new_array (pc->parse_pay.coins_cnt,
   5029                                        struct DepositConfirmation);
   5030 
   5031   /* This loop populates the array 'dc' in 'pc' */
   5032   {
   5033     unsigned int coins_index;
   5034     json_t *coin;
   5035 
   5036     json_array_foreach (coins, coins_index, coin)
   5037     {
   5038       struct DepositConfirmation *dc = &pc->parse_pay.dc[coins_index];
   5039       const char *exchange_url;
   5040       struct GNUNET_JSON_Specification ispec[] = {
   5041         GNUNET_JSON_spec_fixed_auto ("coin_sig",
   5042                                      &dc->cdd.coin_sig),
   5043         GNUNET_JSON_spec_fixed_auto ("coin_pub",
   5044                                      &dc->cdd.coin_pub),
   5045         TALER_JSON_spec_denom_sig ("ub_sig",
   5046                                    &dc->cdd.denom_sig),
   5047         GNUNET_JSON_spec_fixed_auto ("h_denom",
   5048                                      &dc->cdd.h_denom_pub),
   5049         TALER_JSON_spec_amount_any ("contribution",
   5050                                     &dc->cdd.amount),
   5051         TALER_JSON_spec_web_url ("exchange_url",
   5052                                  &exchange_url),
   5053         /* if a minimum age was required, the minimum_age_sig and
   5054          * age_commitment must be provided */
   5055         GNUNET_JSON_spec_mark_optional (
   5056           GNUNET_JSON_spec_fixed_auto ("minimum_age_sig",
   5057                                        &dc->minimum_age_sig),
   5058           &dc->no_minimum_age_sig),
   5059         GNUNET_JSON_spec_mark_optional (
   5060           TALER_JSON_spec_age_commitment ("age_commitment",
   5061                                           &dc->age_commitment),
   5062           &dc->no_age_commitment),
   5063         /* if minimum age was not required, but coin with age restriction set
   5064          * was used, h_age_commitment must be provided. */
   5065         GNUNET_JSON_spec_mark_optional (
   5066           GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
   5067                                        &dc->cdd.h_age_commitment),
   5068           &dc->no_h_age_commitment),
   5069         GNUNET_JSON_spec_end ()
   5070       };
   5071       enum GNUNET_GenericReturnValue res;
   5072       struct ExchangeGroup *eg = NULL;
   5073 
   5074       res = TALER_MHD_parse_json_data (pc->connection,
   5075                                        coin,
   5076                                        ispec);
   5077       if (GNUNET_YES != res)
   5078       {
   5079         GNUNET_break_op (0);
   5080         pay_end (pc,
   5081                  (GNUNET_NO == res)
   5082                  ? MHD_YES
   5083                  : MHD_NO);
   5084         return;
   5085       }
   5086       for (unsigned int j = 0; j<coins_index; j++)
   5087       {
   5088         if (0 ==
   5089             GNUNET_memcmp (&dc->cdd.coin_pub,
   5090                            &pc->parse_pay.dc[j].cdd.coin_pub))
   5091         {
   5092           GNUNET_break_op (0);
   5093           pay_end (pc,
   5094                    TALER_MHD_reply_with_error (pc->connection,
   5095                                                MHD_HTTP_BAD_REQUEST,
   5096                                                TALER_EC_GENERIC_PARAMETER_MALFORMED,
   5097                                                "duplicate coin in list"));
   5098           return;
   5099         }
   5100       }
   5101 
   5102       dc->exchange_url = GNUNET_strdup (exchange_url);
   5103       dc->index = coins_index;
   5104       dc->pc = pc;
   5105 
   5106       /* Check the consistency of the (potential) age restriction
   5107        * information. */
   5108       if (dc->no_age_commitment != dc->no_minimum_age_sig)
   5109       {
   5110         GNUNET_break_op (0);
   5111         pay_end (pc,
   5112                  TALER_MHD_reply_with_error (
   5113                    pc->connection,
   5114                    MHD_HTTP_BAD_REQUEST,
   5115                    TALER_EC_GENERIC_PARAMETER_MALFORMED,
   5116                    "inconsistent: 'age_commitment' vs. 'minimum_age_sig'"
   5117                    ));
   5118         return;
   5119       }
   5120 
   5121       /* Setup exchange group */
   5122       for (unsigned int i = 0; i<pc->parse_pay.num_exchanges; i++)
   5123       {
   5124         if (0 ==
   5125             strcmp (pc->parse_pay.egs[i]->exchange_url,
   5126                     exchange_url))
   5127         {
   5128           eg = pc->parse_pay.egs[i];
   5129           break;
   5130         }
   5131       }
   5132       if (NULL == eg)
   5133       {
   5134         eg = GNUNET_new (struct ExchangeGroup);
   5135         eg->pc = pc;
   5136         eg->exchange_url = dc->exchange_url;
   5137         eg->total = dc->cdd.amount;
   5138         GNUNET_array_append (pc->parse_pay.egs,
   5139                              pc->parse_pay.num_exchanges,
   5140                              eg);
   5141       }
   5142       else
   5143       {
   5144         if (0 >
   5145             TALER_amount_add (&eg->total,
   5146                               &eg->total,
   5147                               &dc->cdd.amount))
   5148         {
   5149           GNUNET_break_op (0);
   5150           pay_end (pc,
   5151                    TALER_MHD_reply_with_error (
   5152                      pc->connection,
   5153                      MHD_HTTP_INTERNAL_SERVER_ERROR,
   5154                      TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_AMOUNT_OVERFLOW,
   5155                      "Overflow adding up amounts"));
   5156           return;
   5157         }
   5158       }
   5159     }
   5160   }
   5161 
   5162   pc->parse_pay.tokens_cnt = json_array_size (tokens);
   5163   if (pc->parse_pay.tokens_cnt > MAX_TOKEN_ALLOWED_INPUTS)
   5164   {
   5165     GNUNET_break_op (0);
   5166     pay_end (pc,
   5167              TALER_MHD_reply_with_error (
   5168                pc->connection,
   5169                MHD_HTTP_BAD_REQUEST,
   5170                TALER_EC_GENERIC_PARAMETER_MALFORMED,
   5171                "'tokens' array too long"));
   5172     return;
   5173   }
   5174 
   5175   pc->parse_pay.tokens = GNUNET_new_array (pc->parse_pay.tokens_cnt,
   5176                                            struct TokenUseConfirmation);
   5177 
   5178   /* This loop populates the array 'tokens' in 'pc' */
   5179   {
   5180     unsigned int tokens_index;
   5181     json_t *token;
   5182 
   5183     json_array_foreach (tokens, tokens_index, token)
   5184     {
   5185       struct TokenUseConfirmation *tuc = &pc->parse_pay.tokens[tokens_index];
   5186       struct GNUNET_JSON_Specification ispec[] = {
   5187         GNUNET_JSON_spec_fixed_auto ("token_sig",
   5188                                      &tuc->sig),
   5189         GNUNET_JSON_spec_fixed_auto ("token_pub",
   5190                                      &tuc->pub),
   5191         GNUNET_JSON_spec_fixed_auto ("h_issue",
   5192                                      &tuc->h_issue),
   5193         TALER_JSON_spec_token_issue_sig ("ub_sig",
   5194                                          &tuc->unblinded_sig),
   5195         GNUNET_JSON_spec_end ()
   5196       };
   5197       enum GNUNET_GenericReturnValue res;
   5198 
   5199       res = TALER_MHD_parse_json_data (pc->connection,
   5200                                        token,
   5201                                        ispec);
   5202       if (GNUNET_YES != res)
   5203       {
   5204         GNUNET_break_op (0);
   5205         pay_end (pc,
   5206                  (GNUNET_NO == res)
   5207                  ? MHD_YES
   5208                  : MHD_NO);
   5209         return;
   5210       }
   5211 
   5212       for (unsigned int j = 0; j<tokens_index; j++)
   5213       {
   5214         if (0 ==
   5215             GNUNET_memcmp (&tuc->pub,
   5216                            &pc->parse_pay.tokens[j].pub))
   5217         {
   5218           GNUNET_break_op (0);
   5219           pay_end (pc,
   5220                    TALER_MHD_reply_with_error (
   5221                      pc->connection,
   5222                      MHD_HTTP_BAD_REQUEST,
   5223                      TALER_EC_GENERIC_PARAMETER_MALFORMED,
   5224                      "duplicate token in list"));
   5225           return;
   5226         }
   5227       }
   5228     }
   5229   }
   5230 
   5231   pc->phase = PP_PARSE_WALLET_DATA;
   5232 }
   5233 
   5234 
   5235 /**
   5236  * Custom cleanup routine for a `struct PayContext`.
   5237  *
   5238  * @param cls the `struct PayContext` to clean up.
   5239  */
   5240 static void
   5241 pay_context_cleanup (void *cls)
   5242 {
   5243   struct PayContext *pc = cls;
   5244 
   5245   if (NULL != pc->batch_deposits.timeout_task)
   5246   {
   5247     GNUNET_SCHEDULER_cancel (pc->batch_deposits.timeout_task);
   5248     pc->batch_deposits.timeout_task = NULL;
   5249   }
   5250   if (NULL != pc->check_contract.contract_terms_json)
   5251   {
   5252     json_decref (pc->check_contract.contract_terms_json);
   5253     pc->check_contract.contract_terms_json = NULL;
   5254   }
   5255   for (unsigned int i = 0; i<pc->parse_pay.coins_cnt; i++)
   5256   {
   5257     struct DepositConfirmation *dc = &pc->parse_pay.dc[i];
   5258 
   5259     TALER_denom_sig_free (&dc->cdd.denom_sig);
   5260     GNUNET_free (dc->exchange_url);
   5261   }
   5262   GNUNET_free (pc->parse_pay.dc);
   5263   for (unsigned int i = 0; i<pc->parse_pay.tokens_cnt; i++)
   5264   {
   5265     struct TokenUseConfirmation *tuc = &pc->parse_pay.tokens[i];
   5266 
   5267     TALER_token_issue_sig_free (&tuc->unblinded_sig);
   5268   }
   5269   GNUNET_free (pc->parse_pay.tokens);
   5270   for (unsigned int i = 0; i<pc->parse_pay.num_exchanges; i++)
   5271   {
   5272     struct ExchangeGroup *eg = pc->parse_pay.egs[i];
   5273 
   5274     if (NULL != eg->fo)
   5275       TMH_EXCHANGES_keys4exchange_cancel (eg->fo);
   5276     if (NULL != eg->bdh)
   5277       TALER_EXCHANGE_post_batch_deposit_cancel (eg->bdh);
   5278     if (NULL != eg->keys)
   5279       TALER_EXCHANGE_keys_decref (eg->keys);
   5280     GNUNET_free (eg);
   5281   }
   5282   GNUNET_free (pc->parse_pay.egs);
   5283   if (NULL != pc->check_contract.contract_terms)
   5284   {
   5285     TALER_MERCHANT_contract_free (pc->check_contract.contract_terms);
   5286     pc->check_contract.contract_terms = NULL;
   5287   }
   5288   if (NULL != pc->response)
   5289   {
   5290     MHD_destroy_response (pc->response);
   5291     pc->response = NULL;
   5292   }
   5293   GNUNET_free (pc->parse_pay.session_id);
   5294   GNUNET_CONTAINER_DLL_remove (pc_head,
   5295                                pc_tail,
   5296                                pc);
   5297   GNUNET_free (pc->check_contract.pos_key);
   5298   GNUNET_free (pc->compute_money_pots.pots);
   5299   GNUNET_free (pc->compute_money_pots.increments);
   5300   if (NULL != pc->parse_wallet_data.bkps)
   5301   {
   5302     for (size_t i = 0; i < pc->parse_wallet_data.num_bkps; i++)
   5303       GNUNET_CRYPTO_blinded_message_decref (
   5304         pc->parse_wallet_data.bkps[i].blinded_udi.blinded_message);
   5305     GNUNET_array_grow (pc->parse_wallet_data.bkps,
   5306                        pc->parse_wallet_data.num_bkps,
   5307                        0);
   5308   }
   5309   if (NULL != pc->parse_wallet_data.donau_keys)
   5310   {
   5311     DONAU_keys_decref (pc->parse_wallet_data.donau_keys);
   5312     pc->parse_wallet_data.donau_keys = NULL;
   5313   }
   5314   GNUNET_free (pc->parse_wallet_data.donau.donau_url);
   5315   for (unsigned int i = 0; i<pc->parse_wallet_data.token_envelopes_cnt; i++)
   5316   {
   5317     struct TokenEnvelope *ev
   5318       = &pc->parse_wallet_data.token_envelopes[i];
   5319 
   5320     GNUNET_CRYPTO_blinded_message_decref (ev->blinded_token.blinded_pub);
   5321   }
   5322   GNUNET_free (pc->parse_wallet_data.token_envelopes);
   5323   if (NULL != pc->output_tokens)
   5324   {
   5325     for (unsigned int i = 0; i<pc->output_tokens_len; i++)
   5326       if (NULL != pc->output_tokens[i].sig.signature)
   5327         GNUNET_CRYPTO_blinded_sig_decref (pc->output_tokens[i].sig.signature);
   5328     GNUNET_free (pc->output_tokens);
   5329   }
   5330   GNUNET_free (pc);
   5331 }
   5332 
   5333 
   5334 enum MHD_Result
   5335 TMH_post_orders_ID_pay (const struct TMH_RequestHandler *rh,
   5336                         struct MHD_Connection *connection,
   5337                         struct TMH_HandlerContext *hc)
   5338 {
   5339   struct PayContext *pc = hc->ctx;
   5340 
   5341   GNUNET_assert (NULL != hc->infix);
   5342   if (NULL == pc)
   5343   {
   5344     pc = GNUNET_new (struct PayContext);
   5345     pc->connection = connection;
   5346     pc->hc = hc;
   5347     pc->order_id = hc->infix;
   5348     hc->ctx = pc;
   5349     hc->cc = &pay_context_cleanup;
   5350     GNUNET_CONTAINER_DLL_insert (pc_head,
   5351                                  pc_tail,
   5352                                  pc);
   5353   }
   5354   while (1)
   5355   {
   5356     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   5357                 "Processing /pay in phase %d\n",
   5358                 (int) pc->phase);
   5359     switch (pc->phase)
   5360     {
   5361     case PP_PARSE_PAY:
   5362       phase_parse_pay (pc);
   5363       break;
   5364     case PP_PARSE_WALLET_DATA:
   5365       phase_parse_wallet_data (pc);
   5366       break;
   5367     case PP_CHECK_CONTRACT:
   5368       phase_check_contract (pc);
   5369       break;
   5370     case PP_VALIDATE_TOKENS:
   5371       phase_validate_tokens (pc);
   5372       break;
   5373     case PP_CONTRACT_PAID:
   5374       phase_contract_paid (pc);
   5375       break;
   5376     case PP_COMPUTE_MONEY_POTS:
   5377       phase_compute_money_pots (pc);
   5378       break;
   5379     case PP_PAY_TRANSACTION:
   5380       phase_execute_pay_transaction (pc);
   5381       break;
   5382     case PP_REQUEST_DONATION_RECEIPT:
   5383       phase_request_donation_receipt (pc);
   5384       break;
   5385     case PP_FINAL_OUTPUT_TOKEN_PROCESSING:
   5386       phase_final_output_token_processing (pc);
   5387       break;
   5388     case PP_PAYMENT_NOTIFICATION:
   5389       phase_payment_notification (pc);
   5390       break;
   5391     case PP_SUCCESS_RESPONSE:
   5392       phase_success_response (pc);
   5393       break;
   5394     case PP_BATCH_DEPOSITS:
   5395       phase_batch_deposits (pc);
   5396       break;
   5397     case PP_RETURN_RESPONSE:
   5398       phase_return_response (pc);
   5399       break;
   5400     case PP_FAIL_LEGAL_REASONS:
   5401       phase_fail_for_legal_reasons (pc);
   5402       break;
   5403     case PP_END_YES:
   5404       return MHD_YES;
   5405     case PP_END_NO:
   5406       return MHD_NO;
   5407     default:
   5408       /* should not be reachable */
   5409       GNUNET_assert (0);
   5410       return MHD_NO;
   5411     }
   5412     switch (pc->suspended)
   5413     {
   5414     case GNUNET_SYSERR:
   5415       /* during shutdown, we don't generate any more replies */
   5416       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   5417                   "Processing /pay ends due to shutdown in phase %d\n",
   5418                   (int) pc->phase);
   5419       return MHD_NO;
   5420     case GNUNET_NO:
   5421       /* continue to next phase */
   5422       break;
   5423     case GNUNET_YES:
   5424       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
   5425                   "Processing /pay suspended in phase %d\n",
   5426                   (int) pc->phase);
   5427       return MHD_YES;
   5428     }
   5429   }
   5430   /* impossible to get here */
   5431   GNUNET_assert (0);
   5432   return MHD_YES;
   5433 }
   5434 
   5435 
   5436 /* end of taler-merchant-httpd_post-orders-ORDER_ID-pay.c */