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:
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);
}