Skip to content

Commit

Permalink
Add a required parameter to the GooglePayButton widget with the pay…
Browse files Browse the repository at this point in the history
…ment configuration, so that `allowedPaymentMethods` can be used when rendering the dynamic button
  • Loading branch information
JlUgia committed Jan 17, 2024
1 parent 20ebbf4 commit 576de2f
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 51 deletions.
3 changes: 3 additions & 0 deletions pay/lib/src/widgets/google_pay_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class GooglePayButton extends PayButton {
GooglePayButton({
super.key,
super.buttonProvider = PayProvider.google_pay,
required final PaymentConfiguration paymentConfiguration,
super.onPaymentResult,
required List<PaymentItem> paymentItems,
int cornerRadius = RawGooglePayButton.defaultButtonHeight ~/ 2,
Expand All @@ -51,7 +52,9 @@ class GooglePayButton extends PayButton {
super.loadingIndicator,
}) : assert(width >= RawGooglePayButton.minimumButtonWidth),
assert(height >= RawGooglePayButton.defaultButtonHeight),
super(paymentConfiguration: paymentConfiguration) {
_googlePayButton = RawGooglePayButton(
paymentConfiguration: paymentConfiguration,
cornerRadius: cornerRadius,
style: style,
type: type,
Expand Down
9 changes: 9 additions & 0 deletions pay_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

Update the Google Pay button to support card last 4 digits, and extend configuration capabilities.

### Features

* Introduce the new dynamic button for Google Pay (#110). This view is part of the Google Pay Android SDK, and handles graphics and translations. The component also features the new design for the Google Pay button.
* Add a configuration parameter to change the corner roundness of the button (#187).
* Update minimum supported SDK version to Flutter 3.10/Dart 3.0 (#233).
* Use `flutter_lints` for static checks (#182, #210).

## 1.0.11 (2023-07-31)

* Update dependencies' versions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ internal class PayButtonView(private val context: Context, binaryMessenger: Bina
val cornerRadiusDp = buttonParams["cornerRadius"] as Int
val cornerRadius = (cornerRadiusDp * context.resources.displayMetrics.density).toInt()

val allowedPaymentMethods: JSONArray = JSONArray().put(cardPaymentMethod())
// Parse payment configuration
val payConfiguration = JSONObject(buttonParams["paymentConfiguration"] as String)
val allowedPaymentMethods: JSONArray = payConfiguration["allowedPaymentMethods"] as JSONArray

payButton.initialize(ButtonOptions.newBuilder()
.setButtonTheme(buttonTheme)
.setButtonType(buttonType)
Expand All @@ -70,52 +73,6 @@ internal class PayButtonView(private val context: Context, binaryMessenger: Bina
override fun getView() = payButton

override fun dispose() = Unit

private fun baseCardPaymentMethod(): JSONObject {

val allowedCardNetworks = JSONArray(listOf(
"AMEX",
"DISCOVER",
"JCB",
"MASTERCARD",
"VISA"))

val allowedCardAuthMethods = JSONArray(listOf(
"PAN_ONLY",
"CRYPTOGRAM_3DS"))

return JSONObject().apply {

val parameters = JSONObject().apply {
put("allowedAuthMethods", allowedCardAuthMethods)
put("allowedCardNetworks", allowedCardNetworks)
put("billingAddressRequired", true)
put("billingAddressParameters", JSONObject().apply {
put("format", "FULL")
})
}

put("type", "CARD")
put("parameters", parameters)
}
}

private fun gatewayTokenizationSpecification(): JSONObject {
return JSONObject().apply {
put("type", "PAYMENT_GATEWAY")
put("parameters", JSONObject(mapOf(
"gateway" to "example",
"gatewayMerchantId" to "exampleGatewayMerchantId"
)))
}
}

private fun cardPaymentMethod(): JSONObject {
val cardPaymentMethod = baseCardPaymentMethod()
cardPaymentMethod.put("tokenizationSpecification", gatewayTokenizationSpecification())

return cardPaymentMethod
}
}

class ButtonThemeFactory {
Expand Down
4 changes: 4 additions & 0 deletions pay_android/lib/pay_android.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,9 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:pay_platform_interface/core/payment_configuration.dart';

export 'package:pay_platform_interface/core/payment_configuration.dart'
show PaymentConfiguration;

part 'src/widgets/google_pay_button.dart';
10 changes: 9 additions & 1 deletion pay_android/lib/src/widgets/google_pay_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ enum GooglePayButtonStyle {
/// onPressed: () => print('Button pressed'));
/// ```
class RawGooglePayButton extends StatelessWidget {
/// The payment configuration for the button to show the last 4 digits of a
/// pre-selected card
final PaymentConfiguration _paymentConfiguration;

/// The default width for the Google Pay Button.
static const double minimumButtonWidth = 168;

Expand Down Expand Up @@ -78,12 +82,14 @@ class RawGooglePayButton extends StatelessWidget {
/// Creates a Google Pay button widget with the parameters specified.
RawGooglePayButton({
super.key,
required final PaymentConfiguration paymentConfiguration,
this.onPressed,
this.cornerRadius = defaultButtonHeight ~/ 2,
this.style = GooglePayButtonStyle.dark,
this.type = GooglePayButtonType.buy,
this.gestureRecognizers = const <Factory<OneSequenceGestureRecognizer>>{},
}) : constraints = const BoxConstraints.tightFor(
}) : _paymentConfiguration = paymentConfiguration,
constraints = const BoxConstraints.tightFor(
width: minimumButtonWidth,
height: defaultButtonHeight,
) {
Expand Down Expand Up @@ -120,6 +126,8 @@ class RawGooglePayButton extends StatelessWidget {
'style': style.enumString,
'type': type.enumString,
'cornerRadius': cornerRadius,
'paymentConfiguration':
_paymentConfiguration.rawConfigurationData(),
},
creationParamsCodec: const StandardMessageCodec(),
onFocus: () {
Expand Down
16 changes: 14 additions & 2 deletions pay_android/test/pay_button_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pay_android/pay_android.dart';
import 'package:pay_platform_interface/core/payment_configuration.dart';

const PayProvider _providerGooglePay = PayProvider.google_pay;
final String _payConfigString =
'{"provider": "${_providerGooglePay.toSimpleString()}",'
'"data": { "allowedPaymentMethods": []}}';

void main() {
setUp(() async {});
Expand All @@ -23,7 +29,10 @@ void main() {
testWidgets('defaults to type buy and dark', (WidgetTester tester) async {
await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr,
child: RawGooglePayButton(onPressed: () {}),
child: RawGooglePayButton(
paymentConfiguration:
PaymentConfiguration.fromJsonString(_payConfigString),
onPressed: () {}),
));

expect(
Expand All @@ -40,7 +49,10 @@ void main() {
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: RawGooglePayButton(onPressed: () {}),
child: RawGooglePayButton(
paymentConfiguration:
PaymentConfiguration.fromJsonString(_payConfigString),
onPressed: () {}),
),
),
);
Expand Down
7 changes: 7 additions & 0 deletions pay_ios/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

Bump versions of dependencies and update static analysis tooling.

### Features

* Use `flutter_lints` for static checks (#182, #210).
* Update minimum supported SDK version to Flutter 3.10/Dart 3.0.

## 1.0.9 (2023-07-31)

* Fix typo in public property.
Expand Down
7 changes: 7 additions & 0 deletions pay_platform_interface/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

Bump versions of dependencies and update static analysis tooling.

### Features

* Use `flutter_lints` for static checks (#182, #210).
* Update minimum supported SDK version to Flutter 3.10/Dart 3.0.

## 1.0.3 (2023-01-24)
Populate the configuration in the initializer list to simplify the business logic perception.

Expand Down
2 changes: 1 addition & 1 deletion pay_platform_interface/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The methods in the interface are:
## Payment configuration
The configuration to setup a payment provider is based on a open-ended schema (with provider-specific classes coming soon) with two required properties:
* `provider`: with the target payment provider (eg.: `PayProvider.apple_pay`, `PayProvider.google_pay`).
* `data`: a schemaless object with specific fields for the target payment provider. Take a look at the [test assets folder](https://github.com/google-pay/flutter-plugin/tree/main/pay_platform_interface/test/assets) to see examples configurations.
* `data`: a schemaless object with specific fields for the target payment provider. Take a look at the [test assets folder](https://github.com/google-pay/flutter-plugin/tree/main/pay_platform_interface/test/assets) to see sample configurations.

## Note on breaking changes

Expand Down
9 changes: 9 additions & 0 deletions pay_platform_interface/lib/core/payment_configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class PaymentConfiguration {
/// The configuration parameters for a given payment provider.
final Future<Map<String, dynamic>> _parameters;

/// The raw configuration provided
final String _rawConfigurationData;

/// Creates a [PaymentConfiguration] object with the properties in the map
/// and ensures the necessary fields are present and valid.
PaymentConfiguration._(Map<String, dynamic> configuration)
Expand All @@ -60,6 +63,7 @@ class PaymentConfiguration {
PayProviders.isValidProvider(configuration['provider'] as String)),
provider =
PayProviders.fromString(configuration['provider'] as String)!,
_rawConfigurationData = jsonEncode(configuration['data']),
_parameters = Configurations.extractParameters(configuration);

/// Creates a [PaymentConfiguration] object from the
Expand Down Expand Up @@ -104,6 +108,11 @@ class PaymentConfiguration {
Future<Map<String, dynamic>> parameterMap() async {
return _parameters;
}

/// Returns the raw data in the configuration
String rawConfigurationData() {
return _rawConfigurationData;
}
}

extension PayProviders on PayProvider {
Expand Down

0 comments on commit 576de2f

Please sign in to comment.