- POST [/instances/$INSTANCE]/orders/$ORDER_ID/abort#
Abort paying for an order and obtain a refund for coins that were already deposited as part of a failed payment.
Request:
The request must be an abort request. We force the wallet to specify the affected coins as it may only request for a subset of the coins (i.e. because the wallet knows that some were double-spent causing the failure). Also we need to know the coins because there may be two wallets “competing” over the same order and one wants to abort while the other still proceeds with the payment. Here we need to again know which subset of the deposits to abort.
Response:
- 200 OK:
The merchant accepted the request, and passed it on to the exchange. The body is a a abort response. Note that the exchange MAY still have encountered errors in processing. Those will then be part of the body. Wallets MUST carefully consider errors for each of the coins as returned by the exchange.
- 400 Bad request:
Either the client request is malformed or some specific processing error happened that may be the fault of the client as detailed in the JSON body of the response.
- 403 Forbidden:
The
h_contractdoes not match the $ORDER_ID.- 404 Not found:
The merchant backend could not find the order or the instance and thus cannot process the abort request.
- 408 Request timeout:
The merchant backend took too long getting a response from the exchange. The wallet SHOULD retry soon.
- 412 Precondition failed:
Aborting the payment is not allowed, as the original payment did succeed. It is possible that a different wallet succeeded with the payment. This wallet should thus try to refresh all of the coins involved in the payment.
- 502 Bad gateway:
The merchant’s interaction with the exchange failed in some way. The error from the exchange is included.
- 504 Gateway timeout:
The merchant’s interaction with the exchange took too long. The client might want to try again later.
The backend will return an abort response, which includes verbatim the error codes received from the exchange’s refund API. The frontend should pass the replies verbatim to the browser/wallet.
Details:
interface AbortRequest { // Hash of the order's contract terms (this is used to authenticate the // wallet/customer in case $ORDER_ID is guessable). h_contract: HashCode; // List of coins the wallet would like to see refunds for. // (Should be limited to the coins for which the original // payment succeeded, as far as the wallet knows.) coins: AbortingCoin[]; }
interface AbortingCoin { // Public key of a coin for which the wallet is requesting an abort-related refund. coin_pub: EddsaPublicKey; // The amount to be refunded (matches the original contribution) // @Deprecated since **v18**. contribution: Amount; // URL of the exchange this coin was withdrawn from. exchange_url: string; }
interface AbortResponse { // List of refund responses about the coins that the wallet // requested an abort for. In the same order as the coins // from the original request. // The rtransaction_id is implied to be 0. refunds: MerchantAbortPayRefundStatus[]; }
type MerchantAbortPayRefundStatus = | MerchantAbortPayRefundSuccessStatus | MerchantAbortPayRefundUndepositedStatus | MerchantAbortPayRefundFailureStatus;
// Details about why a refund failed. interface MerchantAbortPayRefundFailureStatus { // Used as tag for the sum type RefundStatus sum type. type: "failure"; // HTTP status of the exchange request, must NOT be 200. exchange_status: Integer; // Taler error code from the exchange reply, if available. exchange_code?: Integer; // If available, HTTP reply from the exchange. exchange_reply?: Object; }
// Additional details needed to verify the refund confirmation signature // (h_contract_terms and merchant_pub) are already known // to the wallet and thus not included. interface MerchantAbortPayRefundSuccessStatus { // Used as tag for the sum type MerchantCoinRefundStatus sum type. type: "success"; // HTTP status of the exchange request, 200 (integer) required for refund confirmations. exchange_status: 200; // The EdDSA :ref:signature (binary-only) with purpose // TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND using a current signing key of the // exchange affirming the successful refund. exchange_sig: EddsaSignature; // Public EdDSA key of the exchange that was used to generate the signature. // Should match one of the exchange's signing keys from /keys. It is given // explicitly as the client might otherwise be confused by clock skew as to // which signing key was used. exchange_pub: EddsaPublicKey; }
// The merchant didn't deposit the coin in the first place, // no refund possible. interface MerchantAbortPayRefundSuccessStatus { // Used as tag for the sum type MerchantCoinRefundStatus sum type. type: "undeposited"; }