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
| Header | Value | Required | Description |
|---|---|---|---|
Accept | application/json | Yes | Content type for the response |
Content-Type | application/json | Yes | Content type of the request body |
Authorization | Bearer {access_token} | Yes | Bearer token for authentication |
x-api-key | API Key | Yes | API key for authentication |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
card_id | string | Yes | A unique ID of the card to unfreeze |
Request Example
{
"card_id": "card202010161608422883"
}
Response
Success Response (200 OK)
{
"code": "SUCCESS"
}
Response Fields
| Field | Type | Description |
|---|---|---|
code | string | Status string indicating the result. "SUCCESS" refers to a successful unfreeze |
Error Responses
- 400 Bad Request: Invalid
card_idor 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
| Operation | Reversible | Use Case |
|---|---|---|
| Freeze/Unfreeze | ✓ Yes | Temporary security holds, lost cards later found |
| Close | ✗ No | Permanent deactivation, compromised cards |
Related Endpoints
- 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_idor 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