Skip to main content

Unfreeze a Card

Overview

Use this endpoint to unfreeze a previously frozen card. Once unfrozen, the card returns to its active state and can be used for:

  • Making purchases and transactions
  • Receiving top-ups (for Dedicated Funds Cards)
  • Withdrawing funds (for Dedicated Funds Cards)

Unfreezing is typically used when the temporary security concern or issue that led to freezing the card has been resolved.

NOTE: This API is offered on a client-by-client approval basis. Speak to your account manager to check eligibility.

IMPORTANT: You can only unfreeze cards that are currently in a FROZEN state. Active cards cannot be unfrozen.

Resource Access

Production (api.ahrvo.network)

POST https://api.ahrvo.network/card/issuance/api/issuing/card/v2/unfreeze

Staging (gateway.ahrvo.network)

POST https://gateway.ahrvo.network/card/issuance/api/issuing/card/v2/unfreeze

Request Headers

HeaderValueRequiredDescription
Acceptapplication/jsonYesContent type for the response
Content-Typeapplication/jsonYesContent type of the request body
AuthorizationBearer {access_token}YesBearer token for authentication
x-api-keyAPI KeyYesAPI key for authentication

Request Body

FieldTypeRequiredDescription
card_idstringYesA unique ID of the card to unfreeze

Request Example

{
"card_id": "card202010161608422883"
}

Response

Success Response (200 OK)

{
"code": "SUCCESS"
}

Response Fields

FieldTypeDescription
codestringStatus string indicating the result. "SUCCESS" refers to a successful unfreeze

Error Responses

  • 400 Bad Request: Invalid card_id or card is not in frozen state
  • 401 Unauthorized: Invalid or missing authentication token
  • 403 Forbidden: Card issuance feature not enabled for this account
  • 404 Not Found: Card does not exist

Code Examples

cURL

curl -X POST \
'https://gateway.ahrvo.network/card/issuance/api/issuing/card/v2/unfreeze' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'x-api-key: YOUR_API_KEY' \
-d '{
"card_id": "card202010161608422883"
}'

Python

import requests

url = "https://gateway.ahrvo.network/card/issuance/api/issuing/card/v2/unfreeze"
headers = {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"x-api-key": "YOUR_API_KEY"
}
payload = {
"card_id": "card202010161608422883"
}

response = requests.post(url, headers=headers, json=payload)
result = response.json()

if result['code'] == 'SUCCESS':
print("✓ Card unfrozen successfully!")
print(f" Card ID: {payload['card_id']}")
print(" Card is now active and can be used for transactions")
else:
print(f"Failed to unfreeze card: {result}")

JavaScript (Node.js)

const axios = require('axios');

const url = 'https://gateway.ahrvo.network/card/issuance/api/issuing/card/v2/unfreeze';
const headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'x-api-key': 'YOUR_API_KEY'
};
const payload = {
card_id: 'card202010161608422883'
};

axios.post(url, payload, { headers })
.then(response => {
const result = response.data;

if (result.code === 'SUCCESS') {
console.log('✓ Card unfrozen successfully!');
console.log(` Card ID: ${payload.card_id}`);
console.log(' Card is now active and can be used for transactions');
}
})
.catch(error => {
console.error('Failed to unfreeze card:', error.response.data);
});

Usage Notes

  • Immediate Effect: Unfreeze takes effect immediately
  • Frozen State Required: Only cards in FROZEN state can be unfrozen
  • Full Restoration: All card functionality is restored upon unfreezing
  • Status Change: Card status changes from FROZEN to ACTIVE
  • No Limit: Cards can be frozen and unfrozen multiple times
  • Audit Trail: Keep track of freeze/unfreeze operations for compliance

Common Use Cases

Manual Card Unfreeze After Security Check

Unfreeze a card after verifying suspicious activity was legitimate:

def unfreeze_card_after_verification(card_id, verification_notes):
"""
Unfreeze card after security verification

Args:
card_id: Card ID to unfreeze
verification_notes: Notes about the verification
"""
print(f"\n=== Card Unfreeze Process ===")
print(f"Card ID: {card_id}")
print(f"Verification: {verification_notes}\n")

