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 }