taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

post-orders-ORDER_ID-abort.rst (6958B)


      1 .. http:post:: [/instances/$INSTANCE]/orders/$ORDER_ID/abort
      2 
      3   Abort paying for an order and obtain a refund for coins that
      4   were already deposited as part of a failed payment.
      5 
      6   **Request:**
      7 
      8   The request must be an `abort request <AbortRequest>`.  We force the wallet
      9   to specify the affected coins as it may only request for a subset of the coins
     10   (i.e. because the wallet knows that some were double-spent causing the failure).
     11   Also we need to know the coins because there may be two wallets "competing" over
     12   the same order and one wants to abort while the other still proceeds with the
     13   payment. Here we need to again know which subset of the deposits to abort.
     14 
     15   **Response:**
     16 
     17   :http:statuscode:`200 OK`:
     18     The merchant accepted the request, and passed it on to the exchange(s).
     19     The body is an
     20     `abort response <AbortResponse>`.
     21     Note that the exchange MAY still have encountered errors in processing.
     22     Those will then be part of the body.
     23     Wallets MUST carefully consider errors for each of the coins as
     24     returned by the exchange.
     25   :http:statuscode:`400 Bad request`:
     26     Either the client request is malformed or some specific processing error
     27     happened that may be the fault of the client as detailed in the JSON body
     28     of the response.
     29     Returned with ``TALER_EC_MERCHANT_POST_ORDERS_ID_ABORT_COINS_ARRAY_EMPTY`` or
     30     ``TALER_EC_MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_HASH_MISSMATCH``.
     31   :http:statuscode:`403 Forbidden`:
     32     The ``h_contract`` does not match the $ORDER_ID.
     33   :http:statuscode:`404 Not found`:
     34     The merchant backend could not find the order or the instance
     35     and thus cannot process the abort request.
     36     Returned with ``TALER_EC_MERCHANT_POST_ORDERS_ID_ABORT_CONTRACT_NOT_FOUND``.
     37   :http:statuscode:`408 Request timeout`:
     38     The merchant backend took too long getting a response from the exchange.
     39     The wallet SHOULD retry soon.
     40   :http:statuscode:`412 Precondition failed`:
     41     Aborting the payment is not allowed, as the original payment did succeed.
     42     It is possible that a different wallet succeeded with the payment. This
     43     wallet should thus try to refresh all of the coins involved in the payment.
     44     Returned with ``TALER_EC_MERCHANT_POST_ORDERS_ID_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE``.
     45   :http:statuscode:`413 Request entity too large`:
     46     The uploaded body is to long, it exceeds the size limit.
     47     Returned with an error code of
     48     ``TALER_EC_GENERIC_UPLOAD_EXCEEDS_LIMIT``.
     49   :http:statuscode:`500 Internal Server Error`:
     50     The server experienced an internal failure.
     51     Returned with ``TALER_EC_GENERIC_DB_STORE_FAILED``,
     52     ``TALER_EC_GENERIC_DB_FETCH_FAILED``,
     53     ``TALER_EC_GENERIC_DB_START_FAILED``,
     54     ``TALER_EC_GENERIC_DB_COMMIT_FAILED`` or
     55     ``TALER_EC_GENERIC_DB_SOFT_FAILURE``.
     56   :http:statuscode:`502 Bad gateway`:
     57     The merchant's interaction with some exchange failed in some way.
     58     The errors from the exchanges are included.
     59     The body is a `abort response <AbortResponse>`.
     60     Note that the exchange MAY still have encountered errors in processing.
     61     Those will then be part of the body.
     62     Wallets MUST carefully consider errors for each of the coins as
     63     returned by the exchange.
     64   :http:statuscode:`504 Gateway timeout`:
     65     The merchant's interaction with the exchange took too long.
     66     The client might want to try again later.
     67 
     68   The backend will return an `abort response <AbortResponse>`, which includes
     69   verbatim the error codes received from the exchange's
     70   :ref:`refund <exchange_refund>` API.  The frontend should pass the replies verbatim to
     71   the browser/wallet.
     72 
     73   **Details:**
     74 
     75   .. ts:def:: AbortRequest
     76 
     77     interface AbortRequest {
     78 
     79       // Hash of the order's contract terms (this is used to authenticate the
     80       // wallet/customer in case $ORDER_ID is guessable).
     81       h_contract: HashCode;
     82 
     83       // List of coins the wallet would like to see refunds for.
     84       // (Should be limited to the coins for which the original
     85       // payment succeeded, as far as the wallet knows.)
     86       coins: AbortingCoin[];
     87     }
     88 
     89   .. ts:def:: AbortingCoin
     90 
     91     interface AbortingCoin {
     92       // Public key of a coin for which the wallet is requesting an abort-related refund.
     93       coin_pub: EddsaPublicKey;
     94 
     95       // The amount to be refunded (matches the original contribution)
     96       // @Deprecated since **v18**.
     97       contribution: Amount;
     98 
     99       // URL of the exchange this coin was withdrawn from.
    100       exchange_url: string;
    101     }
    102 
    103 
    104   .. ts:def:: AbortResponse
    105 
    106     interface AbortResponse {
    107 
    108       // List of refund responses about the coins that the wallet
    109       // requested an abort for.  In the same order as the ``coins``
    110       // from the original request.
    111       // The ``rtransaction_id`` is implied to be 0.
    112       refunds: MerchantAbortPayRefundStatus[];
    113     }
    114 
    115   .. ts:def:: MerchantAbortPayRefundStatus
    116 
    117     type MerchantAbortPayRefundStatus =
    118       | MerchantAbortPayRefundSuccessStatus
    119       | MerchantAbortPayRefundUndepositedStatus
    120       | MerchantAbortPayRefundFailureStatus;
    121 
    122   .. ts:def:: MerchantAbortPayRefundFailureStatus
    123 
    124     // Details about why a refund failed.
    125     interface MerchantAbortPayRefundFailureStatus {
    126       // Used as tag for the sum type RefundStatus sum type.
    127       type: "failure";
    128 
    129       // HTTP status of the exchange request, must NOT be 200.
    130       exchange_status: Integer;
    131 
    132       // Taler error code from the exchange reply, if available.
    133       exchange_code?: Integer;
    134 
    135       // If available, HTTP reply from the exchange.
    136       exchange_reply?: Object;
    137     }
    138 
    139   .. ts:def:: MerchantAbortPayRefundSuccessStatus
    140 
    141     // Additional details needed to verify the refund confirmation signature
    142     // (``h_contract_terms`` and ``merchant_pub``) are already known
    143     // to the wallet and thus not included.
    144     interface MerchantAbortPayRefundSuccessStatus {
    145       // Used as tag for the sum type MerchantCoinRefundStatus sum type.
    146       type: "success";
    147 
    148       // HTTP status of the exchange request, 200 (integer) required for refund confirmations.
    149       exchange_status: 200;
    150 
    151       // The EdDSA :ref:`signature` (binary-only) with purpose
    152       // `TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND` using a current signing key of the
    153       // exchange affirming the successful refund.
    154       exchange_sig: EddsaSignature;
    155 
    156       // Public EdDSA key of the exchange that was used to generate the signature.
    157       // Should match one of the exchange's signing keys from ``/keys``.  It is given
    158       // explicitly as the client might otherwise be confused by clock skew as to
    159       // which signing key was used.
    160       exchange_pub: EddsaPublicKey;
    161     }
    162 
    163   .. ts:def:: MerchantAbortPayRefundUndepositedStatus
    164 
    165     // The merchant didn't deposit the coin in the first place,
    166     // no refund possible.
    167     interface MerchantAbortPayRefundSuccessStatus {
    168       // Used as tag for the sum type MerchantCoinRefundStatus sum type.
    169       type: "undeposited";
    170     }