# Check current card status
print("Step 1: Verifying card status...")
card_details = query_card_details(card_id)

if card_details['code'] == 'SUCCESS':
card_status = card_details['data']['card_status']
card_number = card_details['data']['card_number']

print(f" Card: {card_number}")
print(f" Current Status: {card_status}")

if card_status != 'FROZEN':
print(f"\n⚠️ Card is not frozen (status: {card_status})")
print(" No action needed")
return {'success': False, 'reason': 'Card not frozen'}

print("\nStep 2: Unfreezing card...")

payload = {
"card_id": card_id
}

response = requests.post(url, headers=headers, json=payload)
result = response.json()

if result['code'] == 'SUCCESS':
print("✓ Card unfrozen successfully!")
print(f"\n{card_number} is now ACTIVE")
print(" • Transactions: Enabled")
print(" • Top-ups: Enabled")
print(" • Withdrawals: Enabled")

# Log the unfreeze action
log_card_action({
'card_id': card_id,
'card_number': card_number,
'action': 'UNFREEZE',
'verification_notes': verification_notes,
'timestamp': datetime.now().isoformat(),
'previous_status': 'FROZEN',
'new_status': 'ACTIVE'
})

# Notify cardholder
send_card_status_notification(
card_number,
'unfrozen',
'Your card has been unfrozen and is now active'
)

return {
'success': True,
'card_number': card_number,
'previous_status': 'FROZEN',
'new_status': 'ACTIVE'
}
else:
print(f"✗ Failed to unfreeze card: {result}")
return {'success': False, 'error': result}
else:
print(f"✗ Failed to get card details: {card_details}")
return {'success': False, 'error': card_details}

# Example usage
result = unfreeze_card_after_verification(
'card202010161608422883',
'Verified transaction with cardholder. Activity confirmed legitimate.'
)

if result['success']:
print(f"\n✅ Card {result['card_number']} successfully unfrozen")
else:
print(f"\n❌ Failed to unfreeze card")

Scheduled Automatic Unfreeze

Automatically unfreeze cards after a specified time period:

const schedule = require('node-schedule');

class ScheduledUnfreezeManager {
constructor() {
this.scheduledUnfreezes = new Map();
}

/**
* Schedule card to be unfrozen after a delay
*
* @param {string} cardId - Card ID to unfreeze
* @param {number} delayMinutes - Minutes to wait before unfreezing
* @param {string} reason - Reason for scheduled unfreeze
*/
scheduleUnfreeze(cardId, delayMinutes, reason) {
console.log(`\n📅 Scheduling Automatic Unfreeze`);
console.log(` Card: ${cardId}`);
console.log(` Delay: ${delayMinutes} minutes`);
console.log(` Reason: ${reason}`);

const unfreezeTime = new Date(Date.now() + delayMinutes * 60 * 1000);
console.log(` Scheduled for: ${unfreezeTime.toISOString()}\n`);

const job = schedule.scheduleJob(unfreezeTime, async () => {
console.log(`\n⏰ Scheduled Unfreeze Triggered`);
console.log(` Card: ${cardId}`);
console.log(` Time: ${new Date().toISOString()}`);

try {
const payload = {
card_id: cardId
};

const response = await unfreezeCard(payload);

if (response.code === 'SUCCESS') {
console.log(` ✓ Card unfrozen successfully`);

// Get card details
const cardDetails = await queryCardDetails(cardId);
if (cardDetails.code === 'SUCCESS') {
const cardNumber = cardDetails.data.card_number;
console.log(` Card ${cardNumber} is now ACTIVE`);

// Send notification
await sendNotification(
`Card ${cardNumber} has been automatically unfrozen`,
{ cardId, reason }
);
}

// Remove from scheduled list
this.scheduledUnfreezes.delete(cardId);
} else {
console.log(` ✗ Failed to unfreeze card:`, response);

// Send alert
await sendAlert(
`Failed to automatically unfreeze card ${cardId}`,
response
);
}
} catch (error) {
console.error(` ✗ Error:`, error.message);
await sendAlert(
`Error automatically unfreezing card ${cardId}`,
error
);
}
});

// Store the scheduled job
this.scheduledUnfreezes.set(cardId, {
job: job,
unfreezeTime: unfreezeTime,
reason: reason
});

console.log(`✓ Automatic unfreeze scheduled`);

return {
scheduled: true,
unfreeze_time: unfreezeTime,
delay_minutes: delayMinutes
};
}

/**
* Cancel scheduled unfreeze
*/
cancelScheduledUnfreeze(cardId) {
const scheduled = this.scheduledUnfreezes.get(cardId);

if (scheduled) {
scheduled.job.cancel();
this.scheduledUnfreezes.delete(cardId);

console.log(`\n🗑️ Cancelled Scheduled Unfreeze`);
console.log(` Card: ${cardId}`);
console.log(` Was scheduled for: ${scheduled.unfreezeTime.toISOString()}`);

return true;
} else {
console.log(`\n⚠️ No scheduled unfreeze found for card ${cardId}`);
return false;
}
}

/**
* List all scheduled unfreezes
*/
listScheduledUnfreezes() {
console.log(`\n📋 Scheduled Unfreezes: ${this.scheduledUnfreezes.size}\n`);

this.scheduledUnfreezes.forEach((info, cardId) => {
const timeRemaining = info.unfreezeTime - new Date();
const minutesRemaining = Math.round(timeRemaining / 60000);

console.log(`Card: ${cardId}`);
console.log(` Scheduled: ${info.unfreezeTime.toISOString()}`);
console.log(` Time Remaining: ${minutesRemaining} minutes`);
console.log(` Reason: ${info.reason}\n`);
});
}
}

