getSessionToken method

Future<String> getSessionToken({
  1. required String orderNumber,
  2. required String orderAmount,
  3. required String orderCurrency,
  4. required String orderDescription,
  5. bool? recurringInit,
  6. String? scheduleId,
  7. bool? reqToken,
  8. List<String>? cardToken,
})

Get session token from Mobibox API

This endpoint requires checkout authentication parameters:

  • operation: "purchase"
  • order: object with number, amount, currency, description
  • hash: signature hash
  • merchant_key: merchant key
  • return_url: mandatory for HPF (for 3DS redirect)
  • success_url, cancel_url, error_url: optional

URL parameters are managed internally as placeholders.

Reference: https://docs.mobibox.io/docs/guides/hosted_payment_fields recurringInit - Initialize recurring payment (optional) scheduleId - Schedule ID for recurring payments (optional) reqToken - Request card token for future payments (optional) cardToken - Array of card tokens for returning customers (optional)

Implementation

Future<String> getSessionToken({
  required String orderNumber,
  required String orderAmount,
  required String orderCurrency,
  required String orderDescription,
  bool? recurringInit,
  String? scheduleId,
  bool? reqToken,
  List<String>? cardToken,
}) async {
  // return_url is required for 3DS redirects and callback handling
  // Using Mobibox's hosted payment processing page
  // success_url, cancel_url, and error_url are optional and not included
  const returnUrl = 'https://sdk.mobibox.io/payment_processing.html';
  final uri = Uri.parse('$checkoutHost/api/v1/session/token');

  // Generate hash signature
  final hash = MobiPayHash.generateAuthHash(
    orderNumber: orderNumber,
    orderAmount: orderAmount,
    orderCurrency: orderCurrency,
    orderDescription: orderDescription,
    password: password,
  );

  // Build request body with required parameters
  final requestBody = <String, dynamic>{
    'operation': 'purchase',
    'merchant_key': merchantKey,
    'order': {
      'number': orderNumber,
      'amount': orderAmount,
      'currency': orderCurrency,
      'description': orderDescription,
    },
    'hash': hash,
    'return_url': returnUrl,
  };

  // Add optional recurring/tokenization parameters if provided
  if (recurringInit != null) {
    requestBody['recurring_init'] = recurringInit;
  }
  if (scheduleId != null) {
    requestBody['schedule_id'] = scheduleId;
  }
  if (reqToken != null) {
    requestBody['req_token'] = reqToken;
  }
  if (cardToken != null && cardToken.isNotEmpty) {
    requestBody['card_token'] = cardToken;
  }

  final headers = <String, String>{
    'Content-Type': 'application/json',
  };

  if (kDebugMode) {
    debugPrint('[MobiPay] Session token request to: $checkoutHost/api/v1/session/token');
  }

  try {
    final response = await http.post(
      uri,
      headers: headers,
      body: jsonEncode(requestBody),
    );

    if (response.statusCode == 200) {
      final jsonResponse = jsonDecode(response.body) as Map<String, dynamic>;
      if (jsonResponse.containsKey('token')) {
        final token = jsonResponse['token'] as String;
        return token;
      } else {
        throw Exception('Token not found in response');
      }
    } else {
      final errorBody = jsonDecode(response.body) as Map<String, dynamic>?;
      final errorMessage = errorBody?['error_message'] as String? ??
                         'Failed to get session token';
      throw Exception(errorMessage);
    }
  } catch (e) {
    if (kDebugMode) {
      debugPrint('[MobiPay] Session token exception: $e');
    }
    // Re-throw with clean error message
    if (e is Exception) {
      throw Exception('Error getting session token: ${e.toString().replaceAll('Exception: ', '')}');
    }
    throw Exception('Error getting session token: $e');
  }
}