google-pay / flutter-plugin Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
With Flutter 2.2, the web platform reached a stable release.
Include the integration for Web as part of this plugin with the two providers supported for mobile (Apple Pay and Google Pay).
Hi,
Instead of card payment i want to enable in app gpay for UPI payments(in India). Is it possible?
One alternative to configure payment providers for this plugin is to create a configuration file in JSON format, and reference it in the instantiation of the payment client or the widgets directly.
This configuration is not fully specified for all providers.:
Create a fully specified JSON schema for the parameters, types and values allowed for each provider. The current plan is to use JSON Schema, currently published as a draft IETF tool, and open to other suggestions.
What do you think about updating the dependencies to work with dart 2.12 and Flutter 2?
I think that once this is released, it should be supported in the latest released version.
Migrating the packages to null safety should be straightforward. I am happy to help and submit a PR once the current one is merged 👍
The sooner we migrate, the lesser changes we will need to do.
After adding pay to pubspec.yaml, the deployment is failing with below error
pub-cache/hosted/pub.dartlang.org/pay_android-1.0.1/android/src/main/kotlin/io/flutter/plugins/pay_android/GooglePayHandler.kt: (112, 27): Expecting a parameter declaration
pub-cache/hosted/pub.dartlang.org/pay_android-1.0.1/android/src/main/kotlin/io/flutter/plugins/pay_android/PayMethodCallHandler.kt: (37, 28): Expecting a parameter declaration
pub-cache/hosted/pub.dartlang.org/pay_android-1.0.1/android/src/main/kotlin/io/flutter/plugins/pay_android/PayMethodCallHandler.kt: (53, 52): Expecting a parameter declaration
pub-cache/hosted/pub.dartlang.org/pay_android-1.0.1/android/src/main/kotlin/io/flutter/plugins/pay_android/PayPlugin.kt: (38, 79): Expecting a parameter declaration
pub-cache/hosted/pub.dartlang.org/pay_android-1.0.1/android/src/main/kotlin/io/flutter/plugins/pay_android/PayPlugin.kt: (52, 67): Expecting a parameter declaration
FAILURE: Build failed with an exception.
When i add postalAddress to my payment profile like this:
{
"provider": "apple_pay",
"data": {
"merchantIdentifier": "merchant.mxxxxx",
"displayName": "xxxxx",
"merchantCapabilities": ["3DS", "debit", "credit"],
"supportedNetworks": ["amex", "visa", "discover", "masterCard"],
"countryCode": "DE",
"currencyCode": "EUR",
"requiredBillingContactFields": ["postalAddress"],
"requiredShippingContactFields": ["emailAddress", "name", "postalAddress"],
}
}
the Apple Pay sheet shows and lets me select a shipping address and a payment address.
I use this ApplePayButton:
pay.ApplePayButton(
height: 50,
paymentConfigurationAsset: 'apple_pay_payment_profile.json',
paymentItems: _paymentItems,
style: pay.ApplePayButtonStyle.black,
type: pay.ApplePayButtonType.buy,
margin: const EdgeInsets.only(top: 15.0),
onPaymentResult: onApplePayResult,
loadingIndicator: const Center(
child: CircularProgressIndicator(),
),
The paymentResult in onApplePayResult contains the name, email and other data but no address.
How can i obtain it?
The GooglePayButton widget receives payment configuration through a conceptually immutable parameter: it's recommended that the same configuration that checks whether a user is ready to pay is used to perform the actual payment.
Consider the following:
AFAIK, Both apple and google allows to tweak border radius of the buttons. It would be great to see the buttons having border radius option.
Use the format section in the Flutter style guide as a default strategy to format files in the repository, unless there is supporting rationale that improves readability, comprehension or grouping of core functionality.
Need to handle the state changes like new subscriptions, renewals, Expirations, and Cancellations to ensure that the state is kept in-sync. Is there documentation explaining how we can achieve that using the "pay" package?
Before displaying the Google Pay button, a readiness call is issued to determine whether the user in question can use Google Pay. Most of the times this value does not change. In some situations, the user may leave the app to configure Google Pay and come back once ready, and expect the button to show this time.
Observe on the WidgetsBindingObserver
class to issue the readiness Future
again when the user brings the app back to the foreground (on resumed
)
Right now there is a single method channel that communicates with native code.
On android, canPay returns true if Google Pay is available
On iOS, canPay returns true if Apple Pay Pay is available.
So the result is, if the native wallet is available, both Google Pay and Google Pay are available.
We could:
1. Create a Method channel different for each Wallet and return false in platforms where canPay is not implemented
2. Use one method channel and check the device platform to figure out the wallet.
3. Send the wallet type to the native code, and check if the given wallet is available
In my opinion, the first method is preferred, because we could modularize in packages for different wallets. It would not make sense to check in swift if GooglePay, SamsungPay, or others are supported when we already know.
The second option may work when only using GooglePay for Android and ApplePay for iOs, but it is not scalable, as there are more wallets available and the web supports these two wallets
We need to support dynamic configurations with different countries and currencies, based on in-app-content.
Also, we can't rely on the press-and-pay native-buttons of this plugin, since we sometimes need the payment to start after using another unrelated button. This worked with the now discontinued stripe_payment.
How can I start native payment from code, not button?
How can I feed the pay-client with a custom configuration that is not stored as an asset?
How do I use the paymentResult
to carry out the necessary transactions and send relevant info to my backend ?
Some payment providers supported accept a list of items to show and calculate the total price of the transaction, while others simply take the total price.
Create a lightweight class to hold price information to pass (in the form of a list) to the widget for the price calculation.
The app is working fine in simulator with simulated card but when i running same code in physical devices, then userCanPay(PayProvider.apple_pay) always retruning false.
This issue captures the main characteristics of adding support for payments on iOS through Apple Pay. This is intended as a design foundation (and a discussion if applicable).
Please do feel free to add to this.
Let's use this overarching foundation to plan the addition of Apple Pay, and potential breakdown of the effort.
Hi,
I am getting this weird issue when building:
e: /Applications/flutter/.pub-cache/hosted/pub.dartlang.org/pay_android-1.0.2/android/src/main/kotlin/io/flutter/plugins/pay_android/GooglePayHandler.kt: (112, 27): Expecting a parameter declaration e: /Applications/flutter/.pub-cache/hosted/pub.dartlang.org/pay_android-1.0.2/android/src/main/kotlin/io/flutter/plugins/pay_android/PayMethodCallHandler.kt: (37, 28): Expecting a parameter declaration e: /Applications/flutter/.pub-cache/hosted/pub.dartlang.org/pay_android-1.0.2/android/src/main/kotlin/io/flutter/plugins/pay_android/PayMethodCallHandler.kt: (53, 52): Expecting a parameter declaration e: /Applications/flutter/.pub-cache/hosted/pub.dartlang.org/pay_android-1.0.2/android/src/main/kotlin/io/flutter/plugins/pay_android/PayPlugin.kt: (38, 79): Expecting a parameter declaration e: /Applications/flutter/.pub-cache/hosted/pub.dartlang.org/pay_android-1.0.2/android/src/main/kotlin/io/flutter/plugins/pay_android/PayPlugin.kt: (52, 67): Expecting a parameter declaration
Any advice on how to fix it?
I am getting a WalletMerchantError when making a payment, it's working fine when the environment is set to ##TEST.
WalletMerchantError: Error in loadPaymentData: PaymentDataRequest.allowedPaymentMethods[0].parameters.allowedAuthMethods[0] = MASTERCARD is not a valid enum value for this field.
json
{
"provider": "google_pay",
"data": {
"environment": "PRODUCTION",
"apiVersion": 2,
"apiVersionMinor": 0,
"allowedPaymentMethods": [
{
"type": "CARD",
"tokenizationSpecification": {
"type": "PAYMENT_GATEWAY",
"parameters": {
"gateway": "example",
"gatewayMerchantId": "Merchant id form dashboard"
}
},
"parameters": {
"allowedCardNetworks": [
"VISA",
"MASTERCARD"
],
"allowedAuthMethods": [
"MASTERCARD",
"VISA"
],
"billingAddressRequired": false,
"billingAddressParameters": {
"format": "FULL",
"phoneNumberRequired": true
}
}
}
],
"merchantInfo": {
"merchantId": "Merchant id form dashboard",
"merchantName": "Merchant Name"
},
"transactionInfo": {
"countryCode": "US",
"currencyCode": "USD"
}
}
}
code
void makePayment() async {
Pay _payClient = Pay.withAssets([
'default_payment_profile_google_pay.json',
]);
final _paymentItems = [
PaymentItem(
label: 'Total',
amount: '100',
status: PaymentItemStatus.final_price,
)
];
try {
final result = await _payClient.showPaymentSelector(
provider: PayProvider.google_pay,
paymentItems: _paymentItems,
);
print(result.toString());
} catch (e) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('An error occourred')));
}
}
EDIT:
Tried removing master cart from the json array and reinstalled the app but now it show
c07-16 18:20:14.125 22243 22243 W WalletMerchantError: Error in loadPaymentData: PaymentDataRequest.allowedPaymentMethods[0].parameters.allowedAuthMethods[0] = VISA is not a valid enum value for this field.
When trying to initiate a payment flow via a button, the payment immediately crashes, with no output to the console about what went wrong.
Not sure if its just me or my configuration.
I am basically checking apple pay support on iOS and once thats done, I am opening the payment dialog using showPaymentSelector
After successful payment I get nothing, no data in return.
Map<String, dynamic> data = await _pay.showPaymentSelector(
provider: PayProvider.apply_pay,
items:[......]
);
Here is my code
late Pay _payClient = Pay(
[PaymentConfiguration.fromJsonString(convertGPaymentConfigToString())]);
String convertGPaymentConfigToString() {
return jsonEncode({
"provider": "google_pay",
"data": {
"environment": "TEST",
"apiVersion": 2,
"apiVersionMinor": 0,
"allowedPaymentMethods": [
{
"type": "CARD",
"tokenizationSpecification": {
"type": "PAYMENT_GATEWAY",
"parameters": {
"gateway": "example",
"gatewayMerchantId": "gatewayMerchantId"
}
},
"parameters": {
"allowedCardNetworks": ["VISA", "MASTERCARD"],
"allowedAuthMethods": ["PAN_ONLY", "CRYPTOGRAM_3DS"],
"billingAddressRequired": true,
"billingAddressParameters": {
"format": "FULL",
"phoneNumberRequired": true
}
}
}
],
"merchantInfo": {
"merchantId": "01234567890123456789",
"merchantName": "Example Merchant Name"
},
"transactionInfo": {"countryCode": "US", "currencyCode": "USD"}
}
});
}
_payClient.userCanPay(PayProvider.google_pay) returns false
Can anyone tell me what is wrong in code?
@JlUgia
Right now both PKPaymentButtonType and PKPaymentNetwork support all versions without conditional macro versions (@available). We should add them to allow lower the minimum version of iOS to match the ones supported by Flutter.
We need support for Google pay in Apple devices.
There are countries where Apple pay isn't supported and people use Google pay instead extensively
Especially in countries like India where Google pay is goto payment interface in both android and Apple users than the app provided by the Indian government for UPI transactions
And Google pay is the leading UPI provider in India contributing for more than 50% of the transactions in the country
I am trying to integrate with a payment gateway that requires transactionIdentifier along with paymentData & paymentMethod
Request your support to add it to the Payment Result.
Please find reference below:
https://developer.apple.com/documentation/passkit/pkpaymenttoken/1617003-transactionidentifier
When Android applications using the plugin need to include their own native ends, there's a requirement for them to use at least the same minSdkVersion
and ext.kotlin.version
as the Android side in the plugin.
Confirm this scenario and add explicit guidance in the documentation.
Related to #29.
@domesticmouse, I've seen this issue in other packages as well, are you able to confirm whether this is known and accurate?
I tried to run flutter pub get in flutter-plugin/pay/ but i'm getting this error
Because every version of flutter_test from sdk depends on test_api 0.3.0 and mockito >=4.1.2 <=5.0.0-nullsafety.7 depends on test_ api ^0.2.19-nullsafety, flutter_test from sdk is incompatible with mockito >=4.1.2 <=5.0.0-nullsafety.7. So, because pay depends on both flutter_test any from sdk and mockito ^4.1.3, version solving failed.
Edit: found solution for this issue it is because the version used in pay/pubspec.yaml is mockito: ^4.1.3
which should be updated to mockito: ^5.0.0
Hey I am new at Payment in flutter and I have some simple questions, I am searching for a payment method for a service app (like uber or food delivery).
Can I use this package to implement this kind of payment (service/ product payment) ?
Where I add my billing information for apple and google?
For example in Stripe I have an account with my own api where I add my billing information and check payment status and analytics
After I have configured the app and all the merchantID etc... When and how Apple an google will send my user payments?
Is there a tax like for in app purchase?
Thank you so much.
Seems simple things but I think should be added to package description to help distribute the usage of this package to new adopter like me :)
The Pay
client accepts loading a payment configuration both from an asset stored within the Flutter module, or a JSON string produced at runtime (eg.: loaded from a backend server). This flexibility is not exposed all the way up to the GooglePayButton widget yet.
Include an additional property in the GooglePayButton widget to load the configuration from a JSON string, similar to how the Pay
client already offers. Make sure to control for existence of at least one field using assert
on the init constructor.
Like we have option for card, how can I enable support for UPI payments?
The intention of this plugin is to support as many payment providers as it's useful to developers. Each provider offers diverse forms of presenting information to return results and errors back to the caller, with JSON being a common format.
Let's evaluate how developers typically interact with this information and offer typed structures for those elements or pieces of information that are handled and processed programmatically (eg.: result/error class, display items, etc) and default to a more generic format for chunks of information (eg.: JSON) that are relied to other systems (eg.: backend, PSP).
Launching lib/main.dart on AOSP on IA Emulator in debug mode...
lib/main.dart:1
Note: /Users/ajaylee/development/flutter/.pub-cache/hosted/pub.dartlang.org/local_auth-1.1.6/android/src/main/java/io/flutter/plugins/localauth/LocalAuthPlugin.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
e: /Users/ajaylee/development/flutter/.pub-cache/hosted/pub.dartlang.org/pay_android-1.0.4/android/src/main/kotlin/io/flutter/plugins/pay_android/GooglePayHandler.kt: (172, 27): Expecting a parameter declaration
e: /Users/ajaylee/development/flutter/.pub-cache/hosted/pub.dartlang.org/pay_android-1.0.4/android/src/main/kotlin/io/flutter/plugins/pay_android/PayMethodCallHandler.kt: (40, 28): Expecting a parameter declaration
e: /Users/ajaylee/development/flutter/.pub-cache/hosted/pub.dartlang.org/pay_android-1.0.4/android/src/main/kotlin/io/flutter/plugins/pay_android/PayMethodCallHandler.kt: (56, 52): Expecting a parameter declaration
e: /Users/ajaylee/development/flutter/.pub-cache/hosted/pub.dartlang.org/pay_android-1.0.4/android/src/main/kotlin/io/flutter/plugins/pay_android/PayPlugin.kt: (41, 79): Expecting a parameter declaration
e: /Users/ajaylee/development/flutter/.pub-cache/hosted/pub.dartlang.org/pay_android-1.0.4/android/src/main/kotlin/io/flutter/plugins/pay_android/PayPlugin.kt: (55, 67): Expecting a parameter declaration
FAILURE: Build failed with an exception.
Compilation error. See log for more details
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
BUILD FAILED in 48s
Exception: Gradle task assembleDebug failed with exit code 1
Exited (sigterm)
what to do now
==========================================================================================
sorry for the duplicate
problem has been fixed by changing the min sdk to 19 and kotlin version to 1.4.20 and com.android.tools.build:gradle:4.1.1
Platforms have the potential to accept multiple payment providers.
Having userCanPay
return readiness results for multiple payment configurations and providers at once, avoids unnecessary drawing magic at build time (eg.: suppose a list of payment buttons –Google, Apple and Microsoft Pay– with dividers of 15 of height, if a payment button is not available, and hence it does not draw itself, the upper and lower dividers overlap, creating a blank space of height 30).
Instead, if the available providers are known at build time, developers can choose what buttons to draw and place them inside of the layout of choice, in a more Flutter-natural and expressive way.
Any alternative ideas @socsieng @jamesblasco @Arkangel12 @domesticmouse?
Hello I get the following error when trying to open Apple Pay
Unhandled Exception: PlatformException(paymentError, Failed to present payment controller, null, null)
#0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:581:7)
#1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:158:18)
#2 PayMethodChannel.showPaymentSelector (package:pay_platform_interface/pay_channel.dart:64:27)
#3 _PurchaseScreenState.payment (package:lalamu/pages/purchase/view/purchase_screen.dart:42:33)
I'm using Apple/Google Pay to generate a Stripe's charge, then I'm passing the token to our backend that takes care of the payment process.
Here's the GPay flow:
Inside the google_pay_config.json
we've all infos about Stripe:
"allowedPaymentMethods": [
{
"type": "CARD",
"tokenizationSpecification": {
"type": "PAYMENT_GATEWAY",
"parameters": {
"gateway": "stripe",
"stripe:version": "2018-11-08",
"stripe:publishableKey": "stripe_key"
}
}
]
Then I'm creating all the PaymentItems
, getting a PaymentResult
and finally from PaymentResult
I can get a token to pass to the backend to complete the payment.
final token = paymentResult['paymentMethodData']['tokenizationData']['token'];
final tokenJson = Map.castFrom(json.decode(token));
String tokenId = tokenJson['id'];
How can I obtain that token using Apple Pay since I couldn't find any way to specify the Stripe data inside apple_pay_config.json
?
final res = await _payClient.showPaymentSelector(
provider: Platform.isAndroid ? PayProvider.google_pay : PayProvider.apple_pay,
paymentItems: [
PaymentItem(
amount: amount.toString(),
label: description,
status: PaymentItemStatus.final_price,
type: PaymentItemType.total)
],
);
print("After showPaymentSelector:"); // this line is not called!
showPaymentSelector starts payment flow, if user click back button at this stage no return occurs
how to detect this situation?
I am facing native crash when I am trying to make a payment using google pay and stripe as tokenizer. The error I get is
E/MethodChannel#plugins.flutter.io/pay_channel: Failed to handle method call
java.lang.NullPointerException: Attempt to invoke virtual method 'org.json.JSONObject org.json.JSONObject.putOpt(java.lang.String, java.lang.Object)' on a null object reference
at io.flutter.plugins.pay_android.GooglePayHandler$Companion.buildPaymentProfile(GooglePayHandler.kt:53)
at io.flutter.plugins.pay_android.GooglePayHandler.loadPaymentData(GooglePayHandler.kt:98)
at io.flutter.plugins.pay_android.PayMethodCallHandler.onMethodCall(PayMethodCallHandler.kt:66)
at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)
at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85)
at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:818)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:336)
at android.os.Looper.loop(Looper.java:174)
at android.app.ActivityThread.main(ActivityThread.java:7682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Seems when we actually try to make a payment, there is no transactionInfo
object on the payment profile where as
transactionInfo
How cam I check if Apple Pay or Google Pay has just a card registered and ready to use ? And there is a way to send user to add card to those payment app?
version 1.0.5
E/flutter (26185): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: PlatformException(10, 10: , null, null)
E/flutter (26185): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:597:7)
E/flutter (26185): #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:158:18)
E/flutter (26185):
E/flutter (26185): #2 PayMethodChannel.userCanPay (package:pay_platform_interface/pay_channel.dart:48:12)
E/flutter (26185):
In our case, we don't need users CONTACT and SHIPPING information.
We would like to have the ability to make them hidden/not required during payment.
I've tried to remove requiredShippingContactFields
& requiredBillingContactFields
fields from default_payment_profile_apple_pay.json
but they are still required
I've placed a GooglePayButton but it does not show. Enabling debug paint, you can see that it is very tiny. Setting height and width parameters also do not help.
I get these errors:
E/flutter (14723): #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
E/flutter (14723): #2 new PaymentConfiguration._ (package:pay_platform_interface/core/payment_configuration.dart:55:16)
E/flutter (14723): #3 PaymentConfiguration.fromAsset (package:pay_platform_interface/core/payment_configuration.dart:85:33)
E/flutter (14723): <asynchronous suspension>
E/flutter (14723): #4 Future.wait.<anonymous closure> (dart:async/future.dart)
E/flutter (14723): <asynchronous suspension>
E/flutter (14723): #5 Pay._loadConfigAssets (package:pay/src/pay.dart:45:25)
E/flutter (14723): <asynchronous suspension>
E/flutter (14723):
The brand guidelines of the button encourage developers to remove the button altogether if the paying with the provider in question is not supported or unavailable. The property childOnError
offers implementers a chance to decide what UI to show in case the button can't be displayed.
Come up with a more intuitive name that conveys not only error, but also successful, yet unavailable responses.
Ideas:
replacement
childIfUnavailable
Launching lib\main.dart on sdk gphone x86 arm in debug mode...
lib\main.dart:1
e: C:\Users\faheem\AppData\Local\Pub\Cache\hosted\pub.dartlang.org\pay_android-1.0.1\android\src\main\kotlin\io\flutter\plugins\pay_android\GooglePayHandler.kt: (112, 27): Expecting a parameter declaration
e: C:\Users\faheem\AppData\Local\Pub\Cache\hosted\pub.dartlang.org\pay_android-1.0.1\android\src\main\kotlin\io\flutter\plugins\pay_android\PayMethodCallHandler.kt: (37, 28): Expecting a parameter declaration
e: C:\Users\faheem\AppData\Local\Pub\Cache\hosted\pub.dartlang.org\pay_android-1.0.1\android\src\main\kotlin\io\flutter\plugins\pay_android\PayMethodCallHandler.kt: (53, 52): Expecting a parameter declaration
e: C:\Users\faheem\AppData\Local\Pub\Cache\hosted\pub.dartlang.org\pay_android-1.0.1\android\src\main\kotlin\io\flutter\plugins\pay_android\PayPlugin.kt: (38, 79): Expecting a parameter declaration
e: C:\Users\faheem\AppData\Local\Pub\Cache\hosted\pub.dartlang.org\pay_android-1.0.1\android\src\main\kotlin\io\flutter\plugins\pay_android\PayPlugin.kt: (52, 67): Expecting a parameter declaration
FAILURE: Build failed with an exception.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.