// Example usage
const unfreezeManager = new ScheduledUnfreezeManager();

// Schedule card to unfreeze in 30 minutes
unfreezeManager.scheduleUnfreeze(
'card202010161608422883',
30,
'Temporary freeze for suspicious transaction verification'
);

// Schedule card to unfreeze in 24 hours (1440 minutes)
unfreezeManager.scheduleUnfreeze(
'card202010161608422884',
1440,
'Cooling-off period after reported lost (found by customer)'
);

// List all scheduled unfreezes
unfreezeManager.listScheduledUnfreezes();

// Cancel a scheduled unfreeze if needed
// unfreezeManager.cancelScheduledUnfreeze('card202010161608422883');

Batch Unfreeze Multiple Cards

Unfreeze multiple cards at once:

def batch_unfreeze_cards(card_ids, reason=None):
"""
Unfreeze multiple cards in batch

Args:
card_ids: List of card IDs to unfreeze
reason: Reason for batch unfreeze
"""
from datetime import datetime

print("\n" + "=" * 70)
print("BATCH CARD UNFREEZE".center(70))
print("=" * 70)
print(f"Started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Total Cards: {len(card_ids)}")
if reason:
print(f"Reason: {reason}")
print()

results = {
'successful': [],
'failed': [],
'skipped': []
}

for idx, card_id in enumerate(card_ids, 1):
print(f"[{idx}/{len(card_ids)}] Processing {card_id}...")

try:
# Check if card is frozen
card_details = query_card_details(card_id)

if card_details['code'] == 'SUCCESS':
card_status = card_details['data']['card_status']
card_number = card_details['data']['card_number']

print(f" Card: {card_number}")
print(f" Status: {card_status}")

if card_status != 'FROZEN':
print(f" ⊘ Skipped - Card not frozen\n")
results['skipped'].append({
'card_id': card_id,
'card_number': card_number,
'current_status': card_status
})
continue

# Unfreeze the card
payload = {
"card_id": card_id
}

response = requests.post(url, headers=headers, json=payload)
result = response.json()

if result['code'] == 'SUCCESS':
print(f" ✓ Unfrozen successfully\n")

results['successful'].append({
'card_id': card_id,
'card_number': card_number
})
else:
print(f" ✗ Failed: {result.get('message', 'Unknown error')}\n")

