Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for How to Accept Payments in Your Flutter Application
Rapyd profile imageKyle Pollock
Kyle Pollock forRapyd

Posted on • Edited on • Originally published atcommunity.rapyd.net

     

How to Accept Payments in Your Flutter Application

By Rexford A. Nyarko

Technological innovations have made it very easy to own an online shop or e-commerce business and to integrate products or services into websites or mobile apps. One thing you need to ensure if you’re an online seller is that you’re offering your customers or users a range of payment options.

TheRapyd Collect API is a service offered byRapyd that allows you to collect payments from customers online or within your app, including one-time, recurring, subscription, or business-to-business payments.

It provides flexibility for your customers by offering access to almost any payment method in almost any country, without the need to set up or manage extra infrastructure.

In this article, you’ll learn how to integrate payments into a Flutter app using the Rapyd Collect API via their Hosted Checkout Page. The only prerequisite for the integration is having a Rapyd account.

The example app used in this tutorial is a simple Flutter mobile application that allows users to donate money to a cause, which was built using aUI design from dribbble artistEmir Abiyyu.

As your use case might be different, this article focuses mainly on the integration and not the building of the entire app from scratch. The complete source code can be foundon GitHub.

Setting Up Your Rapyd Account

As stated earlier, the only prerequisite for integrating the Collect API into your application is a Rapyd account.

Sign Up

You first need to go through the simple process ofsetting up your Rapyd account. You’ll need to verify your email by clicking on the confirmation link sent to the email address provided and also complete multifactor authentication with a mobile number.

Enable Sandbox Mode

After you create your Rapyd account and log in, you have to enable sandbox mode. This provides a sandbox environment to explore Rapyd’s functions and products, including tests and simulations you can try without altering your account.

To enable the sandbox mode, flip the sandbox switch at the bottom of the main navigation on the left side of the dashboard as shown in this image.

Enabling Sandbox Mode

Access and Secret Keys

To use any of Rapyd's APIs, you’ll need the access and secret keys as part of the authentication credentials. To find these keys, from the navigation menu, go toDevelopers > Credential Details on the left. Copy and save them for use later in this tutorial.

Creating and Customizing a Rapyd Checkout Page

To ensure users have a seamless transition between your website and the checkout page, you should customize your Rapyd checkout page to match the theme of your website. You may want to add your company logo or the app logo and thematic color for the buttons. Rapyd provides basic customizations to help you achieve this. These customizations can be found in the settings menu on the left navigation of the dashboard underBranding.

There are various options to customize the look and feel of your checkout page, andRapyd has an extensive guide to customizations.

For this tutorial, a logo was added, the payment options were changed to remove “bank redirect” and “cash”, a color preference for the buttons to match the mobile app was set, and the wording for the call to action was changed from "Place your order" to "Donate".

Customized Checkout Page (Web View)

The following image is the final mobile view after the changes.

Mobile view of customized checkout page

Creating or Preparing the Flutter App for Integration

If you already have a Flutter application you want to work with, you can skip to the next section. But if you prefer to follow along with the prebuilt dummy for this tutorial, please continue reading.

Clone App

From your terminal or command prompt with Git installed, run the command below to clone the project files from GitHub:

$git clone https://github.com/Rapyd-Samples/flutter-donation
Enter fullscreen modeExit fullscreen mode

Change Branch

The default branch for this repo is thedev branch, which contains the completed code for this tutorial, but to follow along you can switch to thebasic branch, which only contains the basic app code without the Collect API integrated:

$git checkout basic
Enter fullscreen modeExit fullscreen mode

Initial App Run

You can run the application or any supported connected device with the following command:

$flutter run
Enter fullscreen modeExit fullscreen mode

You should see a user interface identical to the one below.

Main Screen

Understanding the Current Basic App

As you can see from the previous screenshots, the app consists of three main screens, the main or home screen, theDetails screen, and theDonate screen.The app is not dynamic or data-driven; it’s just a bunch of widgets created to build the UI as in the artwork referenced earlier. The only functionality here is the ability to navigate between screens.

From the main screen, tapping on the main widget takes you to theDetails screen. TheDetails screen presents more information about the cause. Again, the only functional thing on this screen is theDonate Now button at the bottom, which takes you to theDonate page.

