create method

Future<void> create({
  1. required String userId,
  2. required void builder(
    1. Uri endpoint,
    2. Widget webView,
    3. VoidCallback onSuccess,
    4. VoidCallback onCancel,
    ),
  3. VoidCallback? onClosed,
  4. Duration timeout = const Duration(seconds: 15),
})

Create a stripe customer (payment account) associated with userId.

Create a screen using the WebView passed from builder.

The onClosed option allows you to specify what to do when the screen is closed.

userIdに関連するストライプのカスタマー(支払いアカウント)を作成します。

builderから渡されるWebViewを利用して画面を作成してください。

onClosedで画面が閉じられた場合の処理を指定することができます。

Implementation

Future<void> create({
  required String userId,
  required void Function(
    Uri endpoint,
    Widget webView,
    VoidCallback onSuccess,
    VoidCallback onCancel,
  ) builder,
  VoidCallback? onClosed,
  Duration timeout = const Duration(seconds: 15),
}) async {
  if (_completer != null) {
    return _completer!.future;
  }
  _completer = Completer<void>();
  Completer<void>? internalCompleter = Completer<void>();
  try {
    if (userId.isEmpty) {
      throw Exception("You are not logged in. Please log in once.");
    }
    final modelQuery = document(userId).modelQuery;
    final userDocument = StripeUserModelDocument(modelQuery);
    final functionsAdapter =
        StripePurchaseMasamuneAdapter.primary.functionsAdapter ??
            FunctionsAdapter.primary;
    final callbackHost = StripePurchaseMasamuneAdapter
        .primary.callbackURLSchemeOrHost
        .toString()
        .trimQuery()
        .trimString("/");
    final returnPathOptions =
        StripePurchaseMasamuneAdapter.primary.returnPathOptions;

    final response = await functionsAdapter.execute(
      StripeCreateCustomerAndPaymentAction(
        userId: userId,
        successUrl: Uri.parse(
            "$callbackHost/${returnPathOptions.successOnCreateCustormerAndPayment.trimString("/")}"),
        cancelUrl: Uri.parse(
            "$callbackHost/${returnPathOptions.cancelOnCreateCustormerAndPayment.trimString("/")}"),
      ),
    );

    if (response.customerId.isEmpty) {
      throw Exception("Response is invalid.");
    }
    onSuccess() {
      internalCompleter?.complete();
      internalCompleter = null;
    }

    onCancel() {
      internalCompleter?.completeError(StripeCancelException());
      internalCompleter = null;
    }

    final webView = StripeWebview(
      response.endpoint,
      shouldOverrideUrlLoading: (url) {
        final path = url.trimQuery().replaceAll(callbackHost, "");
        if (path ==
            "/${returnPathOptions.successOnCreateCustormerAndPayment.trimString("/")}") {
          onClosed?.call();
          onSuccess.call();
          return StripeNavigationActionPolicy.cancel;
        } else if (path ==
            "/${returnPathOptions.cancelOnCreateCustormerAndPayment.trimString("/")}") {
          onClosed?.call();
          onCancel.call();
          return StripeNavigationActionPolicy.cancel;
        }
        return StripeNavigationActionPolicy.allow;
      },
      onCloseWindow: () {
        onCancel.call();
      },
    );
    builder.call(response.endpoint, webView, onSuccess, onCancel);
    await internalCompleter!.future;
    await Future.doWhile(() async {
      await Future.delayed(const Duration(milliseconds: 100));
      await userDocument.reload();
      return userDocument.value?.customerId.isNotEmpty ?? false;
    }).timeout(timeout);
    _completer?.complete();
    _completer = null;
    internalCompleter?.complete();
    internalCompleter = null;
    notifyListeners();
  } catch (e) {
    _completer?.completeError(e);
    _completer = null;
    internalCompleter?.completeError(e);
    internalCompleter = null;
    rethrow;
  } finally {
    _completer?.complete();
    _completer = null;
    internalCompleter?.complete();
    internalCompleter = null;
  }
}