/*
  This file is part of TALER
  Copyright (C) 2014-2026 Taler Systems SA

  TALER is free software; you can redistribute it and/or modify it under the
  terms of the GNU Lesser General Public License as published by the Free Software
  Foundation; either version 2.1, or (at your option) any later version.

  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public License along with
  TALER; see the file COPYING.LGPL.  If not, see
  <http://www.gnu.org/licenses/>
*/
/**
 * @file include/taler/taler-merchant/post-orders-ORDER_ID-pay.h
 * @brief C interface for POST /orders/$ORDER_ID/pay of the merchant backend
 * @author Christian Grothoff
 * @author Marcello Stanisci
 */
#ifndef _TALER_MERCHANT__POST_ORDERS_ORDER_ID_PAY_H
#define _TALER_MERCHANT__POST_ORDERS_ORDER_ID_PAY_H

#include <taler/taler-merchant/common.h>


/**
 * Handle for a POST /orders/$ORDER_ID/pay request.
 */
struct TALER_MERCHANT_OrderPayHandle;


/**
 * One coin used to pay (frontend / external wallet mode).
 */
struct TALER_MERCHANT_PaidCoin
{

  /**
   * Denomination public key.
   */
  struct TALER_DenominationPublicKey denom_pub;

  /**
   * Hash of the denomination public key.
   */
  struct TALER_DenominationHashP denom_pub_hash;

  /**
   * Denomination signature over the coin.
   */
  struct TALER_DenominationSignature denom_sig;

  /**
   * Face value of the denomination.
   */
  struct TALER_Amount denom_value;

  /**
   * Public key of the coin.
   */
  struct TALER_CoinSpendPublicKeyP coin_pub;

  /**
   * Signature by the coin authorizing the deposit.
   */
  struct TALER_CoinSpendSignatureP coin_sig;

  /**
   * Hash of the age commitment for this coin.
   */
  struct TALER_AgeCommitmentHashP h_age_commitment;

  /**
   * Set to true if this coin has an age commitment.
   */
  bool has_age_commitment;

  /**
   * Total amount contributed including deposit fee.
   */
  struct TALER_Amount amount_with_fee;

  /**
   * Amount contributed without the deposit fee.
   */
  struct TALER_Amount amount_without_fee;

  /**
   * Deposit fee for this coin.
   */
  struct TALER_Amount deposit_fee;

  /**
   * Base URL of the exchange this coin was issued by.
   */
  const char *exchange_url;

};


/**
 * One coin used to pay (wallet-internal mode, private key available).
 */
struct TALER_MERCHANT_PayCoin
{

  /**
   * Denomination public key.
   */
  struct TALER_DenominationPublicKey denom_pub;

  /**
   * Denomination signature over the coin.
   */
  struct TALER_DenominationSignature denom_sig;

  /**
   * Face value of the denomination.
   */
  struct TALER_Amount denom_value;

  /**
   * Private key of the coin (to sign the deposit).
   */
  struct TALER_CoinSpendPrivateKeyP coin_priv;

  /**
   * Hash of the age commitment for this coin, or NULL if none.
   */
  const struct TALER_AgeCommitmentHashP *h_age_commitment;

  /**
   * Total amount contributed including deposit fee.
   */
  struct TALER_Amount amount_with_fee;

  /**
   * Amount contributed without the deposit fee.
   */
  struct TALER_Amount amount_without_fee;

  /**
   * URL of the exchange that issued @e coin_priv.
   */
  const char *exchange_url;

};


/**
 * Response details for a POST /orders/$ORDER_ID/pay request.
 */
struct TALER_MERCHANT_PayResponse
{

  /**
   * HTTP response details.
   */
  struct TALER_MERCHANT_HttpResponse hr;

  /**
   * Details depending on the HTTP status code.
   */
  union
  {

    /**
     * Details on #MHD_HTTP_OK.
     */
    struct
    {

      /**
       * Merchant signature confirming the payment.
       */
      struct TALER_MerchantSignatureP merchant_sig;

      /**
       * POS confirmation string, or NULL if not applicable.
       */
      const char *pos_confirmation;

      /**
       * Number of output tokens in @a tokens.
       */
      unsigned int num_tokens;

      /**
       * Array of output tokens issued upon payment.
       */
      struct TALER_MERCHANT_OutputToken *tokens;

    } ok;

    /**
     * Details on #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS.
     */
    struct
    {

      /**
       * Number of exchange URLs in @a exchanges.
       */
      unsigned int num_exchanges;

      /**
       * Array of exchange URLs that refused the payment for legal reasons.
       */
      const char **exchanges;

    } unavailable_for_legal_reasons;

  } details;

};


/**
 * Token to use for payment (public form, already obtained).
 */
struct TALER_MERCHANT_UsedToken
{

  /**
   * Signature on TALER_TokenUseRequestPS made with the token use private key.
   */
  struct TALER_TokenUseSignatureP token_sig;

  /**
   * Public key of the token. This was blindly signed by the merchant
   * during the issuance and is now being revealed to the merchant.
   */
  struct TALER_TokenUsePublicKeyP token_pub;

  /**
   * Unblinded signature made by the token issue public key of the merchant.
   */
  struct TALER_TokenIssueSignature ub_sig;

  /**
   * Token issue public key associated with this token.
   */
  struct TALER_TokenIssuePublicKey issue_pub;
};


