Overview
The MTB Backend integrates with Flow, a Chilean payment gateway, to process registration payments for events. This integration handles payment creation, token management, order tracking, and payment state management.Flow provides sandbox and production environments. Configure the appropriate base URL via the
FLOW_BASE_URL environment variable.Payment Flow Architecture
Initiate Payment
The frontend requests a payment by sending the
inscripcionId to the /api/flow/pagar endpoint.Create Flow Transaction
The backend creates a payment transaction with Flow, generating a unique
commerceOrder identifier.Receive Payment Token
Flow returns a payment
token that’s stored in the tokenFlow field of the inscripcion record.Redirect to Payment
The user is redirected to Flow’s payment page using the generated payment URL with the token.
Payment Confirmation
Flow sends a webhook notification to the confirmation endpoint with the payment result.
Payment States
TheestadoPago field in the inscripcion schema tracks the current payment status using an enumeration with three possible values:
| Estado | Description |
|---|---|
Pendiente | Default state. Payment has not been completed. This is the initial state when a registration is created. |
Pagado | Payment was successfully processed and confirmed by Flow. |
Rechazado | Payment was rejected or failed. This can occur due to insufficient funds, card issues, or user cancellation. |
Schema Fields
The inscripcion schema includes three key fields for Flow integration:tokenFlow
- Type:
string - Purpose: Stores the unique payment token generated by Flow
- Usage: Used to construct the payment URL and track the transaction
- Set: When the payment is created via the
/pagarendpoint - Example:
"A1B2C3D4E5F6G7H8I9J0"
ordenFlow
- Type:
string - Required:
false - Purpose: Stores the commerce order identifier
- Format:
INS{timestamp}(e.g.,INS1678901234567) - Usage: Links the internal registration with the Flow transaction
- Set: Generated automatically when creating the payment
estadoPago
- Type:
enumeration - Default:
"Pendiente" - Values:
["Pendiente", "Pagado", "Rechazado"] - Purpose: Tracks the current payment status
- Usage: Determines if a payment can be initiated and displays status to users
Payment Creation Endpoint
POST /api/flow/pagar
Creates a Flow payment transaction for a registration. Request Body:src/api/flow/controllers/flow.ts:8) performs the following operations:
- Validation - Verifies the inscripcion exists and has required fields
- State Check - Ensures
estadoPagois"Pendiente" - Order Generation - Creates a unique
commerceOrderusing timestamp - Signature Creation - Generates HMAC-SHA256 signature for security
- Flow API Call - Sends payment creation request to Flow
- Token Storage - Updates inscripcion with
tokenFlowandordenFlow - URL Construction - Builds the complete payment URL for redirection
View Payment Creation Code
View Payment Creation Code
Payment Confirmation Webhook
POST /api/flow/confirmacion
Flow calls this endpoint after a payment is processed (successful, rejected, or cancelled). Purpose:- Receive payment status updates from Flow
- Update the
estadoPagofield accordingly - Trigger any post-payment business logic
The webhook endpoint (
src/api/flow/controllers/flow.ts:131) currently logs the received data. You should implement the logic to verify the payment signature and update the inscripcion’s estadoPago field.1- Pending2- Paid/Successful3- Rejected4- Cancelled by user
Environment Configuration
Configure the following environment variables for Flow integration:| Variable | Description | Required | Example |
|---|---|---|---|
FLOW_API_KEY | Your Flow API key | Yes | A1B2C3-D4E5F6-G7H8I9 |
FLOW_SECRET_KEY | Your Flow secret key for signatures | Yes | secret123key456 |
FLOW_BASE_URL | Flow API base URL | No | https://sandbox.flow.cl/api (default for sandbox) |
BACKEND_URL | Your backend URL for webhooks | Yes | https://api.example.com |
FRONTEND_URL | Frontend URL for return after payment | Yes | https://example.com |
Security Implementation
The Flow integration implements several security measures:HMAC-SHA256 Signature
All requests to Flow are signed using HMAC-SHA256 (src/api/flow/controllers/flow.ts:64):
Webhook Validation
To implement webhook signature validation:- Extract the
sparameter from the webhook payload - Reconstruct the signature using the same sorted-key method
- Compare the signatures to verify authenticity
- Only process the webhook if signatures match
Testing with Sandbox
Flow provides a sandbox environment for testing:-
Set Sandbox URL:
-
Use Test Credentials:
- Obtain sandbox API key and secret from Flow’s developer portal
-
Test Cards:
- Flow sandbox provides test card numbers for different scenarios
- Test successful payments, rejections, and timeouts
-
Webhook Testing:
- Use ngrok or similar tools to expose your local webhook endpoint
- Update
BACKEND_URLto point to the public URL
Common Payment Scenarios
Successful Payment Flow
- User completes registration →
estadoPago: "Pendiente",monto: 15000 - Frontend calls
/pagar→ Receives payment URL - User redirected to Flow → Completes payment
- Flow calls webhook → Backend updates
estadoPago: "Pagado" - User redirected to success page
Rejected Payment
- Payment initiated →
estadoPago: "Pendiente" - User enters invalid card → Payment fails
- Flow calls webhook with status 3 → Update
estadoPago: "Rechazado" - User can retry by calling
/pagaragain (requires manual reset to “Pendiente”)
Abandoned Payment
- Payment initiated →
tokenFlowandordenFlowset - User closes browser without completing
- Payment remains
estadoPago: "Pendiente" - Manual review may be required to reset or cancel
Consider implementing a scheduled job to handle abandoned payments that remain in “Pendiente” state for extended periods.
Error Handling
The payment endpoint handles various error scenarios:| Error | HTTP Status | Description |
|---|---|---|
Missing inscripcionId | 400 | Request body doesn’t include the inscription ID |
| Inscripcion not found | 404 | No inscription exists with the provided ID |
| Missing required data | 400 | Inscription lacks nombreCompleto, email, or monto |
| Not in pending state | 400 | estadoPago is not “Pendiente” |
| Missing API credentials | 500 | FLOW_API_KEY or FLOW_SECRET_KEY not configured |
| Flow API error | 500 | Flow returned an error or no token |
Best Practices
Validate Before Payment
Always verify the inscription has all required data (
email, monto, nombreCompleto) before allowing payment initiation.Check Payment State
Only allow payment for inscriptions with
estadoPago: "Pendiente". Prevent double payments.Store Transaction References
Always save both
tokenFlow and ordenFlow to enable payment tracking and reconciliation.Handle Timeouts
Set appropriate timeouts for Flow API calls (currently 30 seconds) and handle timeout errors gracefully.
Next Steps
Inscripcion API
Explore the complete Inscripcion API documentation
Content Types
Learn about the Inscripcion content type schema
