import * as plugins from './bunq.plugins.js'; import { BunqAccount } from './bunq.classes.account.js'; import { IBunqCard, IBunqAmount } from './bunq.interfaces.js'; export class BunqCard { private bunqAccount: BunqAccount; // Card properties public id: number; public created: string; public updated: string; public publicUuid: string; public type: 'MAESTRO' | 'MASTERCARD'; public subType: string; public secondLine: string; public status: string; public orderStatus?: string; public expiryDate?: string; public nameOnCard: string; public primaryAccountNumberFourDigit?: string; public limit?: IBunqAmount; public monetaryAccountIdFallback?: number; public country?: string; constructor(bunqAccount: BunqAccount, cardData?: any) { this.bunqAccount = bunqAccount; if (cardData) { this.updateFromApiResponse(cardData); } } /** * Update card properties from API response */ private updateFromApiResponse(cardData: any): void { this.id = cardData.id; this.created = cardData.created; this.updated = cardData.updated; this.publicUuid = cardData.public_uuid; this.type = cardData.type; this.subType = cardData.sub_type; this.secondLine = cardData.second_line; this.status = cardData.status; this.orderStatus = cardData.order_status; this.expiryDate = cardData.expiry_date; this.nameOnCard = cardData.name_on_card; this.primaryAccountNumberFourDigit = cardData.primary_account_number_four_digit; this.limit = cardData.limit; this.monetaryAccountIdFallback = cardData.monetary_account_id_fallback; this.country = cardData.country; } /** * List all cards for the user */ public static async list(bunqAccount: BunqAccount): Promise { await bunqAccount.apiContext.ensureValidSession(); const response = await bunqAccount.getHttpClient().list( `/v1/user/${bunqAccount.userId}/card` ); const cards: BunqCard[] = []; if (response.Response) { for (const item of response.Response) { if (item.CardDebit || item.CardCredit) { const cardData = item.CardDebit || item.CardCredit; cards.push(new BunqCard(bunqAccount, cardData)); } } } return cards; } /** * Get a specific card */ public static async get(bunqAccount: BunqAccount, cardId: number): Promise { await bunqAccount.apiContext.ensureValidSession(); const response = await bunqAccount.getHttpClient().get( `/v1/user/${bunqAccount.userId}/card/${cardId}` ); if (response.Response && response.Response[0]) { const cardData = response.Response[0].CardDebit || response.Response[0].CardCredit; return new BunqCard(bunqAccount, cardData); } throw new Error('Card not found'); } /** * Update card settings */ public async update(updates: any): Promise { await this.bunqAccount.apiContext.ensureValidSession(); const cardType = this.type === 'MASTERCARD' ? 'CardCredit' : 'CardDebit'; await this.bunqAccount.getHttpClient().put( `/v1/user/${this.bunqAccount.userId}/card/${this.id}`, { [cardType]: updates } ); // Refresh card data const updatedCard = await BunqCard.get(this.bunqAccount, this.id); this.updateFromApiResponse(updatedCard); } /** * Activate the card */ public async activate(activationCode: string, cardStatus: string = 'ACTIVE'): Promise { await this.update({ activation_code: activationCode, status: cardStatus }); } /** * Block the card */ public async block(reason: string = 'LOST'): Promise { await this.update({ status: 'BLOCKED', cancellation_reason: reason }); } /** * Cancel the card */ public async cancel(reason: string = 'USER_REQUEST'): Promise { await this.update({ status: 'CANCELLED', cancellation_reason: reason }); } /** * Update spending limit */ public async updateLimit(value: string, currency: string = 'EUR'): Promise { await this.update({ monetary_account_id: this.monetaryAccountIdFallback, limit: { value, currency } }); } /** * Update PIN code */ public async updatePin(pinCode: string): Promise { await this.bunqAccount.apiContext.ensureValidSession(); await this.bunqAccount.getHttpClient().put( `/v1/user/${this.bunqAccount.userId}/card/${this.id}/pin-change`, { pin_code: pinCode } ); } /** * Get card limits */ public async getLimits(): Promise { await this.bunqAccount.apiContext.ensureValidSession(); const response = await this.bunqAccount.getHttpClient().list( `/v1/user/${this.bunqAccount.userId}/limit` ); return response.Response || []; } /** * Update mag stripe permissions */ public async updateMagStripePermission(expiryTime?: string): Promise { await this.update({ mag_stripe_permission: { expiry_time: expiryTime } }); } /** * Update country permissions */ public async updateCountryPermissions(permissions: Array<{country: string, expiryTime?: string}>): Promise { await this.update({ country_permission: permissions }); } /** * Link card to monetary account */ public async linkToAccount(monetaryAccountId: number): Promise { await this.update({ monetary_account_id: monetaryAccountId }); } /** * Order a new card */ public static async order( bunqAccount: BunqAccount, options: { secondLine: string; nameOnCard: string; type?: 'MAESTRO' | 'MASTERCARD'; productType?: string; monetaryAccountId?: number; } ): Promise { await bunqAccount.apiContext.ensureValidSession(); const cardData = { second_line: options.secondLine, name_on_card: options.nameOnCard, type: options.type || 'MASTERCARD', product_type: options.productType || 'MASTERCARD_DEBIT', monetary_account_id: options.monetaryAccountId }; const cardType = options.type === 'MASTERCARD' ? 'CardCredit' : 'CardDebit'; const response = await bunqAccount.getHttpClient().post( `/v1/user/${bunqAccount.userId}/card`, { [cardType]: cardData } ); if (response.Response && response.Response[0] && response.Response[0].Id) { return BunqCard.get(bunqAccount, response.Response[0].Id.id); } throw new Error('Failed to order card'); } }