.. This file is part of GNU TALER. Copyright (C) 2014-2024 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 2.1, or (at your option) any later version. TALER is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with TALER; see the file COPYING. If not, see @author Joel Häberli =========================== The C2EC RESTful API =========================== .. note:: **This API is experimental and not yet implemented** This chapter describe the APIs that third party providers need to integrate to allow withdrawals through indirect payment channels like credit cards or ATM. .. contents:: Table of Contents -------------- Authentication -------------- Terminals which authenticate against the C2EC API must provide their respective access token. Therefore they provide a ``Authorization: Bearer $ACCESS_TOKEN`` header, where `$ACCESS_TOKEN`` is a secret authentication token configured by the exchange and must begin with the RFC 8959 prefix. ---------------------------- Configuration of C2EC ---------------------------- .. http:get:: /config Return the protocol version and configuration information about the C2EC API. **Response:** :http:statuscode:`200 OK`: The exchange responds with a `C2ECConfig` object. This request should virtually always be successful. **Details:** .. ts:def:: C2ECConfig interface C2ECConfig { // Name of the API. name: "taler-c2ec"; // libtool-style representation of the C2EC protocol version, see // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning // The format is "current:revision:age". version: string; } ----------------------------- Withdrawing using C2EC ----------------------------- Withdrawals with a C2EC are based on withdrawal operations which register a withdrawal identifier (nonce) at the C2EC component. The provider must first create a unique identifier for the withdrawal operation (the ``WOPID``) to interact with the withdrawal operation and eventually withdraw using the wallet. .. http:post:: /withdrawal-operation Register a `WOPID` belonging to a reserve public key. **Request:** .. ts:def:: C2ECWithdrawRegistration interface C2ECWithdrawRegistration { // Maps a nonce generated by the provider to a reserve public key generated by the wallet. wopid: ShortHashCode; // Reserve public key generated by the wallet. // According to TALER_ReservePublicKeyP (https://docs.taler.net/core/api-common.html#cryptographic-primitives) reserve_pub_key: EddsaPublicKey; // Optional amount for the withdrawal. amount?: Amount; // Id of the terminal of the provider requesting a withdrawal by nonce. // Assigned by the exchange. terminal_id: SafeUint64; } **Response:** :http:statuscode:`204 No content`: The withdrawal was successfully registered. :http:statuscode:`400 Bad request`: The ``WithdrawRegistration`` request was malformed or contained invalid parameters. :http:statuscode:`500 Internal Server error`: The registration of the withdrawal failed due to server side issues. .. http:get:: /withdrawal-operation/$WOPID Query information about a withdrawal operation, identified by the ``WOPID``. **Request:** :query long_poll_ms: *Optional.* If specified, the bank will wait up to ``long_poll_ms`` milliseconds for operationt state to be different from ``old_state`` before sending the HTTP response. A client must never rely on this behavior, as the bank may return a response immediately. :query old_state: *Optional.* Default to "pending". **Response:** :http:statuscode:`200 Ok`: The withdrawal was found and is returned in the response body as ``C2ECWithdrawalStatus``. :http:statuscode:`404 Not found`: C2EC does not have a withdrawal registered with the specified ``WOPID``. **Details** .. ts:def:: C2ECWithdrawalStatus interface C2ECWithdrawalStatus { // Current status of the operation // pending: the operation is pending parameters selection (exchange and reserve public key) // selected: the operations has been selected and is pending confirmation // aborted: the operation has been aborted // confirmed: the transfer has been confirmed and registered by the bank // Since protocol v1. status: "pending" | "selected" | "aborted" | "confirmed"; // Amount that will be withdrawn with this operation // (raw amount without fee considerations). amount: Amount; // A refund address as ``payto`` URI. This address shall be used // in case a refund must be done. Only not-null if the status // is "confirmed" or "aborted" sender_wire?: string; // Reserve public key selected by the exchange, // only non-null if ``status`` is ``selected`` or ``confirmed``. // Since protocol v1. selected_reserve_pub?: string; } .. http:post:: /withdrawal-operation/$WOPID Notifies C2EC about an executed payment for a specific withdrawal. **Request:** .. ts:def:: C2ECPaymentNotification interface C2ECPaymentNotification { // Unique identifier of the provider transaction. provider_transaction_id: string; // Specifies the amount which was payed to the provider (without fees). // This amount shall be put into the reserve linked to by the withdrawal id. amount: Amount; // Fees associated with the payment. fees: Amount; } **Response:** :http:statuscode:`204 No content`: C2EC received the ``C2ECPaymentNotification`` successfully and will further process the withdrawal. :http:statuscode:`400 Bad request`: The ``C2ECPaymentNotification`` request was malformed or contained invalid parameters. :http:statuscode:`404 Not found`: C2EC does not have a withdrawal registered with the specified ``WOPID``. :http:statuscode:`500 Internal Server error`: The ``C2ECPaymentNotification`` could not be processed due to server side issues. -------------- Taler Wire Gateway -------------- C2EC implements the wire gateway API in order to check for incoming transactions and let the exchange get proofs of payments. This will allow the C2EC componente to add reserves and therefore allow the withdrawal of the money. C2EC does not entirely implement all endpoints, because the it is not needed for the case of C2EC. The endpoints not implemented are not described further. They will be available but respond with 400 http error code. .. http:get:: /config Return the protocol version and configuration information about the bank. This specification corresponds to ``current`` protocol being version **0**. **Response:** :http:statuscode:`200 OK`: The exchange responds with a `WireConfig` object. This request should virtually always be successful. **Details:** .. ts:def:: WireConfig interface WireConfig { // Name of the API. name: "taler-wire-gateway"; // libtool-style representation of the Bank protocol version, see // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning // The format is "current:revision:age". version: string; // Currency used by this gateway. currency: string; // URN of the implementation (needed to interpret 'revision' in version). // @since v0, may become mandatory in the future. implementation?: string; } .. http:post:: /transfer This API allows the exchange to make a transaction, typically to a merchant. The bank account of the exchange is not included in the request, but instead derived from the user name in the authentication header and/or the request base URL. To make the API idempotent, the client must include a nonce. Requests with the same nonce are rejected unless the request is the same. **Request:** .. ts:def:: TransferRequest interface TransferRequest { // Nonce to make the request idempotent. Requests with the same // ``request_uid`` that differ in any of the other fields // are rejected. request_uid: HashCode; // Amount to transfer. amount: Amount; // Base URL of the exchange. Shall be included by the bank gateway // in the appropriate section of the wire transfer details. exchange_base_url: string; // Wire transfer identifier chosen by the exchange, // used by the merchant to identify the Taler order(s) // associated with this wire transfer. wtid: ShortHashCode; // The recipient's account identifier as a payto URI. credit_account: string; } **Response:** :http:statuscode:`200 OK`: The request has been correctly handled, so the funds have been transferred to the recipient's account. The body is a `TransferResponse`. :http:statuscode:`400 Bad request`: Request malformed. The bank replies with an `ErrorDetail` object. :http:statuscode:`401 Unauthorized`: Authentication failed, likely the credentials are wrong. :http:statuscode:`404 Not found`: The endpoint is wrong or the user name is unknown. The bank replies with an `ErrorDetail` object. :http:statuscode:`409 Conflict`: A transaction with the same ``request_uid`` but different transaction details has been submitted before. **Details:** .. ts:def:: TransferResponse interface TransferResponse { // Timestamp that indicates when the wire transfer will be executed. // In cases where the wire transfer gateway is unable to know when // the wire transfer will be executed, the time at which the request // has been received and stored will be returned. // The purpose of this field is for debugging (humans trying to find // the transaction) as well as for taxation (determining which // time period a transaction belongs to). timestamp: Timestamp; // Opaque ID of the transaction that the bank has made. row_id: SafeUint64; } .. http:get:: /history/incoming **Request:** :query start: *Optional.* Row identifier to explicitly set the *starting point* of the query. :query delta: The *delta* value that determines the range of the query. :query long_poll_ms: *Optional.* If this parameter is specified and the result of the query would be empty, the bank will wait up to ``long_poll_ms`` milliseconds for new transactions that match the query to arrive and only then send the HTTP response. A client must never rely on this behavior, as the bank may return a response immediately or after waiting only a fraction of ``long_poll_ms``. **Response:** .. ts:def:: IncomingReserveTransaction interface IncomingReserveTransaction { type: "RESERVE"; // Opaque identifier of the returned record. row_id: SafeUint64; // Date of the transaction. date: Timestamp; // Amount transferred. amount: Amount; // Payto URI to identify the sender of funds. debit_account: string; // The reserve public key extracted from the transaction details. reserve_pub: EddsaPublicKey; }