results['failed'].append({
'card_id': card_id,
'card_number': card_number,
'error': result
})
else:
print(f" ✗ Failed to get card details\n")

results['failed'].append({
'card_id': card_id,
'error': card_details
})

except Exception as e:
print(f" ✗ Exception: {e}\n")

results['failed'].append({
'card_id': card_id,
'error': str(e)
})

# Summary
print("=" * 70)
print("BATCH UNFREEZE SUMMARY".center(70))
print("=" * 70)
print(f"Total Cards: {len(card_ids)}")
print(f"Successful: {len(results['successful'])} ✓")
print(f"Failed: {len(results['failed'])} ✗")
print(f"Skipped: {len(results['skipped'])} ⊘")

if results['successful']:
print(f"\n✓ Successfully Unfrozen ({len(results['successful'])}):")
for item in results['successful']:
print(f" • {item['card_number']} ({item['card_id']})")

if results['skipped']:
print(f"\n⊘ Skipped - Not Frozen ({len(results['skipped'])}):")
for item in results['skipped']:
print(f" • {item['card_number']} - Status: {item['current_status']}")

if results['failed']:
print(f"\n✗ Failed ({len(results['failed'])}):")
for item in results['failed']:
card_info = item.get('card_number', item['card_id'])
print(f" • {card_info}")

print("\n" + "=" * 70 + "\n")

return results

# Example usage
card_list = [
'card202010161608422883',
'card202010161608422884',
'card202010161608422885',
'card202010161608422886'
]

results = batch_unfreeze_cards(
card_list,
reason='End of security review - all transactions verified legitimate'
)

print(f"Batch complete: {len(results['successful'])}/{len(card_list)} unfrozen")

Unfreeze with Transaction Retry

Unfreeze card and retry failed transactions:

async function unfreezeAndRetryTransactions(cardId) {
console.log('\n=== Unfreeze Card with Transaction Retry ===\n');

try {
// Step 1: Get card details and failed transactions
console.log('Step 1: Gathering card information...');

const cardDetails = await queryCardDetails(cardId);
if (cardDetails.code !== 'SUCCESS') {
console.log('✗ Failed to get card details');
return { success: false, error: cardDetails };
}

const cardNumber = cardDetails.data.card_number;
const cardStatus = cardDetails.data.card_status;

console.log(` Card: ${cardNumber}`);
console.log(` Current Status: ${cardStatus}`);

if (cardStatus !== 'FROZEN') {
console.log(`\n⚠️ Card is not frozen. No action needed.`);
return { success: false, reason: 'Card not frozen' };
}

// Get failed transactions during freeze period
const failedTransactions = await getFailedTransactionsDuringFreeze(cardId);
console.log(` Failed Transactions: ${failedTransactions.length}`);

// Step 2: Unfreeze the card
console.log('\nStep 2: Unfreezing card...');

const unfreezePayload = {
card_id: cardId
};

const unfreezeResponse = await unfreezeCard(unfreezePayload);

if (unfreezeResponse.code !== 'SUCCESS') {
console.log('✗ Failed to unfreeze card');
return { success: false, error: unfreezeResponse };
}

console.log('✓ Card unfrozen successfully');

// Step 3: Retry failed transactions
if (failedTransactions.length > 0) {
console.log(`\nStep 3: Retrying ${failedTransactions.length} failed transaction(s)...`);

const retryResults = {
successful: [],
failed: []
};

for (const transaction of failedTransactions) {
console.log(`\n Retrying transaction ${transaction.id}...`);
console.log(` Amount: $${transaction.amount}`);
console.log(` Merchant: ${transaction.merchant}`);

try {
const retryResult = await retryTransaction(transaction);

if (retryResult.success) {
console.log(` ✓ Transaction successful`);
retryResults.successful.push(transaction);
} else {
console.log(` ✗ Transaction failed: ${retryResult.reason}`);
retryResults.failed.push({
transaction: transaction,
reason: retryResult.reason
});
}
} catch (error) {
console.log(` ✗ Error: ${error.message}`);
retryResults.failed.push({
transaction: transaction,
reason: error.message
});
}
}

// Summary
console.log('\n=== Transaction Retry Summary ===');
console.log(`Total Transactions: ${failedTransactions.length}`);
console.log(`Successful: ${retryResults.successful.length}`);
console.log(`Failed: ${retryResults.failed.length}`);

if (retryResults.failed.length > 0) {
console.log('\n⚠️ Failed Transactions:');
retryResults.failed.forEach(item => {
console.log(`${item.transaction.id}: ${item.reason}`);
});
}

return {
success: true,
card_number: cardNumber,
unfrozen: true,
transactions_retried: failedTransactions.length,
transactions_successful: retryResults.successful.length,
transactions_failed: retryResults.failed.length,
retry_results: retryResults
};
} else {
console.log('\nNo failed transactions to retry');

return {
success: true,
card_number: cardNumber,
unfrozen: true,
transactions_retried: 0
};
}
} catch (error) {
console.error('Error in unfreeze and retry:', error.message);
return {
success: false,
error: error.message
};
}
}

