taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

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     }