Skip to main content

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:

  1. Create BaseCallbackProcessor with WalletCallbackRecordTable
  2. Validate required fields
  3. Save to WalletCallbackRecordTable
  4. Invoke ProcessPaidWalletOrderInternal if success is True
  5. 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):

  • DynamoDBWritePolicy for WalletCallbackRecordTable (line 297-298)
  • DynamoDBReadPolicy for order-table-dev (line 299-300)
  • DynamoDBCrudPolicy for payment3-card-payment-record-master (line 301-302)
  • LambdaInvokePolicy for ProcessPaidWalletOrderInternal (line 303-304)
  • AWSSecretsManagerGetSecretValuePolicy for kbank-dev (line 305-306)
  • AWSSecretsManagerGetSecretValuePolicy for kbank-prod (line 307-308)
  • DynamoDBWritePolicy for CallbackErrorLogTable (line 309-311)
  • SESCrudPolicy for 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 WalletCallback
  • order-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)
  • 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