taler-docs

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

post-orders-ORDER_ID-pay.rst (23276B)


      1 .. http:post:: [/instances/$INSTANCE]/orders/$ORDER_ID/pay
      2 
      3   Pay for an order by giving a deposit permission for coins.  Typically used by
      4   the customer's wallet.  Note that this request does not include the
      5   usual ``h_contract`` argument to authenticate the wallet, as the hash of
      6   the contract is implied by the signatures of the coins.  Furthermore, this
      7   API doesn't really return useful information about the order.
      8 
      9   Repeating the request for an order that is already paid (a *replay*) is
     10   answered from the state stored with the original payment: the token
     11   signatures are the ones created for the original payment, and donation
     12   receipts that are still missing are requested from the Donau with the
     13   ``budikeypairs`` of the original payment, regardless of the ``wallet_data``
     14   of the replay.  Since protocol **vDonauReceipts**, a replay is refused
     15   once the order has been refunded, even if only in part.
     16 
     17   **Request:**
     18 
     19   The request must be a `pay request <PayRequest>`.
     20 
     21   **Response:**
     22 
     23   :http:statuscode:`200 OK`:
     24     The exchange accepted all of the coins.
     25     The body is a `payment response <PaymentResponse>`.
     26     If the wallet requested donation receipts, the Donau issued them
     27     and they are part of the response.
     28     The ``frontend`` should now fulfill the contract.
     29     Note that it is possible that refunds have been granted.
     30   :http:statuscode:`400 Bad request`:
     31     Either the client request is malformed or some specific processing error
     32     happened that may be the fault of the client as detailed in the JSON body
     33     of the response.
     34     This includes the case where the payment is insufficient (sum is below
     35     the required total amount, for example because the wallet calculated the
     36     fees wrong).
     37     Applicable error codes:
     38 
     39     * ``MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND``: Wallet tried
     40       to pay with a non-existent denomination.
     41     * ``MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_DEPOSIT_EXPIRED``: The
     42       denomination used for payment has expired for deposits.
     43     * ``MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_MISSING``: An age commitment
     44       is required but was not provided.
     45     * ``MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_SIZE_MISMATCH``: The age
     46       commitment has the wrong number of public keys.
     47     * ``MERCHANT_POST_ORDERS_ID_PAY_AGE_VERIFICATION_FAILED``: The age
     48       verification signature is invalid.
     49     * ``MERCHANT_POST_ORDERS_ID_PAY_AGE_COMMITMENT_HASH_MISSING``: The age
     50       commitment hash is required but was not provided.
     51     * ``MERCHANT_POST_ORDERS_ID_PAY_PAYMENT_INSUFFICIENT``: The total payment
     52       amount is insufficient to cover the order.
     53     * ``MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_DUE_TO_FEES``: The payment
     54       is insufficient because fees exceed what is covered.
     55     * ``MERCHANT_POST_ORDERS_ID_PAY_TOKEN_ISSUE_SIG_INVALID``: A token issue
     56       signature is invalid.
     57     * ``MERCHANT_POST_ORDERS_ID_PAY_TOKEN_USE_SIG_INVALID``: A token use
     58       signature is invalid.
     59     * ``MERCHANT_POST_ORDERS_ID_PAY_TOKEN_COUNT_MISMATCH``: The number of
     60       input tokens does not match the expected count.
     61     * ``MERCHANT_POST_ORDERS_ID_PAY_TOKEN_ENVELOPE_COUNT_MISMATCH``: The number
     62       of output token envelopes does not match the expected count.
     63     * ``MERCHANT_POST_ORDERS_ID_PAY_CHOICE_INDEX_OUT_OF_BOUNDS``: The
     64       ``choice_index`` in the wallet data is out of range.
     65     * ``MERCHANT_POST_ORDERS_ID_PAY_CHOICE_INDEX_MISSING``: The
     66       ``choice_index`` is required but was not provided.
     67     * ``MERCHANT_GENERIC_EXCHANGE_UNTRUSTED``: The exchange used for a coin
     68       is not trusted by this merchant.
     69     * ``MERCHANT_POST_ORDERS_ID_PAY_AMOUNT_OVERFLOW``: Payment amount overflowed.
     70     * ``MERCHANT_POST_ORDERS_ID_PAY_FEES_EXCEED_PAYMENT``: Fees exceed the payment.
     71     * ``MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED``: Adding wire fees failed.
     72     * ``MERCHANT_POST_ORDERS_ID_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE``: Refund deadline past wire deadline.
     73     * ``MERCHANT_POST_ORDERS_ID_PAY_WIRE_HASH_UNKNOWN``: Wire hash unknown.
     74     * ``MERCHANT_POST_ORDERS_ID_PAY_WIRE_METHOD_UNSUPPORTED``: Wire method unsupported.
     75     * ``GENERIC_PARAMETER_MALFORMED``: A request parameter is malformed.
     76 
     77   :http:statuscode:`402 Payment required`:
     78     There used to be a sufficient payment, but due to refunds the amount effectively
     79     paid is no longer sufficient. (If the amount is generally insufficient, we
     80     return "400 Bad Request", only if this is because of refunds we return 402.)
     81     Returned with ``TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_REFUNDED``.
     82   :http:statuscode:`403 Forbidden`:
     83     One of the coin signatures was not valid.
     84   :http:statuscode:`404 Not found`:
     85     The merchant backend could not find the order
     86     or the instance or a token family or
     87     the Donau charity specified in
     88     the contract and thus cannot process the payment.
     89     Applicable error codes:
     90 
     91     * ``MERCHANT_GENERIC_TOKEN_KEY_UNKNOWN``
     92     * ``MERCHANT_GENERIC_ORDER_UNKNOWN``
     93     * ``MERCHANT_GENERIC_DONAU_CHARITY_UNKNOWN``
     94     * ``MERCHANT_GENERIC_INSTANCE_UNKNOWN``
     95 
     96   :http:statuscode:`408 Request timeout`:
     97     The backend took too long to process the request. Likely the merchant's connection
     98     to the exchange timed out. Try again.
     99     Applicable error codes:
    100 
    101     * ``MERCHANT_GENERIC_EXCHANGE_TIMEOUT``
    102 
    103   :http:statuscode:`409 Conflict`:
    104     The exchange rejected the payment because a coin was already spent (or
    105     used in a different way for the same purchase previously), or
    106     the merchant rejected the payment because the order was already fully paid
    107     (and then return signatures with refunds) or has been refunded since it
    108     was paid. If a coin was already spent
    109     (this includes re-using the same coin after a refund),
    110     the response will include the ``exchange_url`` for which the payment failed,
    111     in addition to the response from the exchange to the :http:post:`/batch-deposit </batch-deposit>` request.
    112     Applicable error codes:
    113 
    114     * ``MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_FUNDS``:  Exchange reported insufficient
    115       funds for one of the coins.
    116     * ``MERCHANT_POST_ORDERS_ID_PAY_CHOICE_INDEX_MISMATCH``: The order was
    117       already paid, but completing a different choice than the one given in
    118       this request, so the request does not describe the payment that was
    119       made.  The response is an `AlreadyPaidChoiceResponse` and contains the
    120       ``choice_index`` the order was actually paid with.
    121       Since protocol **v42**.
    122     * ``MERCHANT_POST_ORDERS_ID_PAY_ALREADY_PAID``: The order was already
    123       fully paid by another wallet. The response includes refund signatures
    124       for the coins.
    125     * ``MERCHANT_POST_ORDERS_ID_PAY_TOKEN_INVALID``: A token was already used
    126       in a previous payment.
    127     * ``MERCHANT_POST_ORDERS_ID_PAY_DONATION_AMOUNT_MISMATCH``: The donation
    128       amount does not match the expected amount or exceeds what remains of
    129       the charity's yearly limit.  Since protocol **vDonauReceipts**, the
    130       donations whose receipts are still pending count against that limit.
    131     * ``MERCHANT_POST_ORDERS_ID_PAY_DONATION_YEAR_INVALID``: The ``year`` in
    132       the ``donau`` field of the wallet data is not the current year (UTC).
    133       Nothing was paid.  The response is a `DonationYearInvalidResponse`;
    134       the wallet should create donation receipt requests for the returned
    135       ``current_year`` and pay again.
    136       Since protocol **vDonauReceipts**.
    137     * ``MERCHANT_POST_ORDERS_ID_PAY_REPLAY_AFTER_REFUND``: The order was
    138       already paid and has since been refunded, possibly only in part, so the
    139       request cannot be replayed.  The response carries no payment
    140       signature, token signatures or donation receipts; the wallet should
    141       query the refunds instead.
    142       Since protocol **vDonauReceipts**.
    143     * ``MERCHANT_GENERIC_CURRENCY_MISMATCH``: Coin currency does not match
    144       the expected payment currency.
    145 
    146   :http:statuscode:`410 Gone`:
    147     The offer has expired and is no longer available or
    148     the provided payment has expired.
    149     Applicable error codes:
    150 
    151     * ``MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_DEPOSIT_EXPIRED``: payment expired
    152     * ``MERCHANT_POST_ORDERS_ID_PAY_OFFER_EXPIRED``: offer expired
    153 
    154   :http:statuscode:`412 Precondition failed`:
    155     The given exchange is not acceptable for this merchant, as it is not in the
    156     list of accepted exchanges and not audited by an approved auditor.
    157     TODO: Status code may be changed to 409 in the future as 412 is technically wrong.
    158 
    159   :http:statuscode:`413 Request entity too large`:
    160     The uploaded body is to long, it exceeds the size limit.
    161     Returned with an error code of
    162     ``TALER_EC_GENERIC_UPLOAD_EXCEEDS_LIMIT``.
    163 
    164   :http:statuscode:`451 Unavailable for Legal Reasons`:
    165     The exchange has rejected the deposit by the merchant
    166     for legal reasons. This is **not** exactly a client
    167     failure (and possibly nobody's fault except for the
    168     regulator). The wallet should suspend the payment and
    169     retain the selected coins and their deposit permissions.
    170     Once the merchant has resolved the issue, the user may
    171     resume the payment, which retries the same payment with
    172     the same coins, or abort it using the normal payment
    173     recovery procedure.  The wallet must not refresh or
    174     reselect coins solely because of this response.
    175     The body is a `PaymentDeniedLegallyResponse` with
    176     details about the failure.
    177     Since protocol **v17**.
    178     Returned with ``TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LEGALLY_REFUSED`` or
    179     ``TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_TRANSACTION_LIMIT_VIOLATION``.
    180 
    181   :http:statuscode:`500 Internal Server Error`:
    182     The server experienced an internal failure.
    183     Returned with ``TALER_EC_GENERIC_DB_STORE_FAILED``,
    184     ``TALER_EC_GENERIC_DB_FETCH_FAILED``,
    185     ``TALER_EC_GENERIC_DB_START_FAILED``,
    186     ``TALER_EC_GENERIC_DB_COMMIT_FAILED``,
    187     ``TALER_EC_GENERIC_DB_SOFT_FAILURE``,
    188     ``TALER_EC_GENERIC_DB_INVARIANT_FAILURE``,
    189     ``TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE``,
    190     ``TALER_EC_GENERIC_FAILED_COMPUTE_JSON_HASH`` or
    191     ``TALER_EC_MERCHANT_GENERIC_DB_CONTRACT_CONTENT_INVALID``.
    192 
    193   :http:statuscode:`501 Not implemented`:
    194     This is returned if an optional feature required to
    195     process this particular payment is no longer implemented.
    196     This should only be possible if a different version
    197     of the backend software was deployed between order
    198     creation and payment.
    199 
    200     Applicable error codes:
    201 
    202     * ``MERCHANT_GENERIC_DONAU_NOT_CONFIGURED``: returned if donations are not supported
    203     * ``MERCHANT_GENERIC_FEATURE_NOT_AVAILABLE``: usually returned if a token type is not supported
    204 
    205   :http:statuscode:`502 Bad gateway`:
    206     The merchant's interaction with the exchange or the Donau failed in
    207     some way.
    208     For the exchange, the client might want to try again later.
    209     This includes failures such as the denomination key of a coin not being
    210     known to the exchange as far as the merchant can tell.
    211     The merchant only contacts the Donau after the payment succeeded, so
    212     a Donau failure does not undo the payment: the response then carries the
    213     payment confirmation.
    214     Applicable error codes:
    215 
    216     * ``MERCHANT_GENERIC_EXCHANGE_UNEXPECTED_STATUS``
    217     * ``MERCHANT_GENERIC_EXCHANGE_REPLY_MALFORMED``
    218     * ``MERCHANT_POST_ORDERS_ID_PAY_DONAU_RECEIPTS_DELAYED``: The payment
    219       succeeded, but the Donau could not issue the donation receipts at this
    220       time (it was unreachable, timed out, failed internally or replied with
    221       something malformed).  The body is a `PaymentDonauFailureResponse`.
    222       The wallet should treat the order as paid, keep its donation receipt
    223       requests and replay the payment request later.  The merchant keeps
    224       reporting this code until the Donau issues the receipts or stops
    225       issuing receipts for the donation year; from then on it reports
    226       ``MERCHANT_POST_ORDERS_ID_PAY_DONAU_RECEIPTS_REFUSED``.
    227       Since protocol **vDonauReceipts**.
    228     * ``MERCHANT_POST_ORDERS_ID_PAY_DONAU_RECEIPTS_REFUSED``: The payment
    229       succeeded, but the Donau refused to issue the donation receipts.  The
    230       body is a `PaymentDonauFailureResponse`.  The wallet should treat the
    231       order as paid, tell the user that the promised donation receipts will
    232       not be issued, and not replay the request.
    233       Since protocol **vDonauReceipts**.
    234     * ``MERCHANT_GENERIC_DONAU_INVALID_RESPONSE``: Only before protocol
    235       **vDonauReceipts**, for any Donau failure; the response then carried
    236       no payment confirmation.
    237 
    238   :http:statuscode:`504 Gateway timeout`:
    239     The merchant's interaction with the exchange took too long.
    240     The client might want to try again later.
    241 
    242   The backend will return verbatim the error codes received from the exchange's
    243   :ref:`deposit <deposit>` API.  If the wallet made a mistake, like by
    244   double-spending for example, the frontend should pass the reply verbatim to
    245   the browser/wallet.  If the payment was successful, the frontend MAY use
    246   this to trigger some business logic.
    247 
    248   **Details:**
    249 
    250   .. ts:def:: AlreadyPaidChoiceResponse
    251 
    252     interface AlreadyPaidChoiceResponse {
    253       // Error code identifying the conflict, always
    254       // ``MERCHANT_POST_ORDERS_ID_PAY_CHOICE_INDEX_MISMATCH``.
    255       code: number;
    256 
    257       // Index of the choice within the ``choices`` array of the
    258       // contract terms that the order was actually paid with. A client
    259       // that wants to refer to the payment that was made has to use
    260       // this choice instead of the one it asked for.
    261       choice_index: Integer;
    262     }
    263 
    264   .. ts:def:: PaymentResponse
    265 
    266     interface PaymentResponse {
    267       // Signature on ``TALER_PaymentResponsePS`` with the public
    268       // key of the merchant instance.
    269       sig: EddsaSignature;
    270 
    271       // Text to be shown to the point-of-sale staff as a proof of
    272       // payment.
    273       // For OTP devices using a challenge-signature algorithm
    274       // ("ECDSA_CHALLENGE" or "EDDSA_CHALLENGE"), contains the
    275       // Crockford Base32 encoded signature over the hash of the
    276       // order's challenge, made with the device private key.
    277       // Since protocol **v43**.
    278       pos_confirmation?: string;
    279 
    280       // Signed tokens for the outputs of type ``token``. Returned in
    281       // the same order as the token envelopes were provided in the
    282       // request. Specifically, the order will follow the order of the
    283       // outputs from the contract terms, and then within each output
    284       // follow the order in which the ``wallet_data`` contained the
    285       // respective blinded envelopes.
    286       // Since protocol **vDonauReceipts**, donation receipts are never
    287       // part of this array, see ``donau_sigs``.  Before, they were
    288       // present at the offset matching the place where a donation
    289       // receipt was indicated in the outputs array, and ``donau_sigs``
    290       // was absent; clients must still handle that layout when
    291       // ``donau_sigs`` is missing although they requested donation
    292       // receipts.
    293       // @since protocol **v21**
    294       token_sigs?: SignedTokenEnvelope[];
    295 
    296       // Donation receipts blindly signed by the Donau, in the order of
    297       // the ``budikeypairs`` in the ``donau`` field of the
    298       // `PayWalletData`.  Present if the wallet requested donation
    299       // receipts.
    300       // @since protocol **vDonauReceipts**
    301       donau_sigs?: SignedDonationReceipt[];
    302 
    303     }
    304 
    305   .. ts:def:: SignedDonationReceipt
    306 
    307     interface SignedDonationReceipt {
    308 
    309       // Blind signature made by the Donau over one of the
    310       // `BlindedDonationReceiptKeyPair` entries of the request.
    311       blind_sig: BlindedDonationReceiptSignature;
    312 
    313     }
    314 
    315   .. ts:def:: PaymentDonauFailureResponse
    316 
    317     interface PaymentDonauFailureResponse {
    318 
    319       // Numeric `error code <error-codes>`, either
    320       // ``MERCHANT_POST_ORDERS_ID_PAY_DONAU_RECEIPTS_DELAYED`` or
    321       // ``MERCHANT_POST_ORDERS_ID_PAY_DONAU_RECEIPTS_REFUSED``.
    322       code: Integer;
    323 
    324       // Human-readable description of the failure.
    325       hint?: string;
    326 
    327       // The order is paid: as in `PaymentResponse`.
    328       sig: EddsaSignature;
    329 
    330       // As in `PaymentResponse`.
    331       pos_confirmation?: string;
    332 
    333       // As in `PaymentResponse`.  The merchant's own token
    334       // signatures are returned even though the donation
    335       // receipts are missing.
    336       token_sigs?: SignedTokenEnvelope[];
    337 
    338       // Base URL of the Donau that was asked for the receipts.
    339       donau_url: WebURL;
    340 
    341       // HTTP status code of the Donau's reply, or 0 if there was
    342       // no reply (Donau unreachable, timeout, or the request could
    343       // not be created).  A malformed reply keeps its status code.
    344       donau_http_status: Integer;
    345 
    346       // Error code of the Donau's reply, if it had one.
    347       donau_ec?: Integer;
    348 
    349       // Hint of the Donau's reply, if it had one.
    350       donau_hint?: string;
    351 
    352     }
    353 
    354   .. ts:def:: DonationYearInvalidResponse
    355 
    356     interface DonationYearInvalidResponse {
    357 
    358       // Error code, always
    359       // ``MERCHANT_POST_ORDERS_ID_PAY_DONATION_YEAR_INVALID``.
    360       code: Integer;
    361 
    362       // Current year (UTC), the only year for which the merchant
    363       // accepts donation receipt requests.
    364       current_year: Integer;
    365 
    366     }
    367 
    368   .. ts:def:: PayRequest
    369 
    370     interface PayRequest {
    371       // The coins used to make the payment.
    372       coins: CoinPaySig[];
    373 
    374       // Input tokens required by choice indicated by ``choice_index``.
    375       // @since protocol **v21**
    376       tokens?: TokenUseSig[];
    377 
    378       // Custom inputs from the wallet for the contract.
    379       wallet_data?: PayWalletData;
    380 
    381       // The session for which the payment is made (or replayed).
    382       // Only set for session-based payments.  The empty session ID
    383       // is treated like the field being absent (wallets do send it
    384       // that way).
    385       session_id?: SessionID;
    386 
    387     }
    388 
    389   .. ts:def:: SignedTokenEnvelope
    390 
    391     interface SignedTokenEnvelope {
    392 
    393       // Blind signature made by the merchant.
    394       blind_sig: TokenIssueBlindSig;
    395 
    396     }
    397 
    398   .. ts:def:: TokenIssueBlindSig
    399 
    400     type TokenIssueBlindSig = RSATokenIssueBlindSig | CSTokenIssueBlindSig;
    401 
    402   .. ts:def:: RSATokenIssueBlindSig
    403 
    404     interface RSATokenIssueBlindSig {
    405       cipher: "RSA";
    406 
    407       // (blinded) RSA signature
    408       blinded_rsa_signature: BlindedRsaSignature;
    409     }
    410 
    411   .. ts:def:: CSTokenIssueBlindSig
    412 
    413     interface CSTokenIssueBlindSig {
    414       cipher: "CS";
    415 
    416       // Signer chosen bit value, 0 or 1, used
    417       // in Clause Blind Schnorr to make the
    418       // ROS problem harder.
    419       b: Integer;
    420 
    421       // Blinded scalar calculated from c_b.
    422       s: Cs25519Scalar;
    423 
    424     }
    425 
    426   .. ts:def:: PayWalletData
    427 
    428     interface PayWalletData {
    429       // Index of the selected choice within the ``choices`` array of
    430       // the contract terms.
    431       // @since protocol **v21**
    432       choice_index?: Integer;
    433 
    434       // Array of output tokens to be (blindly) signed by the merchant.
    435       // Output tokens specified in choice indicated by ``choice_index``.
    436       // @since protocol **v21**
    437       tokens_evs?: TokenEnvelope[];
    438 
    439       // Request for donation receipts to be issued.
    440       // @since protocol **v21**
    441       donau?: DonationRequestData;
    442     }
    443 
    444   .. ts:def:: DonationRequestData
    445 
    446     interface DonationRequestData {
    447       // Base URL of the selected Donau
    448       url: WebURL;
    449 
    450       // Year for which the donation receipts are expected.
    451       // Also determines which keys are used to sign the
    452       // blinded donation receipts.
    453       year: Integer;
    454 
    455       // Array of blinded donation receipts to sign.
    456       // Must NOT be empty (if no donation receipts
    457       // are desired, just leave the entire ``donau``
    458       // argument blank).
    459       budikeypairs: BlindedDonationReceiptKeyPair[];
    460     }
    461 
    462   .. ts:def:: CoinPaySig
    463 
    464     interface CoinPaySig {
    465       // Signature by the coin.
    466       coin_sig: EddsaSignature;
    467 
    468       // Public key of the coin being spent.
    469       coin_pub: EddsaPublicKey;
    470 
    471       // Signature made by the denomination public key.
    472       ub_sig: UnblindedSignature;
    473 
    474       // The hash of the denomination public key associated with this coin.
    475       h_denom: HashCode;
    476 
    477       // The amount that is subtracted from this coin with this payment.
    478       contribution: Amount;
    479 
    480       // URL of the exchange this coin was withdrawn from.
    481       exchange_url: WebURL;
    482 
    483       // Signature affirming the posession of the
    484       // respective private key proving that the payer
    485       // is old enough. Only provided if the paid contract
    486       // has an age restriction and the coin is
    487       // age-restricted.
    488       minimum_age_sig?: EddsaSignature;
    489 
    490       // Age commitment vector of the coin.
    491       // Only provided if the paid contract
    492       // has an age restriction and the coin is
    493       // age-restricted.
    494       age_commitment?: Edx25519PublicKey[];
    495 
    496       // Hash over the agge commitment vector of the coin.
    497       // Only provided if the paid contract
    498       // does NOT have an age restriction and the coin is
    499       // age-restricted.
    500       h_age_commitment?: AgeCommitmentHash;
    501     }
    502 
    503   .. ts:def:: TokenUseSig
    504 
    505     interface TokenUseSig {
    506 
    507       // Signature on ``TALER_TokenUseRequestPS`` with the token use key of
    508       // the token being used in this request.
    509       token_sig: EddsaSignature;
    510 
    511       // Token use public key.
    512       token_pub: EddsaPublicKey;
    513 
    514       // Unblinded signature on ``TALER_TokenIssueRequestPS`` with the token
    515       // issue public key of the merchant.
    516       ub_sig: UnblindedSignature;
    517 
    518       // Hash of the token issue public key associated with this token.
    519       h_issue: HashCode;
    520     }
    521 
    522   .. ts:def:: TokenEnvelope
    523 
    524     // This type depends on the cipher used to sign token families. This is
    525     // configured by the merchant and defined for each token family in the
    526     // contract terms.
    527     type TokenEnvelope = RSATokenEnvelope | CSTokenEnvelope;
    528 
    529   .. ts:def:: RSATokenEnvelope
    530 
    531     interface RSATokenEnvelope {
    532 
    533       // RSA is used for the blind signature.
    534       cipher: "RSA";
    535 
    536       // Blinded signature of the token's `public EdDSA key <eddsa-token-pub>`.
    537       rsa_blinded_planchet: BlindedRsaSignature;
    538 
    539     }
    540 
    541   .. ts:def:: CSTokenEnvelope
    542 
    543     interface CSTokenEnvelope {
    544       // Blind Clause-Schnorr signature scheme is used for the blind signature.
    545       // See https://taler.net/papers/cs-thesis.pdf for details.
    546       cipher: "CS";
    547 
    548       // Public nonce
    549       cs_nonce: string;      // Crockford `Base32` encoded
    550 
    551       // Two Curve25519 scalars, each representing a blinded challenge
    552       cs_blinded_c0: string; // Crockford `Base32` encoded
    553       cs_blinded_c1: string; // Crockford `Base32` encoded
    554     }
    555 
    556   .. ts:def:: PaymentDeniedLegallyResponse
    557 
    558     interface PaymentDeniedLegallyResponse {
    559 
    560       // Numeric `error code <error-codes>` unique to the condition.
    561       // Error code, must be either
    562       // TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LEGALLY_REFUSED
    563       // or TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_TRANSACTION_LIMIT_VIOLATION.
    564       code: Integer;
    565 
    566       // Base URL of the exchanges that denied the payment.
    567       // This is diagnostic information for the wallet and user.
    568       // It does not instruct the wallet to refresh or reselect coins.
    569       exchange_base_urls: WebURL[];
    570 
    571     }