EBICS
The C ABI exposes EBICS as a backend handle opened with
gln_open_ebics_backend. EBICS supports account/balance/transaction reads and
SEPA transfer/direct-debit submissions through the shared backend operation
surface.
For protocol background and current downloadable specifications, see the official EBICS specification page.
Open a Backend
gln_ebics_config_t config = {0};
gln_default_ebics_config(&config);
config.endpoint = "https://bank.example/ebicsweb";
config.host_id = "BANKHOST";
config.partner_id = "PARTNER01";
config.user_id = "USER01";
config.product_id = "MYPRODUCTID";
gln_backend_t* backend = NULL;
gln_error_t error = {0};
gln_default_error(&error);
gln_status_t status = gln_open_ebics_backend(
&config,
key_store,
&backend,
&error);
| Input | Meaning |
|---|---|
gln_ebics_config_t | Endpoint, host id, partner id, user id, product id, optional language/security/diagnostic fields. |
gln_key_store_t* | EBICS client and bank key material used by signed/encrypted requests. |
Close the backend with gln_close_backend. Release the key store only after
every backend using it has been closed.
Service-Map Presets
gln_get_ebics_service_map_preset_json returns a caller-owned JSON service map
for a named EBICS preset. The supported preset name is dkb; unsupported names
return GLN_ERR_NOT_SUPPORTED and leave the output pointer as NULL.
Release a successful JSON output with gln_release_string.
Supported Operations
| Family | Operations |
|---|---|
| Setup and key lifecycle | ebics_supported_versions, ebics_key_status, ebics_send_ini, ebics_send_hia, ebics_download_bank_keys, ebics_verify_bank_keys, ebics_reset_client_keys, ebics_reset_bank_keys, ebics_generate_ini_brief, ebics_generate_hia_brief |
| Account data | list_accounts, list_balances, list_transactions |
| Transfers | submit_transfer, submit_batch_transfer |
| Direct debits | submit_direct_debit, submit_direct_debit_batch |
EBICS does not report support for TAN mode management, TAN media,
continuation resume, instant transfer, holdings, standing orders, prepaid
top-up, or info through the backend support table.
Setup and Key Lifecycle
The C ABI exposes the EBICS onboarding steps as explicit calls. It does not perform hidden reset or compatibility fallbacks.
| Step | C API | Result |
|---|---|---|
| Check supported protocol versions | gln_get_ebics_supported_versions | GLN_BACKEND_RESULT_KIND_EBICS_SUPPORTED_VERSIONS |
| Inspect local key phase | gln_get_ebics_key_status | GLN_BACKEND_RESULT_KIND_EBICS_KEY_STATUS |
| Send INI | gln_send_ebics_ini | JSON EBICS status envelope |
| Send HIA | gln_send_ebics_hia | JSON EBICS status envelope |
| Download bank keys with HPB | gln_download_ebics_bank_keys | Follow-up envelope carrying GLN_BACKEND_RESULT_KIND_EBICS_BANK_KEYS |
| Verify pending bank keys | gln_verify_pending_ebics_bank_keys | GLN_BACKEND_RESULT_KIND_EBICS_BANK_KEYS |
| Confirm ready phase | gln_get_ebics_key_status | GLN_EBICS_KEY_PHASE_READY when client keys and trusted bank keys are present |
The normal onboarding sequence is HEV, INI, HIA, HPB, verify pending bank keys,
then confirm ready status. gln_download_ebics_bank_keys stages HPB keys as
pending and returns GLN_ERR_FOLLOW_UP_REQUIRED; this is not a resumable TAN
continuation. The envelope still has kind GLN_BACKEND_RESULT_KIND_EBICS_BANK_KEYS.
Read gln_get_ebics_bank_keys_authentication_digest and
gln_get_ebics_bank_keys_encryption_digest, compare both values against the
bank-provided out-of-band source, then pass the expected values to
gln_verify_pending_ebics_bank_keys.
gln_generate_ebics_ini_brief and gln_generate_ebics_hia_brief return
caller-owned text buffers through out_brief_text. Release successful outputs
with gln_release_string.
gln_reset_ebics_client_keys clears local subscriber key pairs and returns the
new key status. gln_reset_ebics_bank_keys clears both trusted and pending bank
keys and returns the new key status. After a bank-key reset, operational EBICS
calls cannot verify bank responses or encrypt uploads until HPB stages fresh
bank keys and gln_verify_pending_ebics_bank_keys promotes them. Do not treat
bank-key reset as an automatic fallback for verification failures.
Provider Status Rows
EBICS success results for submissions can expose provider status through
gln_provider_status_t rows.
| Submission handle | Status accessors |
|---|---|
gln_transfer_submission_t | gln_get_transfer_submission_provider_status_count, gln_get_transfer_submission_provider_status_at |
gln_batch_transfer_submission_t | gln_get_batch_transfer_submission_provider_status_count, gln_get_batch_transfer_submission_provider_status_at |
gln_direct_debit_submission_t | gln_get_direct_debit_submission_provider_status_count, gln_get_direct_debit_submission_provider_status_at |
For EBICS rows, code_or_null carries the business code when a business code
is present and the technical code otherwise. subcode_or_null carries the
technical code when a business code is present.
Result Semantics
| Operation | Result handle | EBICS-specific fields |
|---|---|---|
submit_transfer | gln_transfer_submission_t | gln_get_transfer_submission_id returns the order id when available. |
submit_batch_transfer | gln_batch_transfer_submission_t | Optional order id, transaction count, control sum, provider status rows. |
submit_direct_debit / batch | gln_direct_debit_submission_t | Order id and provider status rows. |
EBICS has no VoP layer in this ABI. Transfer VoP accessors return NULL on
EBICS submission handles.
Example: Submit a Transfer
gln_submit_transfer_request_t request = {0};
gln_default_submit_transfer_request(&request);
request.source_iban = "DE02120300000000202051";
request.source_bic = "BYLADEM1001";
request.source_name = "Example GmbH";
request.recipient_iban = "DE89370400440532013000";
request.recipient_bic = "COBADEFFXXX";
request.recipient_name = "Supplier GmbH";
request.amount = "125.40";
request.purpose = "Invoice 2026-05";
gln_backend_result_t* result = NULL;
if (gln_submit_transfer(backend, &request, &result) == GLN_OK &&
gln_get_backend_result_outcome(result) == GLN_BACKEND_OUTCOME_SUCCESS) {
const gln_transfer_submission_t* submission =
gln_get_backend_result_transfer_submission(result);
const char* order_id = gln_get_transfer_submission_id(submission);
(void)order_id;
}
gln_destroy_backend_result(result);