Hướng dẫn tích hợp Flutterwave v4 với NestJS: Làm chủ chuyển tiền Mobile Money (Phần 1)
Flutterwave vừa ra mắt phiên bản API v4 với nhiều cải tiến vượt trội về bảo mật và quy trình xử lý giao dịch qua OAuth 2.0 và Orchestrator Flow. Bài viết hướng dẫn chi tiết cách xây dựng tích hợp Mobile Money sẵn sàng cho môi trường sản xuất trên nền tảng NestJS.

Hướng dẫn tích hợp Flutterwave v4 với NestJS: Làm chủ chuyển tiền Mobile Money (Phần 1)
Flutterwave đã phát hành phiên bản API v4, đánh dấu một bước thay đổi kiến trúc quan trọng, chuyển từ sử dụng khoá Public/Secret tĩnh sang OAuth 2.0 cùng với mô hình Orchestrator Flow hoàn toàn mới. Bài viết này sẽ hướng dẫn bạn xây dựng một hệ thống tích hợp Mobile Money hiệu quả và an toàn sử dụng NestJS — framework lập trình backend phổ biến hiện nay.
Vì sao Flutterwave v4 là bước tiến vượt bậc?
Phiên bản v4 không chỉ đơn thuần là cập nhật, mà là sự thay đổi toàn diện về kiến trúc bảo mật và quy trình giao dịch. Thay vì gửi Secret Key mỗi lần gọi API, giờ đây bạn sẽ lấy Bearer Token có thời hạn từ OAuth 2.0, giúp tăng cường bảo mật, đồng thời giảm thiểu nguy cơ bị lộ khoá.
Bên cạnh đó, Orchestrator Flow hay còn gọi là Direct Transfers cho phép các giao dịch được xử lý trong một bước duy nhất, gộp cả thông tin người gửi, người nhận và số tiền chuyển vào trong cùng một yêu cầu, thay vì quá trình đa bước phức tạp trước đây.
Bước 1: Lấy thông tin xác thực v4
Trước hết, bạn cần đăng nhập vào dashboard Flutterwave và bật chế độ phát triển v4 (Developer Toggle). Tại đây tạo Client ID và Secret Key mới, đồng thời ghi chú URL mới của sandbox:
https://developersandbox-api.flutterwave.com
Trong dự án NestJS, cấu hình biến môi trường theo mẫu:
FLUTTERWAVE_CLIENT_ID=your_v4_client_id_here
FLUTTERWAVE_SECRET_KEY=your_v4_secret_key_here
FLUTTERWAVE_BASE_URL=https://developersandbox-api.flutterwave.com
Bước 2: Xây dựng dịch vụ xác thực token "im lặng"
Với OAuth 2.0, token sẽ có hạn dùng nên mỗi giao dịch không nên lấy token mới để tránh bị giới hạn tốc độ. Ta sẽ tạo một service lưu cache token và chỉ refresh khi token gần hết hạn:
@Injectable()
export class FlutterwaveAuthService {
private accessToken: string | null = null;
private tokenExpiryTime: number = 0;
constructor(
private readonly httpService: HttpService,
private readonly configService: ConfigService,
) {}
async getValidToken(): Promise<string> {
const currentTime = Date.now();
if (!this.accessToken || (this.tokenExpiryTime - currentTime) < 60000) {
await this.refreshAccessToken();
}
return this.accessToken;
}
private async refreshAccessToken(): Promise<void> {
const clientId = this.configService.get('FLUTTERWAVE_CLIENT_ID');
const clientSecret = this.configService.get('FLUTTERWAVE_SECRET_KEY');
const tokenUrl = 'https://idp.flutterwave.com/realms/flutterwave/protocol/openid-connect/token';
const payload = new URLSearchParams({
client_id: clientId,
client_secret: clientSecret,
grant_type: 'client_credentials',
});
try {
const { data } = await firstValueFrom(this.httpService.post(tokenUrl, payload, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
}));
this.accessToken = data.access_token;
this.tokenExpiryTime = Date.now() + data.expires_in * 1000;
} catch (error) {
throw new HttpException('Failed to authenticate with payment gateway', HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
Bước 3: Định nghĩa các DTO (Data Transfer Objects) cho Mobile Money
Phiên bản mới v4 yêu cầu cấu trúc dữ liệu rất chuẩn xác. Chúng ta dùng class-validator để validate dữ liệu đầu vào, tập trung các thông tin quan trọng như msisdn (số điện thoại) và network (mạng di động):
class MobileMoneyDto {
@ApiProperty({ example: 'MTN' })
@IsString()
@IsNotEmpty()
network: string;
@ApiProperty({ example: 'CMR' })
@IsString()
@IsNotEmpty()
country: string;
@ApiProperty({ example: '653033621', description: 'Số điện thoại người nhận' })
@IsString()
@IsNotEmpty()
msisdn: string;
}
Các DTO phức tạp hơn mô tả sender, recipient, số tiền, thông tin địa chỉ được triển khai chi tiết trong code mẫu, giúp đảm bảo API sạch, rõ ràng và tránh lỗi dữ liệu.
Bước 4: Triển khai chuyển tiền trực tiếp (Direct Transfers) với Orchestrator
Đây là điểm nhấn của v4; dịch vụ có thể gửi một lần tất cả các thông tin của giao dịch Mobile Money, giúp xử lý nhanh và chính xác.
async directTransfer(dto: DirectTransferDto) {
try {
const token = await this.authService.getValidToken();
const headers = {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
'X-Idempotency-Key': `direct-${uuidv4()}`,
'X-Trace-Id': uuidv4(),
};
const { data } = await firstValueFrom(
this.httpService.post(`${this.baseUrl}/direct-transfers`, dto, { headers }),
);
return data;
} catch (error) {
throw new HttpException(
error.response?.data?.message || 'Direct transfer failed',
error.response?.status || HttpStatus.BAD_REQUEST,
);
}
}
Ý nghĩa của các headers đặc biệt
- X-Idempotency-Key: Giúp tránh lặp lại giao dịch khi gửi nhiều lần do lỗi mạng.
- X-Trace-Id: Hữu ích để tra cứu log khi cần hỗ trợ kỹ thuật từ Flutterwave.
Bước 5: Tạo Controller để phơi bày API
Cuối cùng, module controller của NestJS nhận yêu cầu từ client và gọi service xử lý, làm cho API rất gọn gàng và dễ bảo trì.
@ApiTags('Flutterwave')
@Controller('flutterwave')
export class FlutterwaveController {
constructor(private readonly flutterwaveService: FlutterwaveApiService) {}
@Post('direct-transfers')
@ApiOperation({ summary: 'Khởi tạo chuyển tiền trực tiếp (Orchestrator)' })
async initiateDirectTransfer(@Body() dto: DirectTransferDto) {
return await this.flutterwaveService.directTransfer(dto);
}
}
Tổng kết
NestJS với kiến trúc modul giúp tách biệt phần phức tạp nhất của Flutterwave v4 là vòng đời OAuth 2.0 thành một service riêng biệt, đồng thời giữ cho code hiệu quả, bảo mật và sẵn sàng xử lý luồng giao dịch lớn. Đây mới chỉ là phần 1, trong bài tiếp theo chúng tôi sẽ đề cập đến:
- Tích hợp chuyển khoản ngân hàng đa loại tiền tệ (EGP, NGN, XAF).
- Thiết lập webhook để nhận cập nhật trạng thái giao dịch.
- Xử lý lỗi nâng cao đặc thù fintech để cải thiện trải nghiệm.
Bạn đã thử nghiệm v4 chưa? Cùng chia sẻ thắc mắc hoặc những "cạm bẫy" bạn gặp được ở phần bình luận nhé!
Bài viết liên quan

Công nghệ
George Orwell đã tiên đoán sự trỗi dậy của "rác thải AI" trong tác phẩm 1984
16 tháng 4, 2026

Phần mềm
Anthropic ra mắt Claude Opus 4.7: Nâng cấp mạnh mẽ cho lập trình nhưng vẫn thua Mythos Preview
16 tháng 4, 2026

Công nghệ
Qwen3.6-35B-A3B: Quyền năng Lập trình Agentic, Nay Đã Mở Cửa Cho Tất Cả
16 tháng 4, 2026
