post-orders-ORDER_ID-pay.rst (16381B)
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 ``/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 pos_confirmation?: string; 201 202 // Signed tokens. Returned in the same order as the 203 // token envelopes were provided in the request. Specifically, 204 // the order will follow the order of the outputs from the 205 // contract terms, and then within each output follow the 206 // order in which the ``wallet_data`` contained the respective 207 // blinded envelopes. The donation tokens will be present 208 // at the offset matching the place where a donation receipt 209 // was indicated in the outputs array, and of course be skipped 210 // if the ``PayWalletData`` did not have a ``donau`` field. 211 // @since protocol **v21** 212 token_sigs?: SignedTokenEnvelope[]; 213 214 } 215 216 .. ts:def:: PayRequest 217 218 interface PayRequest { 219 // The coins used to make the payment. 220 coins: CoinPaySig[]; 221 222 // Input tokens required by choice indicated by ``choice_index``. 223 // @since protocol **v21** 224 tokens?: TokenUseSig[]; 225 226 // Custom inputs from the wallet for the contract. 227 wallet_data?: PayWalletData; 228 229 // The session for which the payment is made (or replayed). 230 // Only set for session-based payments. 231 session_id?: string; 232 233 } 234 235 .. ts:def:: SignedTokenEnvelope 236 237 interface SignedTokenEnvelope { 238 239 // Blind signature made by the merchant. 240 blind_sig: TokenIssueBlindSig; 241 242 } 243 244 .. ts:def:: TokenIssueBlindSig 245 246 type TokenIssueBlindSig = RSATokenIssueBlindSig | CSTokenIssueBlindSig; 247 248 .. ts:def:: RSATokenIssueBlindSig 249 250 interface RSATokenIssueBlindSig { 251 cipher: "RSA"; 252 253 // (blinded) RSA signature 254 blinded_rsa_signature: BlindedRsaSignature; 255 } 256 257 .. ts:def:: CSTokenIssueBlindSig 258 259 interface CSTokenIssueBlindSig { 260 cipher: "CS"; 261 262 // Signer chosen bit value, 0 or 1, used 263 // in Clause Blind Schnorr to make the 264 // ROS problem harder. 265 b: Integer; 266 267 // Blinded scalar calculated from c_b. 268 s: Cs25519Scalar; 269 270 } 271 272 .. ts:def:: PayWalletData 273 274 interface PayWalletData { 275 // Index of the selected choice within the ``choices`` array of 276 // the contract terms. 277 // @since protocol **v21** 278 choice_index?: Integer; 279 280 // Array of output tokens to be (blindly) signed by the merchant. 281 // Output tokens specified in choice indicated by ``choice_index``. 282 // @since protocol **v21** 283 tokens_evs?: TokenEnvelope[]; 284 285 // Request for donation receipts to be issued. 286 // @since protocol **v21** 287 donau?: DonationRequestData; 288 } 289 290 .. ts:def:: DonationRequestData 291 292 interface DonationRequestData { 293 // Base URL of the selected Donau 294 url: string; 295 296 // Year for which the donation receipts are expected. 297 // Also determines which keys are used to sign the 298 // blinded donation receipts. 299 year: Integer; 300 301 // Array of blinded donation receipts to sign. 302 // Must NOT be empty (if no donation receipts 303 // are desired, just leave the entire ``donau`` 304 // argument blank). 305 budikeypairs: BlindedDonationReceiptKeyPair[]; 306 } 307 308 .. ts:def:: CoinPaySig 309 310 interface CoinPaySig { 311 // Signature by the coin. 312 coin_sig: EddsaSignature; 313 314 // Public key of the coin being spent. 315 coin_pub: EddsaPublicKey; 316 317 // Signature made by the denomination public key. 318 ub_sig: UnblindedSignature; 319 320 // The hash of the denomination public key associated with this coin. 321 h_denom: HashCode; 322 323 // The amount that is subtracted from this coin with this payment. 324 contribution: Amount; 325 326 // URL of the exchange this coin was withdrawn from. 327 exchange_url: string; 328 329 // Signature affirming the posession of the 330 // respective private key proving that the payer 331 // is old enough. Only provided if the paid contract 332 // has an age restriction and the coin is 333 // age-restricted. 334 minimum_age_sig?: EddsaSignature; 335 336 // Age commitment vector of the coin. 337 // Only provided if the paid contract 338 // has an age restriction and the coin is 339 // age-restricted. 340 age_commitment?: Edx25519PublicKey[]; 341 342 // Hash over the agge commitment vector of the coin. 343 // Only provided if the paid contract 344 // does NOT have an age restriction and the coin is 345 // age-restricted. 346 h_age_commitment?: AgeCommitmentHash; 347 } 348 349 .. ts:def:: TokenUseSig 350 351 interface TokenUseSig { 352 353 // Signature on ``TALER_TokenUseRequestPS`` with the token use key of 354 // the token being used in this request. 355 token_sig: EddsaSignature; 356 357 // Token use public key. 358 token_pub: EddsaPublicKey; 359 360 // Unblinded signature on ``TALER_TokenIssueRequestPS`` with the token 361 // issue public key of the merchant. 362 ub_sig: UnblindedSignature; 363 364 // Hash of the token issue public key associated with this token. 365 h_issue: HashCode; 366 } 367 368 .. ts:def:: TokenEnvelope 369 370 // This type depends on the cipher used to sign token families. This is 371 // configured by the merchant and defined for each token family in the 372 // contract terms. 373 type TokenEnvelope = RSATokenEnvelope | CSTokenEnvelope; 374 375 .. ts:def:: RSATokenEnvelope 376 377 interface RSATokenEnvelope { 378 379 // RSA is used for the blind signature. 380 cipher: "RSA"; 381 382 // Blinded signature of the token's `public EdDSA key <eddsa-token-pub>`. 383 rsa_blinded_pub: BlindedRsaSignature; 384 385 } 386 387 .. ts:def:: CSTokenEnvelope 388 389 interface CSTokenEnvelope { 390 // Blind Clause-Schnorr signature scheme is used for the blind signature. 391 // See https://taler.net/papers/cs-thesis.pdf for details. 392 cipher: "CS"; 393 394 // Public nonce 395 cs_nonce: string; // Crockford `Base32` encoded 396 397 // Two Curve25519 scalars, each representing a blinded challenge 398 cs_blinded_c0: string; // Crockford `Base32` encoded 399 cs_blinded_c1: string; // Crockford `Base32` encoded 400 } 401 402 .. ts:def:: PaymentDeniedLegallyResponse 403 404 interface PaymentDeniedLegallyResponse { 405 406 // Numeric `error code <error-codes>` unique to the condition. 407 // Error code, must be 408 // TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LEGALLY_REFUSED. 409 code: Integer; 410 411 // Base URL of the exchanges that denied the payment. 412 // The wallet should refresh the coins from these 413 // exchanges, but may try to pay with coins from 414 // other exchanges. 415 exchange_base_urls: string[]; 416 417 }