BankAppCallback Lambda Function
Quick Reference
- Function Name:
payment3-bankapp-callback-${BRANCH} - Handler:
bankappcallback.lambda_handler - Runtime: Python 3.12 (Docker Image)
- Trigger: API Gateway (POST /bankapp/callback)
- Template.yaml: Lines 287-329
Function Overview
The BankAppCallback function processes bank app payment callbacks (e.g., KBank mobile app payments). It saves callback records to WalletCallbackRecordTable (shared with Wallet) and invokes ProcessPaidWalletOrderInternal for successful payments. This function uses the BaseCallbackProcessor pattern and shares the same table as WalletCallback.
Entry Point
File: functions/callback/bankappcallback.py
Handler: lambda_handler(event, _)
def lambda_handler(event, _):
"""
Record bank app callback.
"""
processor = None
try:
print(f"Processing bank app callback event: {json.dumps(event)}")
processor = BaseCallbackProcessor(
event=event,
record_table_class=WalletCallbackRecordTable,
function_name="BankApp"
)
processor.save()
response = processor.response
print(f"Bank app callback processed successfully: {json.dumps(response)}")
if processor.success:
processor.call_processpaid("wallet-order-internal")
return response
except Exception as e:
error_msg = f"Error processing bank app callback: {e} {errorString()}"
print(error_msg)
sentry_sdk.capture_exception(e)
# Extract orderId and chargeId for error logging
orderId = None
chargeId = None
if processor:
try:
orderId = processor.order_id
chargeId = processor.payment_id
except (AttributeError, KeyError):
# Processor may not have these attributes if initialization failed
pass
log_callback_error(
error=e,
function_name="bankappcallback",
event=event,
orderId=orderId,
chargeId=chargeId,
response_data=None
)
send_callback_error_email(
error=e,
function_name="bankappcallback",
orderId=orderId,
chargeId=chargeId,
event=event
)
return {
"statusCode": 500,
"headers": {"Content-Type": "application/json"},
"body": json.dumps(
{
"success": False,
"error": str(e),
"message": "Failed to process bank app callback",
}
),
}
Event Structure
API Gateway Event
Path: POST /bankapp/callback
Auth: NONE (public endpoint - called by payment gateway)
Request Body (JSON):
{
"orderId": "482500007436",
"paymentId": "pay_bankapp_1234567890",
"success": true,
"amount": 2339.0,
"userId": "b5f392f7-6d89-433c-b24f-bf6a772cab1a",
"message": "Payment successful"
}
Required Fields: Same as WalletCallback
orderId- Villa order ID (required)paymentId- Payment gateway payment ID (required)success- Payment success status: true or false (required)userId- Villa user ID (required)amount- Paid amount (optional)message- Optional message
Response: Same format as WalletCallback
DynamoDB Tables
WalletCallbackRecordTable
Table Name: payment3-wallet-callback-record-{BRANCH}
Region: ap-southeast-1
Note: BankAppCallback uses the same table as WalletCallback (WalletCallbackRecordTable). This allows both payment methods to share the same callback record structure.
PynamoDB Model: Same as WalletCallback
Lambda Invocations
ProcessPaidWalletOrderInternal
Function: payment3-process-paid-wallet-order-internal-${BRANCH}
Invoked When: processor.success is True
Payload: Full request body (JSON string)
Invocation Type: Event (asynchronous)
Note: Same function as WalletCallback - both invoke ProcessPaidWalletOrderInternal
Processing Flow
Same as WalletCallback - uses BaseCallbackProcessor pattern:
- Create BaseCallbackProcessor with WalletCallbackRecordTable
- Validate required fields
- Save to WalletCallbackRecordTable
- Invoke ProcessPaidWalletOrderInternal if success is True
- Return JSON response
Error Handling
Same error handling as WalletCallback:
- Validation errors logged to CallbackErrorLogTable
- Sent to Sentry with context tags
- Error email sent via SES
- Returns 500 error response
IAM Policies
From template.yaml (lines 296-316):
DynamoDBWritePolicyforWalletCallbackRecordTable(line 297-298)DynamoDBReadPolicyfororder-table-dev(line 299-300)DynamoDBCrudPolicyforpayment3-card-payment-record-master(line 301-302)LambdaInvokePolicyforProcessPaidWalletOrderInternal(line 303-304)AWSSecretsManagerGetSecretValuePolicyfor kbank-dev (line 305-306)AWSSecretsManagerGetSecretValuePolicyfor kbank-prod (line 307-308)DynamoDBWritePolicyforCallbackErrorLogTable(line 309-311)SESCrudPolicyfor sending error emails (line 312-314)
Dependencies
External Lambda Functions
payment3-process-paid-wallet-order-internal-${BRANCH}- Process paid wallet/bankapp orders (invoked)
DynamoDB Tables
payment3-wallet-callback-record-${BRANCH}- Callback records (write) - Shared with WalletCallbackorder-table-dev- Order data (read)payment3-card-payment-record-master- Master payment records (read)payment3-callback-error-log-${BRANCH}- Error logs (write)
AWS Services
- SES: Send error notification emails
Testing
Test Event Example
{
"body": "{\"orderId\": \"482500007436\", \"paymentId\": \"pay_bankapp_123\", \"success\": true, \"amount\": 2339.0, \"userId\": \"b5f392f7-6d89-433c-b24f-bf6a772cab1a\", \"message\": \"Payment successful\"}"
}
Code Structure
File Organization:
functions/callback/
├── bankappcallback.py # Main handler
└── src/
├── base_callback_processor.py # Base processor (shared)
└── walletCallbackRecordTable.py # Wallet callback table (shared)
Related Functions
- ProcessPaidWalletOrderInternal - Processes paid wallet/bankapp orders (shared with WalletCallback)
- WalletCallback - Similar callback handler (uses same table and process function)
- AmexCallback - Similar callback handler (different table)
Key Differences from WalletCallback
- Same Table: Uses WalletCallbackRecordTable (not a separate table)
- Same Process Function: Invokes ProcessPaidWalletOrderInternal (same as WalletCallback)
- Different Function Name: Uses "BankApp" as function_name for logging
References
- Template.yaml: Lines 287-329
- Related Functions: ProcessPaidWalletOrderInternal, WalletCallback, AmexCallback
- Base Processor:
src/base_callback_processor.py