working on #3641: more on /refund implementation
This commit is contained in:
parent
07d9978fb9
commit
0c959e75d1
@ -105,12 +105,16 @@ calculate_transaction_list_totals (struct TALER_EXCHANGEDB_TransactionList *tl,
|
|||||||
{
|
{
|
||||||
struct TALER_Amount spent = *off;
|
struct TALER_Amount spent = *off;
|
||||||
struct TALER_EXCHANGEDB_TransactionList *pos;
|
struct TALER_EXCHANGEDB_TransactionList *pos;
|
||||||
|
struct TALER_Amount refunded;
|
||||||
|
|
||||||
|
TALER_amount_get_zero (spent.currency,
|
||||||
|
&refunded);
|
||||||
for (pos = tl; NULL != pos; pos = pos->next)
|
for (pos = tl; NULL != pos; pos = pos->next)
|
||||||
{
|
{
|
||||||
switch (pos->type)
|
switch (pos->type)
|
||||||
{
|
{
|
||||||
case TALER_EXCHANGEDB_TT_DEPOSIT:
|
case TALER_EXCHANGEDB_TT_DEPOSIT:
|
||||||
|
/* spent += pos->amount_with_fee */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_amount_add (&spent,
|
TALER_amount_add (&spent,
|
||||||
&spent,
|
&spent,
|
||||||
@ -121,6 +125,7 @@ calculate_transaction_list_totals (struct TALER_EXCHANGEDB_TransactionList *tl,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TALER_EXCHANGEDB_TT_REFRESH_MELT:
|
case TALER_EXCHANGEDB_TT_REFRESH_MELT:
|
||||||
|
/* spent += pos->amount_with_fee */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_amount_add (&spent,
|
TALER_amount_add (&spent,
|
||||||
&spent,
|
&spent,
|
||||||
@ -130,8 +135,37 @@ calculate_transaction_list_totals (struct TALER_EXCHANGEDB_TransactionList *tl,
|
|||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TALER_EXCHANGEDB_TT_REFUND:
|
||||||
|
/* refunded += pos->refund_amount - pos->refund_fee */
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_amount_add (&refunded,
|
||||||
|
&refunded,
|
||||||
|
&pos->details.refund->refund_amount))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_amount_subtract (&refunded,
|
||||||
|
&refunded,
|
||||||
|
&pos->details.refund->refund_fee))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* spent = spent - refunded */
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_amount_subtract (&spent,
|
||||||
|
&spent,
|
||||||
|
&refunded))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
*ret = spent;
|
*ret = spent;
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
@ -261,6 +295,252 @@ TMH_DB_execute_deposit (struct MHD_Connection *connection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a "/refund". Returns a confirmation that the refund
|
||||||
|
* was successful, or a failure if we are not aware of a matching
|
||||||
|
* /deposit or if it is too late to do the refund.
|
||||||
|
*
|
||||||
|
* @param connection the MHD connection to handle
|
||||||
|
* @param refund refund details
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TMH_DB_execute_refund (struct MHD_Connection *connection,
|
||||||
|
const struct TALER_EXCHANGEDB_Refund *refund)
|
||||||
|
{
|
||||||
|
struct TALER_EXCHANGEDB_Session *session;
|
||||||
|
struct TALER_EXCHANGEDB_TransactionList *tl;
|
||||||
|
struct TALER_EXCHANGEDB_TransactionList *tlp;
|
||||||
|
const struct TALER_EXCHANGEDB_Deposit *dep;
|
||||||
|
const struct TALER_EXCHANGEDB_Refund *ref;
|
||||||
|
struct TMH_KS_StateHandle *mks;
|
||||||
|
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
||||||
|
struct TALER_Amount expect_fee;
|
||||||
|
int ret;
|
||||||
|
int deposit_found;
|
||||||
|
int refund_found;
|
||||||
|
int done;
|
||||||
|
int fee_cmp;
|
||||||
|
|
||||||
|
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls)))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||||
|
}
|
||||||
|
dep = NULL;
|
||||||
|
ref = NULL;
|
||||||
|
START_TRANSACTION (session, connection);
|
||||||
|
tl = TMH_plugin->get_coin_transactions (TMH_plugin->cls,
|
||||||
|
session,
|
||||||
|
&refund->coin.coin_pub);
|
||||||
|
if (NULL == tl)
|
||||||
|
{
|
||||||
|
TMH_plugin->rollback (TMH_plugin->cls,
|
||||||
|
session);
|
||||||
|
return TMH_RESPONSE_reply_refund_failure (connection,
|
||||||
|
MHD_HTTP_NOT_FOUND);
|
||||||
|
}
|
||||||
|
deposit_found = GNUNET_NO;
|
||||||
|
for (tlp = tl; NULL != tlp; tlp = tlp->next)
|
||||||
|
{
|
||||||
|
switch (tlp->type)
|
||||||
|
{
|
||||||
|
case TALER_EXCHANGEDB_TT_DEPOSIT:
|
||||||
|
{
|
||||||
|
dep = tlp->details.deposit;
|
||||||
|
if ( (0 == memcmp (&dep->merchant_pub,
|
||||||
|
&refund->merchant_pub,
|
||||||
|
sizeof (struct TALER_MerchantPublicKeyP))) &&
|
||||||
|
(0 == memcmp (&dep->h_contract,
|
||||||
|
&refund->h_contract,
|
||||||
|
sizeof (struct GNUNET_HashCode))) &&
|
||||||
|
(dep->transaction_id == refund->transaction_id) )
|
||||||
|
{
|
||||||
|
deposit_found = GNUNET_YES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TALER_EXCHANGEDB_TT_REFRESH_MELT:
|
||||||
|
/* Melts cannot be refunded, ignore here */
|
||||||
|
break;
|
||||||
|
case TALER_EXCHANGEDB_TT_REFUND:
|
||||||
|
{
|
||||||
|
ref = tlp->details.refund;
|
||||||
|
/* First, check if existing refund request is identical */
|
||||||
|
if ( (0 == memcmp (&ref->merchant_pub,
|
||||||
|
&refund->merchant_pub,
|
||||||
|
sizeof (struct TALER_MerchantPublicKeyP))) &&
|
||||||
|
(0 == memcmp (&ref->h_contract,
|
||||||
|
&refund->h_contract,
|
||||||
|
sizeof (struct GNUNET_HashCode))) &&
|
||||||
|
(ref->transaction_id == refund->transaction_id) &&
|
||||||
|
(ref->rtransaction_id == refund->rtransaction_id) )
|
||||||
|
{
|
||||||
|
refund_found = GNUNET_YES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Second, check if existing refund request conflicts */
|
||||||
|
if ( (0 == memcmp (&ref->merchant_pub,
|
||||||
|
&refund->merchant_pub,
|
||||||
|
sizeof (struct TALER_MerchantPublicKeyP))) &&
|
||||||
|
(0 == memcmp (&ref->h_contract,
|
||||||
|
&refund->h_contract,
|
||||||
|
sizeof (struct GNUNET_HashCode))) &&
|
||||||
|
(ref->transaction_id == refund->transaction_id) &&
|
||||||
|
(ref->rtransaction_id != refund->rtransaction_id) )
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0); /* conflicting refound found */
|
||||||
|
refund_found = GNUNET_SYSERR;
|
||||||
|
/* NOTE: Alternatively we could total up all existing
|
||||||
|
refunds and check if the sum still permits the
|
||||||
|
refund requested (thus allowing multiple, partial
|
||||||
|
refunds). Fow now, we keep it simple. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* handle if deposit was NOT found */
|
||||||
|
if (GNUNET_NO == deposit_found)
|
||||||
|
{
|
||||||
|
TMH_plugin->rollback (TMH_plugin->cls,
|
||||||
|
session);
|
||||||
|
TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
|
||||||
|
tl);
|
||||||
|
return TMH_RESPONSE_reply_deposit_unknown (connection);
|
||||||
|
}
|
||||||
|
/* handle if conflicting refund found */
|
||||||
|
if (GNUNET_SYSERR == refund_found)
|
||||||
|
{
|
||||||
|
TMH_plugin->rollback (TMH_plugin->cls,
|
||||||
|
session);
|
||||||
|
ret = TMH_RESPONSE_reply_refund_conflict (connection,
|
||||||
|
tl);
|
||||||
|
TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
|
||||||
|
tl);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* handle if identical refund found */
|
||||||
|
if (GNUNET_YES == refund_found)
|
||||||
|
{
|
||||||
|
/* /refund already done, simply re-transmit confirmation */
|
||||||
|
TMH_plugin->rollback (TMH_plugin->cls,
|
||||||
|
session);
|
||||||
|
ret = TMH_RESPONSE_reply_refund_success (connection,
|
||||||
|
ref);
|
||||||
|
TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
|
||||||
|
tl);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check currency is compatible */
|
||||||
|
if ( (GNUNET_YES !=
|
||||||
|
TALER_amount_cmp_currency (&refund->refund_amount,
|
||||||
|
&dep->amount_with_fee)) ||
|
||||||
|
(GNUNET_YES !=
|
||||||
|
TALER_amount_cmp_currency (&refund->refund_fee,
|
||||||
|
&dep->deposit_fee)) )
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0); /* currency missmatch */
|
||||||
|
TMH_plugin->rollback (TMH_plugin->cls,
|
||||||
|
session);
|
||||||
|
return TMH_RESPONSE_reply_refund_failure (connection,
|
||||||
|
MHD_HTTP_PRECONDITION_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if we already send the money for the /deposit */
|
||||||
|
done = TMH_plugin->test_deposit_done (TMH_plugin->cls,
|
||||||
|
session,
|
||||||
|
dep);
|
||||||
|
if (GNUNET_SYSERR == done)
|
||||||
|
{
|
||||||
|
/* Internal error, we first had the deposit in the history,
|
||||||
|
but now it is gone? */
|
||||||
|
GNUNET_break (0);
|
||||||
|
TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
|
||||||
|
tl);
|
||||||
|
TMH_plugin->rollback (TMH_plugin->cls,
|
||||||
|
session);
|
||||||
|
return TMH_RESPONSE_reply_internal_error (connection,
|
||||||
|
"database inconsistent");
|
||||||
|
}
|
||||||
|
if (GNUNET_YES == done)
|
||||||
|
{
|
||||||
|
/* money was already transferred to merchant, can no longer refund */
|
||||||
|
TMH_plugin->rollback (TMH_plugin->cls,
|
||||||
|
session);
|
||||||
|
TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
|
||||||
|
tl);
|
||||||
|
return TMH_RESPONSE_reply_refund_failure (connection,
|
||||||
|
MHD_HTTP_GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We no longer need 'tl' or 'dep' or 'ref' */
|
||||||
|
TMH_plugin->free_coin_transaction_list (TMH_plugin->cls,
|
||||||
|
tl);
|
||||||
|
|
||||||
|
/* check refund amount is sufficiently low */
|
||||||
|
if (1 == TALER_amount_cmp (&refund->refund_amount,
|
||||||
|
&dep->amount_with_fee) )
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0); /* cannot refund more than original value */
|
||||||
|
return TMH_RESPONSE_reply_refund_failure (connection,
|
||||||
|
MHD_HTTP_PRECONDITION_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check refund fee matches fee of denomination key! */
|
||||||
|
mks = TMH_KS_acquire ();
|
||||||
|
dki = TMH_KS_denomination_key_lookup (mks,
|
||||||
|
&dep->coin.denom_pub,
|
||||||
|
TMH_KS_DKU_DEPOSIT);
|
||||||
|
if (NULL == dki)
|
||||||
|
{
|
||||||
|
/* DKI not found, but we do have a coin with this DK in our database;
|
||||||
|
not good... */
|
||||||
|
GNUNET_break (0);
|
||||||
|
TMH_KS_release (mks);
|
||||||
|
return TMH_RESPONSE_reply_internal_error (connection,
|
||||||
|
"denomination key not found");
|
||||||
|
}
|
||||||
|
TALER_amount_ntoh (&expect_fee,
|
||||||
|
&dki->issue.properties.fee_refund);
|
||||||
|
fee_cmp = TALER_amount_cmp (&refund->refund_fee,
|
||||||
|
&expect_fee);
|
||||||
|
TMH_KS_release (mks);
|
||||||
|
|
||||||
|
if (-1 == fee_cmp)
|
||||||
|
{
|
||||||
|
TMH_plugin->rollback (TMH_plugin->cls,
|
||||||
|
session);
|
||||||
|
return TMH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
"refund_fee");
|
||||||
|
}
|
||||||
|
if (1 == fee_cmp)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"Refund fee proposed by merchant is higher than necessary.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally, store new refund data */
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TMH_plugin->insert_refund (TMH_plugin->cls,
|
||||||
|
session,
|
||||||
|
refund))
|
||||||
|
{
|
||||||
|
TALER_LOG_WARNING ("Failed to store /refund information in database\n");
|
||||||
|
TMH_plugin->rollback (TMH_plugin->cls,
|
||||||
|
session);
|
||||||
|
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||||
|
}
|
||||||
|
COMMIT_TRANSACTION(session, connection);
|
||||||
|
|
||||||
|
return TMH_RESPONSE_reply_refund_success (connection,
|
||||||
|
refund);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a /reserve/status. Given the public key of a reserve,
|
* Execute a /reserve/status. Given the public key of a reserve,
|
||||||
* return the associated transaction history.
|
* return the associated transaction history.
|
||||||
|
@ -40,6 +40,20 @@ TMH_DB_execute_deposit (struct MHD_Connection *connection,
|
|||||||
const struct TALER_EXCHANGEDB_Deposit *deposit);
|
const struct TALER_EXCHANGEDB_Deposit *deposit);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a "/refund". Returns a confirmation that the refund
|
||||||
|
* was successful, or a failure if we are not aware of a matching
|
||||||
|
* /deposit or if it is too late to do the refund.
|
||||||
|
*
|
||||||
|
* @param connection the MHD connection to handle
|
||||||
|
* @param refund refund details
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TMH_DB_execute_refund (struct MHD_Connection *connection,
|
||||||
|
const struct TALER_EXCHANGEDB_Refund *refund);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a "/reserve/status". Given the public key of a reserve,
|
* Execute a "/reserve/status". Given the public key of a reserve,
|
||||||
* return the associated transaction history.
|
* return the associated transaction history.
|
||||||
|
@ -63,6 +63,21 @@ verify_and_execute_refund (struct MHD_Connection *connection,
|
|||||||
&refund->refund_fee);
|
&refund->refund_fee);
|
||||||
dr.merchant = refund->merchant_pub;
|
dr.merchant = refund->merchant_pub;
|
||||||
dr.coin_pub = refund->coin.coin_pub;
|
dr.coin_pub = refund->coin.coin_pub;
|
||||||
|
if (GNUNET_YES !=
|
||||||
|
TALER_amount_cmp_currency (&refund->refund_amount,
|
||||||
|
&refund->refund_fee) )
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return TMH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
"refund_fee");
|
||||||
|
}
|
||||||
|
if (-1 == TALER_amount_cmp (&refund->refund_amount,
|
||||||
|
&refund->refund_fee) )
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return TMH_RESPONSE_reply_signature_invalid (connection,
|
||||||
|
"refund_amount");
|
||||||
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
|
||||||
&dr.purpose,
|
&dr.purpose,
|
||||||
@ -73,13 +88,8 @@ verify_and_execute_refund (struct MHD_Connection *connection,
|
|||||||
return TMH_RESPONSE_reply_signature_invalid (connection,
|
return TMH_RESPONSE_reply_signature_invalid (connection,
|
||||||
"merchant_sig");
|
"merchant_sig");
|
||||||
}
|
}
|
||||||
#if 1
|
|
||||||
GNUNET_break (0); // FIXME: not implemented
|
|
||||||
return MHD_NO;
|
|
||||||
#else
|
|
||||||
return TMH_DB_execute_refund (connection,
|
return TMH_DB_execute_refund (connection,
|
||||||
refund);
|
refund);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -642,6 +642,86 @@ compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHistory *rh,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate refund conflict failure message. Returns the
|
||||||
|
* transaction list @a tl with the details about the conflict.
|
||||||
|
*
|
||||||
|
* @param connection connection to the client
|
||||||
|
* @param tl transaction list showing the conflict
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TMH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection,
|
||||||
|
const struct TALER_EXCHANGEDB_TransactionList *tl)
|
||||||
|
{
|
||||||
|
return TMH_RESPONSE_reply_json_pack (connection,
|
||||||
|
MHD_HTTP_CONFLICT,
|
||||||
|
"{s:s, s:o}",
|
||||||
|
"status", "conflicting refund",
|
||||||
|
"history", compile_transaction_history (tl));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate generic refund failure message. All the details
|
||||||
|
* are in the @a response_code. The body can be empty.
|
||||||
|
*
|
||||||
|
* @param connection connection to the client
|
||||||
|
* @param response_code response code to generate
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TMH_RESPONSE_reply_refund_failure (struct MHD_Connection *connection,
|
||||||
|
unsigned int response_code)
|
||||||
|
{
|
||||||
|
return TMH_RESPONSE_reply_json_pack (connection,
|
||||||
|
response_code,
|
||||||
|
"{s:s}",
|
||||||
|
"error",
|
||||||
|
"no details");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate successful refund confirmation message.
|
||||||
|
*
|
||||||
|
* @param connection connection to the client
|
||||||
|
* @param refund details about the successful refund
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TMH_RESPONSE_reply_refund_success (struct MHD_Connection *connection,
|
||||||
|
const struct TALER_EXCHANGEDB_Refund *refund)
|
||||||
|
{
|
||||||
|
struct TALER_RefundConfirmationPS rc;
|
||||||
|
struct TALER_ExchangePublicKeyP pub;
|
||||||
|
struct TALER_ExchangeSignatureP sig;
|
||||||
|
|
||||||
|
rc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND);
|
||||||
|
rc.purpose.size = htonl (sizeof (struct TALER_RefundConfirmationPS));
|
||||||
|
rc.h_contract = refund->h_contract;
|
||||||
|
rc.transaction_id = GNUNET_htonll (refund->transaction_id);
|
||||||
|
rc.coin_pub = refund->coin.coin_pub;
|
||||||
|
rc.merchant = refund->merchant_pub;
|
||||||
|
rc.rtransaction_id = GNUNET_htonll (refund->rtransaction_id);
|
||||||
|
TALER_amount_hton (&rc.refund_amount,
|
||||||
|
&refund->refund_amount);
|
||||||
|
TALER_amount_hton (&rc.refund_fee,
|
||||||
|
&refund->refund_fee);
|
||||||
|
TMH_KS_sign (&rc.purpose,
|
||||||
|
&pub,
|
||||||
|
&sig);
|
||||||
|
return TMH_RESPONSE_reply_json_pack (connection,
|
||||||
|
MHD_HTTP_OK,
|
||||||
|
"{s:s, s:o, s:o}",
|
||||||
|
"status", "REFUND_OK",
|
||||||
|
"sig", GNUNET_JSON_from_data (&sig,
|
||||||
|
sizeof (sig)),
|
||||||
|
"pub", GNUNET_JSON_from_data (&pub,
|
||||||
|
sizeof (pub)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send reserve status information to client.
|
* Send reserve status information to client.
|
||||||
*
|
*
|
||||||
|
@ -247,6 +247,44 @@ TMH_RESPONSE_reply_deposit_insufficient_funds (struct MHD_Connection *connection
|
|||||||
const struct TALER_EXCHANGEDB_TransactionList *tl);
|
const struct TALER_EXCHANGEDB_TransactionList *tl);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate refund conflict failure message. Returns the
|
||||||
|
* transaction list @a tl with the details about the conflict.
|
||||||
|
*
|
||||||
|
* @param connection connection to the client
|
||||||
|
* @param tl transaction list showing the conflict
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TMH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection,
|
||||||
|
const struct TALER_EXCHANGEDB_TransactionList *tl);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate generic refund failure message. All the details
|
||||||
|
* are in the @a response_code. The body can be empty.
|
||||||
|
*
|
||||||
|
* @param connection connection to the client
|
||||||
|
* @param response_code response code to generate
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TMH_RESPONSE_reply_refund_failure (struct MHD_Connection *connection,
|
||||||
|
unsigned int response_code);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate successful refund confirmation message.
|
||||||
|
*
|
||||||
|
* @param connection connection to the client
|
||||||
|
* @param refund details about the successful refund
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TMH_RESPONSE_reply_refund_success (struct MHD_Connection *connection,
|
||||||
|
const struct TALER_EXCHANGEDB_Refund *refund);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A merchant asked for details about a deposit, but
|
* A merchant asked for details about a deposit, but
|
||||||
* we do not know anything about the deposit. Generate the
|
* we do not know anything about the deposit. Generate the
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2015 GNUnet e.V.
|
Copyright (C) 2015, 2016 Inria & GNUnet e.V.
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify it under the
|
TALER is free software; you can redistribute it and/or modify it under the
|
||||||
terms of the GNU General Public License as published by the Free Software
|
terms of the GNU General Public License as published by the Free Software
|
||||||
@ -107,6 +107,9 @@ common_free_coin_transaction_list (void *cls,
|
|||||||
case TALER_EXCHANGEDB_TT_REFRESH_MELT:
|
case TALER_EXCHANGEDB_TT_REFRESH_MELT:
|
||||||
GNUNET_free (list->details.melt);
|
GNUNET_free (list->details.melt);
|
||||||
break;
|
break;
|
||||||
|
case TALER_EXCHANGEDB_TT_REFUND:
|
||||||
|
GNUNET_free (list->details.refund);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
GNUNET_free (list);
|
GNUNET_free (list);
|
||||||
list = next;
|
list = next;
|
||||||
|
@ -2176,6 +2176,26 @@ postgres_mark_deposit_tiny (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if a deposit was marked as done, thereby declaring that it cannot be
|
||||||
|
* refunded anymore.
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param session connection to the database
|
||||||
|
* @param deposit the deposit to check
|
||||||
|
* @return #GNUNET_YES if is is marked done done, #GNUNET_NO if not,
|
||||||
|
* #GNUNET_SYSERR on error (deposit unknown)
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
postgres_test_deposit_done (void *cls,
|
||||||
|
struct TALER_EXCHANGEDB_Session *session,
|
||||||
|
const struct TALER_EXCHANGEDB_Deposit *deposit)
|
||||||
|
{
|
||||||
|
GNUNET_break (0); // not implemented
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark a deposit as done, thereby declaring that it cannot be
|
* Mark a deposit as done, thereby declaring that it cannot be
|
||||||
* executed at all anymore, and should no longer be returned by
|
* executed at all anymore, and should no longer be returned by
|
||||||
@ -2466,6 +2486,24 @@ postgres_insert_deposit (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert information about refunded coin into the database.
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param session connection to the database
|
||||||
|
* @param refund refund information to store
|
||||||
|
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
postgres_insert_refund (void *cls,
|
||||||
|
struct TALER_EXCHANGEDB_Session *session,
|
||||||
|
const struct TALER_EXCHANGEDB_Refund *refund)
|
||||||
|
{
|
||||||
|
GNUNET_break (0); // not implemented
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup refresh session data under the given @a session_hash.
|
* Lookup refresh session data under the given @a session_hash.
|
||||||
*
|
*
|
||||||
@ -4242,10 +4280,12 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
|
|||||||
plugin->free_reserve_history = &common_free_reserve_history;
|
plugin->free_reserve_history = &common_free_reserve_history;
|
||||||
plugin->have_deposit = &postgres_have_deposit;
|
plugin->have_deposit = &postgres_have_deposit;
|
||||||
plugin->mark_deposit_tiny = &postgres_mark_deposit_tiny;
|
plugin->mark_deposit_tiny = &postgres_mark_deposit_tiny;
|
||||||
|
plugin->test_deposit_done = &postgres_test_deposit_done;
|
||||||
plugin->mark_deposit_done = &postgres_mark_deposit_done;
|
plugin->mark_deposit_done = &postgres_mark_deposit_done;
|
||||||
plugin->get_ready_deposit = &postgres_get_ready_deposit;
|
plugin->get_ready_deposit = &postgres_get_ready_deposit;
|
||||||
plugin->iterate_matching_deposits = &postgres_iterate_matching_deposits;
|
plugin->iterate_matching_deposits = &postgres_iterate_matching_deposits;
|
||||||
plugin->insert_deposit = &postgres_insert_deposit;
|
plugin->insert_deposit = &postgres_insert_deposit;
|
||||||
|
plugin->insert_refund = &postgres_insert_refund;
|
||||||
plugin->get_refresh_session = &postgres_get_refresh_session;
|
plugin->get_refresh_session = &postgres_get_refresh_session;
|
||||||
plugin->create_refresh_session = &postgres_create_refresh_session;
|
plugin->create_refresh_session = &postgres_create_refresh_session;
|
||||||
plugin->insert_refresh_melt = &postgres_insert_refresh_melt;
|
plugin->insert_refresh_melt = &postgres_insert_refresh_melt;
|
||||||
|
@ -499,7 +499,12 @@ enum TALER_EXCHANGEDB_TransactionType
|
|||||||
/**
|
/**
|
||||||
* /refresh/melt operation.
|
* /refresh/melt operation.
|
||||||
*/
|
*/
|
||||||
TALER_EXCHANGEDB_TT_REFRESH_MELT = 1
|
TALER_EXCHANGEDB_TT_REFRESH_MELT = 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* /refund operation.
|
||||||
|
*/
|
||||||
|
TALER_EXCHANGEDB_TT_REFUND = 2
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -536,6 +541,11 @@ struct TALER_EXCHANGEDB_TransactionList
|
|||||||
*/
|
*/
|
||||||
struct TALER_EXCHANGEDB_RefreshMelt *melt;
|
struct TALER_EXCHANGEDB_RefreshMelt *melt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Details if transaction was a /refund operation.
|
||||||
|
*/
|
||||||
|
struct TALER_EXCHANGEDB_Refund *refund;
|
||||||
|
|
||||||
} details;
|
} details;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -953,6 +963,20 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
const struct TALER_EXCHANGEDB_Deposit *deposit);
|
const struct TALER_EXCHANGEDB_Deposit *deposit);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert information about refunded coin into the database.
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param session connection to the database
|
||||||
|
* @param refund refund information to store
|
||||||
|
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
(*insert_refund) (void *cls,
|
||||||
|
struct TALER_EXCHANGEDB_Session *session,
|
||||||
|
const struct TALER_EXCHANGEDB_Refund *refund);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark a deposit as tiny, thereby declaring that it cannot be
|
* Mark a deposit as tiny, thereby declaring that it cannot be
|
||||||
* executed by itself and should no longer be returned by
|
* executed by itself and should no longer be returned by
|
||||||
@ -969,6 +993,22 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
unsigned long long rowid);
|
unsigned long long rowid);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if a deposit was marked as done, thereby declaring that it cannot be
|
||||||
|
* refunded anymore.
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param session connection to the database
|
||||||
|
* @param deposit the deposit to check
|
||||||
|
* @return #GNUNET_YES if is is marked done done, #GNUNET_NO if not,
|
||||||
|
* #GNUNET_SYSERR on error (deposit unknown)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
(*test_deposit_done) (void *cls,
|
||||||
|
struct TALER_EXCHANGEDB_Session *session,
|
||||||
|
const struct TALER_EXCHANGEDB_Deposit *deposit);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark a deposit as done, thereby declaring that it cannot be
|
* Mark a deposit as done, thereby declaring that it cannot be
|
||||||
* executed at all anymore, and should no longer be returned by
|
* executed at all anymore, and should no longer be returned by
|
||||||
|
Loading…
Reference in New Issue
Block a user