merchant

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

commit 508b748f8e0e4817b04cf57bae0c5f528f3377a6
parent a3b07879bb98d6f6b4c9a833467cbfb5fb74cfb3
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri,  6 Sep 2024 09:40:08 +0200

pass on 451 replies from exchange to wallets on /pay

Diffstat:
Msrc/backend/taler-merchant-httpd_post-orders-ID-pay.c | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+), 0 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c @@ -137,6 +137,12 @@ enum PayPhase PP_RETURN_RESPONSE, /** + * An exchange denied a deposit, fail for + * legal reasons. + */ + PP_FAIL_LEGAL_REASONS, + + /** * Return #MHD_YES to end processing. */ PP_END_YES, @@ -346,6 +352,11 @@ struct ExchangeGroup * true if we already tried a forced /keys download. */ bool tried_force_keys; + + /** + * Did this exchange deny the transaction for legal reasons? + */ + bool got_451; }; @@ -651,6 +662,10 @@ struct PayContext */ bool refund_currency_mismatch; + /** + * Did any exchange deny a deposit for legal reasons? + */ + bool got_451; }; @@ -810,6 +825,43 @@ phase_return_response (struct PayContext *pc) /** + * Return a response indicating failure for legal reasons. + * + * @param[in,out] pc payment context we are processing + */ +static void +phase_fail_for_legal_reasons (struct PayContext *pc) +{ + json_t *exchanges; + + GNUNET_assert (0 == pc->pending); + GNUNET_assert (pc->got_451); + exchanges = json_array (); + GNUNET_assert (NULL != exchanges); + for (unsigned int i = 0; i<pc->num_exchanges; i++) + { + struct ExchangeGroup *eg = pc->egs[i]; + + GNUNET_assert (NULL == eg->fo); + GNUNET_assert (NULL == eg->bdh); + if (! eg->got_451) + continue; + GNUNET_assert ( + 0 == + json_array_append_new ( + exchanges, + json_string (eg->exchange_url))); + } + pay_end (pc, + TALER_MHD_REPLY_JSON_PACK ( + pc->connection, + MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS, + GNUNET_JSON_pack_array_steal ("exchange_base_urls", + exchanges))); +} + + +/** * Do database transaction for a completed batch deposit. * * @param eg group that completed @@ -1018,6 +1070,27 @@ batch_deposit_cb ( pay_resume (pc); } return; + case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: + eg->got_451 = true; + pc->got_451 = true; + /* update pc->pending */ + for (size_t i = 0; i<pc->coins_cnt; i++) + { + struct DepositConfirmation *dc = &pc->dc[i]; + + if (0 != strcmp (eg->exchange_url, + pc->dc[i].exchange_url)) + continue; + if (dc->found_in_db) + continue; + pc->pending--; + } + if (0 == pc->pending_at_eg) + { + pc->phase = PP_PAY_TRANSACTION; + pay_resume (pc); + } + return; default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Deposit operation failed with HTTP code %u/%d\n", @@ -2034,6 +2107,11 @@ phase_execute_pay_transaction (struct PayContext *pc) struct TMH_HandlerContext *hc = pc->hc; const char *instance_id = hc->instance->settings.id; + if (pc->got_451) + { + pc->phase = PP_FAIL_LEGAL_REASONS; + return; + } /* Avoid re-trying transactions on soft errors forever! */ if (pc->retry_counter++ > MAX_RETRIES) { @@ -3651,6 +3729,9 @@ TMH_post_orders_ID_pay (const struct TMH_RequestHandler *rh, case PP_RETURN_RESPONSE: phase_return_response (pc); break; + case PP_FAIL_LEGAL_REASONS: + phase_fail_for_legal_reasons (pc); + break; case PP_END_YES: return MHD_YES; case PP_END_NO: