# Payments ## List payment statuses for an account - [GET /v1/accounts/{accountNumber}/payments](https://developers.bcb.bm/apis/open-banking-api/open-banking-api/accounts/transactionstatus_getaccounttransactionstatuses.md): Retrieves status information for all payments associated with a specific account. This endpoint: - Provides comprehensive payment status details including type, status, transaction ID, external reference, remittance information, amounts, value date, and exchange rate. - Supports both JSON and CSV response formats based on the Accept header. - Supports cursor-based pagination for efficient handling of large payment status datasets. ### Pagination This endpoint uses cursor-based pagination with server-side result-set management: - First Request: Optionally specify pageSize (default: 100, max: 1000). The server creates a cursor and returns a pageToken. - Subsequent Requests: Use the pageToken from previous responses with pageStart to navigate pages. - Page Token: Contains encoded pagination context including pageSize, so don't specify pageSize in subsequent requests. - Total Pages: Calculate using Math.ceil(total_size / page_size) from the response metadata. ### Content Negotiation Clients must use the HTTP Accept header to indicate the desired response format: - Set Accept: application/json for JSON responses (default) - Set Accept: text/csv for CSV responses If the Accept header is omitted, application/json is assumed. ### Base URL All API requests use the versioned base URL: https://api.bcb.bm/v1/accounts/{accountNumber}/payments ### Sample Request in JavaScript javascript async function getAllPaymentStatusesPaginated(accountNumber) { try { let allPaymentStatuses = []; let pageStart = 1; let pageToken = null; let totalPages = 0; do { // Build URL with pagination parameters let url = https://api.bcb.bm/v1/accounts/${accountNumber}/payments; const params = new URLSearchParams(); if (pageStart === 1) { // First request: specify pageSize params.append('pageSize', '100'); } else { // Subsequent requests: use pageToken and pageStart params.append('pageToken', pageToken); params.append('pageStart', pageStart.toString()); } if (params.toString()) { url += '?' + params.toString(); } const response = await fetch(url, { method: 'GET', headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', 'Accept': 'application/json' } }); if (!response.ok) { const errorData = await response.json(); throw new Error(Error: ${errorData.message || 'Unknown error'}); } const data = await response.json(); console.log(Page ${pageStart} data:, data); // Store pagination info from first request if (pageStart === 1 && data.meta && data.meta.pagination) { pageToken = data.meta.pagination.page_token; totalPages = Math.ceil(data.meta.pagination.total_size / data.meta.pagination.page_size); console.log(Total pages: ${totalPages}, Page token: ${pageToken}); } // Collect payment statuses from this page if (data.data && data.data.length > 0) { allPaymentStatuses.push(...data.data); console.log(Collected ${data.data.length} payment statuses from page ${pageStart}); } pageStart++; } while (pageStart { console.log(Payment ${index + 1}:, payment.transactionId); console.log('Type:', payment.type); console.log('Status:', payment.status); console.log('External Reference:', payment.externalReference); console.log('Remittance Information:', payment.remittanceInformation); console.log('Value Date:', payment.valueDate); console.log('Debit Amount:', ${payment.debitAmount.amount} ${payment.debitAmount.currency}); if (payment.creditAmount && payment.creditAmount.amount) { console.log('Credit Amount:', ${payment.creditAmount.amount} ${payment.creditAmount.currency}); } console.log('-------------------'); }); return allPaymentStatuses; } catch (error) { console.error('There was a problem with the fetch operation:', error.message); throw error; } } // Alternative: Get single page of payment statuses async function getPaymentStatusesPage(accountNumber, pageStart = 1, pageToken = null) { try { let url = https://api.bcb.bm/v1/accounts/${accountNumber}/payments; const params = new URLSearchParams(); if (pageStart === 1 && !pageToken) { params.append('pageSize', '50'); // Custom page size } else { params.append('pageToken', pageToken); params.append('pageStart', pageStart.toString()); } if (params.toString()) { url += '?' + params.toString(); } const response = await fetch(url, { method: 'GET', headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', 'Accept': 'application/json' } }); if (!response.ok) { const errorData = await response.json(); throw new Error(Error: ${errorData.message || 'Unknown error'}); } const data = await response.json(); console.log('Payment statuses page:', data); return data; } catch (error) { console.error('There was a problem with the fetch operation:', error.message); throw error; } } // Example usage: getAllPaymentStatusesPaginated('123456789'); // Retrieves all payment statuses across multiple pages // OR getPaymentStatusesPage('123456789', 1).then(firstPage => { console.log('First page:', firstPage); // Use firstPage.meta.pagination.page_token for subsequent requests }); Required Permission: get-payment-status This endpoint requires the permission claim get-payment-status to be present in the JWT token. These permissions are embedded in the token during the authentication process and cannot be modified afterward. The token must be obtained with the appropriate permissions to access this endpoint. ## ACH Local Payment - [POST /v1/payments/ach-local](https://developers.bcb.bm/apis/open-banking-api/open-banking-api/payments/achlocalpayments_post.md): Initiates a domestic ACH (Automated Clearing House) local bank transfer. The request must include all required payment details including: - Source (debtor) account identification - Payment amount and currency - Debit currency (must match instructed amount currency) - Beneficiary account identification and name - Creditor bank reference (bank code and currency) - Remittance information (1–2 lines) ### Key Features - Supports local same-currency bank transfers via the ACH clearing network - Implements idempotency to prevent duplicate transactions - Validates payment requests before processing - Supports both JSON and CSV response formats - Same-day ACH settlement ### Supported Currencies Only USD and BMD are accepted. The debitCurrency and instructedAmount.currency must be identical (cross-currency is not supported for ACH local transfers). ### Cut-Off Time ACH local transfers must be submitted before 3:15 PM local AST for same-day processing. Submissions after the cut-off will be queued for the next business day. ### Settlement ACH local transfers settle same-day when submitted before the cut-off time. The value/effective date returned in the response reflects the settlement date. ### Creditor Bank Reference Provide creditorBank with the destination bank bankCode and currency. The API validates this combination against the configured bank reference lookup. If the bankCode and currency combination is not found, the API returns 400 Bad Request with error code BANK_REFERENCE_NOT_FOUND. The ACH local bank reference lookup contains the following values: | Bank Code | Currency | Bank Name | |-----------|----------|-----------| | BUTTERFIELD | BMD | Bank of N.T. Butterfield & Sons | | HSBC | BMD | HSBC Bermuda | | CLARIEN | BMD | Clarien Bank Bermuda | | BUTTERFIELD | USD | Bank of N.T. Butterfield & Sons | | HSBC | USD | HSBC Bermuda | | CLARIEN | USD | Clarien Bank Bermuda | Clients must provide a creditorBank.currency value of USD or BMD, and it must match debitCurrency. ### Headers - Authorization: Bearer {token} (required) - Content-Type: application/json (required) - Accept: application/json (default) or Accept: text/csv - Idempotency-Key: {uuid} (optional, UUID format) ### Content Negotiation Clients must use the HTTP Accept header to indicate the desired response format: - Set Accept: application/json for JSON responses (default) - Set Accept: text/csv for CSV responses If the Accept header is omitted, application/json is assumed. ### Base URL All API requests use the versioned base URL: https://api.bcb.bm/v1/payments/ach-local ### Idempotency The API supports idempotency through the optional Idempotency-Key header: - If no idempotency key is provided, the request is processed normally (duplicates are possible) - If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results - If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response - Idempotency keys are user-specific - different users with the same keys don't share cached responses - The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000") ### Validation Rules | Field | Constraint | |-------|-----------| | instructionIdentification | Optional, max 16 characters | | debtorAccount.identification | Required, max 36 characters | | debitCurrency | Required, exactly 3 characters, USD or BMD only | | instructedAmount.amount | Required, max 18 characters, valid decimal (up to 2 decimal places) | | instructedAmount.currency | Required, exactly 3 characters, USD or BMD only, must equal debitCurrency | | creditorAccount.identification | Required, max 17 characters | | creditorAccount.name | Required, max 22 characters | | creditorBank.bankCode | Required, 1-100 characters (see Creditor Bank Reference below) | | creditorBank.currency | Required, exactly 3 characters, must match debitCurrency | | remittanceInformation | Required, 1–2 non-empty lines, each max 35 characters | ### Sample Request javascript async function processAchLocalPayment() { try { const response = await fetch('https://api.bcb.bm/v1/payments/ach-local', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', 'Accept': 'application/json', 'Idempotency-Key': '123e4567-e89b-12d3-a456-426614174000' }, body: JSON.stringify({ instructionIdentification: "REF-123456", debtorAccount: { identification: "123456789012" }, debitCurrency: "USD", instructedAmount: { currency: "USD", amount: "1500.00" }, creditorAccount: { identification: "9876543210123", name: "John Doe" }, creditorBank: { bankCode: "HSBC", currency: "USD" }, remittanceInformation: ["Invoice 2026-0001"] }) }); if (!response.ok) { const errorData = await response.json(); throw new Error(Error: ${errorData.message || 'Unknown error'}); } const result = await response.json(); console.log('Payment ID:', result.id); console.log('Status:', result.status); console.log('Transaction Status:', result.transactionStatus); } catch (error) { console.error('Error:', error); } } processAchLocalPayment(); ### Response Structure | Field | Type | Description | |-------|------|-------------| | id | string | Unique identifier for the payment | | status | string | Payment status (success or failed) | | transactionStatus | string | Detailed transaction status | | uniqueIdentifier | string | Unique identifier for tracking | | details | object | Payment details including amounts, accounts, settlement | | linkedActivities | array | Related financial activities | Required Permission: payment-ach This endpoint requires the permission claim payment-ach to be present in the JWT token. These permissions are embedded in the token during the authentication process and cannot be modified afterward. The token must be obtained with the appropriate permissions to access this endpoint. ## SWIFT Payment - [POST /v1/payments/swift](https://developers.bcb.bm/apis/open-banking-api/open-banking-api/payments/payments_post.md): Initiates a SWIFT payment transfer. The request must include all required payment details including: - Source and destination account information - Payment amount and currency (or, for FX cross-currency, optional debitAmount in source currency with instructedAmount currency only) - Beneficiary details - Payment purpose and reference information ### Key Features: - Supports international wire transfers via SWIFT network - Implements idempotency to prevent duplicate transactions - Validates payment requests before processing - Supports both JSON and CSV response formats - Supports additive cross-currency FX formatting (supplying debitAmount instead of instructedAmount.amount) ### Cross-Currency FX For cross-currency payments, you can provide the debit amount instead of the instructed amount: - Provide debitAmount (currency and amount) and instructedAmount.currency (no amount). - The API will process the payment using the debit amount and allow the core banking system to calculate the credited amount based on the exchange rate. - Do not provide both debitAmount.amount and instructedAmount.amount. - Supports Cross-Currency FX (Additive) format ### Cross-Currency FX Format When converting currencies, you can use the additive format: - Send debitAmount (with currency and amount) as the exact amount you wish to be debited. - Provide instructedAmount with just the currency (amount omitted) to let the bank assign the exchange rate. - If debitAmount is omitted, the instructedAmount (currency + amount) will be used as the standard behaviour. ### Creditor Agent (Beneficiary Bank) - If creditorAgent.identification (BIC/bank identifier) is provided, creditorAgent.name and creditorAgent.additionalInformation are optional and may be omitted. - If creditorAgent.identification is not provided, supply creditorAgent.name and creditorAgent.additionalInformation to identify the beneficiary bank. ### Content Negotiation Clients must use the HTTP Accept header to indicate the desired response format: - Set Accept: application/json for JSON responses (default) - Set Accept: text/csv for CSV responses If the Accept header is omitted, application/json is assumed. ### Base URL: All API requests use the versioned base URL: https://api.bcb.bm/v1/payments/swift ### Idempotency The API supports idempotency through the optional Idempotency-Key header: - If no idempotency key is provided, the request is processed normally (duplicates are possible) - If a valid UUID idempotency key is provided for a new transaction, the system stores the key and associates it with the transaction results - If the same idempotency key is received again for the same endpoint/action, the system returns the previously stored response - Idempotency keys are user-specific - different users with the same keys don't share cached responses - The idempotency key must be a valid UUID format (e.g., "123e4567-e89b-12d3-a456-426614174000"). ### Sample Request in JavaScript: javascript async function processSwiftPayment() { try { const response = await fetch('https://api.bcb.bm/v1/payments/swift', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', 'Accept': 'application/json', 'Idempotency-Key': '123e4567-e89b-12d3-a456-426614174000' // Optional: UUID format required if provided }, body: JSON.stringify({ instructionIdentification: "PAYMENT-123456", // Optional debtorAccount: { identification: "DEBTOR-ACC-123" }, instructedAmount: { currency: "USD", amount: "1000.00" }, creditorAccount: { identification: "CREDITOR-ACC-456", name: "John Doe", additionalInformation: ["Additional details"] }, creditorAgent: { identification: "BANKBIC123", // Optional when a BIC/bank identifier is provided: // name: "Beneficiary Bank", // additionalInformation: ["SWIFT/BIC code"] }, chargesType: "OUR", remittanceInformation: ["Payment for services"] }) }); if (!response.ok) { const errorData = await response.json(); throw new Error(Error processing payment: ${errorData.message || 'Unknown error'}); } const result = await response.json(); // Check payment status if (result.status === 'success') { console.log('Payment processed successfully'); // Log payment details console.log('Payment ID:', result.id); console.log('Transaction Status:', result.transactionStatus); console.log('Unique Identifier:', result.uniqueIdentifier); // Process payment details const details = result.details; console.log('External Reference:', details.extReference); console.log('Instructed Amount:', details.instructedAmount.amount, details.instructedAmount.currency); // Process account information console.log('Debtor Account:', details.debtorAccount.identification); console.log('Creditor Account:', details.creditorAccount.identification); console.log('Beneficiary Account:', details.beneficiaryAccount.identification); // Process settlement details const settlement = details.settlementDetails; console.log('Amount Credited:', settlement.amountCredited.amount, settlement.amountCredited.currency); console.log('Amount Debited:', settlement.amountDebited.amount, settlement.amountDebited.currency); console.log('Value Date:', settlement.valueDate); console.log('Record Status:', settlement.recordStatus); // Process charge details const charges = details.chargeDetails; console.log('Charges Type:', charges.chargesType); console.log('Total Charges:', charges.chargeAmount.amount, charges.chargeAmount.currency); // Process charge analysis const chargeAnalysis = charges.chargeAnalysis; console.log('Sender Charges:', chargeAnalysis.sender.amount, chargeAnalysis.sender.currency); console.log('Receiver Charges:', chargeAnalysis.receiver.amount, chargeAnalysis.receiver.currency); // Process beneficiary information console.log('Beneficiary Name:', details.beneficiary.name); console.log('Beneficiary Bank:', details.beneficiaryAgent.name); // Process remittance information if (details.remittanceInformation) { console.log('Remittance Information:'); details.remittanceInformation.forEach(info => console.log('-', info)); } // Process linked activities if (result.linkedActivities && result.linkedActivities.length > 0) { console.log('Linked Activities:'); result.linkedActivities.forEach(activity => { console.log('- Activity ID:', activity.id); console.log(' Status:', activity.status); console.log(' Transaction Status:', activity.transactionStatus); console.log(' Unique Identifier:', activity.uniqueIdentifier); }); } } else { console.error('Payment processing failed:', result.status); // Handle failed payment if (result.details) { console.error('Error details:', result.details); } } } catch (error) { console.error('Error:', error); // Handle error appropriately } } // Example usage: processSwiftPayment(); ### Response Structure | Field | Type | Description | |-------|------|-------------| | id | string | Unique identifier for the payment | | status | string | Payment status (success or failed) | | transactionStatus | string | Detailed transaction status | | uniqueIdentifier | string | Unique identifier for tracking | | details | object | Payment details object | | linkedActivities | array | Related financial activities | Required Permission: payment-swift This endpoint requires the permission claim payment-swift to be present in the JWT token. These permissions are embedded in the token during the authentication process and cannot be modified afterward. The token must be obtained with the appropriate permissions to access this endpoint. ## List payment statuses for an account - [GET /v1/accounts/{accountNumber}/payments](https://developers.bcb.bm/apis/open-banking-api/open-banking-api/payments/transactionstatus_getaccounttransactionstatuses.md): Retrieves status information for all payments associated with a specific account. This endpoint: - Provides comprehensive payment status details including type, status, transaction ID, external reference, remittance information, amounts, value date, and exchange rate. - Supports both JSON and CSV response formats based on the Accept header. - Supports cursor-based pagination for efficient handling of large payment status datasets. ### Pagination This endpoint uses cursor-based pagination with server-side result-set management: - First Request: Optionally specify pageSize (default: 100, max: 1000). The server creates a cursor and returns a pageToken. - Subsequent Requests: Use the pageToken from previous responses with pageStart to navigate pages. - Page Token: Contains encoded pagination context including pageSize, so don't specify pageSize in subsequent requests. - Total Pages: Calculate using Math.ceil(total_size / page_size) from the response metadata. ### Content Negotiation Clients must use the HTTP Accept header to indicate the desired response format: - Set Accept: application/json for JSON responses (default) - Set Accept: text/csv for CSV responses If the Accept header is omitted, application/json is assumed. ### Base URL All API requests use the versioned base URL: https://api.bcb.bm/v1/accounts/{accountNumber}/payments ### Sample Request in JavaScript javascript async function getAllPaymentStatusesPaginated(accountNumber) { try { let allPaymentStatuses = []; let pageStart = 1; let pageToken = null; let totalPages = 0; do { // Build URL with pagination parameters let url = https://api.bcb.bm/v1/accounts/${accountNumber}/payments; const params = new URLSearchParams(); if (pageStart === 1) { // First request: specify pageSize params.append('pageSize', '100'); } else { // Subsequent requests: use pageToken and pageStart params.append('pageToken', pageToken); params.append('pageStart', pageStart.toString()); } if (params.toString()) { url += '?' + params.toString(); } const response = await fetch(url, { method: 'GET', headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', 'Accept': 'application/json' } }); if (!response.ok) { const errorData = await response.json(); throw new Error(Error: ${errorData.message || 'Unknown error'}); } const data = await response.json(); console.log(Page ${pageStart} data:, data); // Store pagination info from first request if (pageStart === 1 && data.meta && data.meta.pagination) { pageToken = data.meta.pagination.page_token; totalPages = Math.ceil(data.meta.pagination.total_size / data.meta.pagination.page_size); console.log(Total pages: ${totalPages}, Page token: ${pageToken}); } // Collect payment statuses from this page if (data.data && data.data.length > 0) { allPaymentStatuses.push(...data.data); console.log(Collected ${data.data.length} payment statuses from page ${pageStart}); } pageStart++; } while (pageStart { console.log(Payment ${index + 1}:, payment.transactionId); console.log('Type:', payment.type); console.log('Status:', payment.status); console.log('External Reference:', payment.externalReference); console.log('Remittance Information:', payment.remittanceInformation); console.log('Value Date:', payment.valueDate); console.log('Debit Amount:', ${payment.debitAmount.amount} ${payment.debitAmount.currency}); if (payment.creditAmount && payment.creditAmount.amount) { console.log('Credit Amount:', ${payment.creditAmount.amount} ${payment.creditAmount.currency}); } console.log('-------------------'); }); return allPaymentStatuses; } catch (error) { console.error('There was a problem with the fetch operation:', error.message); throw error; } } // Alternative: Get single page of payment statuses async function getPaymentStatusesPage(accountNumber, pageStart = 1, pageToken = null) { try { let url = https://api.bcb.bm/v1/accounts/${accountNumber}/payments; const params = new URLSearchParams(); if (pageStart === 1 && !pageToken) { params.append('pageSize', '50'); // Custom page size } else { params.append('pageToken', pageToken); params.append('pageStart', pageStart.toString()); } if (params.toString()) { url += '?' + params.toString(); } const response = await fetch(url, { method: 'GET', headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', 'Accept': 'application/json' } }); if (!response.ok) { const errorData = await response.json(); throw new Error(Error: ${errorData.message || 'Unknown error'}); } const data = await response.json(); console.log('Payment statuses page:', data); return data; } catch (error) { console.error('There was a problem with the fetch operation:', error.message); throw error; } } // Example usage: getAllPaymentStatusesPaginated('123456789'); // Retrieves all payment statuses across multiple pages // OR getPaymentStatusesPage('123456789', 1).then(firstPage => { console.log('First page:', firstPage); // Use firstPage.meta.pagination.page_token for subsequent requests }); Required Permission: get-payment-status This endpoint requires the permission claim get-payment-status to be present in the JWT token. These permissions are embedded in the token during the authentication process and cannot be modified afterward. The token must be obtained with the appropriate permissions to access this endpoint. ## Get payment status - [GET /v1/payments/{paymentId}/status](https://developers.bcb.bm/apis/open-banking-api/open-banking-api/payments/transactionstatus_gettransactionstatus.md): Retrieves detailed status information for a specific payment identified by its payment ID (also known as transaction ID). This endpoint provides comprehensive status details including: - Type: The type of payment (e.g., "Outward Swift Payment MT103 API") - Status: Current status of the payment (e.g., "Pending", "Completed", "Reversed") - TransactionId: Unique payment identifier (or Transaction Id) - ExternalReference: External reference number for the payment - RemittanceInformation: Free-text information about the purpose of the payment - DebitAmount: The amount debited from the account, including currency code - CreditAmount: The amount credited to the account, including currency code - ValueDate: The date when the payment was/will be processed - ExchangeRate: The exchange rate applied to the payment ### Content Negotiation Clients must use the HTTP Accept header to indicate the desired response format: - Set Accept: application/json for JSON responses (default) - Set Accept: text/csv for CSV responses If the Accept header is omitted, application/json is assumed. ### Base URL: All API requests use the versioned base URL: https://api.bcb.bm/v1/payments/{paymentId}/status ### Sample Request in JavaScript: javascript async function getPaymentStatus(paymentId) { try { const response = await fetch(https://api.bcb.bm/v1/payments/${paymentId}/status, { method: 'GET', headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', 'Accept': 'application/json' } }); if (!response.ok) { const errorData = await response.json(); throw new Error(Error: ${errorData.message || 'Unknown error'}); } const paymentStatus = await response.json(); console.log('Payment Status Details:'); console.log('Payment ID:', paymentStatus.transactionId); console.log('Type:', paymentStatus.type); console.log('Status:', paymentStatus.status); console.log('External Reference:', paymentStatus.externalReference); console.log('Remittance Information:', paymentStatus.remittanceInformation); console.log('Value Date:', paymentStatus.valueDate); console.log('Debit Amount:', ${paymentStatus.debitAmount.amount} ${paymentStatus.debitAmount.currency}); if (paymentStatus.creditAmount && paymentStatus.creditAmount.amount) { console.log('Credit Amount:', ${paymentStatus.creditAmount.amount} ${paymentStatus.creditAmount.currency}); } // Implement business logic based on payment status if (paymentStatus.status === 'Completed') { console.log('Payment has been successfully completed.'); } else if (paymentStatus.status === 'Pending') { console.log('Payment is still being processed.'); } else if (paymentStatus.status === 'Failed') { console.log('Payment failed. Please check the details or contact support.'); } } catch (error) { console.error('There was a problem retrieving the payment status:', error.message); } } // Example usage: getPaymentStatus('PAY-001-2023'); Required Permission: get-payment-status This endpoint requires the permission claim get-payment-status to be present in the JWT token. These permissions are embedded in the token during the authentication process and cannot be modified afterward. The token must be obtained with the appropriate permissions to access this endpoint.