processPayment method
Processes a payment by opening the provided checkout URL in a webview.
The implementation should:
- Open the checkout URL in a platform-appropriate webview
- Handle Paystack's callback mechanisms (redirects, postMessage, etc.)
- Return a PaymentResponse based on the payment outcome
checkoutUrl
The Paystack checkout URL to load in the webview
Returns a PaymentResponse containing the payment result
Implementation
@override
Future<PaymentResponse> processPayment(String checkoutUrl) async {
// Extract reference from checkout URL
final uri = Uri.parse(checkoutUrl);
final reference =
uri.queryParameters['reference'] ??
uri.queryParameters['trxref'] ??
'linux_webview_${DateTime.now().millisecondsSinceEpoch}';
try {
// Call platform method to show webview (opens in browser) with timeout
final result = await _channel
.invokeMethod<Map<dynamic, dynamic>>('showWebView', {
'checkoutUrl': checkoutUrl,
})
.timeout(
const Duration(minutes: 10),
onTimeout: () {
throw PaystackError(
message:
'Payment timeout - user took too long to complete payment',
code: 'PAYMENT_TIMEOUT',
);
},
);
if (result == null) {
throw PaystackError(message: 'No response from webview');
}
final castedResult = result.cast<String, dynamic>();
if (castedResult['status'] != 'success') {
throw PaystackError.fromApiResponse(castedResult);
}
// Parse the payment result
final data = castedResult['data'] as Map<String, dynamic>;
final paymentReference = data['reference'] as String? ?? reference;
final status = data['status'] as String? ?? 'success';
return PaymentResponse(
reference: paymentReference,
status: _parsePaymentStatus(status),
amount: 0, // Would be determined from verification
currency: Currency.ngn, // Would be determined from verification
paymentMethod: PaymentMethod.card, // Would be determined from payment
gatewayResponse: data['message'] as String? ?? 'Payment completed',
);
} on PlatformException catch (e) {
throw PaystackError(
message: e.message ?? 'Webview payment failed',
code: e.code,
);
} on TimeoutException {
throw PaystackError(
message: 'Payment timeout - user took too long to complete payment',
code: 'PAYMENT_TIMEOUT',
);
} catch (_) {
throw PaystackError(
message: 'Unexpected error during payment',
code: 'WEBVIEW_ERROR',
);
}
}