confirm method
Future<void>
confirm({
- required DocumentBase<
StripePurchaseModel> purchase, - bool online = true,
- required void builder(
- Uri endpoint,
- Widget webView,
- VoidCallback onClosed
- VoidCallback? onClosed,
- Duration timeout = const Duration(seconds: 15),
Confirm purchase
.
3D Secure authentication of your credit card is performed at this point.
If online
is true
, WebView is displayed by builder
if 3D Secure authentication is enabled.
If online
is false
, you will be notified by email.
onClosed
is called when the WebView displayed by builder
is closed.
purchase
を確定させます。
クレジットカードの3Dセキュア認証をこの時点で行います。
online
がtrue
の場合は、3Dセキュア認証が有効な場合builder
によってWebViewが表示されます。
online
がfalse
の場合は、メールによって通知が届きます。
onClosed
はbuilder
によって表示されたWebViewが閉じられた際に呼び出されます。
Implementation
Future<void> confirm({
required DocumentBase<StripePurchaseModel> purchase,
bool online = true,
required void Function(
Uri endpoint,
Widget webView,
VoidCallback onClosed,
) 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 {
final value = purchase.value;
if (value == null) {
throw Exception(
"Purchase information is empty. Please run [create] method.",
);
}
if (value.error) {
throw Exception(
"There has been an error with your payment. Please check and Refresh your payment information once.",
);
}
if (value.canceled) {
throw Exception("This purchase has already canceled.");
}
if (value.confirm && value.verified) {
throw Exception("This purchase has already confirmed.");
}
var language = value.locale?.split("_").firstOrNull;
if (!StripePurchaseMasamuneAdapter
.primary.threeDSecureOptions.acceptLanguage
.contains(language)) {
language = StripePurchaseMasamuneAdapter
.primary.threeDSecureOptions.acceptLanguage.first;
}
final functionsAdapter =
StripePurchaseMasamuneAdapter.primary.functionsAdapter ??
FunctionsAdapter.primary;
final callbackHost = StripePurchaseMasamuneAdapter
.primary.callbackURLSchemeOrHost
.toString()
.trimQuery()
.trimString("/");
final hostingEndpoint = StripePurchaseMasamuneAdapter
.primary.hostingEndpoint
?.call(language!) ??
callbackHost;
final returnPathOptions =
StripePurchaseMasamuneAdapter.primary.returnPathOptions;
final response = await functionsAdapter.execute(
StripeConfirmPurchaseAction(
userId: userId,
orderId: value.orderId,
returnUrl: online
? Uri.parse(
"$callbackHost/${returnPathOptions.finishedOnConfirmPurchase.trimString("/")}")
: Uri.parse(
"${functionsAdapter.endpoint}/${StripePurchaseMasamuneAdapter.primary.threeDSecureOptions.redirectFunctionPath}"),
failureUrl: Uri.parse(
"$hostingEndpoint/${StripePurchaseMasamuneAdapter.primary.threeDSecureOptions.failurePath}"),
successUrl: Uri.parse(
"$hostingEndpoint/${StripePurchaseMasamuneAdapter.primary.threeDSecureOptions.successPath}"),
),
);
if (response.purchaseId.isEmpty) {
throw Exception("Response is invalid.");
}
bool authenticated = true;
onCompleted() {
if (authenticated) {
internalCompleter?.complete();
internalCompleter = null;
} else {
internalCompleter
?.completeError(Exception("3D Secure authentication failed."));
internalCompleter = null;
}
}
final nextAction = response.nextActionUrl?.toString();
if (nextAction.isNotEmpty) {
final webView = StripeWebview(
response.nextActionUrl!,
shouldOverrideUrlLoading: (url) {
final path = url.trimQuery().replaceAll(callbackHost, "");
if (path ==
"/${returnPathOptions.finishedOnConfirmPurchase.trimString("/")}") {
onClosed?.call();
onCompleted();
return StripeNavigationActionPolicy.cancel;
}
final uri = Uri.parse(url);
if (uri.host == "hooks.stripe.com" &&
uri.queryParameters.containsKey("authenticated")) {
authenticated = uri.queryParameters["authenticated"] == "true";
}
return StripeNavigationActionPolicy.allow;
},
onCloseWindow: () {
onCompleted();
},
);
builder.call(response.nextActionUrl!, webView, onCompleted);
await internalCompleter!.future;
}
await Future.doWhile(() async {
await Future.delayed(const Duration(milliseconds: 100));
await purchase.reload();
return purchase.value != null &&
(!purchase.value!.confirm || !purchase.value!.verified);
}).timeout(timeout);
_completer?.complete();
_completer = null;
internalCompleter?.complete();
internalCompleter = null;
notifyListeners();
} catch (e) {
_completer?.completeError(e);
_completer = null;
internalCompleter?.complete();
internalCompleter = null;
rethrow;
} finally {
_completer?.complete();
_completer = null;
internalCompleter?.complete();
internalCompleter = null;
}
}