post-orders-ORDER_ID-pay.rst (16711B)
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_ALREADY_PAID``: The order was already 106 fully paid by another wallet. The response includes refund signatures 107 for the coins. 108 * ``MERCHANT_POST_ORDERS_ID_PAY_TOKEN_INVALID``: A token was already used 109 in a previous payment. 110 * ``MERCHANT_POST_ORDERS_ID_PAY_DONATION_AMOUNT_MISMATCH``: The donation 111 amount does not match the expected amount or exceeds the yearly limit. 112 * ``MERCHANT_GENERIC_CURRENCY_MISMATCH``: Coin currency does not match 113 the expected payment currency. 114 115 :http:statuscode:`410 Gone`: 116 The offer has expired and is no longer available or 117 the provided payment has expired. 118 Applicable error codes: 119 120 * ``MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_DEPOSIT_EXPIRED``: payment expired 121 * ``MERCHANT_POST_ORDERS_ID_PAY_OFFER_EXPIRED``: offer expired 122 123 :http:statuscode:`412 Precondition failed`: 124 The given exchange is not acceptable for this merchant, as it is not in the 125 list of accepted exchanges and not audited by an approved auditor. 126 TODO: Status code may be changed to 409 in the future as 412 is technically wrong. 127 :http:statuscode:`413 Request entity too large`: 128 The uploaded body is to long, it exceeds the size limit. 129 Returned with an error code of 130 ``TALER_EC_GENERIC_UPLOAD_EXCEEDS_LIMIT``. 131 :http:statuscode:`451 Unavailable for Legal Reasons`: 132 The exchange has rejected the deposit by the merchant 133 for legal reasons. This is **not** exactly a client 134 failure (and possibly nobody's fault except for the 135 regulator). In any case, the wallet should refresh 136 the deposited coins of the affected exchange and 137 may try to pay with coins from another exchange if 138 possible (it has such coins and the merchant accepts 139 coins from another exchange). 140 The body is a `PaymentDeniedLegallyResponse` with 141 details about the failure. 142 Since protocol **v17**. 143 Returned with ``TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LEGALLY_REFUSED`` or 144 ``TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_TRANSACTION_LIMIT_VIOLATION``. 145 :http:statuscode:`501 Not implemented`: 146 This is returned if an optional feature required to 147 process this particular payment is no longer implemented. 148 This should only be possible if a different version 149 of the backend software was deployed between order 150 creation and payment. 151 152 Applicable error codes: 153 154 * ``MERCHANT_GENERIC_DONAU_NOT_CONFIGURED``: returned if donations are not supported 155 * ``MERCHANT_GENERIC_FEATURE_NOT_AVAILABLE``: usually returned if a token type is not supported 156 157 :http:statuscode:`502 Bad gateway`: 158 The merchant's interaction with the exchange failed in some way. 159 The client might want to try again later. 160 This includes failures such as the denomination key of a coin not being 161 known to the exchange as far as the merchant can tell. 162 Applicable error codes: 163 164 * ``MERCHANT_GENERIC_EXCHANGE_UNEXPECTED_STATUS`` 165 * ``MERCHANT_GENERIC_EXCHANGE_REPLY_MALFORMED`` 166 * ``MERCHANT_GENERIC_DONAU_INVALID_RESPONSE`` 167 168 :http:statuscode:`500 Internal Server Error`: 169 The server experienced an internal failure. 170 Returned with ``TALER_EC_GENERIC_DB_STORE_FAILED``, 171 ``TALER_EC_GENERIC_DB_FETCH_FAILED``, 172 ``TALER_EC_GENERIC_DB_START_FAILED``, 173 ``TALER_EC_GENERIC_DB_COMMIT_FAILED``, 174 ``TALER_EC_GENERIC_DB_SOFT_FAILURE``, 175 ``TALER_EC_GENERIC_DB_INVARIANT_FAILURE``, 176 ``TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE``, 177 ``TALER_EC_GENERIC_FAILED_COMPUTE_JSON_HASH`` or 178 ``TALER_EC_MERCHANT_GENERIC_DB_CONTRACT_CONTENT_INVALID``. 179 :http:statuscode:`504 Gateway timeout`: 180 The merchant's interaction with the exchange took too long. 181 The client might want to try again later. 182 183 The backend will return verbatim the error codes received from the exchange's 184 :ref:`deposit <deposit>` API. If the wallet made a mistake, like by 185 double-spending for example, the frontend should pass the reply verbatim to 186 the browser/wallet. If the payment was successful, the frontend MAY use 187 this to trigger some business logic. 188 189 **Details:** 190 191 .. ts:def:: PaymentResponse 192 193 interface PaymentResponse { 194 // Signature on ``TALER_PaymentResponsePS`` with the public 195 // key of the merchant instance. 196 sig: EddsaSignature; 197 198 // Text to be shown to the point-of-sale staff as a proof of 199 // payment. 200 // For OTP devices using a challenge-signature algorithm 201 // ("ECDSA_CHALLENGE" or "EDDSA_CHALLENGE"), contains the 202 // Crockford Base32 encoded signature over the hash of the 203 // order's challenge, made with the device private key. 204 // Since protocol **vChallengeConfirmation**. 205 pos_confirmation?: string; 206 207 // Signed tokens. Returned in the same order as the 208 // token envelopes were provided in the request. Specifically, 209 // the order will follow the order of the outputs from the 210 // contract terms, and then within each output follow the 211 // order in which the ``wallet_data`` contained the respective 212 // blinded envelopes. The donation tokens will be present 213 // at the offset matching the place where a donation receipt 214 // was indicated in the outputs array, and of course be skipped 215 // if the `PayWalletData` did not have a ``donau`` field. 216 // @since protocol **v21** 217 token_sigs?: SignedTokenEnvelope[]; 218 219 } 220 221 .. ts:def:: PayRequest 222 223 interface PayRequest { 224 // The coins used to make the payment. 225 coins: CoinPaySig[]; 226 227 // Input tokens required by choice indicated by ``choice_index``. 228 // @since protocol **v21** 229 tokens?: TokenUseSig[]; 230 231 // Custom inputs from the wallet for the contract. 232 wallet_data?: PayWalletData; 233 234 // The session for which the payment is made (or replayed). 235 // Only set for session-based payments. 236 session_id?: string; 237 238 } 239 240 .. ts:def:: SignedTokenEnvelope 241 242 interface SignedTokenEnvelope { 243 244 // Blind signature made by the merchant. 245 blind_sig: TokenIssueBlindSig; 246 247 } 248 249 .. ts:def:: TokenIssueBlindSig 250 251 type TokenIssueBlindSig = RSATokenIssueBlindSig | CSTokenIssueBlindSig; 252 253 .. ts:def:: RSATokenIssueBlindSig 254 255 interface RSATokenIssueBlindSig { 256 cipher: "RSA"; 257 258 // (blinded) RSA signature 259 blinded_rsa_signature: BlindedRsaSignature; 260 } 261 262 .. ts:def:: CSTokenIssueBlindSig 263 264 interface CSTokenIssueBlindSig { 265 cipher: "CS"; 266 267 // Signer chosen bit value, 0 or 1, used 268 // in Clause Blind Schnorr to make the 269 // ROS problem harder. 270 b: Integer; 271 272 // Blinded scalar calculated from c_b. 273 s: Cs25519Scalar; 274 275 } 276 277 .. ts:def:: PayWalletData 278 279 interface PayWalletData { 280 // Index of the selected choice within the ``choices`` array of 281 // the contract terms. 282 // @since protocol **v21** 283 choice_index?: Integer; 284 285 // Array of output tokens to be (blindly) signed by the merchant. 286 // Output tokens specified in choice indicated by ``choice_index``. 287 // @since protocol **v21** 288 tokens_evs?: TokenEnvelope[]; 289 290 // Request for donation receipts to be issued. 291 // @since protocol **v21** 292 donau?: DonationRequestData; 293 } 294 295 .. ts:def:: DonationRequestData 296 297 interface DonationRequestData { 298 // Base URL of the selected Donau 299 url: string; 300 301 // Year for which the donation receipts are expected. 302 // Also determines which keys are used to sign the 303 // blinded donation receipts. 304 year: Integer; 305 306 // Array of blinded donation receipts to sign. 307 // Must NOT be empty (if no donation receipts 308 // are desired, just leave the entire ``donau`` 309 // argument blank). 310 budikeypairs: BlindedDonationReceiptKeyPair[]; 311 } 312 313 .. ts:def:: CoinPaySig 314 315 interface CoinPaySig { 316 // Signature by the coin. 317 coin_sig: EddsaSignature; 318 319 // Public key of the coin being spent. 320 coin_pub: EddsaPublicKey; 321 322 // Signature made by the denomination public key. 323 ub_sig: UnblindedSignature; 324 325 // The hash of the denomination public key associated with this coin. 326 h_denom: HashCode; 327 328 // The amount that is subtracted from this coin with this payment. 329 contribution: Amount; 330 331 // URL of the exchange this coin was withdrawn from. 332 exchange_url: string; 333 334 // Signature affirming the posession of the 335 // respective private key proving that the payer 336 // is old enough. Only provided if the paid contract 337 // has an age restriction and the coin is 338 // age-restricted. 339 minimum_age_sig?: EddsaSignature; 340 341 // Age commitment vector of the coin. 342 // Only provided if the paid contract 343 // has an age restriction and the coin is 344 // age-restricted. 345 age_commitment?: Edx25519PublicKey[]; 346 347 // Hash over the agge commitment vector of the coin. 348 // Only provided if the paid contract 349 // does NOT have an age restriction and the coin is 350 // age-restricted. 351 h_age_commitment?: AgeCommitmentHash; 352 } 353 354 .. ts:def:: TokenUseSig 355 356 interface TokenUseSig { 357 358 // Signature on ``TALER_TokenUseRequestPS`` with the token use key of 359 // the token being used in this request. 360 token_sig: EddsaSignature; 361 362 // Token use public key. 363 token_pub: EddsaPublicKey; 364 365 // Unblinded signature on ``TALER_TokenIssueRequestPS`` with the token 366 // issue public key of the merchant. 367 ub_sig: UnblindedSignature; 368 369 // Hash of the token issue public key associated with this token. 370 h_issue: HashCode; 371 } 372 373 .. ts:def:: TokenEnvelope 374 375 // This type depends on the cipher used to sign token families. This is 376 // configured by the merchant and defined for each token family in the 377 // contract terms. 378 type TokenEnvelope = RSATokenEnvelope | CSTokenEnvelope; 379 380 .. ts:def:: RSATokenEnvelope 381 382 interface RSATokenEnvelope { 383 384 // RSA is used for the blind signature. 385 cipher: "RSA"; 386 387 // Blinded signature of the token's `public EdDSA key <eddsa-token-pub>`. 388 rsa_blinded_pub: BlindedRsaSignature; 389 390 } 391 392 .. ts:def:: CSTokenEnvelope 393 394 interface CSTokenEnvelope { 395 // Blind Clause-Schnorr signature scheme is used for the blind signature. 396 // See https://taler.net/papers/cs-thesis.pdf for details. 397 cipher: "CS"; 398 399 // Public nonce 400 cs_nonce: string; // Crockford `Base32` encoded 401 402 // Two Curve25519 scalars, each representing a blinded challenge 403 cs_blinded_c0: string; // Crockford `Base32` encoded 404 cs_blinded_c1: string; // Crockford `Base32` encoded 405 } 406 407 .. ts:def:: PaymentDeniedLegallyResponse 408 409 interface PaymentDeniedLegallyResponse { 410 411 // Numeric `error code <error-codes>` unique to the condition. 412 // Error code, must be 413 // TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LEGALLY_REFUSED. 414 code: Integer; 415 416 // Base URL of the exchanges that denied the payment. 417 // The wallet should refresh the coins from these 418 // exchanges, but may try to pay with coins from 419 // other exchanges. 420 exchange_base_urls: string[]; 421 422 }