PaymentSheetEvent.fromJson constructor
Parses and validates a lifecycle event from the native bridge.
Implementation
factory PaymentSheetEvent.fromJson(Map<Object?, Object?> value) {
const baseFields = {'type', 'occurredAt', 'flowId', 'sequence'};
final rawType = value['type'];
final rawOccurredAt = value['occurredAt'];
final flowId = value['flowId'];
final sequence = value['sequence'];
final type = rawType is String
? PaymentSheetEventType.fromWireValue(rawType)
: null;
final occurredAt = rawOccurredAt is String
? DateTime.tryParse(rawOccurredAt)
: null;
if (type == null ||
occurredAt == null ||
flowId is! String ||
!_uuidPattern.hasMatch(flowId) ||
sequence is! int ||
sequence < 1) {
throw const FormatException('Invalid payment sheet lifecycle event');
}
final extraFields = switch (type) {
PaymentSheetEventType.presented || PaymentSheetEventType.ready =>
const <String>{},
PaymentSheetEventType.change => const {'complete', 'paymentMethod'},
PaymentSheetEventType.orderPrepared ||
PaymentSheetEventType.paymentAttemptStarted ||
PaymentSheetEventType.paymentProcessing ||
PaymentSheetEventType.completed =>
const {'order'},
PaymentSheetEventType.paymentActionRequired => const {'order', 'action'},
PaymentSheetEventType.paymentAttemptFailed => const {'order', 'failure'},
PaymentSheetEventType.canceled => const {'order'},
PaymentSheetEventType.failed => const {'order', 'failure'},
};
_expectFields(value, {...baseFields, ...extraFields});
final rawOrder = value['order'];
final rawAction = value['action'];
final rawFailure = value['failure'];
final complete = value['complete'];
final paymentMethod = value['paymentMethod'];
final order = rawOrder is Map
? CheckoutOrder.fromJson(Map<Object?, Object?>.from(rawOrder))
: null;
final action = rawAction is Map
? CheckoutAction.fromJson(Map<Object?, Object?>.from(rawAction))
: null;
final failure = rawFailure is Map
? CheckoutFailure.fromJson(Map<Object?, Object?>.from(rawFailure))
: null;
final valid = switch (type) {
PaymentSheetEventType.presented || PaymentSheetEventType.ready => true,
PaymentSheetEventType.change =>
complete is bool &&
(paymentMethod == null || paymentMethod == 'mobile_money'),
PaymentSheetEventType.orderPrepared ||
PaymentSheetEventType.paymentAttemptStarted ||
PaymentSheetEventType.paymentProcessing ||
PaymentSheetEventType.completed =>
order != null,
PaymentSheetEventType.paymentActionRequired =>
order != null && action != null,
PaymentSheetEventType.paymentAttemptFailed =>
order != null && failure != null,
PaymentSheetEventType.canceled => rawOrder == null || order != null,
PaymentSheetEventType.failed => failure != null,
};
if (!valid ||
(rawOrder != null && order == null) ||
(rawAction != null && action == null) ||
(rawFailure != null && failure == null)) {
throw const FormatException('Invalid payment sheet lifecycle event');
}
return PaymentSheetEvent(
flowId: flowId,
sequence: sequence,
type: type,
occurredAt: occurredAt,
order: order,
action: action,
failure: failure,
complete: complete as bool?,
paymentMethod: paymentMethod as String?,
);
}