bankapi

io.token.proto.bankapi external/src/main/proto/bankapi/bankapi.proto


syntax = "proto3";
package io.token.proto.bankapi;

import "google/api/annotations.proto";

import "account.proto";
import "transfer.proto";
import "consent.proto";
import "money.proto";
import "transaction.proto";
import "transferinstructions.proto";
import "notification.proto";
import "subscriber.proto";
import "banklink.proto";
import "providerspecific.proto";
import "token.proto";
import "extensions/field.proto";
import "extensions/method.proto";

////////////////////////////////////////////////////////////////////////////////////////////////////
// Shared objects
//
enum StatusCode {
  INVALID_STATUS = 0;                   // invalid status, reserved
  PROCESSING = 1;                       // transaction is being processed
  SUCCESS = 2;                          // transaction succeeded
  FAILURE_CANCELED = 3;                 // transaction has been canceled, rolled back
  FAILURE_INSUFFICIENT_FUNDS = 4;       // the transaction failed due to insufficient funds
  FAILURE_INVALID_CURRENCY = 5;         // the transaction failed due to currency mismatch
  FAILURE_PERMISSION_DENIED = 6;        // the transaction failed due to access violation
  FAILURE_QUOTE_EXPIRED = 7;            // the transaction failed because the quote has expired
  FAILURE_INVALID_AMOUNT = 8;           // the transaction failed due to invalid amount
  FAILURE_INVALID_QUOTE = 9;            // the transaction failed due to invalid quote (wrong fx rate)
  FAILURE_EXPIRED = 10;                 // the transaction failed to complete within alotted time
  FAILURE_GENERIC = 11;                 // the transaction has failed due to other reasons
  FAILURE_ACCOUNT_NOT_FOUND = 12;       // the account is not found
  FAILURE_TRANSACTION_NOT_FOUND = 13;   // the transaction has failed due to other reasons
  FAILURE_UNSUPPORTED_DESTINATION = 14; // the transaction failed because bank does not support requested destination
  FAILURE_UNSUPPORTED_FREQUENCY = 17;   // the standing order failed because bank does not support requested frequency
  FAILURE_DECLINED = 18;                // the transaction failed because bank has declined
  SENT = 15;                            // legacy transfers only: the transaction has been sent but has not been acknowledged by the bank
  INITIATED = 16;                       // not recommended: the transaction has been initiated but the result is unknown, this may be the final status and may not get updated later
}