async function getFailedTransactionsDuringFreeze(cardId) {
// Mock function - implement based on your transaction tracking system
return [
{ id: 'txn_001', amount: '45.99', merchant: 'Amazon' },
{ id: 'txn_002', amount: '12.50', merchant: 'Starbucks' }
];
}

async function retryTransaction(transaction) {
// Mock function - implement based on your transaction system
return { success: true };
}

// Example usage
const result = await unfreezeAndRetryTransactions('card202010161608422883');

if (result.success && result.unfrozen) {
console.log(`\n✅ Card ${result.card_number} unfrozen successfully`);
if (result.transactions_retried > 0) {
console.log(` ${result.transactions_successful}/${result.transactions_retried} transactions successful`);
}
}

Unfreeze with Customer Confirmation

Require customer confirmation before unfreezing:

def unfreeze_with_confirmation(card_id, customer_id):
"""
Unfreeze card after customer confirmation

Args:
card_id: Card ID to unfreeze
customer_id: Customer ID for verification
"""
print(f"\n=== Card Unfreeze with Customer Confirmation ===\n")

# Get card details
card_details = query_card_details(card_id)

if card_details['code'] != 'SUCCESS':
print(f"✗ Failed to get card details")
return {'success': False, 'error': card_details}

card_number = card_details['data']['card_number']
card_status = card_details['data']['card_status']

print(f"Card: {card_number}")
print(f"Status: {card_status}")

if card_status != 'FROZEN':
print(f"\n⚠️ Card is not frozen")
return {'success': False, 'reason': 'Card not frozen'}

# Send confirmation request to customer
print(f"\nSending confirmation request to customer {customer_id}...")

confirmation_code = generate_confirmation_code()

send_confirmation_request(
customer_id,
f"Your card ending in {card_number[-4:]} is frozen. "
f"To unfreeze, reply with code: {confirmation_code}"
)

print(f" Confirmation code sent: {confirmation_code}")
print(f" Waiting for customer response...")

# Wait for customer confirmation (mock implementation)
confirmed = wait_for_customer_confirmation(
customer_id,
confirmation_code,
timeout_seconds=300 # 5 minutes
)

if confirmed:
print(f"\n✓ Customer confirmation received")
print(f"Proceeding with card unfreeze...")

payload = {
"card_id": card_id
}

response = requests.post(url, headers=headers, json=payload)
result = response.json()

if result['code'] == 'SUCCESS':
print(f"\n✓ Card unfrozen successfully!")
print(f" Card {card_number} is now ACTIVE")

# Send success notification
send_notification(
customer_id,
f"Your card {card_number[-4:]} has been unfrozen and is now active"
)

# Log the action
log_card_action({
'card_id': card_id,
'action': 'UNFREEZE',
'confirmed_by': customer_id,
'confirmation_code': confirmation_code,
'timestamp': datetime.now().isoformat()
})

