It has passed a while from when Flutter was a "new thing" and it had quite a wild run. One thing did miss however was a pure dart support for paying physical goods but now we have the boringly named "pay" plugin (here's the pub.dev page)! Let's get on with it and let's check how to start integrating payment on our app!
The basics
First thing first we need to create a payment account both from Apple and Google. For Apple we should need to:
- Create a merchant identifier.
- Create a payment processing certificate to encrypt payment information.
For Google Pay we need to
- Sign up to the business console and create an account
We can also use a gateway for our payment, like Stripe. Unfortunately not all services are supported and, also, on iOS some other payment methods can be completely not working at the moment (check out this issue).
Configuration
Done the basics we can then start configuring our client. First we'll obviously need to add our dependency to our .yaml
file.
dependencies:
pay: ^1.0.5
Main configuration is handled by creating a json file inside our assets
folder. It is needed to have 2 separate files, one for Apple Pay and one for Google Pay. If you wish to use only one you can skip the other. You can find full specifications on how your json should be created here for an example and here for all the possible variables (Apple Pay and Google Pay). You can find below a example of a Google Pay json with Stripe configuration:
{
"provider": "google_pay",
"data": {
"environment": [TEST/LIVE],
"apiVersion": 2,
"apiVersionMinor": 0,
"allowedPaymentMethods": [
{
"type": "CARD",
"tokenizationSpecification": {
"type": "PAYMENT_GATEWAY",
"parameters": {
"gateway": "stripe",
"stripe:version": "2018-11-08",
"stripe:publishableKey": [YOUR_STRIPE_PUBLISHABLE KEY]
}
},
"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": "IT",
"currencyCode": "EUR"
}
}
}
Implementation on code
Code implementation is pretty straight-forward. First we need to initalize our Pay
object with the json files.
_payClient = Pay.withAssets(
[
'google_pay_config.json',
'apple_pay_config.json',
],
);
Then we'll have to create our array of payment items (we can also use only one with the total amount we want our user to pay) and then show the payment selector.
var _paymentItems = [
PaymentItem(
label: LABEL,
amount: OUR_AMOUNT,
status: PaymentItemStatus.final_price,
)
];
if (await payClient.userCanPay(PayProvider.google_pay /*Or apple_pay*/)) {
final paymentResult = await payClient.showPaymentSelector(
provider: PayProvider.google_pay, //Or apple_pay
paymentItems: _paymentItems,
);
try {
final token =
paymentResult['paymentMethodData']['tokenizationData']['token'];
final tokenJson = Map.castFrom(json.decode(token));
var tokenId = tokenJson['id'];
//Send token to a server or to Google or Apple for confirmation
} catch (e) {
//An error has occured
}
}
The plugin will automatically show the main UI for our OS and handle all the 3D secure and other boring stuff herself. Be aware that according to your configuration you may not need to check out your payment or obtain the same result object.
You can also use a Pay button directly from the plugin, which will show the native button directly. Refer on the official plugin page for discovering more.
Wrapping all up
Using pay can be not really easy, especially if you need to use a gateway to confirm your payment. Anyway this plugin has just started to show its potential and we are sure that in the near future it will start being absolutely great to use.
Want to check out more great tutorials? Click here!
Top comments (1)
Thank you for such great tuto. It seems we have to do a server side code as well, don't we?