Skip to content

Commit

Permalink
Add support for checking platform pay availability on web
Browse files Browse the repository at this point in the history
* Partially addresses #1122
  • Loading branch information
cornwe19 committed Nov 30, 2023
1 parent 306f6e1 commit 7d8a4ae
Show file tree
Hide file tree
Showing 14 changed files with 1,292 additions and 7 deletions.
8 changes: 6 additions & 2 deletions packages/stripe/lib/src/stripe.dart
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,16 @@ class Stripe {
///
/// The [googlePay] param can be provided to check if platform pay is supported on
/// Google Pay test env or if a payment method is required.
/// The [webPaymentRequestCreateOptions] param can be provided to confirm what
/// if any platform pay options are available on web.
Future<bool> isPlatformPaySupported({
IsGooglePaySupportedParams? googlePay,
PlatformPayWebPaymentRequestCreateOptions? webPaymentRequestCreateOptions,
}) async {
await _awaitForSettings();
final isSupported =
await _platform.isPlatformPaySupported(params: googlePay);
final isSupported = await _platform.isPlatformPaySupported(
params: googlePay,
paymentRequestOptions: webPaymentRequestCreateOptions);

_isPlatformPaySupported ??= ValueNotifier(false);
_isPlatformPaySupported?.value = isSupported;
Expand Down
1 change: 1 addition & 0 deletions packages/stripe_js/lib/src/js/js.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export 'setup_intents/setup_intents.dart';
export 'tokens/tokens.dart';
export 'payment_methods/payment_methods.dart';
export 'payment_intents/payment_intents.dart';
export 'payment_requests/payment_requests.dart';
export 'elements/elements.dart';
export 'core/core.dart';
15 changes: 15 additions & 0 deletions packages/stripe_js/lib/src/js/payment_requests/payment_item.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'package:js/js.dart';

@anonymous
@JS()
abstract class PaymentItem {
external factory PaymentItem({
required num amount,
required String label,
bool pending,
});

external String label;
external num amount;
external bool pending;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import 'package:js/js.dart';
import 'package:stripe_js/stripe_js.dart';

extension PaymentRequestExtension on Stripe {
_JS get _js => this as _JS;

PaymentRequest paymentRequest(
PaymentRequestCreateOptions options,
) {
return PaymentRequest.of(_js.paymentRequest(options));
}
}

class PaymentRequest {
final _JSPaymentRequest _js;

PaymentRequest.of(this._js);

String get id => _js.id;

Future<CanMakePaymentResponse?> canMakePayment() =>
promiseToFuture(_js.canMakePayment());
}

@anonymous
@JS()
abstract class _JS {
external _JSPaymentRequest paymentRequest(
PaymentRequestCreateOptions options,
);
}

@anonymous
@JS()
abstract class _JSPaymentRequest {
external String get id;
external Promise<CanMakePaymentResponse?> canMakePayment();
}

@anonymous
@JS()
abstract class CanMakePaymentResponse {
external bool get applePay;
external bool get googlePay;
external bool get link;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'package:js/js.dart';
import 'package:stripe_js/stripe_js.dart';

@anonymous
@JS()
abstract class PaymentRequestCreateOptions {
@JS("PaymentRequestCreateOptions")
external factory PaymentRequestCreateOptions({
required String country,
required String currency,
required PaymentItem total,
bool requestPayerName,
bool requestPayerEmail,
bool requestPayerPhone,
bool requestShipping,
List<ShippingOption> shippingOptions,
List<String> disableWallets,
});

external String country;
external String currency;
external PaymentItem total;
external bool requestPayerName;
external bool requestPayerEmail;
external bool requestPayerPhone;
external bool requestShipping;
external ShippingOption shippingOptions;
external List<String> disableWallets;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export 'payment_item.dart';
export 'payment_request.dart';
export 'payment_request_creation_options.dart';
export 'shipping_option.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:js/js.dart';

@anonymous
@JS()
abstract class ShippingOption {
external factory ShippingOption({
required String id,
required String label,
required String detail,
required num amount,
});

external String id;
external String label;
external String detail;
external num amount;
}
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ class MethodChannelStripe extends StripePlatform {
@override
Future<bool> isPlatformPaySupported({
IsGooglePaySupportedParams? params,
PlatformPayWebPaymentRequestCreateOptions? paymentRequestOptions,
}) async {
bool? isSupported;
if (params == null) {
Expand Down
118 changes: 117 additions & 1 deletion packages/stripe_platform_interface/lib/src/models/platform_pay.dart
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ class PaymentRequestType with _$PaymentRequestType {
///
/// For example a subscription
const factory PaymentRequestType.recurring({
/// Descirption that you provide to the recurring payment.
/// Description that you provide to the recurring payment.
///
/// Apple will display this in the sheet
required String description,
Expand Down Expand Up @@ -411,3 +411,119 @@ class PlatformPayOrderDetails with _$PlatformPayOrderDetails {
factory PlatformPayOrderDetails.fromJson(Map<String, dynamic> json) =>
_$PlatformPayOrderDetailsFromJson(json);
}

enum PlatformPayWebWalletType {
applePay,
googlePay,
link,
browserCard,
}

@freezed
class PlatformPayWebPaymentRequestCreateOptions with _$PlatformPayWebPaymentRequestCreateOptions {
@JsonSerializable(explicitToJson: true)
const factory PlatformPayWebPaymentRequestCreateOptions({
/// The two-letter country code of your Stripe account (e.g., US).
required String country,

/// Three character currency code (e.g., usd).
required String currency,

/// A PaymentItem object. This PaymentItem is shown to the customer in the browser’s payment interface.
required PlatformPayWebPaymentItem total,

/// An array of PaymentItem objects. These objects are shown as line items in the browser’s payment interface.
/// Note that the sum of the line item amounts does not need to add up to the total amount above.
@Default([])
List<PlatformPayWebPaymentItem> displayItems,

/// By default, the browser‘s payment interface only asks the customer for actual payment information. A customer
/// name can be collected by setting this option to true. This collected name will appears in the PaymentResponse object.
///
/// We highly recommend you collect name as this also results in collection of billing address for Apple Pay.
/// The billing address can be used to perform address verification and block fraudulent payments.
/// For all other payment methods, the billing address is automatically collected when available.
@Default(false)
bool requestPayerName,

/// See the requestPayerName option.
@Default(false)
bool requestPayerEmail,

/// See the requestPayerName option.
@Default(false)
bool requestPayerPhone,

/// Collect shipping address by setting this option to true. The address appears in the PaymentResponse.
///
/// You must also supply a valid [ShippingOptions] to the shippingOptions property. This can be up front at the
/// time stripe.paymentRequest is called, or in response to a shippingaddresschange event using the updateWith callback.
@Default(false)
bool requestShipping,

/// An array of ShippingOption objects. The first shipping option listed appears in the browser payment interface as the default option.
@Default([])
List<PlatformPayWebShippingOption> shippingOptions,

/// An array of wallet strings. Can be one or more of applePay, googlePay, link, and browserCard. Use this option
/// to disable Apple Pay, Google Pay, Link, and/or browser-saved cards.
@Default([])
List<PlatformPayWebWalletType> disableWallets,
}) = _PaymentRequestCreateOptions;

factory PlatformPayWebPaymentRequestCreateOptions.fromJson(Map<String, dynamic> json) =>
_$PlatformPayWebPaymentRequestCreateOptionsFromJson(json);

static const defaultOptions = PlatformPayWebPaymentRequestCreateOptions(
country: 'US',
currency: 'usd',
total: PlatformPayWebPaymentItem(
amount: 0,
label: 'Payment',
),
);
}

@freezed
class PlatformPayWebShippingOption with _$PlatformPayWebShippingOption {
@JsonSerializable(explicitToJson: true)
const factory PlatformPayWebShippingOption({
/// A unique ID you create to keep track of this shipping option. You’ll be told the ID of the selected option
/// on changes and on completion.
required String id,

/// A short label for this shipping option.
required String label,

/// A longer description of this shipping option.
required String detail,

/// The amount to show for this shipping option. If the cost of this shipping option depends on the shipping address
/// the customer enters, listen for the shippingaddresschange event.
required num amount,
}) = _$ShippingOption;

factory PlatformPayWebShippingOption.fromJson(Map<String, dynamic> json) =>
_$PlatformPayWebShippingOptionFromJson(json);
}

@freezed
class PlatformPayWebPaymentItem with _$PlatformPayWebPaymentItem {
@JsonSerializable(explicitToJson: true)
const factory PlatformPayWebPaymentItem({
/// The amount in the currency's subunit (e.g. cents, yen, etc.)
required num amount,

/// A name that the browser shows the customer in the payment interface.
required String label,

/// If you might change this amount later (for example, after you have calculated shipping costs), set this to true.
/// Note that browsers treat this as a hint for how to display things, and not necessarily as something that will
/// prevent submission.
@Default(false)
bool pending,
}) = _$PaymentItem;

factory PlatformPayWebPaymentItem.fromJson(Map<String, dynamic> json) =>
_$PlatformPayWebPaymentItemFromJson(json);
}
Loading

0 comments on commit 7d8a4ae

Please sign in to comment.