return {
'success': True,
'card_number': card_number,
'confirmed_by': customer_id,
'new_status': 'ACTIVE'
}
else:
print(f"\n✗ Failed to unfreeze card: {result}")
return {'success': False, 'error': result}
else:
print(f"\n✗ Customer confirmation not received or timeout")
print(f"Card remains frozen for security")

return {
'success': False,
'reason': 'Customer confirmation not received'
}

def generate_confirmation_code():
"""Generate 6-digit confirmation code"""
import random
return f"{random.randint(100000, 999999)}"

def send_confirmation_request(customer_id, message):
"""Send confirmation request via SMS/email"""
# Implement your notification system
print(f" 📱 SMS sent to customer {customer_id}")

def wait_for_customer_confirmation(customer_id, code, timeout_seconds):
"""Wait for customer to confirm with code"""
# Implement your confirmation system
# This is a mock that returns True after 2 seconds
import time
time.sleep(2)
return True # Mock confirmation

def send_notification(customer_id, message):
"""Send notification to customer"""
print(f" 📧 Notification sent to customer {customer_id}")

# Example usage
result = unfreeze_with_confirmation(
'card202010161608422883',
'customer_12345'
)

if result['success']:
print(f"\n✅ Card unfrozen with customer confirmation")
else:
print(f"\n❌ Card unfreeze cancelled or failed")

Monitor Frozen Cards and Auto-Unfreeze

Monitor frozen cards and unfreeze based on criteria:

def monitor_and_auto_unfreeze():
"""
Monitor all frozen cards and auto-unfreeze based on criteria
"""
from datetime import datetime, timedelta

print("\n" + "=" * 70)
print("FROZEN CARDS MONITOR & AUTO-UNFREEZE".center(70))
print("=" * 70)
print(f"Scan Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")

# Get all frozen cards
print("Step 1: Fetching all frozen cards...")

all_cards = query_all_cards(card_status='FROZEN')

if all_cards['code'] != 'SUCCESS':
print(f"✗ Failed to fetch cards")
return

frozen_cards = all_cards['data']['details']
print(f" Found {len(frozen_cards)} frozen card(s)\n")

if not frozen_cards:
print("✓ No frozen cards found\n")
return

# Criteria for auto-unfreeze
auto_unfreeze_criteria = {
'max_freeze_duration_hours': 72, # Auto-unfreeze after 3 days
'verified_transactions': True, # All transactions verified
'customer_confirmed': False # Customer confirmation (optional)
}

print("Step 2: Evaluating auto-unfreeze criteria...")
print(f" Max freeze duration: {auto_unfreeze_criteria['max_freeze_duration_hours']} hours\n")

results = {
'evaluated': 0,
'unfrozen': 0,
'kept_frozen': 0
}

for card in frozen_cards:
card_id = card['card_id']
card_number = card['card_number']

print(f"Evaluating: {card_number}")
results['evaluated'] += 1

# Get freeze history
freeze_history = get_card_freeze_history(card_id)

if not freeze_history:
print(f" ⚠️ No freeze history found - keeping frozen\n")
results['kept_frozen'] += 1
continue

last_freeze_time = freeze_history[-1]['timestamp']
freeze_duration = datetime.now() - last_freeze_time
freeze_hours = freeze_duration.total_seconds() / 3600

print(f" Frozen since: {last_freeze_time.strftime('%Y-%m-%d %H:%M:%S')}")
print(f" Duration: {freeze_hours:.1f} hours")

# Check if should auto-unfreeze
should_unfreeze = False
unfreeze_reason = None

if freeze_hours >= auto_unfreeze_criteria['max_freeze_duration_hours']:
should_unfreeze = True
unfreeze_reason = f"Auto-unfreeze: Frozen for {freeze_hours:.1f} hours (exceeded max {auto_unfreeze_criteria['max_freeze_duration_hours']} hours)"

if should_unfreeze:
print(f" ✓ Criteria met: {unfreeze_reason}")
print(f" Unfreezing...")

payload = {
"card_id": card_id
}

response = requests.post(url, headers=headers, json=payload)
result = response.json()

if result['code'] == 'SUCCESS':
print(f" ✓ Unfrozen successfully\n")
results['unfrozen'] += 1

