feat: implement idempotency key for critical API endpoints

This commit is contained in:
Efril
2026-06-04 00:48:50 +07:00
parent 2ab20a1150
commit b228538725
21 changed files with 431 additions and 37 deletions
@@ -18,6 +18,15 @@ class OrderRemoteDataProvider {
final _logName = 'OrderRemoteDataProvider';
OrderRemoteDataProvider(this._apiClient);
/// Helper untuk merge auth header dengan idempotency key
Map<String, dynamic> _buildHeaders({String? idempotencyKey}) {
final headers = getAuthorizationHeader();
if (idempotencyKey != null) {
headers['X-Idempotency-Key'] = idempotencyKey;
}
return headers;
}
Future<DC<OrderFailure, ListOrderDto>> fetchOrders({
int page = 1,
int limit = 10,
@@ -151,13 +160,14 @@ class OrderRemoteDataProvider {
}
Future<DC<OrderFailure, PaymentDto>> storePayment(
PaymentRequestDto request,
) async {
PaymentRequestDto request, {
String? idempotencyKey,
}) async {
try {
final response = await _apiClient.post(
ApiPath.payments,
data: request.toJson(),
headers: getAuthorizationHeader(),
headers: _buildHeaders(idempotencyKey: idempotencyKey),
);
if (response.data['success'] == false) {
@@ -178,6 +188,7 @@ class OrderRemoteDataProvider {
Future<DC<OrderFailure, OrderDto>> addItemOrder({
required String id,
required List<AddItemOrderRequestDto> request,
String? idempotencyKey,
}) async {
try {
final response = await _apiClient.post(
@@ -186,7 +197,7 @@ class OrderRemoteDataProvider {
'notes': '',
'order_items': request.map((e) => e.toRequest()).toList(),
},
headers: getAuthorizationHeader(),
headers: _buildHeaders(idempotencyKey: idempotencyKey),
);
if (response.data['success'] == false) {
@@ -209,6 +220,7 @@ class OrderRemoteDataProvider {
required String reason,
String type = "ITEM", // TYPE: ALL, ITEM
required List<OrderItemDto> orderItems,
String? idempotencyKey,
}) async {
try {
final response = await _apiClient.post(
@@ -223,7 +235,7 @@ class OrderRemoteDataProvider {
)
.toList(),
},
headers: getAuthorizationHeader(),
headers: _buildHeaders(idempotencyKey: idempotencyKey),
);
if (response.data['success'] == false) {
@@ -238,14 +250,15 @@ class OrderRemoteDataProvider {
}
Future<DC<OrderFailure, PaymentDto>> createSplitBill(
PaymentSplitBillRequestDto request,
) async {
PaymentSplitBillRequestDto request, {
String? idempotencyKey,
}) async {
log(request.toRequest().toString());
try {
final response = await _apiClient.post(
"${ApiPath.orders}/split-bill",
data: request.toRequest(),
headers: getAuthorizationHeader(),
headers: _buildHeaders(idempotencyKey: idempotencyKey),
);
if (response.data['success'] == false) {
@@ -267,12 +280,13 @@ class OrderRemoteDataProvider {
required String id,
required String reason,
required int refundAmount,
String? idempotencyKey,
}) async {
try {
final response = await _apiClient.post(
'${ApiPath.orders}/$id/refund',
data: {'refund_amount': refundAmount, 'reason': reason},
headers: getAuthorizationHeader(),
headers: _buildHeaders(idempotencyKey: idempotencyKey),
);
if (response.data['success'] == false) {