Details Screen

TheDonate screen provides four donation value options, which you can easily select by tapping, or you can directly enter an amount in theEnter Price Manually text box below the options.

Donate Screen

ThePay & Confirm button (currently just capturing the values) will later take you to the checkout screen where you can see the Rapyd Collect API in action; however, the checkout page has not yet been created in this part of the tutorial and is the focus of the next section.

Generating the Rapyd Checkout Page

To start with the integration, you first need to make a basic HTTP POST request to the Collect API to create the checkout page and then display it. In this section, you’ll write the necessary code to make that request.

Creating a Class

You create a directory calledpayment under thelib directory of your project, and in that directory, create a new filerapyd.dart. In the following lines of code, replace the keys with the respective values from your dashboard, and place the code into the file to create a class and declare some constants that are needed:

importdart:convert;Importdart:math;classRapyd{// Declaring variablesfinalString_ACCESS_KEY="YOUR-ACCESS-KEY";finalString_SECRET_KEY="YOUR-SECRET-KEY";finalString_BASEURL="https://sandboxapi.rapyd.net";finaldoubleamount;Rapyd(this.amount);}
Enter fullscreen modeExit fullscreen mode

The constructor of this class requiresamount to be passed to it. This will be the amount selected or typed on theDonate screen of the app.

Adding the Necessary Packages

You need to add the following packages to your app:http for making the request,crypto to access and run some cryptographic algorithms, andconvert for text encoding functions:

  1. Add thehttp package to your application:
$flutter pub add"http";
Enter fullscreen modeExit fullscreen mode
  1. Add thecrypto package to the application:
$flutter pub add"crypto";
Enter fullscreen modeExit fullscreen mode
  1. Add theconvert package:
$flutter pub add"convert";
Enter fullscreen modeExit fullscreen mode
  1. Add the imports for the packages to the top of therapyd.dart file:
import'package:convert/convert.dart';import'package:http/http.dart'ashttp;import'package:crypto/crypto.dart';
Enter fullscreen modeExit fullscreen mode

Generating Random String for Salt

According to the documentation, requests are accompanied by a random eight to sixteen character string containing digits, letters, and special characters. This is achieved with the code below, which you need to paste in the class definition right after the constructor:

//1. Generating random string for each request with specific length as saltString_getRandString(intlen){varvalues=List<int>.generate(len,(i)=>Random.secure().nextInt(256));returnbase64Url.encode(values);}
Enter fullscreen modeExit fullscreen mode

Building the Request Body

The body will hold various key value pairs that will be passed along in the HTTP request and used to configure the checkout page you're creating. You can paste the following code snippet below the previous method:

//2. Generating bodyMap<String,String>_getBody(){return<String,String>{"amount":amount.toString(),"currency":"USD","country":"US","complete_checkout_url":"https://www.rapyd.net/cancel","cancel_checkout_url":"https://www.rapyd.net/cancel"};}
Enter fullscreen modeExit fullscreen mode

Here, you specify theamount,currency, andcountry as required by the API. Two non-required options are also defined,cancel_checkout_url andcomplete_checkout_url, which determine the pages that the user will be redirected to when they either cancel or complete the transaction. You can also define this from the client portal.

Note that there’s a completelist of options that can be specified when creating the checkout page.

Generating the Signature

The Rapyd API documentation provides information about securing requests by signing them using a signature that’s generated by a number of characters, encoding functions, and cryptographic functions.

Below is the entire code snippet on each step to get this working properly:

//3. Generating SignatureString_getSignature(StringhttpMethod,StringurlPath,Stringsalt,Stringtimestamp,StringbodyString){//concatenating string values together before hashing string according to Rapyd documentationStringsigString=httpMethod+urlPath+salt+timestamp+_ACCESS_KEY+_SECRET_KEY+bodyString;//passing the concatenated string through HMAC with the SHA256 algorithmHmachmac=Hmac(sha256,utf8.encode(_SECRET_KEY));Digestdigest=hmac.convert(utf8.encode(sigString));varss=hex.encode(digest.bytes);//base64 encoding the results and returning it.returnbase64UrlEncode(ss.codeUnits);}
Enter fullscreen modeExit fullscreen mode

Building the Headers

The various values generated earlier are put together to build a set of request headers to help authenticate and securely undertake the request in the snippet below:

//4. Generating HeadersMap<String,String>_getHeaders(StringurlEndpoint,{Stringbody=""}){//generate a random string of length 16Stringsalt=_getRandString(16);//calculating the unix timestamp in secondsStringtimestamp=(DateTime.now().toUtc().millisecondsSinceEpoch/1000).round().toString();//generating the signature for the request according to the docsStringsignature=_getSignature("post",urlEndpoint,salt,timestamp,body);//Returning a map containing the headers and generated valuesreturn<String,String>{"access_key":_ACCESS_KEY,"signature":signature,"salt":salt,"timestamp":timestamp,"Content-Type":"application/json",};}
Enter fullscreen modeExit fullscreen mode

Making the Request to Create the Checkout Page

Finally, you write the function to make the HTTP request. When successful, the method is expected to return aMap with the created checkout page details. If the request fails, the function will throw an error with aMap of error details from the API service. Both are used later in this tutorial:

//5. making post requestFuture<Map>createCheckoutPage()async{finalresponseURL=Uri.parse("$_BASEURL/v1/checkout");finalStringbody=jsonEncode(_getBody());//making post request with headers and body.varresponse=awaithttp.post(responseURL,headers:_getHeaders("/v1/checkout",body:body),body:body,);MaprepBody=jsonDecode(response.body)asMap;//return data if request was successfulif(response.statusCode==200){returnrepBody["data"]asMap;}//throw error if request was unsuccessfulthrowrepBody["status"]asMap;}
Enter fullscreen modeExit fullscreen mode

Retrieving and Displaying the Rapyd Checkout Page

After successfully creating the checkout page, you need to display the page. This can be done by allowing the user to complete the process in a web browser on the same device running the application, or you can embed a web view in the application to provide a seamless feel and more control, as well as to keep the user in your app.

Create the CheckoutScreen Widget

In thescreens directory in thelib directory of your project, there’s an empty file calledCheckoutScreen.dart.

In this file, you can use the following snippet to create a stateful widget that accepts an instance of theRapyd class and returns aScaffold widget:

import'package:donation/payment/rapyd.dart';import'package:donation/widgets/back_button.dart';import'package:flutter/material.dart';import'package:webview_flutter/webview_flutter.dart';classCheckOutScreenextendsStatefulWidget{finalRapydrapyd;constCheckOutScreen({super.key,requiredthis.rapyd});@overrideState<StatefulWidget>createState(){return_CheckOutScreenState();}}class_CheckOutScreenStateextendsState<CheckOutScreen>{@overrideWidgetbuild(BuildContextcontext){returnScaffold(resizeToAvoidBottomInset:true,appBar:AppBar(leading:CustomBackButton(),title:constAlign(child:Text("Checkout",textAlign:TextAlign.center,style:TextStyle(color:Colors.black,fontWeight:FontWeight.bold)),),backgroundColor:Colors.white,actions:const[SizedBox(width:55,),],elevation:0,),);}}
Enter fullscreen modeExit fullscreen mode

Initialize Request to Create Checkout Page

In the_CheckoutScreenState, declare a variable of typeFuture<Map> and initialize it by calling thecreateCheckoutPage() method of theRapyd object passed to this widget.

This means that once theCheckoutScreen is launched, the request to create the checkout page is executed and the results are stored in the created checkout page variable. This can be implemented with the following code snippet:

...lateFuture<Map>createdCheckoutPage;@overridevoidinitState(){super.initState();createdCheckoutPage=widget.rapyd.createCheckoutPage();}...
Enter fullscreen modeExit fullscreen mode

Adding Navigation to the Open Checkout Page

Once you've created the basic widgets for the checkout screen, you need to modify the button on theDonateScreen widget to also navigate to theCheckoutScreen widget when clicked, passing on the value to be paid in an instance of theRapyd class as a parameter to theCheckoutScreen widget.

To do this, first add the following lines of imports to thelib/screens/DonateScreen.dart file:

import'package:donation/payment/rapyd.dart';import'package:donation/screens/CheckoutScreen.dart';
Enter fullscreen modeExit fullscreen mode

Next, in the same file, replace theproceed method of theDonateScreen widget class with the code in the following snippet:

voidproceed(context){if(selected==0){selectedAmount=double.parse(controller.text);}Rapydrapyd=Rapyd(selectedAmount);Navigator.push(context,MaterialPageRoute(builder:(context)=>CheckOutScreen(rapyd:rapyd)));}
Enter fullscreen modeExit fullscreen mode

In the same file, you should also modify the definition of theMaterialButton widget for thePay & Confirm button by passing the context to theproceed method call as seen below:

...onPressed:(){proceed(context);},...
Enter fullscreen modeExit fullscreen mode

Using a FutureBuilder

At this point, the users see no indication of the process running to create the checkout page when the checkout screen is launched. Since the API request call may take a few seconds, it’s good practice to display a busy or loading status. You can use a future builder to show the user a progress indicator until that method call completes and returns a result.

The future builder also enables you to show an appropriate widget based on the returned result. For example, if the request is successful, a web page is loaded to continue the process, and if the request is unsuccessful, the user is directed to another widget with an error.

In theCheckoutScreen.dart file, add the following snippet for thebody of theScaffold widget:

body:FutureBuilder(future:createdCheckoutPage,builder:(BuildContextcontext,AsyncSnapshot<dynamic>snapshot){switch(snapshot.connectionState){caseConnectionState.waiting:returnconstCenter(child:CircularProgressIndicator());default:if(snapshot.hasError){returnconstCenter(child:Text('Some error occurred!'));}else{returnText("Success");}}},)
Enter fullscreen modeExit fullscreen mode

Adding the webview_flutter Package

To display a web page within the app without exiting or navigating outside the app, you use a web view plug-in, which can be added by using the following command:

$flutter pub add"webview_flutter"
Enter fullscreen modeExit fullscreen mode

For Android builds, you’re required to set the minimumminSdkVersion inandroid/app/build.gradle to 19, as seen below:

android{defaultConfig{minSdkVersion19//previously: flutter.minSdkVersion}}
Enter fullscreen modeExit fullscreen mode

Displaying Page in a Webview

Now add theWebView widget to display the checkout page by passing theredirect\_url value from the successful response of the request made earlier. This can be done by replacing thereturn Text("Success"); line with the following:

returnWebView(initialUrl:snapshot.data["redirect_url"].toString(),javascriptMode:JavascriptMode.unrestricted,);
Enter fullscreen modeExit fullscreen mode

Returning to the App Donate Page from Webview

A user may decide to complete the payment or cancel the payment. Once they cancel or complete the payment you need to return to theDonateScreen from theCheckoutScreen. To do this, you can use theonPageStarted parameter of theWebView widget to detect changes to the URL during a redirect from the checkout page.

If the URL contains the value of thecancel_checkout_url or thecomplete_checkout_url , the app will exit theCheckoutScreen widget. The value of theonPageStarted parameter should look like the following:

onPageStarted:(url){//Exit webview widget once the current url matches either checkout completed or canceled urlsif(url.contains(snapshot.data["complete_checkout_url"])){Navigator.pop(context);}elseif(url.contains(snapshot.data["cancel_checkout_url"])){Navigator.pop(context);}},
Enter fullscreen modeExit fullscreen mode

Running the App

Now, using either a virtual or physically connected device, you can run the app using the following command:

$flutter run
Enter fullscreen modeExit fullscreen mode

You should now have a functioning app with Rapyd Collect API integrated and working, and a Hosted Checkout Page that looks like the following image.

Completed Working App

Conclusion

In this tutorial, you learned how to accept payments from users in your Flutter app using the Rapyd Collect API. You also learned how to customize your checkout page with elements like your logo, color, and payment options. You saw how to generate the signature and headers needed to make secure and authenticated requests to the Rapyd API.

Finally, you learned how to display the checkout web page within your app and how to exit the web page seamlessly, and return to your app screens.

TheRapyd Collect API is a payment solution that provides a plethora of options for your customers or app users to patronize your products and services across the globe without limitations. Integration is simple, secure, and flexible.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Build Bold.

All the tools, and resources you need in one place to quickly start building and growing your business globally.

More fromRapyd

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp