Contents

POST /batch-deposit#

Deposit multiple coins and ask the exchange to transfer the given Amounts into the merchant’s bank account. This API is used by the merchant to redeem the digital coins.

Request:

The request body must be a BatchDepositRequest object.

Response:

200 OK:

The operation succeeded, the exchange confirms that no double-spending took place. The response will be a DepositSuccessResponse object.

400 Bad Request:

The request is malformed or a parameter is invalid. This response comes with a standard ErrorDetail response. Possible error codes include TALER_EC_GENERIC_PARAMETER_MALFORMED, TALER_EC_EXCHANGE_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE, TALER_EC_EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE, TALER_EC_EXCHANGE_DEPOSIT_WIRE_DEADLINE_IS_NEVER, TALER_EC_EXCHANGE_GENERIC_AMOUNT_EXCEEDS_DENOMINATION_VALUE, TALER_EC_EXCHANGE_GENERIC_CIPHER_MISMATCH, or TALER_EC_EXCHANGE_DEPOSITS_POLICY_NOT_ACCEPTED.

403 Forbidden:

One of the signatures is invalid. This response comes with a standard ErrorDetail response. Possible error codes include TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID or TALER_EC_EXCHANGE_DENOMINATION_SIGNATURE_INVALID.

404 Not found:

Either one of the denomination keys is not recognized (expired or invalid), or the wire type is not recognized. If a denomination key is unknown, the response will be a DenominationUnknownMessage.

409 Conflict:

The deposit operation has either failed because a coin has insufficient residual value, or because the same public key of a coin has been previously used with a different denomination. Which case it is can be decided by looking at the error code:

  1. TALER_EC_EXCHANGE_DEPOSIT_CONFLICTING_CONTRACT (same coin used in different ways),

  2. TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS (balance insufficient),

  3. TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY (same coin public key, but different denomination).

  4. TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_AGE_HASH (same coin public key, but different age commitment).

The response is a DepositDoubleSpendError for cases 1 and 2, a CoinDenominationConflictError for case 3 and a CoinAgeCommitmentConflictError for case 4. The request should not be repeated again with this coin. Instead, the client can get from the exchange via the /coin/$COIN_PUB/history endpoint the record of the transactions known for this coin’s public key.

410 Gone:

The requested denomination key is no longer valid. It is past the expiration or was revoked. The response is a DenominationGoneMessage. Clients must evaluate the error code provided to understand which of the cases this is and handle it accordingly. Possible error codes include TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED or TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED.

412 Precondition Failed:

The requested denomination key is not yet valid. It is before the validity start time. The response is a DenominationGoneMessage with TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE.

413 Request entity too large:

The uploaded body is to long, it exceeds the size limit. Returned with an error code of TALER_EC_GENERIC_UPLOAD_EXCEEDS_LIMIT.

451 Unavailable For Legal Reasons:

This merchant has not yet passed the KYC checks. The client must pass KYC checks before proceeding with the deposit. The response will be an LegitimizationNeededResponse object. @since protocol v21.

500 Internal Server Error:

The server experienced an internal error. This response comes with a standard ErrorDetail response. Possible error codes include TALER_EC_GENERIC_DB_STORE_FAILED, TALER_EC_GENERIC_DB_START_FAILED, or TALER_EC_GENERIC_DB_FETCH_FAILED.

Details:

interface BatchDepositRequest {

  // The merchant's account details as a full payto URI.
  merchant_payto_uri: string;

  // The salt is used to hide the payto_uri from customers
  // when computing the h_wire of the merchant.
  wire_salt: WireSalt;

  // SHA-512 hash of the contract of the merchant with the customer.  Further
  // details are never disclosed to the exchange.
  h_contract_terms: HashCode;

  // Merchant's signature over the h_contract_terms.
  // @since protocol **v22**
  merchant_sig: EddsaSignature;

  // The list of coins that are going to be deposited with this Request.
  coins: BatchDepositRequestCoin[];

