pay method

Future<void> pay({
  1. required BuildContext context,
  2. required PaymentRequest request,
  3. PaymentSuccessCallback? onSuccess,
  4. PaymentFailureCallback? onFailure,
  5. Duration? timeout,
})

Make a payment

Implementation

Future<void> pay({
  required BuildContext context,
  required PaymentRequest request,
  PaymentSuccessCallback? onSuccess,
  PaymentFailureCallback? onFailure,
  Duration? timeout,
}) async {
  if (_config == null || _provider == null) {
    throw StateError('PaymentService not initialized. Call init() first.');
  }

  try {
    // Create payment URL via backend
    final paymentUrlResponse = await _provider!.createPaymentUrl(request);

    if (!context.mounted) return;

    // Launch WebView with payment URL
    await Navigator.of(context).push(
      MaterialPageRoute<void>(
        builder: (context) => PaymentWebView(
          paymentUrl: paymentUrlResponse.paymentUrl,
          provider: _config!.provider,
          orderId: request.orderId,
          successUrlPattern: _getSuccessUrlPattern(),
          cancelUrlPattern: _getCancelUrlPattern(),
          failureUrlPattern: _getFailureUrlPattern(),
          timeout: timeout ?? const Duration(minutes: 15),
          onSuccess: (response) async {
            // Verify payment with backend if transaction ID is available
            if (response.transactionId != null) {
              try {
                final verifiedResponse = await _provider!.verifyPayment(
                  response.transactionId!,
                );
                onSuccess?.call(verifiedResponse);
              } catch (e) {
                // If verification fails, still call success with original response
                onSuccess?.call(response);
              }
            } else {
              onSuccess?.call(response);
            }

            if (context.mounted) {
              Navigator.of(context).pop();
            }
          },
          onFailure: (response) {
            onFailure?.call(response);
            if (context.mounted) {
              Navigator.of(context).pop();
            }
          },
          onCancelled: () {
            onFailure?.call(PaymentResponse.cancelled(
              message: 'Payment was cancelled by user',
              orderId: request.orderId,
              provider: _config!.provider,
            ));
          },
        ),
      ),
    );
  } catch (e) {
    final errorResponse = PaymentResponse.failure(
      message: 'Failed to initiate payment: $e',
      orderId: request.orderId,
      provider: _config!.provider,
    );
    onFailure?.call(errorResponse);
  }
}