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