# Log and notify
log_card_action({
'card_id': card_id,
'action': 'AUTO_UNFREEZE',
'reason': unfreeze_reason,
'freeze_duration_hours': freeze_hours,
'timestamp': datetime.now().isoformat()
})

send_notification(
card['cardholder_id'],
f"Your card {card_number[-4:]} has been automatically unfrozen"
)
else:
print(f" ✗ Failed to unfreeze: {result}\n")
results['kept_frozen'] += 1
else:
print(f" ⊘ Criteria not met - keeping frozen\n")
results['kept_frozen'] += 1

# Summary
print("=" * 70)
print("MONITOR SUMMARY".center(70))
print("=" * 70)
print(f"Cards Evaluated: {results['evaluated']}")
print(f"Auto-Unfrozen: {results['unfrozen']} ✓")
print(f"Kept Frozen: {results['kept_frozen']} ⊘")
print("\n" + "=" * 70 + "\n")

return results

def get_card_freeze_history(card_id):
"""Get freeze/unfreeze history for a card"""
# Mock implementation - replace with your actual logging system
from datetime import datetime, timedelta
return [
{
'action': 'FREEZE',
'timestamp': datetime.now() - timedelta(hours=80),
'reason': 'Suspicious transaction detected'
}
]

# Example usage - can be run as a scheduled job
results = monitor_and_auto_unfreeze()

print(f"Monitor complete: {results['unfrozen']} card(s) auto-unfrozen")

Best Practices

  • Verify Status: Always check card status before attempting to unfreeze
  • Document Reason: Keep audit logs of why cards were unfrozen
  • Customer Communication: Notify cardholders when their card is unfrozen
  • Immediate Action: Unfreeze takes effect immediately - ensure it's intentional
  • Coordinate with Freeze: Use freeze/unfreeze pairs for temporary holds
  • Security Review: Complete security review before unfreezing cards frozen for fraud
  • Automation: Consider automated unfreezes for temporary/scheduled freezes

Understanding Freeze/Unfreeze Lifecycle

Card Status Flow

ACTIVE → FREEZE → FROZEN → UNFREEZE → ACTIVE

When to Unfreeze

  • Resolved Security Issue: Suspicious activity verified as legitimate
  • Customer Request: Customer found lost card or resolved concern
  • Scheduled Unfreeze: Temporary freeze period ended
  • Verification Complete: Transaction or account verification completed
  • Administrative: End of maintenance or review period

Freeze vs. Close

OperationReversibleUse Case
Freeze/Unfreeze✓ YesTemporary security holds, lost cards later found
Close✗ NoPermanent deactivation, compromised cards
  • Freeze a Card - Temporarily suspend card usage
  • Close a Card - Permanently deactivate a card
  • Query Card Details - Check current card status
  • Query All Cards - List all cards with specific status
  • Update Card Remark - Add notes about freeze/unfreeze actions

Troubleshooting

Card Not Frozen (400)

  • Cause: Attempting to unfreeze a card that is not in FROZEN state
  • Solution:
    • Query card details to check current status
    • Only FROZEN cards can be unfrozen
    • If card is ACTIVE, no action needed

Card Not Found (404)

  • Cause: Invalid card_id or card doesn't exist
  • Solution:
    • Verify the card ID is correct
    • Use Query All Cards to list available cards
    • Check if card was deleted

Unfreeze Not Taking Effect

  • Cause: Cache or processing delay
  • Solution:
    • Wait 2-5 seconds and query card status again
    • Unfreeze typically takes effect immediately
    • Check card details to verify status changed to ACTIVE

Security Considerations

  • Access Control: Restrict unfreeze operations to authorized users only
  • Verification: Verify security concerns resolved before unfreezing
  • Audit Trail: Log all unfreeze operations with reason and operator
  • Customer Consent: Consider requiring customer confirmation for unfreezes
  • Fraud Prevention: Don't unfreeze cards frozen for fraud without investigation
  • Rate Limiting: Monitor for unusual patterns of freeze/unfreeze operations

Interactive API Explorer