// Simplified transaction object used in bulk transfer lookup.
message BulkTransaction {
  string ref_id = 1;
  string transaction_id = 2;
  io.token.proto.common.transaction.TransactionStatus status = 3;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Account API types
//
message GetTransactionRequest {
  string transaction_id = 1;
  io.token.proto.common.account.BankAccount account = 2;
  string consent_id = 3;
}

message GetTransactionResponse {
  io.token.proto.common.transaction.Transaction transaction = 1;
}

message GetTransactionsRequest {
  io.token.proto.common.account.BankAccount account = 1;
  int32 integer_offset = 2 [deprecated=true];  // use offset instead
  int32 limit = 3;
  string offset = 4;
  // Optional lower bound for a transaction's booking date as returned by the bank, in the format 'YYYY-MM-DD' (e.g. '2016-01-01').
  // If specified, then only transactions whose bank booking date is equal to or later than the given date will be regarded.
  string start_date = 5;
  // Optional upper bound for a transaction's booking date as returned by the bank (= original booking date), in the format 'YYYY-MM-DD' (e.g. '2016-01-01').
  // If specified, then only transactions whose bank booking date is equal to or earlier than the given date will be regarded.
  string end_date = 6;
  string consent_id = 7;
}

message GetTransactionsResponse {
  repeated io.token.proto.common.transaction.Transaction transactions = 1;
  string offset = 2;
}

message GetStandingOrderRequest {
  io.token.proto.common.account.BankAccount account = 1;
  string standing_order_id = 2;
  string consent_id = 3;
}

message GetStandingOrderResponse {
  io.token.proto.common.transaction.StandingOrder standing_order = 1;
}

message GetStandingOrdersRequest {
  io.token.proto.common.account.BankAccount account = 1;
  int32 limit = 2;
  string offset = 3;
  string consent_id = 4;
}

message GetStandingOrdersResponse {
  repeated io.token.proto.common.transaction.StandingOrder standing_orders = 1;
  string offset = 2;
}

message GetBalanceRequest {
  io.token.proto.common.account.BankAccount account = 1;
  string consent_id = 2;
}

message GetBalanceResponse {
  io.token.proto.common.money.Money current = 1;
  io.token.proto.common.money.Money available = 2;
  int64 updated_at_ms = 3;
  repeated io.token.proto.common.transaction.Balance.TypedBalance other_balances = 4; // optional
}

message GetCustomerDataRequest {
  io.token.proto.common.account.BankAccount account = 1;
  string consent_id = 2;
}

message GetCustomerDataResponse {
  io.token.proto.common.transferinstructions.CustomerData customer_data = 1;
  StatusCode status = 2;
  string status_description = 3;
}

message ResolveTransferDestinationRequest {
  option deprecated = true;
  io.token.proto.common.account.BankAccount account = 1;
}

message ResolveTransferDestinationResponse {
  option deprecated = true;
  repeated io.token.proto.common.account.BankAccount destinations = 1 [deprecated=true];
  repeated io.token.proto.common.transferinstructions.TransferEndpoint endpoints = 2 [deprecated=true];
  repeated io.token.proto.common.transferinstructions.TransferDestination transfer_destinations = 3;
}

message ResolveTransferDestinationsRequest {
  option deprecated = true;
  io.token.proto.common.account.BankAccount account = 1;
  string consent_id = 2;
}

message ResolveTransferDestinationsResponse {
  option deprecated = true;
  repeated io.token.proto.common.transferinstructions.TransferDestination destinations = 3;
}

message GetAccountDetailsRequest {
  option deprecated = true;
  io.token.proto.common.account.BankAccount account = 1;
}

message GetAccountDetailsResponse {
  option deprecated = true;
  io.token.proto.common.account.AccountDetails account_details = 1;
}

message GetAccountRequest {
  io.token.proto.common.account.BankAccount account = 1;
  string consent_id = 2;
}

message GetAccountResponse {
  Account account = 1;
  message Account {
    string name = 1 [(io.token.proto.extensions.field.redact) = true]; // human-friendly name. E.g., "Checking account with number ...1234"
    io.token.proto.common.account.AccountFeatures account_features = 2; // features account supports
    io.token.proto.common.account.AccountDetails account_details = 3;   // optional additional account details
  }
}

message ConfirmFundsRequest {
  io.token.proto.common.account.BankAccount account = 1;
  io.token.proto.common.money.Money money = 2;
  string consent_id = 3;
}

message ConfirmFundsResponse {
  bool funds_available = 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Account linking API types
//
message GetBankAuthorizationRequest {
  string access_token = 1;
}

message GetBankAuthorizationResponse {
  io.token.proto.banklink.BankAuthorization bank_authorization = 1;
}


////////////////////////////////////////////////////////////////////////////////////////////////////
// Notification API types
//
message NotifyRequest {
  io.token.proto.common.notification.Notification notification = 1;
  io.token.proto.common.subscriber.Subscriber subscriber = 2;
}

message NotifyResponse {}


////////////////////////////////////////////////////////////////////////////////////////////////////
// Storage API types
//
message SetValueRequest {
  enum ContentCategory {
    INVALID = 0;
    ACCOUNT_INFO = 1;
    TOKEN_INFO = 2;
  }

  string key = 1;
  bytes value = 2 [(io.token.proto.extensions.field.redact) = true];
  ContentCategory category = 3;
}

message SetValueResponse {
  bytes previous = 1 [(io.token.proto.extensions.field.redact) = true];
}

message GetValueRequest {
  string key = 1;
}

message GetValueResponse {
  bytes value = 1 [(io.token.proto.extensions.field.redact) = true];
}

message RemoveValueRequest {
  string key = 1;
}

message RemoveValueResponse {
}


////////////////////////////////////////////////////////////////////////////////////////////////////
// Transfer API types
//
message TransferRequest {
  string transfer_id = 1;
  io.token.proto.common.money.Money requested_amount = 2 [deprecated = true];
  io.token.proto.common.money.Money transaction_amount = 3;
  io.token.proto.common.account.BankAccount source = 4 [deprecated=true];
  repeated io.token.proto.common.transferinstructions.TransferEndpoint destinations = 5 [deprecated=true];
  string description = 9; // optional transfer description
  string token_ref_id = 10; // reference ID of the token, set by the initiator
  string transfer_ref_id = 11;
  io.token.proto.common.transferinstructions.TransferInstructions.Metadata metadata = 12 [deprecated=true];
  string token_initiator_id = 13; // ID of member who requested token creation
  repeated io.token.proto.common.transferinstructions.TransferDestination transfer_destinations = 14 [deprecated=true];
  string execution_date = 15; // execution date of the transfer
  bool confirm_funds = 16;
  io.token.proto.common.transferinstructions.TransferInstructions transfer_instructions = 17;
  string consent_id = 18;
  string remittance_reference = 19 [(io.token.proto.extensions.field.hash) = true];
  bool return_refund_account = 20;                                                       // Returns a refundable account.
}

message TransferResponse {
  string transaction_id = 1;
  StatusCode status = 2;
  string status_description = 3;
  io.token.proto.common.transferinstructions.TransferEndpoint source = 4;
  io.token.proto.common.providerspecific.ProviderTransferDetails provider_details = 5;  // optional if there are provider details
  io.token.proto.common.account.Refund refund = 7;    // Optional: a refund object will be returned
  bool continue_polling = 8; // force status polling despite the status.
  io.token.proto.common.transfer.Transfer.ScaStatus sca_status = 9; // Optional: SCA Status object will be returned
}

message CreateStandingOrderRequest {
  string token_submission_id = 1; // Token reference for the standing order submission
  string ref_id = 2; // reference ID of the standing order, set by the initiator
  string token_initiator_id = 3; // ID of member who requested token creation
  io.token.proto.common.token.StandingOrderBody payload = 4;
  io.token.proto.common.account.BankAccount source = 5 [deprecated=true];
  repeated io.token.proto.common.transferinstructions.TransferDestination transfer_destinations = 6 [deprecated=true];
  string description = 7; // optional transfer description
  io.token.proto.common.transferinstructions.TransferInstructions.Metadata metadata = 8 [deprecated=true];
  io.token.proto.common.transferinstructions.TransferInstructions transfer_instructions = 9;
  string consent_id = 10;
  bool return_refund_account = 11;                                                       // Returns a refundable account.
}

message CreateStandingOrderResponse {
  string standing_order_id = 1;
  StatusCode status = 2;
  string status_description = 3;
  io.token.proto.common.providerspecific.ProviderStandingOrderSubmissionDetails provider_details = 4; // optional if there are provider details
  io.token.proto.common.account.Refund refund = 6;    // Optional: a refund object will be returned
}

message CreateBulkTransferRequest {
  string token_bulk_transfer_id = 1; // Token reference for the bulk transfer
  string ref_id = 2;
  string token_initiator_id = 3; // ID of member who requested token creation
  io.token.proto.common.token.BulkTransferBody payload = 4;
  io.token.proto.common.account.BankAccount source = 5 [deprecated=true]; // resolved source
  string description = 6; // optional transfer description
  io.token.proto.common.transferinstructions.TransferEndpoint source_account = 7;
  string consent_id = 8;
}

message CreateBulkTransferResponse {
  string bulk_transfer_id = 1;
  StatusCode status = 2;
  repeated BulkTransaction transactions = 3;
}

message BatchTransferRequest {
  repeated TransferRequest transfers = 1;
}

message BatchTransferResponse {
  TransferResponse transfer_response = 1;
}

message GetTransferStatusRequest {
  string transfer_id = 1;
  string consent_id = 2;
  io.token.proto.common.transfer.Transfer.ScaStatus sca_status = 3;
}

message GetTransferStatusResponse {
  io.token.proto.common.transaction.TransactionStatus status = 1;
  string raw_status = 2; // optional if there is a raw status
  string status_reason_information = 3; // Optional: provides detailed information on the status reason
  bool continue_polling = 4; // force status polling despite the status.
  io.token.proto.common.transfer.Transfer.ScaStatus sca_status = 5;
}

message GetBulkTransferRequest {
  string bulk_transfer_id = 1;
}

message GetBulkTransferResponse {
  repeated BulkTransaction transactions = 1;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Account Management API types
//
message OnAccountLinkedRequest {
  io.token.proto.common.account.BankAccount account = 1;
  string account_id = 2;
}

message OnAccountLinkedResponse {}

message OnAccountUnlinkedRequest {
  io.token.proto.common.account.BankAccount account = 1;
  string account_id = 2;
}

message OnAccountUnlinkedResponse {}


////////////////////////////////////////////////////////////////////////////////////////////////////
// Consent Management API types
//
message OnConsentCreatedRequest {
  io.token.proto.common.consent.Consent consent = 1;
}

message OnConsentCreatedResponse {}

message OnConsentRevokedRequest {
  string token_id = 1;
}

message OnConsentRevokedResponse {}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Health Check API types
//
message HealthCheckRequest {
  string bank_id = 1;
}

message HealthCheckResponse {

}


////////////////////////////////////////////////////////////////////////////////////////////////////
// Account API
//
service AccountService {
  rpc GetBalance (GetBalanceRequest) returns (GetBalanceResponse) {
    option (google.api.http) = {
        get: "/accounts/balance?account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
    };
  }

  rpc GetTransaction (GetTransactionRequest) returns (GetTransactionResponse) {
    option (google.api.http) = {
        get: "/accounts/transactions?transaction_id={transaction_id}&account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
    };
  }

  rpc GetTransactions (GetTransactionsRequest) returns (GetTransactionsResponse) {
    option (google.api.http) = {
        get: "/accounts/transactions?offset={offset}&limit={limit}&account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
    };
  }

  rpc GetStandingOrder (GetStandingOrderRequest) returns (GetStandingOrderResponse) {
    option (google.api.http) = {
        get: "/account/standing-orders/{standing_order_id}"
    };
  }

  rpc GetStandingOrders (GetStandingOrdersRequest) returns (GetStandingOrdersResponse) {
    option (google.api.http) = {
        get: "/account/standing-orders"
    };
  }

  rpc GetCustomerData(GetCustomerDataRequest) returns (GetCustomerDataResponse) {
    option deprecated = true;
    option (google.api.http) = {
        get: "/accounts/{account.custom.bank_id}/{account.custom.payload}/customer-data"
    };
  }

  rpc ResolveTransferDestination(ResolveTransferDestinationRequest) returns (ResolveTransferDestinationResponse) {
    option deprecated = true; // Use ResolveTransferDestinations instead
    option (google.api.http) = {
        get: "/accounts/transfer-destination?account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
    };
  }

  rpc ResolveTransferDestinations(ResolveTransferDestinationsRequest) returns (ResolveTransferDestinationsResponse) {
    // AccountIdentifier is now populated in Account.AccountDetails - no need to resolve it anymore;
    // linked accounts are no longer used as transfer destinations (were used in p2p flow before)
    option deprecated = true;
    option (google.api.http) = {
        get: "/accounts/transfer-destinations?account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
    };
  }

  rpc GetAccountDetails(GetAccountDetailsRequest) returns (GetAccountDetailsResponse) {
    option deprecated = true; // Use GetAccount instead
    option (google.api.http) = {
        get: "/accounts/account-details?account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
    };
  }

  rpc GetAccount(GetAccountRequest) returns (GetAccountResponse) {
    option (google.api.http) = {
        get: "/accounts?account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
    };
  }

  rpc ConfirmFunds(ConfirmFundsRequest) returns (ConfirmFundsResponse) {
    option (google.api.http) = {
        get: "/accounts/funds-confirmation?money.currency={money.currency}&money.value={money.value}&account.swift.bic={account.swift.bic}&account.swift.account={account.swift.account}&account.sepa.iban={account.sepa.iban}&account.sepa.bic={account.sepa.bic}&account.ach.routing={account.ach.routing}&account.ach.account={account.ach.account}&account.faster_payments.sort_code={account.faster_payments.sort_code}&account.faster_payments.account_number={account.faster_payments.account_number}&account.custom.bank_id={account.custom.bank_id}&account.custom.payload={account.custom.payload}"
    };
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Account Linking API
//
service AccountLinkingService {
  rpc GetBankAuthorization (GetBankAuthorizationRequest) returns (GetBankAuthorizationResponse) {
    option (google.api.http) = {
        get: "/bank-authorization?access_token={access_token}"
    };
  }
}


////////////////////////////////////////////////////////////////////////////////////////////////////
// Notification API
//
service NotificationService {
  rpc Notify (NotifyRequest) returns (NotifyResponse) {
    option (google.api.http) = {
        post: "/notifications"
        body: "*"
    };
  }
}


////////////////////////////////////////////////////////////////////////////////////////////////////
// Storage API
//
service StorageService {
  rpc SetValue (SetValueRequest) returns (SetValueResponse) {
    option (google.api.http) = {
        put: "/storage/{key}"
    };
  }

  rpc GetValue (GetValueRequest) returns (GetValueResponse) {
    option (google.api.http) = {
        get: "/storage/{key}"
    };
  }

  rpc RemoveValue (RemoveValueRequest) returns (RemoveValueResponse) {
    option (google.api.http) = {
        delete: "/storage/{key}"
    };
  }
}


////////////////////////////////////////////////////////////////////////////////////////////////////
// Transfer API
//
service TransferService {
  rpc Transfer (TransferRequest) returns (TransferResponse) {
    option (google.api.http) = {
        post: "/transfers"
        body: "*"
    };
  }

  rpc CreateStandingOrder (CreateStandingOrderRequest) returns (CreateStandingOrderResponse) {
    option (google.api.http) = {
        post: "/standing-orders"
        body: "*"
    };
  }

  rpc CreateBulkTransfer (CreateBulkTransferRequest) returns (CreateBulkTransferResponse) {
    option (google.api.http) = {
        post: "/bulk-transfers"
        body: "*"
    };
  }

  rpc GetBulkTransfer (GetBulkTransferRequest) returns (GetBulkTransferResponse) {
    option (google.api.http) = {
        get: "/bulk-transfers/{bulk_transfer_id}"
    };
  }

  rpc BatchTransfer (BatchTransferRequest) returns (BatchTransferResponse) {
    option (google.api.http) = {
        post: "/batch/transfers"
        body: "*"
    };
  }

  rpc GetTransferStatus (GetTransferStatusRequest) returns (GetTransferStatusResponse) {
    option (google.api.http) = {
        get: "/transfers/{transfer_id}/status"
    };
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Account Management API
//
service AccountManagementService {
  rpc OnAccountLinked (OnAccountLinkedRequest) returns (OnAccountLinkedResponse) {
    option (google.api.http) = {
        put: "/accounts/linked"
    };
  }

  rpc OnAccountUnlinked (OnAccountUnlinkedRequest) returns (OnAccountUnlinkedResponse) {
    option (google.api.http) = {
        put: "/accounts/unlinked"
    };
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Consent Management API
//
service ConsentManagementService {
  rpc OnConsentCreated (OnConsentCreatedRequest) returns (OnConsentCreatedResponse) {
    option (google.api.http) = {
        put: "/consent/created"
    };
  }

  rpc OnConsentRevoked (OnConsentRevokedRequest) returns (OnConsentRevokedResponse) {
    option (google.api.http) = {
        put: "/consent/revoked"
    };
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Health Check API
//
service HealthCheckService {
  rpc HealthCheck (HealthCheckRequest) returns (HealthCheckResponse) {
    option (google.api.http) = {
        get: "/health-check?bank_id={bank_id}"
    };
  }
}