import 'package:adyen_checkout/adyen_checkout.dart';
import 'package:payment_plugin/utils/json.dart';
class PaymentEventHandler {
//Response keys
static const errorCodeKey = "errorCode";
static const resultCodeKey = "resultCode";
static const actionKey = "action";
static const messageKey = "message";
static const refusalReasonKey = "refusalReason";
PaymentEvent handleResponse({
required Json jsonResponse,
Json updatedPaymentMethodsJson = const {},
}) {
if (_isError(jsonResponse)) {
final message = jsonResponse[messageKey] as String?;
final reason = jsonResponse[refusalReasonKey] as String;
return Error(
errorMessage: message,
reason: message ?? reason,
dismissDropIn: true,
);
}
if (_isRefusedInPartialPaymentFlow(jsonResponse)) {
return Error(
errorMessage: "Payment is refused",
reason: "Refused",
dismissDropIn: true,
);
}
if (_isAction(jsonResponse)) {
return Action(actionResponse: jsonResponse[actionKey] as Json);
}
if (_isNonFullyPaidOrder(jsonResponse) &&
updatedPaymentMethodsJson.isNotEmpty) {
return Update(
orderJson: jsonResponse["order"] as Json,
paymentMethodsJson: updatedPaymentMethodsJson,
);
}
if (jsonResponse.containsKey(resultCodeKey)) {
return Finished(resultCode: jsonResponse[resultCodeKey] as String);
}
return Finished(resultCode: "EMPTY");
}
bool _isError(Json jsonResponse) {
final hasErrorCodeKey = jsonResponse.containsKey(errorCodeKey);
final hasErrorResultCode = (jsonResponse[resultCodeKey] as String?)
?.toUpperCase()
.contains(ResultCode.error.name.toUpperCase()) ??
false;
return hasErrorCodeKey || hasErrorResultCode;
}
bool _isRefusedInPartialPaymentFlow(Json jsonResponse) =>
_isRefused(jsonResponse) && _isNonFullyPaidOrder(jsonResponse);
bool _isRefused(Json jsonResponse) => jsonResponse[resultCodeKey]
.toString()
.toUpperCase()
.contains(ResultCode.refused.name.toUpperCase());
bool _isAction(Json jsonResponse) => jsonResponse.containsKey(actionKey);
bool _isNonFullyPaidOrder(Json jsonResponse) {
if (jsonResponse.containsKey("order")) {
final remainingAmount = jsonResponse["order"]["remainingAmount"]["value"] as num;
return remainingAmount > 0;
} else {
return false;
}
}
}