post-orders-ORDER_ID-pay.rst (12462B)
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 32 :http:statuscode:`402 Payment required`: 33 There used to be a sufficient payment, but due to refunds the amount effectively 34 paid is no longer sufficient. (If the amount is generally insufficient, we 35 return "400 Bad Request", only if this is because of refunds we return 402.) 36 :http:statuscode:`403 Forbidden`: 37 One of the coin signatures was not valid. 38 :http:statuscode:`404 Not found`: 39 The merchant backend could not find the order 40 or the instance or a token family or 41 the Donau charity specified in 42 the contract and thus cannot process the payment. 43 Applicable error codes: 44 45 * ``MERCHANT_GENERIC_TOKEN_KEY_UNKNOWN`` 46 * ``MERCHANT_GENERIC_ORDER_UNKNOWN`` 47 * ``MERCHANT_GENERIC_DONAU_CHARITY_UNKNOWN`` 48 * ``MERCHANT_GENERIC_INSTANCE_UNKNOWN`` 49 50 :http:statuscode:`408 Request timeout`: 51 The backend took too long to process the request. Likely the merchant's connection 52 to the exchange timed out. Try again. 53 Applicable error codes: 54 55 * ``MERCHANT_GENERIC_EXCHANGE_TIMEOUT`` 56 57 :http:statuscode:`409 Conflict`: 58 The exchange rejected the payment because a coin was already spent (or 59 used in a different way for the same purchase previously), or 60 the merchant rejected the payment because the order was already fully paid 61 (and then return signatures with refunds). If a coin was already spent 62 (this includes re-using the same coin after a refund), 63 the response will include the ``exchange_url`` for which the payment failed, 64 in addition to the response from the exchange to the ``/batch-deposit`` request. 65 Applicable error codes: 66 67 * ``MERCHANT_POST_ORDERS_ID_PAY_INSUFFICIENT_FUNDS``: Exchange reported insufficient 68 funds for one of the coins. 69 70 :http:statuscode:`410 Gone`: 71 The offer has expired and is no longer available or 72 the provided payment has expired. 73 Applicable error codes: 74 75 * ``MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_DEPOSIT_EXPIRED``: payment expired 76 * ``MERCHANT_POST_ORDERS_ID_PAY_OFFER_EXPIRED``: offer expired 77 78 :http:statuscode:`412 Precondition failed`: 79 The given exchange is not acceptable for this merchant, as it is not in the 80 list of accepted exchanges and not audited by an approved auditor. 81 TODO: Status code may be changed to 409 in the future as 412 is technically wrong. 82 :http:statuscode:`451 Unavailable for Legal Reasons`: 83 The exchange has rejected the deposit by the merchant 84 for legal reasons. This is **not** exactly a client 85 failure (and possibly nobody's fault except for the 86 regulator). In any case, the wallet should refresh 87 the deposited coins of the affected exchange and 88 may try to pay with coins from another exchange if 89 possible (it has such coins and the merchant accepts 90 coins from another exchange). 91 The body is a `PaymentDeniedLegallyResponse` with 92 details about the failure. 93 Since protocol **v17**. 94 :http:statuscode:`501 Not implemented`: 95 This is returned if an optional feature required to 96 process this particular payment is no longer implemented. 97 This should only be possible if a different version 98 of the backend software was deployed between order 99 creation and payment. 100 101 Applicable error codes: 102 103 * ``MERCHANT_GENERIC_DONAU_NOT_CONFIGURED``: returned if donations are not supported 104 * ``MERCHANT_GENERIC_FEATURE_NOT_AVAILABLE``: usually returned if a token type is not supported 105 106 :http:statuscode:`502 Bad gateway`: 107 The merchant's interaction with the exchange failed in some way. 108 The client might want to try again later. 109 This includes failures such as the denomination key of a coin not being 110 known to the exchange as far as the merchant can tell. 111 Applicable error codes: 112 113 * ``MERCHANT_GENERIC_EXCHANGE_UNEXPECTED_STATUS`` 114 * ``MERCHANT_GENERIC_EXCHANGE_REPLY_MALFORMED`` 115 116 :http:statuscode:`504 Gateway timeout`: 117 The merchant's interaction with the exchange took too long. 118 The client might want to try again later. 119 120 The backend will return verbatim the error codes received from the exchange's 121 :ref:`deposit <deposit>` API. If the wallet made a mistake, like by 122 double-spending for example, the frontend should pass the reply verbatim to 123 the browser/wallet. If the payment was successful, the frontend MAY use 124 this to trigger some business logic. 125 126 **Details:** 127 128 .. ts:def:: PaymentResponse 129 130 interface PaymentResponse { 131 // Signature on ``TALER_PaymentResponsePS`` with the public 132 // key of the merchant instance. 133 sig: EddsaSignature; 134 135 // Text to be shown to the point-of-sale staff as a proof of 136 // payment. 137 pos_confirmation?: string; 138 139 // Signed tokens. Returned in the same order as the 140 // token envelopes were provided in the request. Specifically, 141 // the order will follow the order of the outputs from the 142 // contract terms, and then within each output follow the 143 // order in which the ``wallet_data`` contained the respective 144 // blinded envelopes. The donation tokens will be present 145 // at the offset matching the place where a donation receipt 146 // was indicated in the outputs array, and of course be skipped 147 // if the ``PayWalletData`` did not have a ``donau`` field. 148 // @since protocol **v21** 149 token_sigs?: SignedTokenEnvelope[]; 150 151 } 152 153 .. ts:def:: PayRequest 154 155 interface PayRequest { 156 // The coins used to make the payment. 157 coins: CoinPaySig[]; 158 159 // Input tokens required by choice indicated by ``choice_index``. 160 // @since protocol **v21** 161 tokens?: TokenUseSig[]; 162 163 // Custom inputs from the wallet for the contract. 164 wallet_data?: PayWalletData; 165 166 // The session for which the payment is made (or replayed). 167 // Only set for session-based payments. 168 session_id?: string; 169 170 } 171 172 .. ts:def:: SignedTokenEnvelope 173 174 interface SignedTokenEnvelope { 175 176 // Blind signature made by the merchant. 177 blind_sig: TokenIssueBlindSig; 178 179 } 180 181 .. ts:def:: TokenIssueBlindSig 182 183 type TokenIssueBlindSig = RSATokenIssueBlindSig | CSTokenIssueBlindSig; 184 185 .. ts:def:: RSATokenIssueBlindSig 186 187 interface RSATokenIssueBlindSig { 188 cipher: "RSA"; 189 190 // (blinded) RSA signature 191 blinded_rsa_signature: BlindedRsaSignature; 192 } 193 194 .. ts:def:: CSTokenIssueBlindSig 195 196 interface CSTokenIssueBlindSig { 197 cipher: "CS"; 198 199 // Signer chosen bit value, 0 or 1, used 200 // in Clause Blind Schnorr to make the 201 // ROS problem harder. 202 b: Integer; 203 204 // Blinded scalar calculated from c_b. 205 s: Cs25519Scalar; 206 207 } 208 209 .. ts:def:: PayWalletData 210 211 interface PayWalletData { 212 // Index of the selected choice within the ``choices`` array of 213 // the contract terms. 214 // @since protocol **v21** 215 choice_index?: Integer; 216 217 // Array of output tokens to be (blindly) signed by the merchant. 218 // Output tokens specified in choice indicated by ``choice_index``. 219 // @since protocol **v21** 220 tokens_evs?: TokenEnvelope[]; 221 222 // Request for donation receipts to be issued. 223 // @since protocol **v21** 224 donau?: DonationRequestData; 225 } 226 227 .. ts:def:: DonationRequestData 228 229 interface DonationRequestData { 230 // Base URL of the selected Donau 231 url: string; 232 233 // Year for which the donation receipts are expected. 234 // Also determines which keys are used to sign the 235 // blinded donation receipts. 236 year: Integer; 237 238 // Array of blinded donation receipts to sign. 239 // Must NOT be empty (if no donation receipts 240 // are desired, just leave the entire ``donau`` 241 // argument blank). 242 budikeypairs: BlindedDonationReceiptKeyPair[]; 243 } 244 245 .. ts:def:: CoinPaySig 246 247 interface CoinPaySig { 248 // Signature by the coin. 249 coin_sig: EddsaSignature; 250 251 // Public key of the coin being spent. 252 coin_pub: EddsaPublicKey; 253 254 // Signature made by the denomination public key. 255 ub_sig: UnblindedSignature; 256 257 // The hash of the denomination public key associated with this coin. 258 h_denom: HashCode; 259 260 // The amount that is subtracted from this coin with this payment. 261 contribution: Amount; 262 263 // URL of the exchange this coin was withdrawn from. 264 exchange_url: string; 265 266 // Signature affirming the posession of the 267 // respective private key proving that the payer 268 // is old enough. Only provided if the paid contract 269 // has an age restriction and the coin is 270 // age-restricted. 271 minimum_age_sig?: EddsaSignature; 272 273 // Age commitment vector of the coin. 274 // Only provided if the paid contract 275 // has an age restriction and the coin is 276 // age-restricted. 277 age_commitment?: Edx25519PublicKey[]; 278 279 // Hash over the agge commitment vector of the coin. 280 // Only provided if the paid contract 281 // does NOT have an age restriction and the coin is 282 // age-restricted. 283 h_age_commitment?: AgeCommitmentHash; 284 } 285 286 .. ts:def:: TokenUseSig 287 288 interface TokenUseSig { 289 290 // Signature on ``TALER_TokenUseRequestPS`` with the token use key of 291 // the token being used in this request. 292 token_sig: EddsaSignature; 293 294 // Token use public key. 295 token_pub: EddsaPublicKey; 296 297 // Unblinded signature on ``TALER_TokenIssueRequestPS`` with the token 298 // issue public key of the merchant. 299 ub_sig: UnblindedSignature; 300 301 // Hash of the token issue public key associated with this token. 302 h_issue: HashCode; 303 } 304 305 .. ts:def:: TokenEnvelope 306 307 // This type depends on the cipher used to sign token families. This is 308 // configured by the merchant and defined for each token family in the 309 // contract terms. 310 type TokenEnvelope = RSATokenEnvelope | CSTokenEnvelope; 311 312 .. ts:def:: RSATokenEnvelope 313 314 interface RSATokenEnvelope { 315 316 // RSA is used for the blind signature. 317 cipher: "RSA"; 318 319 // Blinded signature of the token's `public EdDSA key <eddsa-token-pub>`. 320 rsa_blinded_pub: BlindedRsaSignature; 321 322 } 323 324 .. ts:def:: CSTokenEnvelope 325 326 interface CSTokenEnvelope { 327 // Blind Clause-Schnorr signature scheme is used for the blind signature. 328 // See https://taler.net/papers/cs-thesis.pdf for details. 329 cipher: "CS"; 330 331 // Public nonce 332 cs_nonce: string; // Crockford `Base32` encoded 333 334 // Two Curve25519 scalars, each representing a blinded challenge 335 cs_blinded_c0: string; // Crockford `Base32` encoded 336 cs_blinded_c1: string; // Crockford `Base32` encoded 337 } 338 339 .. ts:def:: PaymentDeniedLegallyResponse 340 341 interface PaymentDeniedLegallyResponse { 342 343 // Numeric `error code <error-codes>` unique to the condition. 344 // Error code, must be 345 // TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_LEGALLY_REFUSED. 346 code: Integer; 347 348 // Base URL of the exchanges that denied the payment. 349 // The wallet should refresh the coins from these 350 // exchanges, but may try to pay with coins from 351 // other exchanges. 352 exchange_base_urls: string[]; 353 354 }