/**
 * Information we need from the wallet to use a token for an order.
 */
struct TALER_MERCHANT_UseToken
{

  /**
   * Private key of the token (to sign the use authorization).
   */
  struct TALER_TokenUsePrivateKeyP token_priv;

  /**
   * Unblinded signature made by the token issue public key of the merchant.
   */
  struct TALER_TokenIssueSignature ub_sig;

  /**
   * Token issue public key associated with this token.
   */
  struct TALER_TokenIssuePublicKey issue_pub;

};


/**
 * Output token: used both as input to pay (envelope to be signed)
 * and as output in the pay response (blind signature received).
 */
struct TALER_MERCHANT_OutputToken
{

  /**
   * Blinded token envelope to be signed by the issuer (input to pay).
   */
  struct TALER_TokenEnvelope envelope;

  /**
   * Blinded token issue signature received from the issuer (output of pay).
   */
  struct TALER_BlindedTokenIssueSignature blinded_sig;

};


/**
 * Callback for a POST /orders/$ORDER_ID/pay request.
 *
 * @param cls closure
 * @param opr response details
 */
typedef void
(*TALER_MERCHANT_OrderPayCallback)(
  void *cls,
  const struct TALER_MERCHANT_PayResponse *opr);


/**
 * Issue a POST /orders/$ORDER_ID/pay request in frontend mode
 * (coins already signed by the wallet).
 *
 * @param ctx CURL context to use
 * @param merchant_url base URL of the merchant backend
 * @param order_id identifier of the order to pay
 * @param session_id session identifier, or NULL
 * @param wallet_data wallet-specific data (JSON), or NULL
 * @param num_coins number of coins in @a coins
 * @param coins array of coins to pay with (already signed)
 * @param num_tokens number of input tokens in @a tokens
 * @param tokens array of tokens to use for payment
 * @param j_output_tokens JSON array describing desired output tokens, or NULL
 * @param pay_cb callback to invoke with the result
 * @param pay_cb_cls closure for @a pay_cb
 * @return handle for the request, NULL on hard error
 */
struct TALER_MERCHANT_OrderPayHandle *
TALER_MERCHANT_order_pay_frontend (
  struct GNUNET_CURL_Context *ctx,
  const char *merchant_url,
  const char *order_id,
  const char *session_id,
  const json_t *wallet_data,
  unsigned int num_coins,
  const struct TALER_MERCHANT_PaidCoin coins[static num_coins],
  unsigned int num_tokens,
  const struct TALER_MERCHANT_UsedToken *tokens,
  json_t *j_output_tokens,
  TALER_MERCHANT_OrderPayCallback pay_cb,
  void *pay_cb_cls);


/**
 * Issue a POST /orders/$ORDER_ID/pay request in wallet-internal mode
 * (signing done internally).
 *
 * @param ctx CURL context to use
 * @param merchant_url base URL of the merchant backend
 * @param session_id session identifier, or NULL
 * @param h_contract_terms hash of the contract terms
 * @param choice_index payment choice index
 * @param amount total payment amount
 * @param max_fee maximum acceptable fee
 * @param merchant_pub merchant public key
 * @param merchant_sig merchant signature
 * @param timestamp contract timestamp
 * @param refund_deadline refund deadline
 * @param pay_deadline payment deadline
 * @param h_wire hash of the merchant wire details
 * @param order_id identifier of the order to pay
 * @param num_coins number of coins in @a coins
 * @param coins array of coins with private keys
 * @param num_tokens number of input tokens in @a tokens
 * @param tokens array of tokens with private keys
 * @param num_output_tokens number of output tokens in @a output_tokens
 * @param output_tokens array of expected output tokens
 * @param pay_cb callback to invoke with the result
 * @param pay_cb_cls closure for @a pay_cb
 * @return handle for the request, NULL on hard error
 */
struct TALER_MERCHANT_OrderPayHandle *
TALER_MERCHANT_order_pay (
  struct GNUNET_CURL_Context *ctx,
  const char *merchant_url,
  const char *session_id,
  const struct TALER_PrivateContractHashP *h_contract_terms,
  int choice_index,
  const struct TALER_Amount *amount,
  const struct TALER_Amount *max_fee,
  const struct TALER_MerchantPublicKeyP *merchant_pub,
  const struct TALER_MerchantSignatureP *merchant_sig,
  struct GNUNET_TIME_Timestamp timestamp,
  struct GNUNET_TIME_Timestamp refund_deadline,
  struct GNUNET_TIME_Timestamp pay_deadline,
  const struct TALER_MerchantWireHashP *h_wire,
  const char *order_id,
  unsigned int num_coins,
  const struct TALER_MERCHANT_PayCoin coins[static num_coins],
  unsigned int num_tokens,
  const struct TALER_MERCHANT_UseToken *tokens,
  unsigned int num_output_tokens,
  const struct TALER_MERCHANT_OutputToken *output_tokens,
  TALER_MERCHANT_OrderPayCallback pay_cb,
  void *pay_cb_cls);


/**
 * Cancel a POST /orders/$ORDER_ID/pay request.
 *
 * @param[in] oph handle to cancel
 */
void
TALER_MERCHANT_order_pay_cancel (
  struct TALER_MERCHANT_OrderPayHandle *oph);


#endif
