merchant

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

commit 864a55a530b2e311ada9507bde4dd621826d6028
parent b8fa0dde35ddd207a3239f97954c547676e89b21
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 14 Jun 2020 14:25:58 +0200

add logic to parse refund details

Diffstat:
Msrc/lib/merchant_api_wallet_get_order.c | 212++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 166 insertions(+), 46 deletions(-)

diff --git a/src/lib/merchant_api_wallet_get_order.c b/src/lib/merchant_api_wallet_get_order.c @@ -66,6 +66,37 @@ struct TALER_MERCHANT_OrderWalletGetHandle /** + * Convenience function to call the callback in @a owgh with an error code of + * @a ec and the exchange body being set to @a reply. + * + * @param owgh handle providing callback + * @param ec error code to return to application + * @param reply JSON reply we got from the exchange, can be NULL + */ +static void +cb_failure (struct TALER_MERCHANT_OrderWalletGetHandle *owgh, + enum TALER_ErrorCode ec, + const json_t *reply) +{ + struct TALER_MERCHANT_HttpResponse hr = { + .ec = TALER_EC_CHECK_PAYMENT_RESPONSE_MALFORMED, + .reply = reply + }; + + owgh->cb (owgh->cb_cls, + &hr, + GNUNET_SYSERR, + GNUNET_SYSERR, + NULL, + NULL, + NULL, + NULL, + 0, + NULL); +} + + +/** * Function called when we're done processing the GET /check-payment request. * * @param cls the `struct TALER_MERCHANT_OrderWalletGetHandle` @@ -116,22 +147,10 @@ handle_wallet_get_order_finished (void *cls, "already_paid_order_id")); if (NULL == taler_pay_uri) { - struct TALER_MERCHANT_HttpResponse hr = { - .ec = TALER_EC_CHECK_PAYMENT_RESPONSE_MALFORMED, - .reply = json - }; - GNUNET_break_op (0); - owgh->cb (owgh->cb_cls, - &hr, - GNUNET_SYSERR, - GNUNET_SYSERR, - NULL, - NULL, - NULL, - NULL, - 0, - NULL); + cb_failure (owgh, + TALER_EC_CHECK_PAYMENT_RESPONSE_MALFORMED, + json); } else { @@ -160,7 +179,7 @@ handle_wallet_get_order_finished (void *cls, json_t *refunds; bool refunded; struct TALER_MerchantPublicKeyP merchant_pub; - + unsigned int refund_len; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_bool ("refunded", &refunded), @@ -178,44 +197,145 @@ handle_wallet_get_order_finished (void *cls, spec, NULL, NULL)) { - struct TALER_MERCHANT_HttpResponse hr = { - .ec = TALER_EC_CHECK_PAYMENT_RESPONSE_MALFORMED, - .reply = json - }; - GNUNET_break_op (0); - owgh->cb (owgh->cb_cls, - &hr, - GNUNET_SYSERR, - GNUNET_SYSERR, - NULL, - NULL, - NULL, - NULL, - 0, - NULL); + cb_failure (owgh, + TALER_EC_CHECK_PAYMENT_RESPONSE_MALFORMED, + json); TALER_MERCHANT_wallet_order_get_cancel (owgh); return; } - // FIXME: check 'refunds' is an array! + if (! json_is_array (refunds)) + { + GNUNET_break_op (0); + cb_failure (owgh, + TALER_EC_CHECK_PAYMENT_RESPONSE_MALFORMED, + json); + GNUNET_JSON_parse_free (spec); + TALER_MERCHANT_wallet_order_get_cancel (owgh); + return; + } + refund_len = json_array_size (refunds); { - struct TALER_MERCHANT_HttpResponse hr = { - .reply = json, - .http_status = MHD_HTTP_OK - }; + struct TALER_MERCHANT_RefundDetail rds[refund_len]; - owgh->cb (owgh->cb_cls, - &hr, - GNUNET_YES, - refunded ? GNUNET_YES : GNUNET_NO, - refunded ? &refund_amount : NULL, - NULL, /* paid! */ - NULL, /* paid! */ - &merchant_pub, - 0, // FIXME: parse refunds! - NULL); // FIXME: parse refunds! + memset (rds, + 0, + sizeof (rds)); + for (unsigned int i = 0; i<refund_len; i++) + { + struct TALER_MERCHANT_RefundDetail *rd = &rds[i]; + const json_t *jrefund = json_array_get (refunds, + i); + uint32_t exchange_status; + int ret; + struct GNUNET_JSON_Specification espec[] = { + GNUNET_JSON_spec_uint32 ("exchange_status", + &exchange_status), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (jrefund, + espec, + NULL, NULL)) + { + GNUNET_break_op (0); + cb_failure (owgh, + TALER_EC_CHECK_PAYMENT_RESPONSE_MALFORMED, + json); + TALER_MERCHANT_wallet_order_get_cancel (owgh); + return; + } + + if (MHD_HTTP_OK == exchange_status) + { + struct GNUNET_JSON_Specification rspec[] = { + GNUNET_JSON_spec_fixed_auto ("exchange_sig", + &rd->exchange_sig), + GNUNET_JSON_spec_fixed_auto ("exchange_pub", + &rd->exchange_pub), + GNUNET_JSON_spec_uint64 ("rtransaction_id", + &rd->rtransaction_id), + GNUNET_JSON_spec_fixed_auto ("coin_pub", + &rd->coin_pub), + TALER_JSON_spec_amount ("refund_amount", + &rd->refund_amount), + GNUNET_JSON_spec_end () + }; + + ret = GNUNET_JSON_parse (jrefund, + rspec, + NULL, NULL); + } + else + { + struct GNUNET_JSON_Specification rspec[] = { + GNUNET_JSON_spec_fixed_auto ("coin_pub", + &rd->coin_pub), + GNUNET_JSON_spec_uint64 ("rtransaction_id", + &rd->rtransaction_id), + TALER_JSON_spec_amount ("refund_amount", + &rd->refund_amount), + GNUNET_JSON_spec_end () + }; + + ret = GNUNET_JSON_parse (jrefund, + rspec, + NULL, NULL); + if (GNUNET_OK == ret) + { + /* parse optional arguments */ + json_t *jec; + + jec = json_object_get (jrefund, + "exchange_code"); + if (NULL != jec) + { + if (! json_is_integer (jec)) + { + GNUNET_break_op (0); + ret = GNUNET_SYSERR; + } + else + { + rd->hr.ec = (enum TALER_ErrorCode) json_integer_value (jec); + } + } + rd->hr.reply = json_object_get (jrefund, + "exchange_reply"); + } + } + if (GNUNET_OK != ret) + { + GNUNET_break_op (0); + cb_failure (owgh, + TALER_EC_CHECK_PAYMENT_RESPONSE_MALFORMED, + json); + TALER_MERCHANT_wallet_order_get_cancel (owgh); + return; + } + rd->hr.http_status = exchange_status; + } + + { + struct TALER_MERCHANT_HttpResponse hr = { + .reply = json, + .http_status = MHD_HTTP_OK + }; + + owgh->cb (owgh->cb_cls, + &hr, + GNUNET_YES, + refunded ? GNUNET_YES : GNUNET_NO, + refunded ? &refund_amount : NULL, + NULL, /* paid! */ + NULL, /* paid! */ + &merchant_pub, + refund_len, + rds); + } } GNUNET_JSON_parse_free (spec); }