  // Timestamp when the contract was finalized.
  timestamp: Timestamp;

  // Indicative time by which the exchange undertakes to transfer the funds to
  // the merchant, in case of successful payment. A wire transfer deadline of 'never'
  // is not allowed.
  wire_transfer_deadline: Timestamp;

  // EdDSA public key of the merchant, so that the client can identify the
  // merchant for refund requests.
  merchant_pub: EddsaPublicKey;

  // Additional text to include in the wire transfer subject when
  // settling the payment. Note that the merchant MUST use this
  // consistently for the same merchant_pub and merchant_payto_uri
  // as during aggregation *any* of these values may be selected
  // for the actual aggregated wire transfer. If a merchant wants
  // to use different extra_subject values for the same IBAN,
  // it should thus create multiple instances (with different
  // merchant_pub values). When changing the extra_subject,
  // the change may thus not be immediately reflected in the
  // settlements.
  //
  // Must match [a-zA-Z0-9-.:]{1, 40}
  //
  // Optional. Since **v32**.
  extra_wire_subject_metadata?: string;

  // Date until which the merchant can issue a refund to the customer via the
  // exchange, to be omitted if refunds are not allowed.
  refund_deadline?: Timestamp;
}
interface BatchDepositRequestCoin {
  // EdDSA public key of the coin being deposited.
  coin_pub: EddsaPublicKey;

  // Hash of denomination RSA key with which the coin is signed.
  denom_pub_hash: HashCode;

  // Exchange's unblinded RSA signature of the coin.
  ub_sig: DenominationSignature;

  // Amount to be deposited, can be a fraction of the
  // coin's total value.
  contribution: Amount;

  // Signature over TALER_DepositRequestPS, made by the customer with the
  // coin's private key.
  coin_sig: EddsaSignature;

  // Hash over the age commitment of the coin.
  // Only present if the coin is actually age-restricted.
  h_age_commitment?: HashCode;
}
type DenominationSignature = DenomCipher & (
  | RsaDenominationSignature
  | CSDenominationSignature
);
interface RsaDenominationSignature extends DenomCipher {
  cipher: "RSA";

  // RSA signature
  rsa_signature: RsaSignature;
}
interface CSDenominationSignature extends DenomCipher {
  cipher: "CS";

  // R value component of the signature.
  cs_signature_r: Cs25519Point;

  // s value component of the signature.
  cs_signature_s: Cs25519Scalar;

}

The deposit operation succeeds if the coin is valid for making a deposit and has enough residual value that has not already been deposited or melted.

 interface DepositSuccessResponse {

  // Total amount deposited so far under this contract terms for
  // this merchant.
  // Since **v33**.
  accumulated_total_without_fee: Amount;

  // Timestamp when the deposit was received by the exchange.
  exchange_timestamp: Timestamp;

  // Public EdDSA key of the exchange that was used to
  // generate the signature.
  // Should match one of the exchange's signing keys from /keys.  It is given
  // explicitly as the client might otherwise be confused by clock skew as to
  // which signing key was used.
  exchange_pub: EddsaPublicKey;

  // Deposit confirmation signature from the exchange.
  // The EdDSA signature of TALER_DepositConfirmationPS using a current
  // signing key of the exchange affirming the successful
  // deposit and that the exchange will transfer the funds after the refund
  // deadline, or as soon as possible if the refund deadline is zero.
  exchange_sig: EddsaSignature;
}
interface DepositDoubleSpendError {

  // Must be TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS
  // or TALER_EC_EXCHANGE_DEPOSIT_CONFLICTING_CONTRACT.
  // (Since **vCONFLICT**, a conflicting denomination is
  // reported with a CoinDenominationConflictError instead.)
  code: Integer;

  // A string explaining that the user tried to
  // double-spend.
  hint: string;

  // EdDSA public key of a coin being double-spent.
  coin_pub: EddsaPublicKey;

  // Hash of the public key of the denomination of the coin.
  h_denom_pub: HashCode;

}