├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── assets └── example_demo_video.mp4 ├── example ├── .gitignore ├── .metadata ├── README.md ├── analysis_options.yaml ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── example │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable-v21 │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values-night │ │ │ │ └── styles.xml │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h ├── lib │ └── main.dart ├── pubspec.yaml └── test │ └── widget_test.dart ├── lib ├── flutter_bkash.dart └── src │ ├── apis │ ├── create_agreement_api.dart │ ├── models │ │ ├── create_agreement │ │ │ ├── create_agreement_response_model.dart │ │ │ └── execute_agreement_response.dart │ │ ├── pay_with_agreement │ │ │ ├── pay_with_agreement_execute_response_model.dart │ │ │ └── pay_with_agreement_response_model.dart │ │ ├── pay_without_agreement │ │ │ ├── pay_without_agreement_execute_response_model.dart │ │ │ └── pay_without_agreement_response.dart │ │ └── token_response_model.dart │ ├── pay_with_agreement_api.dart │ ├── pay_without_agreement_api.dart │ └── token_api.dart │ ├── bkash_api.dart │ ├── bkash_credentials.dart │ ├── bkash_payment_response.dart │ ├── bkash_payment_status.dart │ ├── flutter_bkash.dart │ ├── flutter_bkash_view.dart │ └── utils │ ├── api_helper.dart │ └── failure.dart ├── pubspec.yaml └── test └── flutter_bkash_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.lock 4 | *.log 5 | *.pyc 6 | *.swp 7 | .DS_Store 8 | .atom/ 9 | .buildlog/ 10 | .history 11 | .svn/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # Visual Studio Code related 20 | .classpath 21 | .project 22 | .settings/ 23 | .vscode/ 24 | .fvm/ 25 | 26 | # Flutter repo-specific 27 | /bin/cache/ 28 | /bin/internal/bootstrap.bat 29 | /bin/internal/bootstrap.sh 30 | /bin/mingit/ 31 | /dev/benchmarks/mega_gallery/ 32 | /dev/bots/.recipe_deps 33 | /dev/bots/android_tools/ 34 | /dev/devicelab/ABresults*.json 35 | /dev/docs/doc/ 36 | /dev/docs/flutter.docs.zip 37 | /dev/docs/lib/ 38 | /dev/docs/pubspec.yaml 39 | /dev/integration_tests/**/xcuserdata 40 | /dev/integration_tests/**/Pods 41 | /packages/flutter/coverage/ 42 | version 43 | analysis_benchmark.json 44 | 45 | # packages file containing multi-root paths 46 | .packages.generated 47 | 48 | # Flutter/Dart/Pub related 49 | **/doc/api/ 50 | .dart_tool/ 51 | .flutter-plugins 52 | .flutter-plugins-dependencies 53 | **/generated_plugin_registrant.dart 54 | .packages 55 | .pub-cache/ 56 | .pub/ 57 | build/ 58 | flutter_*.png 59 | linked_*.ds 60 | unlinked.ds 61 | unlinked_spec.ds 62 | 63 | # Android related 64 | **/android/**/gradle-wrapper.jar 65 | .gradle/ 66 | **/android/captures/ 67 | **/android/gradlew 68 | **/android/gradlew.bat 69 | **/android/local.properties 70 | **/android/**/GeneratedPluginRegistrant.java 71 | **/android/key.properties 72 | *.jks 73 | 74 | # iOS/XCode related 75 | **/ios/**/*.mode1v3 76 | **/ios/**/*.mode2v3 77 | **/ios/**/*.moved-aside 78 | **/ios/**/*.pbxuser 79 | **/ios/**/*.perspectivev3 80 | **/ios/**/*sync/ 81 | **/ios/**/.sconsign.dblite 82 | **/ios/**/.tags* 83 | **/ios/**/.vagrant/ 84 | **/ios/**/DerivedData/ 85 | **/ios/**/Icon? 86 | **/ios/**/Pods/ 87 | **/ios/**/.symlinks/ 88 | **/ios/**/profile 89 | **/ios/**/xcuserdata 90 | **/ios/.generated/ 91 | **/ios/Flutter/.last_build_id 92 | **/ios/Flutter/App.framework 93 | **/ios/Flutter/Flutter.framework 94 | **/ios/Flutter/Flutter.podspec 95 | **/ios/Flutter/Generated.xcconfig 96 | **/ios/Flutter/ephemeral 97 | **/ios/Flutter/app.flx 98 | **/ios/Flutter/app.zip 99 | **/ios/Flutter/flutter_assets/ 100 | **/ios/Flutter/flutter_export_environment.sh 101 | **/ios/ServiceDefinitions.json 102 | **/ios/Runner/GeneratedPluginRegistrant.* 103 | 104 | # macOS 105 | **/Flutter/ephemeral/ 106 | **/Pods/ 107 | **/macos/Flutter/GeneratedPluginRegistrant.swift 108 | **/macos/Flutter/ephemeral 109 | **/xcuserdata/ 110 | 111 | # Windows 112 | **/windows/flutter/generated_plugin_registrant.cc 113 | **/windows/flutter/generated_plugin_registrant.h 114 | 115 | # Coverage 116 | coverage/ 117 | 118 | # Symbols 119 | app.*.symbols 120 | 121 | # Exceptions to above rules. 122 | !**/ios/**/default.mode1v3 123 | !**/ios/**/default.mode2v3 124 | !**/ios/**/default.pbxuser 125 | !**/ios/**/default.perspectivev3 126 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 127 | !/dev/ci/**/Gemfile.lock -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 8 | channel: stable 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.1.0 2 | * initial release. 3 | 4 | ## 0.1.1 5 | * Modified the readme file 6 | * Added code example on more details view 7 | * Pass static analysis 8 | * Support up-to-date dependencies 9 | 10 | ## 0.1.2 11 | * Changed the parameter of BkashPayment 12 | * Added to as isSandbox is true/false 13 | * Modified the README.md and example of code more comment also style of formatting. 14 | 15 | ## 0.1.3 16 | * Modified the README.md 17 | * Flutter formats the code [flutter format .] 18 | 19 | ## 0.2.0 20 | * Modified the README.md 21 | * Added Tokenized API feature 22 | * Changed API of flutter Bkash 23 | * Added some feature 24 | * Pay using bKash without an agreement 25 | * Create a bKash agreement for future payments 26 | * Pay using bKash with an agreement 27 | 28 | ## 0.3.0 29 | * Modified as per new version of bKash API 30 | * Added minor code changes 31 | * Added tokenized api changes 32 | 33 | ## 0.3.1 34 | * Changed documentation 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2022, Codeboxr.com Team 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 |

5 | 6 |

bKash(BD) Mobile Finance Payment Gateway Flutter Package

7 |

8 |

9 | 10 | 11 | [![Pub](https://img.shields.io/pub/v/flutter_bkash.svg)](https://pub.dartlang.org/packages/flutter_bkash) 12 | [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) 13 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)]() [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)]() 14 | [![Open Source Love svg1](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/) 15 | 16 | This is a [Flutter package](https://pub.dartlang.org/packages/flutter_bkash) for [bKash](https://www.bkash.com/) BD Payment Gateway. This package can be used in flutter project. We created this package while working for a project and thought to release for all so that it helps. 17 | 18 | > :warning: Please note that, you have to contact with bKash sales team for any kind of dev or production access keys or tokens. We don't provide any test account or access keys or don't contact us for such 19 | 20 | Check the package in github and also available in flutter/dart package 21 | ## How to use: 22 | Depend on it, Run this command With Flutter: 23 | ``` 24 | $ flutter pub add flutter_bkash 25 | ``` 26 | This will add a line like this to your package's `pubspec.yaml` (and run an implicit **`flutter pub get`**): 27 | ``` 28 | dependencies: 29 | flutter_bkash: ^0.3.1 30 | ``` 31 | Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more. Import it, Now in your Dart code, you can use: 32 | ``` 33 | import 'package:flutter_bkash/flutter_bkash.dart'; 34 | ``` 35 | ## Features 36 | - Pay using bKash without an agreement 37 | - Create a bKash agreement for future payments 38 | - Pay using bKash with an agreement 39 | 40 | ## Usage 41 | Official Link for API documentation and demo checkout 42 | - [bKash API Specifications](https://developer.bka.sh/v1.2.0-beta/reference) 43 | - [bKash Payment Checkout Demo](https://merchantdemo.sandbox.bka.sh/frontend/checkout) 44 | 45 | ### Initialize the `FlutterBkash` instance: 46 | 47 | ***Sandbox*** 48 | ``` 49 | final flutterBkash = FlutterBkash(); 50 | ``` 51 | ***Production*** 52 | ``` 53 | final flutterBkash = FlutterBkash( 54 | credentials: BkashCredentials( 55 | username: "app_username", 56 | password: "app_password", 57 | appKey: "app_key", 58 | appSecret: "app_secret", 59 | isSandbox: false, 60 | ), 61 | ); 62 | ``` 63 | > Make sure to replace the provided credentials with your own bKash sandbox or production credentials depending on your development environment. 64 | 65 | ### Pay without Agreement 66 | To make a payment without an agreement, use the `pay` method: 67 | 68 | ***Request*** 69 | ``` 70 | final result = await flutterBkash.pay( 71 | context: context, // BuildContext context 72 | amount: 100.0, // amount as double 73 | merchantInvoiceNumber: "invoice123", 74 | ); 75 | ``` 76 | ***Response*** 77 | ``` 78 | BkashPaymentResponse( 79 | trxId: AFI60BAC94, 80 | payerReference: , 81 | paymentId: TR0011fd4uZMS1687062024354, 82 | customerMsisdn: 01877722345, 83 | merchantInvoiceNumber: tranId, 84 | _executeTime: 2023-06-18T10:22:31:623 GMT+0600 85 | ) 86 | ``` 87 | ### Create Agreement 88 | To create a new agreement, use the `createAgreement` method: 89 | 90 | ***Request*** 91 | ``` 92 | final result = await flutterBkash.createAgreement(context: context); 93 | ``` 94 | ***Response*** 95 | ``` 96 | BkashAgreementResponse( 97 | payerReference: , 98 | paymentId: TR0000RCHQGmX1687063332607, 99 | customerMsisdn: 01877722345, 100 | agreementId: TokenizedMerchant02P1AIJ7G1687063381235, 101 | _executeTime: 2023-06-18T10:43:01:235 GMT+0600 102 | ) 103 | ``` 104 | ### Pay with Agreement 105 | To make a payment with an existing agreement, use the `payWithAgreement` method: 106 | 107 | ***Request*** 108 | ``` 109 | final result = await flutterBkash.payWithAgreement( 110 | context: context, // BuildContext context 111 | amount: 100.0, // type as double 112 | agreementId: "agreement123", 113 | merchantInvoiceNumber: "invoice123", 114 | ); 115 | ``` 116 | ***Response*** 117 | ``` 118 | BkashPaymentResponse( 119 | trxId: AFI60BAC94, 120 | payerReference: , 121 | paymentId: TR0011fd4uZMS1687062024354, 122 | customerMsisdn: 01877722345, 123 | merchantInvoiceNumber: tranId, 124 | _executeTime: 2023-06-18T10:22:31:623 GMT+0600 125 | ) 126 | ``` 127 | ### Error Handling 128 | The methods mentioned above may throw a `BkashFailure` exception in case of an error. You can catch and handle the exception using a try-catch block: 129 | ``` 130 | try { 131 | // Make a payment or create an agreement 132 | } on BkashFailure catch (e) { 133 | // Handle the error 134 | print(e.message); 135 | } 136 | ``` 137 | 138 | Examples for see the `/example` folder. 139 | 140 | **Here is the example code** [link](https://github.com/codeboxrcodehub/flutter-bkash/blob/master/example/lib/main.dart) 141 | 142 | **Example Video Demo** 143 | 144 |
145 | 146 |
147 | 148 | 149 | ### Importance Notes 150 | - Read the comments in the example of code 151 | - See the documents and demo checkout [bKash API Specifications](https://developer.bka.sh/v1.2.0-beta/reference), [bKash Payment Checkout Demo](https://merchantdemo.sandbox.bka.sh/frontend/checkout) 152 | 153 | 154 | ## Contributing 155 | **Core Maintainer** 156 | - [Md Riadul Islam](https://github.com/rdnasim) 157 | - [ABDULLAH AL MASUM](https://github.com/dev-masum) 158 | 159 | Contributions to the **flutter_bkash** package are welcome. Please note the following guidelines before submitting your pull request. 160 | 161 | - Follow [Effective Dart: Style](https://dart.dev/guides/language/effective-dart/style) coding standards. 162 | - Read bKash API documentations first.Please contact with bKash for their api documentation and sandbox access. 163 | 164 | ## License 165 | 166 | flutter_bkash package is licensed under the [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause). 167 | 168 | Copyright 2023 [Codeboxr.com Team](https://codeboxr.com/team-codeboxr/). We are not affiliated with bKash and don't give any guarantee. 169 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | # Additional information about this file can be found at 4 | # https://dart.dev/guides/language/analysis-options 5 | -------------------------------------------------------------------------------- /assets/example_demo_video.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/assets/example_demo_video.mp4 -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.lock 4 | *.log 5 | *.pyc 6 | *.swp 7 | .DS_Store 8 | .atom/ 9 | .buildlog/ 10 | .history 11 | .svn/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # Visual Studio Code related 20 | .classpath 21 | .project 22 | .settings/ 23 | .vscode/ 24 | 25 | # Flutter repo-specific 26 | /bin/cache/ 27 | /bin/internal/bootstrap.bat 28 | /bin/internal/bootstrap.sh 29 | /bin/mingit/ 30 | /dev/benchmarks/mega_gallery/ 31 | /dev/bots/.recipe_deps 32 | /dev/bots/android_tools/ 33 | /dev/devicelab/ABresults*.json 34 | /dev/docs/doc/ 35 | /dev/docs/flutter.docs.zip 36 | /dev/docs/lib/ 37 | /dev/docs/pubspec.yaml 38 | /dev/integration_tests/**/xcuserdata 39 | /dev/integration_tests/**/Pods 40 | /packages/flutter/coverage/ 41 | version 42 | analysis_benchmark.json 43 | 44 | # packages file containing multi-root paths 45 | .packages.generated 46 | 47 | # Flutter/Dart/Pub related 48 | **/doc/api/ 49 | .dart_tool/ 50 | .flutter-plugins 51 | .flutter-plugins-dependencies 52 | **/generated_plugin_registrant.dart 53 | .packages 54 | .pub-cache/ 55 | .pub/ 56 | build/ 57 | flutter_*.png 58 | linked_*.ds 59 | unlinked.ds 60 | unlinked_spec.ds 61 | 62 | # Android related 63 | **/android/**/gradle-wrapper.jar 64 | .gradle/ 65 | **/android/captures/ 66 | **/android/gradlew 67 | **/android/gradlew.bat 68 | **/android/local.properties 69 | **/android/**/GeneratedPluginRegistrant.java 70 | **/android/key.properties 71 | *.jks 72 | 73 | # iOS/XCode related 74 | **/ios/**/*.mode1v3 75 | **/ios/**/*.mode2v3 76 | **/ios/**/*.moved-aside 77 | **/ios/**/*.pbxuser 78 | **/ios/**/*.perspectivev3 79 | **/ios/**/*sync/ 80 | **/ios/**/.sconsign.dblite 81 | **/ios/**/.tags* 82 | **/ios/**/.vagrant/ 83 | **/ios/**/DerivedData/ 84 | **/ios/**/Icon? 85 | **/ios/**/Pods/ 86 | **/ios/**/.symlinks/ 87 | **/ios/**/profile 88 | **/ios/**/xcuserdata 89 | **/ios/.generated/ 90 | **/ios/Flutter/.last_build_id 91 | **/ios/Flutter/App.framework 92 | **/ios/Flutter/Flutter.framework 93 | **/ios/Flutter/Flutter.podspec 94 | **/ios/Flutter/Generated.xcconfig 95 | **/ios/Flutter/ephemeral 96 | **/ios/Flutter/app.flx 97 | **/ios/Flutter/app.zip 98 | **/ios/Flutter/flutter_assets/ 99 | **/ios/Flutter/flutter_export_environment.sh 100 | **/ios/ServiceDefinitions.json 101 | **/ios/Runner/GeneratedPluginRegistrant.* 102 | 103 | # macOS 104 | **/Flutter/ephemeral/ 105 | **/Pods/ 106 | **/macos/Flutter/GeneratedPluginRegistrant.swift 107 | **/macos/Flutter/ephemeral 108 | **/xcuserdata/ 109 | 110 | # Windows 111 | **/windows/flutter/generated_plugin_registrant.cc 112 | **/windows/flutter/generated_plugin_registrant.h 113 | 114 | # Coverage 115 | coverage/ 116 | 117 | # Symbols 118 | app.*.symbols 119 | 120 | # Exceptions to above rules. 121 | !**/ios/**/default.mode1v3 122 | !**/ios/**/default.mode2v3 123 | !**/ios/**/default.pbxuser 124 | !**/ios/**/default.perspectivev3 125 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 126 | !/dev/ci/**/Gemfile.lock 127 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled. 5 | 6 | version: 7 | revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 17 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 18 | - platform: android 19 | create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 20 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 21 | - platform: ios 22 | create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 23 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 24 | - platform: linux 25 | create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 26 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 27 | - platform: macos 28 | create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 29 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 30 | - platform: web 31 | create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 32 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 33 | - platform: windows 34 | create_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 35 | base_revision: e3c29ec00c9c825c891d75054c63fcc46454dca1 36 | 37 | # User provided section 38 | 39 | # List of Local paths (relative to this file) that should be 40 | # ignored by the migrate tool. 41 | # 42 | # Files that are not part of the templates will be ignored by default. 43 | unmanaged_files: 44 | - 'lib/main.dart' 45 | - 'ios/Runner.xcodeproj/project.pbxproj' 46 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # example 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) 13 | 14 | For help getting started with Flutter development, view the 15 | [online documentation](https://docs.flutter.dev/), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | depend_on_referenced_packages: false 26 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 27 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 28 | 29 | # Additional information about this file can be found at 30 | # https://dart.dev/guides/language/analysis-options 31 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 33 30 | ndkVersion flutter.ndkVersion 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | 37 | kotlinOptions { 38 | jvmTarget = '1.8' 39 | } 40 | 41 | sourceSets { 42 | main.java.srcDirs += 'src/main/kotlin' 43 | } 44 | 45 | defaultConfig { 46 | // Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 47 | applicationId "com.example.example" 48 | // You can update the following values to match your application needs. 49 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. 50 | minSdkVersion 21 51 | targetSdkVersion 32 52 | versionCode flutterVersionCode.toInteger() 53 | versionName flutterVersionName 54 | } 55 | 56 | buildTypes { 57 | release { 58 | // Add your own signing config for the release build. 59 | // Signing with the debug keys for now, so `flutter run --release` works. 60 | signingConfig signingConfigs.debug 61 | } 62 | } 63 | } 64 | 65 | flutter { 66 | source '../..' 67 | } 68 | 69 | dependencies { 70 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 71 | } 72 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 20 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/example/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.6.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.1.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | tasks.register("clean", Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip 6 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '12.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | # target 'RunnerTests' do 36 | # inherit! :search_paths 37 | # end 38 | end 39 | 40 | post_install do |installer| 41 | installer.pods_project.targets.each do |target| 42 | flutter_additional_ios_build_settings(target) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | FCF1198DC0B12EFF9E3F16D9 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49E80F17D2C49BF343E65259 /* Pods_Runner.framework */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXCopyFilesBuildPhase section */ 20 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 21 | isa = PBXCopyFilesBuildPhase; 22 | buildActionMask = 2147483647; 23 | dstPath = ""; 24 | dstSubfolderSpec = 10; 25 | files = ( 26 | ); 27 | name = "Embed Frameworks"; 28 | runOnlyForDeploymentPostprocessing = 0; 29 | }; 30 | /* End PBXCopyFilesBuildPhase section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 34 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 35 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 36 | 49E80F17D2C49BF343E65259 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | 5EEE1F3F32F1E3D3A63B9618 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 38 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 39 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 40 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 41 | 933BD13B0A00CC5838B9EC8F /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 42 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 43 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 44 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 46 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 47 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 48 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 49 | AB3B8A7F94676C8F78C9BD56 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | FCF1198DC0B12EFF9E3F16D9 /* Pods_Runner.framework in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 4909DC94C7DEBF7AE4E13C73 /* Frameworks */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 49E80F17D2C49BF343E65259 /* Pods_Runner.framework */, 68 | ); 69 | name = Frameworks; 70 | sourceTree = ""; 71 | }; 72 | 83438D90C34003D64B2CE0FF /* Pods */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 5EEE1F3F32F1E3D3A63B9618 /* Pods-Runner.debug.xcconfig */, 76 | 933BD13B0A00CC5838B9EC8F /* Pods-Runner.release.xcconfig */, 77 | AB3B8A7F94676C8F78C9BD56 /* Pods-Runner.profile.xcconfig */, 78 | ); 79 | name = Pods; 80 | path = Pods; 81 | sourceTree = ""; 82 | }; 83 | 9740EEB11CF90186004384FC /* Flutter */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 87 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 88 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 89 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 90 | ); 91 | name = Flutter; 92 | sourceTree = ""; 93 | }; 94 | 97C146E51CF9000F007C117D = { 95 | isa = PBXGroup; 96 | children = ( 97 | 9740EEB11CF90186004384FC /* Flutter */, 98 | 97C146F01CF9000F007C117D /* Runner */, 99 | 97C146EF1CF9000F007C117D /* Products */, 100 | 83438D90C34003D64B2CE0FF /* Pods */, 101 | 4909DC94C7DEBF7AE4E13C73 /* Frameworks */, 102 | ); 103 | sourceTree = ""; 104 | }; 105 | 97C146EF1CF9000F007C117D /* Products */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 97C146EE1CF9000F007C117D /* Runner.app */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | 97C146F01CF9000F007C117D /* Runner */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 117 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 118 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 119 | 97C147021CF9000F007C117D /* Info.plist */, 120 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 121 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 122 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 123 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 124 | ); 125 | path = Runner; 126 | sourceTree = ""; 127 | }; 128 | /* End PBXGroup section */ 129 | 130 | /* Begin PBXNativeTarget section */ 131 | 97C146ED1CF9000F007C117D /* Runner */ = { 132 | isa = PBXNativeTarget; 133 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 134 | buildPhases = ( 135 | 05B832C32126C21A0BB18185 /* [CP] Check Pods Manifest.lock */, 136 | 9740EEB61CF901F6004384FC /* Run Script */, 137 | 97C146EA1CF9000F007C117D /* Sources */, 138 | 97C146EB1CF9000F007C117D /* Frameworks */, 139 | 97C146EC1CF9000F007C117D /* Resources */, 140 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 141 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 142 | CC3EE1B8D9D03A8C46F4ED1A /* [CP] Embed Pods Frameworks */, 143 | ); 144 | buildRules = ( 145 | ); 146 | dependencies = ( 147 | ); 148 | name = Runner; 149 | productName = Runner; 150 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 151 | productType = "com.apple.product-type.application"; 152 | }; 153 | /* End PBXNativeTarget section */ 154 | 155 | /* Begin PBXProject section */ 156 | 97C146E61CF9000F007C117D /* Project object */ = { 157 | isa = PBXProject; 158 | attributes = { 159 | LastUpgradeCheck = 1510; 160 | ORGANIZATIONNAME = ""; 161 | TargetAttributes = { 162 | 97C146ED1CF9000F007C117D = { 163 | CreatedOnToolsVersion = 7.3.1; 164 | LastSwiftMigration = 1100; 165 | }; 166 | }; 167 | }; 168 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 169 | compatibilityVersion = "Xcode 9.3"; 170 | developmentRegion = en; 171 | hasScannedForEncodings = 0; 172 | knownRegions = ( 173 | en, 174 | Base, 175 | ); 176 | mainGroup = 97C146E51CF9000F007C117D; 177 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 178 | projectDirPath = ""; 179 | projectRoot = ""; 180 | targets = ( 181 | 97C146ED1CF9000F007C117D /* Runner */, 182 | ); 183 | }; 184 | /* End PBXProject section */ 185 | 186 | /* Begin PBXResourcesBuildPhase section */ 187 | 97C146EC1CF9000F007C117D /* Resources */ = { 188 | isa = PBXResourcesBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 192 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 193 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 194 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | }; 198 | /* End PBXResourcesBuildPhase section */ 199 | 200 | /* Begin PBXShellScriptBuildPhase section */ 201 | 05B832C32126C21A0BB18185 /* [CP] Check Pods Manifest.lock */ = { 202 | isa = PBXShellScriptBuildPhase; 203 | buildActionMask = 2147483647; 204 | files = ( 205 | ); 206 | inputFileListPaths = ( 207 | ); 208 | inputPaths = ( 209 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 210 | "${PODS_ROOT}/Manifest.lock", 211 | ); 212 | name = "[CP] Check Pods Manifest.lock"; 213 | outputFileListPaths = ( 214 | ); 215 | outputPaths = ( 216 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | shellPath = /bin/sh; 220 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 221 | showEnvVarsInLog = 0; 222 | }; 223 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 224 | isa = PBXShellScriptBuildPhase; 225 | alwaysOutOfDate = 1; 226 | buildActionMask = 2147483647; 227 | files = ( 228 | ); 229 | inputPaths = ( 230 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 231 | ); 232 | name = "Thin Binary"; 233 | outputPaths = ( 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | shellPath = /bin/sh; 237 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 238 | }; 239 | 9740EEB61CF901F6004384FC /* Run Script */ = { 240 | isa = PBXShellScriptBuildPhase; 241 | alwaysOutOfDate = 1; 242 | buildActionMask = 2147483647; 243 | files = ( 244 | ); 245 | inputPaths = ( 246 | ); 247 | name = "Run Script"; 248 | outputPaths = ( 249 | ); 250 | runOnlyForDeploymentPostprocessing = 0; 251 | shellPath = /bin/sh; 252 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 253 | }; 254 | CC3EE1B8D9D03A8C46F4ED1A /* [CP] Embed Pods Frameworks */ = { 255 | isa = PBXShellScriptBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | ); 259 | inputFileListPaths = ( 260 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 261 | ); 262 | name = "[CP] Embed Pods Frameworks"; 263 | outputFileListPaths = ( 264 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 265 | ); 266 | runOnlyForDeploymentPostprocessing = 0; 267 | shellPath = /bin/sh; 268 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 269 | showEnvVarsInLog = 0; 270 | }; 271 | /* End PBXShellScriptBuildPhase section */ 272 | 273 | /* Begin PBXSourcesBuildPhase section */ 274 | 97C146EA1CF9000F007C117D /* Sources */ = { 275 | isa = PBXSourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 279 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 280 | ); 281 | runOnlyForDeploymentPostprocessing = 0; 282 | }; 283 | /* End PBXSourcesBuildPhase section */ 284 | 285 | /* Begin PBXVariantGroup section */ 286 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 287 | isa = PBXVariantGroup; 288 | children = ( 289 | 97C146FB1CF9000F007C117D /* Base */, 290 | ); 291 | name = Main.storyboard; 292 | sourceTree = ""; 293 | }; 294 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 295 | isa = PBXVariantGroup; 296 | children = ( 297 | 97C147001CF9000F007C117D /* Base */, 298 | ); 299 | name = LaunchScreen.storyboard; 300 | sourceTree = ""; 301 | }; 302 | /* End PBXVariantGroup section */ 303 | 304 | /* Begin XCBuildConfiguration section */ 305 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | ALWAYS_SEARCH_USER_PATHS = NO; 309 | CLANG_ANALYZER_NONNULL = YES; 310 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 311 | CLANG_CXX_LIBRARY = "libc++"; 312 | CLANG_ENABLE_MODULES = YES; 313 | CLANG_ENABLE_OBJC_ARC = YES; 314 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 315 | CLANG_WARN_BOOL_CONVERSION = YES; 316 | CLANG_WARN_COMMA = YES; 317 | CLANG_WARN_CONSTANT_CONVERSION = YES; 318 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 319 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 320 | CLANG_WARN_EMPTY_BODY = YES; 321 | CLANG_WARN_ENUM_CONVERSION = YES; 322 | CLANG_WARN_INFINITE_RECURSION = YES; 323 | CLANG_WARN_INT_CONVERSION = YES; 324 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 325 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 326 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 327 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 328 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 329 | CLANG_WARN_STRICT_PROTOTYPES = YES; 330 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 331 | CLANG_WARN_UNREACHABLE_CODE = YES; 332 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 333 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 334 | COPY_PHASE_STRIP = NO; 335 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 336 | ENABLE_NS_ASSERTIONS = NO; 337 | ENABLE_STRICT_OBJC_MSGSEND = YES; 338 | GCC_C_LANGUAGE_STANDARD = gnu99; 339 | GCC_NO_COMMON_BLOCKS = YES; 340 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 341 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 342 | GCC_WARN_UNDECLARED_SELECTOR = YES; 343 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 344 | GCC_WARN_UNUSED_FUNCTION = YES; 345 | GCC_WARN_UNUSED_VARIABLE = YES; 346 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 347 | MTL_ENABLE_DEBUG_INFO = NO; 348 | SDKROOT = iphoneos; 349 | SUPPORTED_PLATFORMS = iphoneos; 350 | TARGETED_DEVICE_FAMILY = "1,2"; 351 | VALIDATE_PRODUCT = YES; 352 | }; 353 | name = Profile; 354 | }; 355 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 356 | isa = XCBuildConfiguration; 357 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 358 | buildSettings = { 359 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 360 | CLANG_ENABLE_MODULES = YES; 361 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 362 | ENABLE_BITCODE = NO; 363 | INFOPLIST_FILE = Runner/Info.plist; 364 | LD_RUNPATH_SEARCH_PATHS = ( 365 | "$(inherited)", 366 | "@executable_path/Frameworks", 367 | ); 368 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 369 | PRODUCT_NAME = "$(TARGET_NAME)"; 370 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 371 | SWIFT_VERSION = 5.0; 372 | VERSIONING_SYSTEM = "apple-generic"; 373 | }; 374 | name = Profile; 375 | }; 376 | 97C147031CF9000F007C117D /* Debug */ = { 377 | isa = XCBuildConfiguration; 378 | buildSettings = { 379 | ALWAYS_SEARCH_USER_PATHS = NO; 380 | CLANG_ANALYZER_NONNULL = YES; 381 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 382 | CLANG_CXX_LIBRARY = "libc++"; 383 | CLANG_ENABLE_MODULES = YES; 384 | CLANG_ENABLE_OBJC_ARC = YES; 385 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 386 | CLANG_WARN_BOOL_CONVERSION = YES; 387 | CLANG_WARN_COMMA = YES; 388 | CLANG_WARN_CONSTANT_CONVERSION = YES; 389 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 390 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 391 | CLANG_WARN_EMPTY_BODY = YES; 392 | CLANG_WARN_ENUM_CONVERSION = YES; 393 | CLANG_WARN_INFINITE_RECURSION = YES; 394 | CLANG_WARN_INT_CONVERSION = YES; 395 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 396 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 397 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 398 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 399 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 400 | CLANG_WARN_STRICT_PROTOTYPES = YES; 401 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 402 | CLANG_WARN_UNREACHABLE_CODE = YES; 403 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 404 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 405 | COPY_PHASE_STRIP = NO; 406 | DEBUG_INFORMATION_FORMAT = dwarf; 407 | ENABLE_STRICT_OBJC_MSGSEND = YES; 408 | ENABLE_TESTABILITY = YES; 409 | GCC_C_LANGUAGE_STANDARD = gnu99; 410 | GCC_DYNAMIC_NO_PIC = NO; 411 | GCC_NO_COMMON_BLOCKS = YES; 412 | GCC_OPTIMIZATION_LEVEL = 0; 413 | GCC_PREPROCESSOR_DEFINITIONS = ( 414 | "DEBUG=1", 415 | "$(inherited)", 416 | ); 417 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 418 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 419 | GCC_WARN_UNDECLARED_SELECTOR = YES; 420 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 421 | GCC_WARN_UNUSED_FUNCTION = YES; 422 | GCC_WARN_UNUSED_VARIABLE = YES; 423 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 424 | MTL_ENABLE_DEBUG_INFO = YES; 425 | ONLY_ACTIVE_ARCH = YES; 426 | SDKROOT = iphoneos; 427 | TARGETED_DEVICE_FAMILY = "1,2"; 428 | }; 429 | name = Debug; 430 | }; 431 | 97C147041CF9000F007C117D /* Release */ = { 432 | isa = XCBuildConfiguration; 433 | buildSettings = { 434 | ALWAYS_SEARCH_USER_PATHS = NO; 435 | CLANG_ANALYZER_NONNULL = YES; 436 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 437 | CLANG_CXX_LIBRARY = "libc++"; 438 | CLANG_ENABLE_MODULES = YES; 439 | CLANG_ENABLE_OBJC_ARC = YES; 440 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 441 | CLANG_WARN_BOOL_CONVERSION = YES; 442 | CLANG_WARN_COMMA = YES; 443 | CLANG_WARN_CONSTANT_CONVERSION = YES; 444 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 445 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 446 | CLANG_WARN_EMPTY_BODY = YES; 447 | CLANG_WARN_ENUM_CONVERSION = YES; 448 | CLANG_WARN_INFINITE_RECURSION = YES; 449 | CLANG_WARN_INT_CONVERSION = YES; 450 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 451 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 452 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 453 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 454 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 455 | CLANG_WARN_STRICT_PROTOTYPES = YES; 456 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 457 | CLANG_WARN_UNREACHABLE_CODE = YES; 458 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 459 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 460 | COPY_PHASE_STRIP = NO; 461 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 462 | ENABLE_NS_ASSERTIONS = NO; 463 | ENABLE_STRICT_OBJC_MSGSEND = YES; 464 | GCC_C_LANGUAGE_STANDARD = gnu99; 465 | GCC_NO_COMMON_BLOCKS = YES; 466 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 467 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 468 | GCC_WARN_UNDECLARED_SELECTOR = YES; 469 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 470 | GCC_WARN_UNUSED_FUNCTION = YES; 471 | GCC_WARN_UNUSED_VARIABLE = YES; 472 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 473 | MTL_ENABLE_DEBUG_INFO = NO; 474 | SDKROOT = iphoneos; 475 | SUPPORTED_PLATFORMS = iphoneos; 476 | SWIFT_COMPILATION_MODE = wholemodule; 477 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 478 | TARGETED_DEVICE_FAMILY = "1,2"; 479 | VALIDATE_PRODUCT = YES; 480 | }; 481 | name = Release; 482 | }; 483 | 97C147061CF9000F007C117D /* Debug */ = { 484 | isa = XCBuildConfiguration; 485 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 486 | buildSettings = { 487 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 488 | CLANG_ENABLE_MODULES = YES; 489 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 490 | ENABLE_BITCODE = NO; 491 | INFOPLIST_FILE = Runner/Info.plist; 492 | LD_RUNPATH_SEARCH_PATHS = ( 493 | "$(inherited)", 494 | "@executable_path/Frameworks", 495 | ); 496 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 497 | PRODUCT_NAME = "$(TARGET_NAME)"; 498 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 499 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 500 | SWIFT_VERSION = 5.0; 501 | VERSIONING_SYSTEM = "apple-generic"; 502 | }; 503 | name = Debug; 504 | }; 505 | 97C147071CF9000F007C117D /* Release */ = { 506 | isa = XCBuildConfiguration; 507 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 508 | buildSettings = { 509 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 510 | CLANG_ENABLE_MODULES = YES; 511 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 512 | ENABLE_BITCODE = NO; 513 | INFOPLIST_FILE = Runner/Info.plist; 514 | LD_RUNPATH_SEARCH_PATHS = ( 515 | "$(inherited)", 516 | "@executable_path/Frameworks", 517 | ); 518 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 519 | PRODUCT_NAME = "$(TARGET_NAME)"; 520 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 521 | SWIFT_VERSION = 5.0; 522 | VERSIONING_SYSTEM = "apple-generic"; 523 | }; 524 | name = Release; 525 | }; 526 | /* End XCBuildConfiguration section */ 527 | 528 | /* Begin XCConfigurationList section */ 529 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 530 | isa = XCConfigurationList; 531 | buildConfigurations = ( 532 | 97C147031CF9000F007C117D /* Debug */, 533 | 97C147041CF9000F007C117D /* Release */, 534 | 249021D3217E4FDB00AE95B9 /* Profile */, 535 | ); 536 | defaultConfigurationIsVisible = 0; 537 | defaultConfigurationName = Release; 538 | }; 539 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 540 | isa = XCConfigurationList; 541 | buildConfigurations = ( 542 | 97C147061CF9000F007C117D /* Debug */, 543 | 97C147071CF9000F007C117D /* Release */, 544 | 249021D4217E4FDB00AE95B9 /* Profile */, 545 | ); 546 | defaultConfigurationIsVisible = 0; 547 | defaultConfigurationName = Release; 548 | }; 549 | /* End XCConfigurationList section */ 550 | }; 551 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 552 | } 553 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @main 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeboxrcodehub/flutter-bkash/561934b46da8b7fa25e90c4dfc0d62e9a2b77d65/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | example 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | UIApplicationSupportsIndirectInputEvents 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer' as dev; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_bkash/flutter_bkash.dart'; 4 | 5 | void main() { 6 | // it should be the first line in main method 7 | WidgetsFlutterBinding.ensureInitialized(); 8 | runApp(const MyApp()); 9 | } 10 | 11 | class MyApp extends StatelessWidget { 12 | const MyApp({super.key}); 13 | 14 | // This widget is the root of your application. 15 | @override 16 | Widget build(BuildContext context) { 17 | return MaterialApp( 18 | theme: ThemeData( 19 | primarySwatch: Colors.pink, 20 | visualDensity: VisualDensity.adaptivePlatformDensity, 21 | ), 22 | debugShowCheckedModeBanner: false, 23 | home: const HomePage(title: 'bKash Demo'), 24 | ); 25 | } 26 | } 27 | 28 | /// paymentType: payWithAgreement, payWithoutAgreement, createAgreement 29 | /// enum values: as per your requirement 30 | enum PaymentType { payWithAgreement, payWithoutAgreement, createAgreement } 31 | 32 | class HomePage extends StatefulWidget { 33 | final String title; 34 | 35 | const HomePage({Key? key, required this.title}) : super(key: key); 36 | 37 | @override 38 | HomePageState createState() => HomePageState(); 39 | } 40 | 41 | class HomePageState extends State { 42 | final GlobalKey _scaffoldKey = GlobalKey(); 43 | final TextEditingController _amountController = TextEditingController(); 44 | final TextEditingController _agreementIdController = TextEditingController(); 45 | 46 | bool isLoading = false; 47 | 48 | PaymentType _paymentType = PaymentType.payWithoutAgreement; 49 | 50 | @override 51 | Widget build(BuildContext context) { 52 | return Scaffold( 53 | key: _scaffoldKey, 54 | appBar: AppBar(title: Text(widget.title)), 55 | body: Stack( 56 | children: [ 57 | isLoading 58 | ? const Center( 59 | child: CircularProgressIndicator( 60 | color: Colors.pink, 61 | ), 62 | ) 63 | : SingleChildScrollView( 64 | padding: const EdgeInsets.all(40), 65 | child: Column( 66 | crossAxisAlignment: CrossAxisAlignment.start, 67 | children: [ 68 | if (_paymentType != PaymentType.createAgreement) ...[ 69 | const Text( 70 | 'Amount :', 71 | style: TextStyle(fontWeight: FontWeight.bold), 72 | ), 73 | const SizedBox( 74 | height: 10, 75 | ), 76 | TextFormField( 77 | controller: _amountController, 78 | decoration: const InputDecoration( 79 | hintText: "1240", 80 | contentPadding: EdgeInsets.symmetric( 81 | horizontal: 10, vertical: 0), 82 | border: OutlineInputBorder( 83 | borderRadius: 84 | BorderRadius.all(Radius.circular(5)), 85 | borderSide: BorderSide(color: Colors.grey)), 86 | focusedBorder: OutlineInputBorder( 87 | borderSide: 88 | BorderSide(color: Colors.pink, width: 2.0), 89 | ), 90 | // hintText: reviewTitle, 91 | ), 92 | keyboardType: TextInputType.number, 93 | maxLines: 1, 94 | minLines: 1, 95 | ), 96 | if (_paymentType == PaymentType.payWithAgreement) ...[ 97 | const SizedBox( 98 | height: 20, 99 | ), 100 | const Text( 101 | 'AgreementID :', 102 | style: TextStyle(fontWeight: FontWeight.bold), 103 | ), 104 | const SizedBox( 105 | height: 10, 106 | ), 107 | TextFormField( 108 | controller: _agreementIdController, 109 | decoration: const InputDecoration( 110 | hintText: "User Agreement Id", 111 | contentPadding: EdgeInsets.symmetric( 112 | horizontal: 10, vertical: 0), 113 | border: OutlineInputBorder( 114 | borderRadius: 115 | BorderRadius.all(Radius.circular(5)), 116 | borderSide: BorderSide(color: Colors.grey)), 117 | focusedBorder: OutlineInputBorder( 118 | borderSide: 119 | BorderSide(color: Colors.pink, width: 2.0), 120 | ), 121 | // hintText: reviewTitle, 122 | ), 123 | keyboardType: TextInputType.text, 124 | maxLines: 1, 125 | minLines: 1, 126 | ), 127 | ], 128 | const SizedBox(height: 20.0), 129 | ], 130 | const Divider(), 131 | ListTile( 132 | title: const Text('Pay (without agreement)'), 133 | leading: Radio( 134 | value: PaymentType.payWithoutAgreement, 135 | groupValue: _paymentType, 136 | onChanged: (value) { 137 | setState(() => _paymentType = value!); 138 | }, 139 | ), 140 | dense: true, 141 | ), 142 | ListTile( 143 | title: const Text('Pay with Agreement'), 144 | leading: Radio( 145 | value: PaymentType.payWithAgreement, 146 | groupValue: _paymentType, 147 | onChanged: (value) { 148 | setState(() => _paymentType = value!); 149 | }, 150 | ), 151 | dense: true, 152 | ), 153 | ListTile( 154 | title: const Text('Create agreement'), 155 | leading: Radio( 156 | value: PaymentType.createAgreement, 157 | groupValue: _paymentType, 158 | onChanged: (value) { 159 | setState(() => _paymentType = value!); 160 | }, 161 | ), 162 | dense: true, 163 | ), 164 | const Divider(), 165 | Center( 166 | child: TextButton( 167 | style: TextButton.styleFrom( 168 | shape: RoundedRectangleBorder( 169 | borderRadius: BorderRadius.circular(3.0), 170 | ), 171 | backgroundColor: Colors.pink), 172 | child: const Text( 173 | "Checkout", 174 | style: TextStyle(color: Colors.white), 175 | ), 176 | onPressed: () async { 177 | setState(() { 178 | isLoading = true; 179 | }); 180 | 181 | /// create an instance of FlutterBkash 182 | final flutterBkash = 183 | FlutterBkash(logResponse: true); 184 | 185 | /// if the payment type is createAgreement 186 | if (_paymentType == PaymentType.createAgreement) { 187 | try { 188 | // remove focus from TextField to hide keyboard 189 | FocusManager.instance.primaryFocus?.unfocus(); 190 | 191 | /// call createAgreement method to create an agreement as parameter pass the context 192 | final result = await flutterBkash 193 | .createAgreement(context: context); 194 | 195 | /// show the log 196 | dev.log(result.toString()); 197 | 198 | /// show the snack-bar 199 | _showSnackbar( 200 | "(Success) AgreementId: ${result.agreementId}"); 201 | } on BkashFailure catch (e, st) { 202 | /// if any error occurred then show the log 203 | dev.log(e.message, error: e, stackTrace: st); 204 | 205 | /// show the snack-bar 206 | _showSnackbar(e.message); 207 | } catch (e, st) { 208 | /// if any error occurred then show the log 209 | dev.log("Something went wrong", 210 | error: e, stackTrace: st); 211 | 212 | /// show the snack-bar 213 | _showSnackbar("Something went wrong"); 214 | } 215 | setState(() { 216 | isLoading = false; 217 | }); 218 | return; 219 | } 220 | 221 | /// if the payment type is payWithoutAgreement 222 | if (_paymentType == 223 | PaymentType.payWithoutAgreement) { 224 | final amount = _amountController.text.trim(); 225 | 226 | if (amount.isEmpty) { 227 | // if the amount is empty then show the snack-bar 228 | ScaffoldMessenger.of(context).showSnackBar( 229 | const SnackBar( 230 | content: Text( 231 | "Amount is empty. Without amount you can't pay. Try again"))); 232 | setState(() { 233 | isLoading = false; 234 | }); 235 | return; 236 | } 237 | 238 | /// remove focus from TextField to hide keyboard 239 | FocusManager.instance.primaryFocus?.unfocus(); 240 | 241 | /// Goto BkashPayment page & pass the params 242 | try { 243 | /// call pay method to pay without agreement as parameter pass the context, amount, merchantInvoiceNumber 244 | final result = await flutterBkash.pay( 245 | context: context, 246 | // need the context as BuildContext 247 | amount: double.parse(amount), 248 | // need it double type 249 | merchantInvoiceNumber: "tranId", 250 | ); 251 | 252 | /// if the payment is success then show the log 253 | dev.log(result.toString()); 254 | 255 | /// if the payment is success then show the snack-bar 256 | _showSnackbar( 257 | "(Success) tranId: ${result.trxId}"); 258 | } on BkashFailure catch (e, st) { 259 | /// if something went wrong then show the log 260 | dev.log(e.message, error: e, stackTrace: st); 261 | 262 | /// if something went wrong then show the snack-bar 263 | _showSnackbar(e.message); 264 | } catch (e, st) { 265 | /// if something went wrong then show the log 266 | dev.log("Something went wrong", 267 | error: e, stackTrace: st); 268 | 269 | /// if something went wrong then show the snack-bar 270 | _showSnackbar("Something went wrong"); 271 | } 272 | setState(() { 273 | isLoading = false; 274 | }); 275 | return; 276 | } 277 | 278 | /// if the payment type is payWithAgreement 279 | if (_paymentType == PaymentType.payWithAgreement) { 280 | /// amount & agreementId is required 281 | final amount = _amountController.text.trim(); 282 | final agreementId = 283 | _agreementIdController.text.trim(); 284 | 285 | /// if the amount is empty then show the snack-bar 286 | if (amount.isEmpty) { 287 | // if the amount is empty then show the snack-bar 288 | ScaffoldMessenger.of(context).showSnackBar( 289 | const SnackBar( 290 | content: Text( 291 | "Amount is empty. Without amount you can't pay. Try again"))); 292 | setState(() { 293 | isLoading = false; 294 | }); 295 | return; 296 | } 297 | 298 | /// is the agreementId is empty then show the snack-bar 299 | if (agreementId.isEmpty) { 300 | // if the agreementId is empty then show the snack-bar 301 | ScaffoldMessenger.of(context).showSnackBar( 302 | const SnackBar( 303 | content: Text( 304 | "AgreementId is empty. Without AgreementId you can't pay. Try again"))); 305 | setState(() { 306 | isLoading = false; 307 | }); 308 | return; 309 | } 310 | 311 | /// remove focus from TextField to hide keyboard 312 | FocusManager.instance.primaryFocus?.unfocus(); 313 | 314 | /// Goto BkashPayment page & pass the params 315 | try { 316 | /// call payWithAgreement method to pay with agreement as parameter pass the context, amount, agreementId, marchentInvoiceNumber 317 | final result = 318 | await flutterBkash.payWithAgreement( 319 | context: context, 320 | amount: double.parse(amount), 321 | agreementId: agreementId, 322 | marchentInvoiceNumber: 323 | "merchantInvoiceNumber", 324 | ); 325 | 326 | /// print the result 327 | dev.log(result.toString()); 328 | 329 | /// show the snack-bar with success message 330 | _showSnackbar( 331 | "(Success) tranId: ${result.trxId}"); 332 | } on BkashFailure catch (e, st) { 333 | /// print the error message & stackTrace 334 | dev.log(e.message, error: e, stackTrace: st); 335 | _showSnackbar(e.message); 336 | } catch (e, st) { 337 | /// print the error message & stackTrace 338 | dev.log("Something went wrong", 339 | error: e, stackTrace: st); 340 | 341 | /// show the snack-bar with error message 342 | _showSnackbar("Something went wrong"); 343 | } 344 | setState(() { 345 | isLoading = false; 346 | }); 347 | return; 348 | } 349 | }, 350 | ), 351 | ) 352 | ], 353 | ), 354 | ), 355 | ], 356 | ), 357 | ); 358 | } 359 | 360 | /// show snack-bar with message 361 | void _showSnackbar(String message) => ScaffoldMessenger.of(context) 362 | ..hideCurrentSnackBar() 363 | ..showSnackBar(SnackBar(content: Text(message))); 364 | } 365 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | description: A new Flutter project. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `flutter pub publish`. This is preferred for private packages. 6 | publish_to: "none" # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | # In Windows, build-name is used as the major, minor, and patch parts 19 | # of the product and file versions while build-number is used as the build suffix. 20 | version: 1.0.0+1 21 | 22 | environment: 23 | sdk: ">=2.18.1 <3.0.0" 24 | 25 | # Dependencies specify other packages that your package needs in order to work. 26 | # To automatically upgrade your package dependencies to the latest versions 27 | # consider running `flutter pub upgrade --major-versions`. Alternatively, 28 | # dependencies can be manually updated by changing the version numbers below to 29 | # the latest version available on pub.dev. To see which dependencies have newer 30 | # versions available, run `flutter pub outdated`. 31 | dependencies: 32 | flutter: 33 | sdk: flutter 34 | 35 | # The following adds the Cupertino Icons font to your application. 36 | # Use with the CupertinoIcons class for iOS style icons. 37 | cupertino_icons: ^1.0.2 38 | 39 | dev_dependencies: 40 | flutter_test: 41 | sdk: flutter 42 | 43 | flutter_bkash: 44 | path: ../ 45 | # The "flutter_lints" package below contains a set of recommended lints to 46 | # encourage good coding practices. The lint set provided by the package is 47 | # activated in the `analysis_options.yaml` file located at the root of your 48 | # package. See that file for information about deactivating specific lint 49 | # rules and activating additional ones. 50 | flutter_lints: ^2.0.0 51 | 52 | # For information on the generic Dart part of this file, see the 53 | # following page: https://dart.dev/tools/pub/pubspec 54 | 55 | # The following section is specific to Flutter packages. 56 | flutter: 57 | # The following line ensures that the Material Icons font is 58 | # included with your application, so that you can use the icons in 59 | # the material Icons class. 60 | uses-material-design: true 61 | 62 | # To add assets to your application, add an assets section, like this: 63 | # assets: 64 | # - images/a_dot_burr.jpeg 65 | # - images/a_dot_ham.jpeg 66 | 67 | # An image asset can refer to one or more resolution-specific "variants", see 68 | # https://flutter.dev/assets-and-images/#resolution-aware 69 | 70 | # For details regarding adding assets from package dependencies, see 71 | # https://flutter.dev/assets-and-images/#from-packages 72 | 73 | # To add custom fonts to your application, add a fonts section here, 74 | # in this "flutter" section. Each entry in this list should have a 75 | # "family" key with the font family name, and a "fonts" key with a 76 | # list giving the asset and other descriptors for the font. For 77 | # example: 78 | # fonts: 79 | # - family: Schyler 80 | # fonts: 81 | # - asset: fonts/Schyler-Regular.ttf 82 | # - asset: fonts/Schyler-Italic.ttf 83 | # style: italic 84 | # - family: Trajan Pro 85 | # fonts: 86 | # - asset: fonts/TrajanPro.ttf 87 | # - asset: fonts/TrajanPro_Bold.ttf 88 | # weight: 700 89 | # 90 | # For details regarding fonts from package dependencies, 91 | # see https://flutter.dev/custom-fonts/#from-packages 92 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility in the flutter_test package. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:example/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(const MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /lib/flutter_bkash.dart: -------------------------------------------------------------------------------- 1 | library flutter_bkash; 2 | 3 | export 'src/flutter_bkash.dart'; 4 | export 'src/bkash_credentials.dart'; 5 | export 'src/utils/failure.dart'; 6 | export 'src/bkash_api.dart'; 7 | -------------------------------------------------------------------------------- /lib/src/apis/create_agreement_api.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:fpdart/fpdart.dart'; 4 | import 'package:http/http.dart' as http; 5 | 6 | import '../bkash_credentials.dart'; 7 | import '../utils/api_helper.dart'; 8 | import '../utils/failure.dart'; 9 | import 'models/create_agreement/create_agreement_response_model.dart'; 10 | import 'models/create_agreement/execute_agreement_response.dart'; 11 | 12 | class CreateAgreementApi with ApiHelper { 13 | final BkashCredentials _bkashCredentials; 14 | final bool logResponse; 15 | 16 | late String _baseUrl; 17 | 18 | CreateAgreementApi( 19 | this._bkashCredentials, { 20 | required this.logResponse, 21 | }) { 22 | _baseUrl = 23 | "https://tokenized.${_bkashCredentials.isSandbox ? "sandbox" : "pay"}.bka.sh/v1.2.0-beta"; 24 | } 25 | 26 | Future> createAgreement({ 27 | required String idToken, 28 | required String payerReference, 29 | }) async { 30 | final headers = { 31 | "accept": 'application/json', 32 | "Authorization": idToken, 33 | "X-APP-Key": _bkashCredentials.appKey, 34 | 'content-type': 'application/json' 35 | }; 36 | final body = { 37 | "mode": '0000', 38 | "payerReference": payerReference, 39 | "callbackURL": 'https://example.com/', 40 | }; 41 | 42 | final data = await networkCallHelper( 43 | logResponse: logResponse, 44 | function: () => http.post( 45 | Uri.parse("$_baseUrl/tokenized/checkout/create"), 46 | headers: headers, 47 | body: json.encode(body), 48 | ), 49 | ); 50 | 51 | return data.fold( 52 | (l) => left(l), 53 | (r) => right(CreateAgreementResponseModel.fromMap(r)), 54 | ); 55 | } 56 | 57 | Future> 58 | executeCreateAgreement({ 59 | required String paymentId, 60 | required String idToken, 61 | }) async { 62 | final headers = { 63 | "accept": 'application/json', 64 | "Authorization": idToken, 65 | "X-APP-Key": _bkashCredentials.appKey, 66 | 'content-type': 'application/json' 67 | }; 68 | final body = { 69 | "paymentID": paymentId, 70 | }; 71 | final data = await networkCallHelper( 72 | logResponse: logResponse, 73 | function: () => http.post( 74 | Uri.parse("$_baseUrl/tokenized/checkout/execute"), 75 | headers: headers, 76 | body: json.encode(body), 77 | )); 78 | 79 | return data.fold( 80 | (l) => left(l), 81 | (r) => right(ExecuteAgreementResponse.fromMap(r)), 82 | ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/src/apis/models/create_agreement/create_agreement_response_model.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | class CreateAgreementResponseModel { 4 | final String statusCode; 5 | final String statusMessage; 6 | final String paymentID; 7 | final String bkashURL; 8 | final String callbackURL; 9 | final String successCallbackURL; 10 | final String failureCallbackURL; 11 | final String cancelledCallbackURL; 12 | final String payerReference; 13 | final String agreementStatus; 14 | final String agreementCreateTime; 15 | 16 | const CreateAgreementResponseModel({ 17 | required this.statusCode, 18 | required this.statusMessage, 19 | required this.paymentID, 20 | required this.bkashURL, 21 | required this.callbackURL, 22 | required this.successCallbackURL, 23 | required this.failureCallbackURL, 24 | required this.cancelledCallbackURL, 25 | required this.payerReference, 26 | required this.agreementStatus, 27 | required this.agreementCreateTime, 28 | }); 29 | 30 | CreateAgreementResponseModel copyWith({ 31 | String? statusCode, 32 | String? statusMessage, 33 | String? paymentID, 34 | String? bkashURL, 35 | String? callbackURL, 36 | String? successCallbackURL, 37 | String? failureCallbackURL, 38 | String? cancelledCallbackURL, 39 | String? payerReference, 40 | String? agreementStatus, 41 | String? agreementCreateTime, 42 | }) { 43 | return CreateAgreementResponseModel( 44 | statusCode: statusCode ?? this.statusCode, 45 | statusMessage: statusMessage ?? this.statusMessage, 46 | paymentID: paymentID ?? this.paymentID, 47 | bkashURL: bkashURL ?? this.bkashURL, 48 | callbackURL: callbackURL ?? this.callbackURL, 49 | successCallbackURL: successCallbackURL ?? this.successCallbackURL, 50 | failureCallbackURL: failureCallbackURL ?? this.failureCallbackURL, 51 | cancelledCallbackURL: cancelledCallbackURL ?? this.cancelledCallbackURL, 52 | payerReference: payerReference ?? this.payerReference, 53 | agreementStatus: agreementStatus ?? this.agreementStatus, 54 | agreementCreateTime: agreementCreateTime ?? this.agreementCreateTime, 55 | ); 56 | } 57 | 58 | Map toMap() { 59 | return { 60 | 'statusCode': statusCode, 61 | 'statusMessage': statusMessage, 62 | 'paymentID': paymentID, 63 | 'bkashURL': bkashURL, 64 | 'callbackURL': callbackURL, 65 | 'successCallbackURL': successCallbackURL, 66 | 'failureCallbackURL': failureCallbackURL, 67 | 'cancelledCallbackURL': cancelledCallbackURL, 68 | 'payerReference': payerReference, 69 | 'agreementStatus': agreementStatus, 70 | 'agreementCreateTime': agreementCreateTime, 71 | }; 72 | } 73 | 74 | factory CreateAgreementResponseModel.fromMap(Map map) { 75 | return CreateAgreementResponseModel( 76 | statusCode: map['statusCode'] as String? ?? "", 77 | statusMessage: map['statusMessage'] as String? ?? "", 78 | paymentID: map['paymentID'] as String? ?? "", 79 | bkashURL: map['bkashURL'] as String? ?? "", 80 | callbackURL: map['callbackURL'] as String? ?? "", 81 | successCallbackURL: map['successCallbackURL'] as String? ?? "", 82 | failureCallbackURL: map['failureCallbackURL'] as String? ?? "", 83 | cancelledCallbackURL: map['cancelledCallbackURL'] as String? ?? "", 84 | payerReference: map['payerReference'] as String? ?? "", 85 | agreementStatus: map['agreementStatus'] as String? ?? "", 86 | agreementCreateTime: map['agreementCreateTime'] as String? ?? "", 87 | ); 88 | } 89 | 90 | String toJson() => json.encode(toMap()); 91 | 92 | factory CreateAgreementResponseModel.fromJson(String source) => 93 | CreateAgreementResponseModel.fromMap( 94 | json.decode(source) as Map); 95 | 96 | @override 97 | String toString() { 98 | return 'AgreementResponseModel(statusCode: $statusCode, statusMessage: $statusMessage, paymentID: $paymentID, bkashURL: $bkashURL, callbackURL: $callbackURL, successCallbackURL: $successCallbackURL, failureCallbackURL: $failureCallbackURL, cancelledCallbackURL: $cancelledCallbackURL, payerReference: $payerReference, agreementStatus: $agreementStatus, agreementCreateTime: $agreementCreateTime)'; 99 | } 100 | 101 | @override 102 | bool operator ==(covariant CreateAgreementResponseModel other) { 103 | if (identical(this, other)) return true; 104 | 105 | return other.statusCode == statusCode && 106 | other.statusMessage == statusMessage && 107 | other.paymentID == paymentID && 108 | other.bkashURL == bkashURL && 109 | other.callbackURL == callbackURL && 110 | other.successCallbackURL == successCallbackURL && 111 | other.failureCallbackURL == failureCallbackURL && 112 | other.cancelledCallbackURL == cancelledCallbackURL && 113 | other.payerReference == payerReference && 114 | other.agreementStatus == agreementStatus && 115 | other.agreementCreateTime == agreementCreateTime; 116 | } 117 | 118 | @override 119 | int get hashCode { 120 | return statusCode.hashCode ^ 121 | statusMessage.hashCode ^ 122 | paymentID.hashCode ^ 123 | bkashURL.hashCode ^ 124 | callbackURL.hashCode ^ 125 | successCallbackURL.hashCode ^ 126 | failureCallbackURL.hashCode ^ 127 | cancelledCallbackURL.hashCode ^ 128 | payerReference.hashCode ^ 129 | agreementStatus.hashCode ^ 130 | agreementCreateTime.hashCode; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /lib/src/apis/models/create_agreement/execute_agreement_response.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'dart:convert'; 3 | 4 | class ExecuteAgreementResponse { 5 | final String statusCode; 6 | final String statusMessage; 7 | final String paymentID; 8 | final String agreementID; 9 | final String payerReference; 10 | final String agreementExecuteTime; 11 | final String agreementStatus; 12 | final String customerMsisdn; 13 | 14 | ExecuteAgreementResponse({ 15 | required this.statusCode, 16 | required this.statusMessage, 17 | required this.paymentID, 18 | required this.agreementID, 19 | required this.payerReference, 20 | required this.agreementExecuteTime, 21 | required this.agreementStatus, 22 | required this.customerMsisdn, 23 | }); 24 | 25 | ExecuteAgreementResponse copyWith({ 26 | String? statusCode, 27 | String? statusMessage, 28 | String? paymentID, 29 | String? agreementID, 30 | String? payerReference, 31 | String? agreementExecuteTime, 32 | String? agreementStatus, 33 | String? customerMsisdn, 34 | }) { 35 | return ExecuteAgreementResponse( 36 | statusCode: statusCode ?? this.statusCode, 37 | statusMessage: statusMessage ?? this.statusMessage, 38 | paymentID: paymentID ?? this.paymentID, 39 | agreementID: agreementID ?? this.agreementID, 40 | payerReference: payerReference ?? this.payerReference, 41 | agreementExecuteTime: agreementExecuteTime ?? this.agreementExecuteTime, 42 | agreementStatus: agreementStatus ?? this.agreementStatus, 43 | customerMsisdn: customerMsisdn ?? this.customerMsisdn, 44 | ); 45 | } 46 | 47 | Map toMap() { 48 | return { 49 | 'statusCode': statusCode, 50 | 'statusMessage': statusMessage, 51 | 'paymentID': paymentID, 52 | 'agreementID': agreementID, 53 | 'payerReference': payerReference, 54 | 'agreementExecuteTime': agreementExecuteTime, 55 | 'agreementStatus': agreementStatus, 56 | 'customerMsisdn': customerMsisdn, 57 | }; 58 | } 59 | 60 | factory ExecuteAgreementResponse.fromMap(Map map) { 61 | return ExecuteAgreementResponse( 62 | statusCode: map['statusCode'] as String? ?? "", 63 | statusMessage: map['statusMessage'] as String? ?? "", 64 | paymentID: map['paymentID'] as String? ?? "", 65 | agreementID: map['agreementID'] as String? ?? "", 66 | payerReference: map['payerReference'] as String? ?? "", 67 | agreementExecuteTime: map['agreementExecuteTime'] as String? ?? "", 68 | agreementStatus: map['agreementStatus'] as String? ?? "", 69 | customerMsisdn: map['customerMsisdn'] as String? ?? "", 70 | ); 71 | } 72 | 73 | String toJson() => json.encode(toMap()); 74 | 75 | factory ExecuteAgreementResponse.fromJson(String source) => 76 | ExecuteAgreementResponse.fromMap( 77 | json.decode(source) as Map); 78 | 79 | @override 80 | String toString() { 81 | return 'ExecuteAgreementResponse(statusCode: $statusCode, statusMessage: $statusMessage, paymentID: $paymentID, agreementID: $agreementID, payerReference: $payerReference, agreementExecuteTime: $agreementExecuteTime, agreementStatus: $agreementStatus, customerMsisdn: $customerMsisdn)'; 82 | } 83 | 84 | @override 85 | bool operator ==(covariant ExecuteAgreementResponse other) { 86 | if (identical(this, other)) return true; 87 | 88 | return other.statusCode == statusCode && 89 | other.statusMessage == statusMessage && 90 | other.paymentID == paymentID && 91 | other.agreementID == agreementID && 92 | other.payerReference == payerReference && 93 | other.agreementExecuteTime == agreementExecuteTime && 94 | other.agreementStatus == agreementStatus && 95 | other.customerMsisdn == customerMsisdn; 96 | } 97 | 98 | @override 99 | int get hashCode { 100 | return statusCode.hashCode ^ 101 | statusMessage.hashCode ^ 102 | paymentID.hashCode ^ 103 | agreementID.hashCode ^ 104 | payerReference.hashCode ^ 105 | agreementExecuteTime.hashCode ^ 106 | agreementStatus.hashCode ^ 107 | customerMsisdn.hashCode; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /lib/src/apis/models/pay_with_agreement/pay_with_agreement_execute_response_model.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | class PayWithAgreementExecuteResponseModel { 4 | final String statusCode; 5 | final String statusMessage; 6 | final String paymentID; 7 | final String agreementID; 8 | final String payerReference; 9 | final String customerMsisdn; 10 | final String trxID; 11 | final String amount; 12 | final String transactionStatus; 13 | final String paymentExecuteTime; 14 | final String currency; 15 | final String intent; 16 | final String merchantInvoiceNumber; 17 | 18 | PayWithAgreementExecuteResponseModel({ 19 | required this.statusCode, 20 | required this.statusMessage, 21 | required this.paymentID, 22 | required this.agreementID, 23 | required this.payerReference, 24 | required this.customerMsisdn, 25 | required this.trxID, 26 | required this.amount, 27 | required this.transactionStatus, 28 | required this.paymentExecuteTime, 29 | required this.currency, 30 | required this.intent, 31 | required this.merchantInvoiceNumber, 32 | }); 33 | 34 | PayWithAgreementExecuteResponseModel copyWith({ 35 | String? statusCode, 36 | String? statusMessage, 37 | String? paymentID, 38 | String? agreementID, 39 | String? payerReference, 40 | String? customerMsisdn, 41 | String? trxID, 42 | String? amount, 43 | String? transactionStatus, 44 | String? paymentExecuteTime, 45 | String? currency, 46 | String? intent, 47 | String? merchantInvoiceNumber, 48 | }) { 49 | return PayWithAgreementExecuteResponseModel( 50 | statusCode: statusCode ?? this.statusCode, 51 | statusMessage: statusMessage ?? this.statusMessage, 52 | paymentID: paymentID ?? this.paymentID, 53 | agreementID: agreementID ?? this.agreementID, 54 | payerReference: payerReference ?? this.payerReference, 55 | customerMsisdn: customerMsisdn ?? this.customerMsisdn, 56 | trxID: trxID ?? this.trxID, 57 | amount: amount ?? this.amount, 58 | transactionStatus: transactionStatus ?? this.transactionStatus, 59 | paymentExecuteTime: paymentExecuteTime ?? this.paymentExecuteTime, 60 | currency: currency ?? this.currency, 61 | intent: intent ?? this.intent, 62 | merchantInvoiceNumber: 63 | merchantInvoiceNumber ?? this.merchantInvoiceNumber, 64 | ); 65 | } 66 | 67 | Map toMap() { 68 | return { 69 | 'statusCode': statusCode, 70 | 'statusMessage': statusMessage, 71 | 'paymentID': paymentID, 72 | 'agreementID': agreementID, 73 | 'payerReference': payerReference, 74 | 'customerMsisdn': customerMsisdn, 75 | 'trxID': trxID, 76 | 'amount': amount, 77 | 'transactionStatus': transactionStatus, 78 | 'paymentExecuteTime': paymentExecuteTime, 79 | 'currency': currency, 80 | 'intent': intent, 81 | 'merchantInvoiceNumber': merchantInvoiceNumber, 82 | }; 83 | } 84 | 85 | factory PayWithAgreementExecuteResponseModel.fromMap( 86 | Map map) { 87 | return PayWithAgreementExecuteResponseModel( 88 | statusCode: map['statusCode'] as String? ?? "", 89 | statusMessage: map['statusMessage'] as String? ?? "", 90 | paymentID: map['paymentID'] as String? ?? "", 91 | agreementID: map['agreementID'] as String? ?? "", 92 | payerReference: map['payerReference'] as String? ?? "", 93 | customerMsisdn: map['customerMsisdn'] as String? ?? "", 94 | trxID: map['trxID'] as String? ?? "", 95 | amount: map['amount'] as String? ?? "", 96 | transactionStatus: map['transactionStatus'] as String? ?? "", 97 | paymentExecuteTime: map['paymentExecuteTime'] as String? ?? "", 98 | currency: map['currency'] as String? ?? "", 99 | intent: map['intent'] as String? ?? "", 100 | merchantInvoiceNumber: map['merchantInvoiceNumber'] as String? ?? "", 101 | ); 102 | } 103 | 104 | String toJson() => json.encode(toMap()); 105 | 106 | factory PayWithAgreementExecuteResponseModel.fromJson(String source) => 107 | PayWithAgreementExecuteResponseModel.fromMap( 108 | json.decode(source) as Map); 109 | 110 | @override 111 | String toString() { 112 | return 'PayWithAgreementExecuteResponseModel(statusCode: $statusCode, statusMessage: $statusMessage, paymentID: $paymentID, agreementID: $agreementID, payerReference: $payerReference, customerMsisdn: $customerMsisdn, trxID: $trxID, amount: $amount, transactionStatus: $transactionStatus, paymentExecuteTime: $paymentExecuteTime, currency: $currency, intent: $intent, merchantInvoiceNumber: $merchantInvoiceNumber)'; 113 | } 114 | 115 | @override 116 | bool operator ==(covariant PayWithAgreementExecuteResponseModel other) { 117 | if (identical(this, other)) return true; 118 | 119 | return other.statusCode == statusCode && 120 | other.statusMessage == statusMessage && 121 | other.paymentID == paymentID && 122 | other.agreementID == agreementID && 123 | other.payerReference == payerReference && 124 | other.customerMsisdn == customerMsisdn && 125 | other.trxID == trxID && 126 | other.amount == amount && 127 | other.transactionStatus == transactionStatus && 128 | other.paymentExecuteTime == paymentExecuteTime && 129 | other.currency == currency && 130 | other.intent == intent && 131 | other.merchantInvoiceNumber == merchantInvoiceNumber; 132 | } 133 | 134 | @override 135 | int get hashCode { 136 | return statusCode.hashCode ^ 137 | statusMessage.hashCode ^ 138 | paymentID.hashCode ^ 139 | agreementID.hashCode ^ 140 | payerReference.hashCode ^ 141 | customerMsisdn.hashCode ^ 142 | trxID.hashCode ^ 143 | amount.hashCode ^ 144 | transactionStatus.hashCode ^ 145 | paymentExecuteTime.hashCode ^ 146 | currency.hashCode ^ 147 | intent.hashCode ^ 148 | merchantInvoiceNumber.hashCode; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /lib/src/apis/models/pay_with_agreement/pay_with_agreement_response_model.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'dart:convert'; 3 | 4 | class PayWithAgreementResponseModel { 5 | final String statusCode; 6 | final String statusMessage; 7 | final String paymentID; 8 | final String bkashURL; 9 | final String callbackURL; 10 | final String successCallbackURL; 11 | final String failureCallbackURL; 12 | final String cancelledCallbackURL; 13 | final String amount; 14 | final String intent; 15 | final String currency; 16 | final String agreementID; 17 | final String paymentCreateTime; 18 | final String transactionStatus; 19 | final String merchantInvoiceNumber; 20 | 21 | PayWithAgreementResponseModel({ 22 | required this.statusCode, 23 | required this.statusMessage, 24 | required this.paymentID, 25 | required this.bkashURL, 26 | required this.callbackURL, 27 | required this.successCallbackURL, 28 | required this.failureCallbackURL, 29 | required this.cancelledCallbackURL, 30 | required this.amount, 31 | required this.intent, 32 | required this.currency, 33 | required this.agreementID, 34 | required this.paymentCreateTime, 35 | required this.transactionStatus, 36 | required this.merchantInvoiceNumber, 37 | }); 38 | 39 | PayWithAgreementResponseModel copyWith({ 40 | String? statusCode, 41 | String? statusMessage, 42 | String? paymentID, 43 | String? bkashURL, 44 | String? callbackURL, 45 | String? successCallbackURL, 46 | String? failureCallbackURL, 47 | String? cancelledCallbackURL, 48 | String? amount, 49 | String? intent, 50 | String? currency, 51 | String? agreementID, 52 | String? paymentCreateTime, 53 | String? transactionStatus, 54 | String? merchantInvoiceNumber, 55 | }) { 56 | return PayWithAgreementResponseModel( 57 | statusCode: statusCode ?? this.statusCode, 58 | statusMessage: statusMessage ?? this.statusMessage, 59 | paymentID: paymentID ?? this.paymentID, 60 | bkashURL: bkashURL ?? this.bkashURL, 61 | callbackURL: callbackURL ?? this.callbackURL, 62 | successCallbackURL: successCallbackURL ?? this.successCallbackURL, 63 | failureCallbackURL: failureCallbackURL ?? this.failureCallbackURL, 64 | cancelledCallbackURL: cancelledCallbackURL ?? this.cancelledCallbackURL, 65 | amount: amount ?? this.amount, 66 | intent: intent ?? this.intent, 67 | currency: currency ?? this.currency, 68 | agreementID: agreementID ?? this.agreementID, 69 | paymentCreateTime: paymentCreateTime ?? this.paymentCreateTime, 70 | transactionStatus: transactionStatus ?? this.transactionStatus, 71 | merchantInvoiceNumber: 72 | merchantInvoiceNumber ?? this.merchantInvoiceNumber, 73 | ); 74 | } 75 | 76 | Map toMap() { 77 | return { 78 | 'statusCode': statusCode, 79 | 'statusMessage': statusMessage, 80 | 'paymentID': paymentID, 81 | 'bkashURL': bkashURL, 82 | 'callbackURL': callbackURL, 83 | 'successCallbackURL': successCallbackURL, 84 | 'failureCallbackURL': failureCallbackURL, 85 | 'cancelledCallbackURL': cancelledCallbackURL, 86 | 'amount': amount, 87 | 'intent': intent, 88 | 'currency': currency, 89 | 'agreementID': agreementID, 90 | 'paymentCreateTime': paymentCreateTime, 91 | 'transactionStatus': transactionStatus, 92 | 'merchantInvoiceNumber': merchantInvoiceNumber, 93 | }; 94 | } 95 | 96 | factory PayWithAgreementResponseModel.fromMap(Map map) { 97 | return PayWithAgreementResponseModel( 98 | statusCode: map['statusCode'] as String? ?? "", 99 | statusMessage: map['statusMessage'] as String? ?? "", 100 | paymentID: map['paymentID'] as String? ?? "", 101 | bkashURL: map['bkashURL'] as String? ?? "", 102 | callbackURL: map['callbackURL'] as String? ?? "", 103 | successCallbackURL: map['successCallbackURL'] as String? ?? "", 104 | failureCallbackURL: map['failureCallbackURL'] as String? ?? "", 105 | cancelledCallbackURL: map['cancelledCallbackURL'] as String? ?? "", 106 | amount: map['amount'] as String? ?? "", 107 | intent: map['intent'] as String? ?? "", 108 | currency: map['currency'] as String? ?? "", 109 | agreementID: map['agreementID'] as String? ?? "", 110 | paymentCreateTime: map['paymentCreateTime'] as String? ?? "", 111 | transactionStatus: map['transactionStatus'] as String? ?? "", 112 | merchantInvoiceNumber: map['merchantInvoiceNumber'] as String? ?? "", 113 | ); 114 | } 115 | 116 | String toJson() => json.encode(toMap()); 117 | 118 | factory PayWithAgreementResponseModel.fromJson(String source) => 119 | PayWithAgreementResponseModel.fromMap( 120 | json.decode(source) as Map); 121 | 122 | @override 123 | String toString() { 124 | return 'PayWithAgreementResponseModel(statusCode: $statusCode, statusMessage: $statusMessage, paymentID: $paymentID, bkashURL: $bkashURL, callbackURL: $callbackURL, successCallbackURL: $successCallbackURL, failureCallbackURL: $failureCallbackURL, cancelledCallbackURL: $cancelledCallbackURL, amount: $amount, intent: $intent, currency: $currency, agreementID: $agreementID, paymentCreateTime: $paymentCreateTime, transactionStatus: $transactionStatus, merchantInvoiceNumber: $merchantInvoiceNumber)'; 125 | } 126 | 127 | @override 128 | bool operator ==(covariant PayWithAgreementResponseModel other) { 129 | if (identical(this, other)) return true; 130 | 131 | return other.statusCode == statusCode && 132 | other.statusMessage == statusMessage && 133 | other.paymentID == paymentID && 134 | other.bkashURL == bkashURL && 135 | other.callbackURL == callbackURL && 136 | other.successCallbackURL == successCallbackURL && 137 | other.failureCallbackURL == failureCallbackURL && 138 | other.cancelledCallbackURL == cancelledCallbackURL && 139 | other.amount == amount && 140 | other.intent == intent && 141 | other.currency == currency && 142 | other.agreementID == agreementID && 143 | other.paymentCreateTime == paymentCreateTime && 144 | other.transactionStatus == transactionStatus && 145 | other.merchantInvoiceNumber == merchantInvoiceNumber; 146 | } 147 | 148 | @override 149 | int get hashCode { 150 | return statusCode.hashCode ^ 151 | statusMessage.hashCode ^ 152 | paymentID.hashCode ^ 153 | bkashURL.hashCode ^ 154 | callbackURL.hashCode ^ 155 | successCallbackURL.hashCode ^ 156 | failureCallbackURL.hashCode ^ 157 | cancelledCallbackURL.hashCode ^ 158 | amount.hashCode ^ 159 | intent.hashCode ^ 160 | currency.hashCode ^ 161 | agreementID.hashCode ^ 162 | paymentCreateTime.hashCode ^ 163 | transactionStatus.hashCode ^ 164 | merchantInvoiceNumber.hashCode; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /lib/src/apis/models/pay_without_agreement/pay_without_agreement_execute_response_model.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'dart:convert'; 3 | 4 | class PayWithoutAgreementExecuteResponseModel { 5 | final String statusCode; 6 | final String statusMessage; 7 | final String paymentID; 8 | final String payerReference; 9 | final String customerMsisdn; 10 | final String trxID; 11 | final String amount; 12 | final String transactionStatus; 13 | final String paymentExecuteTime; 14 | final String currency; 15 | final String intent; 16 | final String merchantInvoiceNumber; 17 | 18 | PayWithoutAgreementExecuteResponseModel({ 19 | required this.statusCode, 20 | required this.statusMessage, 21 | required this.paymentID, 22 | required this.payerReference, 23 | required this.customerMsisdn, 24 | required this.trxID, 25 | required this.amount, 26 | required this.transactionStatus, 27 | required this.paymentExecuteTime, 28 | required this.currency, 29 | required this.intent, 30 | required this.merchantInvoiceNumber, 31 | }); 32 | 33 | PayWithoutAgreementExecuteResponseModel copyWith({ 34 | String? statusCode, 35 | String? statusMessage, 36 | String? paymentID, 37 | String? payerReference, 38 | String? customerMsisdn, 39 | String? trxID, 40 | String? amount, 41 | String? transactionStatus, 42 | String? paymentExecuteTime, 43 | String? currency, 44 | String? intent, 45 | String? merchantInvoiceNumber, 46 | }) { 47 | return PayWithoutAgreementExecuteResponseModel( 48 | statusCode: statusCode ?? this.statusCode, 49 | statusMessage: statusMessage ?? this.statusMessage, 50 | paymentID: paymentID ?? this.paymentID, 51 | payerReference: payerReference ?? this.payerReference, 52 | customerMsisdn: customerMsisdn ?? this.customerMsisdn, 53 | trxID: trxID ?? this.trxID, 54 | amount: amount ?? this.amount, 55 | transactionStatus: transactionStatus ?? this.transactionStatus, 56 | paymentExecuteTime: paymentExecuteTime ?? this.paymentExecuteTime, 57 | currency: currency ?? this.currency, 58 | intent: intent ?? this.intent, 59 | merchantInvoiceNumber: 60 | merchantInvoiceNumber ?? this.merchantInvoiceNumber, 61 | ); 62 | } 63 | 64 | Map toMap() { 65 | return { 66 | 'statusCode': statusCode, 67 | 'statusMessage': statusMessage, 68 | 'paymentID': paymentID, 69 | 'payerReference': payerReference, 70 | 'customerMsisdn': customerMsisdn, 71 | 'trxID': trxID, 72 | 'amount': amount, 73 | 'transactionStatus': transactionStatus, 74 | 'paymentExecuteTime': paymentExecuteTime, 75 | 'currency': currency, 76 | 'intent': intent, 77 | 'merchantInvoiceNumber': merchantInvoiceNumber, 78 | }; 79 | } 80 | 81 | factory PayWithoutAgreementExecuteResponseModel.fromMap( 82 | Map map) { 83 | return PayWithoutAgreementExecuteResponseModel( 84 | statusCode: map['statusCode'] as String? ?? "", 85 | statusMessage: map['statusMessage'] as String? ?? "", 86 | paymentID: map['paymentID'] as String? ?? "", 87 | payerReference: map['payerReference'] as String? ?? "", 88 | customerMsisdn: map['customerMsisdn'] as String? ?? "", 89 | trxID: map['trxID'] as String? ?? "", 90 | amount: map['amount'] as String? ?? "", 91 | transactionStatus: map['transactionStatus'] as String? ?? "", 92 | paymentExecuteTime: map['paymentExecuteTime'] as String? ?? "", 93 | currency: map['currency'] as String? ?? "", 94 | intent: map['intent'] as String? ?? "", 95 | merchantInvoiceNumber: map['merchantInvoiceNumber'] as String? ?? "", 96 | ); 97 | } 98 | 99 | String toJson() => json.encode(toMap()); 100 | 101 | factory PayWithoutAgreementExecuteResponseModel.fromJson(String source) => 102 | PayWithoutAgreementExecuteResponseModel.fromMap( 103 | json.decode(source) as Map); 104 | 105 | @override 106 | String toString() { 107 | return 'PayWithoutAgreementExecuteResponseModel(statusCode: $statusCode, statusMessage: $statusMessage, paymentID: $paymentID, payerReference: $payerReference, customerMsisdn: $customerMsisdn, trxID: $trxID, amount: $amount, transactionStatus: $transactionStatus, paymentExecuteTime: $paymentExecuteTime, currency: $currency, intent: $intent, merchantInvoiceNumber: $merchantInvoiceNumber)'; 108 | } 109 | 110 | @override 111 | bool operator ==(covariant PayWithoutAgreementExecuteResponseModel other) { 112 | if (identical(this, other)) return true; 113 | 114 | return other.statusCode == statusCode && 115 | other.statusMessage == statusMessage && 116 | other.paymentID == paymentID && 117 | other.payerReference == payerReference && 118 | other.customerMsisdn == customerMsisdn && 119 | other.trxID == trxID && 120 | other.amount == amount && 121 | other.transactionStatus == transactionStatus && 122 | other.paymentExecuteTime == paymentExecuteTime && 123 | other.currency == currency && 124 | other.intent == intent && 125 | other.merchantInvoiceNumber == merchantInvoiceNumber; 126 | } 127 | 128 | @override 129 | int get hashCode { 130 | return statusCode.hashCode ^ 131 | statusMessage.hashCode ^ 132 | paymentID.hashCode ^ 133 | payerReference.hashCode ^ 134 | customerMsisdn.hashCode ^ 135 | trxID.hashCode ^ 136 | amount.hashCode ^ 137 | transactionStatus.hashCode ^ 138 | paymentExecuteTime.hashCode ^ 139 | currency.hashCode ^ 140 | intent.hashCode ^ 141 | merchantInvoiceNumber.hashCode; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /lib/src/apis/models/pay_without_agreement/pay_without_agreement_response.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | class PayWithoutAgreementResponse { 4 | final String statusCode; 5 | final String statusMessage; 6 | final String paymentID; 7 | final String bkashURL; 8 | final String callbackURL; 9 | final String successCallbackURL; 10 | final String failureCallbackURL; 11 | final String cancelledCallbackURL; 12 | final String amount; 13 | final String intent; 14 | final String currency; 15 | final String paymentCreateTime; 16 | final String transactionStatus; 17 | final String merchantInvoiceNumber; 18 | 19 | PayWithoutAgreementResponse({ 20 | required this.statusCode, 21 | required this.statusMessage, 22 | required this.paymentID, 23 | required this.bkashURL, 24 | required this.callbackURL, 25 | required this.successCallbackURL, 26 | required this.failureCallbackURL, 27 | required this.cancelledCallbackURL, 28 | required this.amount, 29 | required this.intent, 30 | required this.currency, 31 | required this.paymentCreateTime, 32 | required this.transactionStatus, 33 | required this.merchantInvoiceNumber, 34 | }); 35 | 36 | PayWithoutAgreementResponse copyWith({ 37 | String? statusCode, 38 | String? statusMessage, 39 | String? paymentID, 40 | String? bkashURL, 41 | String? callbackURL, 42 | String? successCallbackURL, 43 | String? failureCallbackURL, 44 | String? cancelledCallbackURL, 45 | String? amount, 46 | String? intent, 47 | String? currency, 48 | String? paymentCreateTime, 49 | String? transactionStatus, 50 | String? merchantInvoiceNumber, 51 | }) { 52 | return PayWithoutAgreementResponse( 53 | statusCode: statusCode ?? this.statusCode, 54 | statusMessage: statusMessage ?? this.statusMessage, 55 | paymentID: paymentID ?? this.paymentID, 56 | bkashURL: bkashURL ?? this.bkashURL, 57 | callbackURL: callbackURL ?? this.callbackURL, 58 | successCallbackURL: successCallbackURL ?? this.successCallbackURL, 59 | failureCallbackURL: failureCallbackURL ?? this.failureCallbackURL, 60 | cancelledCallbackURL: cancelledCallbackURL ?? this.cancelledCallbackURL, 61 | amount: amount ?? this.amount, 62 | intent: intent ?? this.intent, 63 | currency: currency ?? this.currency, 64 | paymentCreateTime: paymentCreateTime ?? this.paymentCreateTime, 65 | transactionStatus: transactionStatus ?? this.transactionStatus, 66 | merchantInvoiceNumber: 67 | merchantInvoiceNumber ?? this.merchantInvoiceNumber, 68 | ); 69 | } 70 | 71 | Map toMap() { 72 | return { 73 | 'statusCode': statusCode, 74 | 'statusMessage': statusMessage, 75 | 'paymentID': paymentID, 76 | 'bkashURL': bkashURL, 77 | 'callbackURL': callbackURL, 78 | 'successCallbackURL': successCallbackURL, 79 | 'failureCallbackURL': failureCallbackURL, 80 | 'cancelledCallbackURL': cancelledCallbackURL, 81 | 'amount': amount, 82 | 'intent': intent, 83 | 'currency': currency, 84 | 'paymentCreateTime': paymentCreateTime, 85 | 'transactionStatus': transactionStatus, 86 | 'merchantInvoiceNumber': merchantInvoiceNumber, 87 | }; 88 | } 89 | 90 | factory PayWithoutAgreementResponse.fromMap(Map map) { 91 | return PayWithoutAgreementResponse( 92 | statusCode: map['statusCode'] as String? ?? "", 93 | statusMessage: map['statusMessage'] as String? ?? "", 94 | paymentID: map['paymentID'] as String? ?? "", 95 | bkashURL: map['bkashURL'] as String? ?? "", 96 | callbackURL: map['callbackURL'] as String? ?? "", 97 | successCallbackURL: map['successCallbackURL'] as String? ?? "", 98 | failureCallbackURL: map['failureCallbackURL'] as String? ?? "", 99 | cancelledCallbackURL: map['cancelledCallbackURL'] as String? ?? "", 100 | amount: map['amount'] as String? ?? "", 101 | intent: map['intent'] as String? ?? "", 102 | currency: map['currency'] as String? ?? "", 103 | paymentCreateTime: map['paymentCreateTime'] as String? ?? "", 104 | transactionStatus: map['transactionStatus'] as String? ?? "", 105 | merchantInvoiceNumber: map['merchantInvoiceNumber'] as String? ?? "", 106 | ); 107 | } 108 | 109 | String toJson() => json.encode(toMap()); 110 | 111 | factory PayWithoutAgreementResponse.fromJson(String source) => 112 | PayWithoutAgreementResponse.fromMap( 113 | json.decode(source) as Map); 114 | 115 | @override 116 | String toString() { 117 | return 'PayWithoutAgreementResponse(statusCode: $statusCode, statusMessage: $statusMessage, paymentID: $paymentID, bkashURL: $bkashURL, callbackURL: $callbackURL, successCallbackURL: $successCallbackURL, failureCallbackURL: $failureCallbackURL, cancelledCallbackURL: $cancelledCallbackURL, amount: $amount, intent: $intent, currency: $currency, paymentCreateTime: $paymentCreateTime, transactionStatus: $transactionStatus, merchantInvoiceNumber: $merchantInvoiceNumber)'; 118 | } 119 | 120 | @override 121 | bool operator ==(covariant PayWithoutAgreementResponse other) { 122 | if (identical(this, other)) return true; 123 | 124 | return other.statusCode == statusCode && 125 | other.statusMessage == statusMessage && 126 | other.paymentID == paymentID && 127 | other.bkashURL == bkashURL && 128 | other.callbackURL == callbackURL && 129 | other.successCallbackURL == successCallbackURL && 130 | other.failureCallbackURL == failureCallbackURL && 131 | other.cancelledCallbackURL == cancelledCallbackURL && 132 | other.amount == amount && 133 | other.intent == intent && 134 | other.currency == currency && 135 | other.paymentCreateTime == paymentCreateTime && 136 | other.transactionStatus == transactionStatus && 137 | other.merchantInvoiceNumber == merchantInvoiceNumber; 138 | } 139 | 140 | @override 141 | int get hashCode { 142 | return statusCode.hashCode ^ 143 | statusMessage.hashCode ^ 144 | paymentID.hashCode ^ 145 | bkashURL.hashCode ^ 146 | callbackURL.hashCode ^ 147 | successCallbackURL.hashCode ^ 148 | failureCallbackURL.hashCode ^ 149 | cancelledCallbackURL.hashCode ^ 150 | amount.hashCode ^ 151 | intent.hashCode ^ 152 | currency.hashCode ^ 153 | paymentCreateTime.hashCode ^ 154 | transactionStatus.hashCode ^ 155 | merchantInvoiceNumber.hashCode; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /lib/src/apis/models/token_response_model.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | class TokenResponseModel { 4 | final String statusCode; 5 | final String statusMessage; 6 | final String idToken; 7 | final String tokenType; 8 | final int expiresIn; 9 | final String refreshToken; 10 | 11 | const TokenResponseModel({ 12 | required this.statusCode, 13 | required this.statusMessage, 14 | required this.idToken, 15 | required this.tokenType, 16 | required this.expiresIn, 17 | required this.refreshToken, 18 | }); 19 | 20 | TokenResponseModel copyWith({ 21 | String? statusCode, 22 | String? statusMessage, 23 | String? idToken, 24 | String? tokenType, 25 | int? expiresIn, 26 | String? refreshToken, 27 | }) { 28 | return TokenResponseModel( 29 | statusCode: statusCode ?? this.statusCode, 30 | statusMessage: statusMessage ?? this.statusMessage, 31 | idToken: idToken ?? this.idToken, 32 | tokenType: tokenType ?? this.tokenType, 33 | expiresIn: expiresIn ?? this.expiresIn, 34 | refreshToken: refreshToken ?? this.refreshToken, 35 | ); 36 | } 37 | 38 | Map toMap() { 39 | return { 40 | 'statusCode': statusCode, 41 | 'statusMessage': statusMessage, 42 | 'id_token': idToken, 43 | 'token_type': tokenType, 44 | 'expires_in': expiresIn, 45 | 'refresh_token': refreshToken, 46 | }; 47 | } 48 | 49 | factory TokenResponseModel.fromMap(Map map) { 50 | return TokenResponseModel( 51 | statusCode: map['statusCode'] as String? ?? "", 52 | statusMessage: map['statusMessage'] as String? ?? "", 53 | idToken: map['id_token'] as String? ?? "", 54 | tokenType: map['token_type'] as String? ?? "", 55 | expiresIn: map['expires_in'] as int? ?? 0, 56 | refreshToken: map['refresh_token'] as String? ?? "", 57 | ); 58 | } 59 | 60 | String toJson() => json.encode(toMap()); 61 | 62 | factory TokenResponseModel.fromJson(String source) => 63 | TokenResponseModel.fromMap(json.decode(source) as Map); 64 | 65 | @override 66 | String toString() { 67 | return 'TokenResponseModel(statusCode: $statusCode, statusMessage: $statusMessage, idToken: $idToken, tokenType: $tokenType, expiresIn: $expiresIn, refreshToken: $refreshToken)'; 68 | } 69 | 70 | @override 71 | bool operator ==(covariant TokenResponseModel other) { 72 | if (identical(this, other)) return true; 73 | 74 | return other.statusCode == statusCode && 75 | other.statusMessage == statusMessage && 76 | other.idToken == idToken && 77 | other.tokenType == tokenType && 78 | other.expiresIn == expiresIn && 79 | other.refreshToken == refreshToken; 80 | } 81 | 82 | @override 83 | int get hashCode { 84 | return statusCode.hashCode ^ 85 | statusMessage.hashCode ^ 86 | idToken.hashCode ^ 87 | tokenType.hashCode ^ 88 | expiresIn.hashCode ^ 89 | refreshToken.hashCode; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /lib/src/apis/pay_with_agreement_api.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:fpdart/fpdart.dart'; 4 | import 'package:http/http.dart' as http; 5 | 6 | import '../bkash_credentials.dart'; 7 | import '../utils/api_helper.dart'; 8 | import '../utils/failure.dart'; 9 | import 'models/pay_with_agreement/pay_with_agreement_execute_response_model.dart'; 10 | import 'models/pay_with_agreement/pay_with_agreement_response_model.dart'; 11 | 12 | class PayWithAgreementApi with ApiHelper { 13 | final BkashCredentials _bkashCredentials; 14 | final bool logResponse; 15 | 16 | late String _baseUrl; 17 | 18 | PayWithAgreementApi( 19 | this._bkashCredentials, { 20 | required this.logResponse, 21 | }) { 22 | _baseUrl = 23 | "https://tokenized.${_bkashCredentials.isSandbox ? "sandbox" : "pay"}.bka.sh/v1.2.0-beta"; 24 | } 25 | 26 | Future> payWithAgreement({ 27 | required String idToken, 28 | required String amount, 29 | required String agreementId, 30 | required String marchentInvoiceNumber, 31 | }) async { 32 | final headers = { 33 | "accept": 'application/json', 34 | "Authorization": idToken, 35 | "X-APP-Key": _bkashCredentials.appKey, 36 | 'content-type': 'application/json' 37 | }; 38 | final body = { 39 | "mode": '0001', 40 | "callbackURL": 'https://example.com/', 41 | "agreementID": agreementId, 42 | "amount": amount, 43 | "currency": 'BDT', 44 | "intent": 'sale', 45 | "merchantInvoiceNumber": marchentInvoiceNumber, 46 | }; 47 | 48 | final data = await networkCallHelper( 49 | logResponse: logResponse, 50 | function: () => http.post( 51 | Uri.parse("$_baseUrl/tokenized/checkout/create"), 52 | headers: headers, 53 | body: json.encode(body), 54 | ), 55 | ); 56 | 57 | return data.fold( 58 | (l) => left(l), 59 | (r) => right(PayWithAgreementResponseModel.fromMap(r)), 60 | ); 61 | } 62 | 63 | Future> 64 | executePayWithAgreement({ 65 | required String paymentId, 66 | required String idToken, 67 | }) async { 68 | final headers = { 69 | "accept": 'application/json', 70 | "Authorization": idToken, 71 | "X-APP-Key": _bkashCredentials.appKey, 72 | 'content-type': 'application/json' 73 | }; 74 | final body = { 75 | "paymentID": paymentId, 76 | }; 77 | final data = await networkCallHelper( 78 | logResponse: logResponse, 79 | function: () => http.post( 80 | Uri.parse("$_baseUrl/tokenized/checkout/execute"), 81 | headers: headers, 82 | body: json.encode(body), 83 | )); 84 | 85 | return data.fold( 86 | (l) => left(l), 87 | (r) => right(PayWithAgreementExecuteResponseModel.fromMap(r)), 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /lib/src/apis/pay_without_agreement_api.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:fpdart/fpdart.dart'; 4 | import 'package:http/http.dart' as http; 5 | 6 | import '../bkash_credentials.dart'; 7 | import '../utils/api_helper.dart'; 8 | import '../utils/failure.dart'; 9 | import 'models/pay_without_agreement/pay_without_agreement_execute_response_model.dart'; 10 | import 'models/pay_without_agreement/pay_without_agreement_response.dart'; 11 | 12 | class PayWithoutAgreementApi with ApiHelper { 13 | final BkashCredentials _bkashCredentials; 14 | final bool logResponse; 15 | 16 | late String _baseUrl; 17 | 18 | PayWithoutAgreementApi( 19 | this._bkashCredentials, { 20 | required this.logResponse, 21 | }) { 22 | _baseUrl = 23 | "https://tokenized.${_bkashCredentials.isSandbox ? "sandbox" : "pay"}.bka.sh/v1.2.0-beta"; 24 | } 25 | 26 | Future> 27 | payWithoutAgreement({ 28 | required String idToken, 29 | required String amount, 30 | required String payerReference, 31 | required String marchentInvoiceNumber, 32 | }) async { 33 | final headers = { 34 | "accept": 'application/json', 35 | "Authorization": idToken, 36 | "X-APP-Key": _bkashCredentials.appKey, 37 | 'content-type': 'application/json' 38 | }; 39 | final body = { 40 | "mode": '0011', 41 | "payerReference": payerReference, 42 | "callbackURL": 'https://example.com/', 43 | "amount": amount, 44 | "currency": 'BDT', 45 | "intent": 'sale', 46 | "merchantInvoiceNumber": marchentInvoiceNumber, 47 | }; 48 | 49 | final data = await networkCallHelper( 50 | logResponse: logResponse, 51 | function: () => http.post( 52 | Uri.parse("$_baseUrl/tokenized/checkout/create"), 53 | headers: headers, 54 | body: json.encode(body), 55 | ), 56 | ); 57 | 58 | return data.fold( 59 | (l) => left(l), 60 | (r) => right(PayWithoutAgreementResponse.fromMap(r)), 61 | ); 62 | } 63 | 64 | Future> 65 | executePayWithoutAgreement({ 66 | required String paymentId, 67 | required String idToken, 68 | }) async { 69 | final headers = { 70 | "accept": 'application/json', 71 | "Authorization": idToken, 72 | "X-APP-Key": _bkashCredentials.appKey, 73 | 'content-type': 'application/json' 74 | }; 75 | final body = { 76 | "paymentID": paymentId, 77 | }; 78 | final data = await networkCallHelper( 79 | logResponse: logResponse, 80 | function: () => http.post( 81 | Uri.parse("$_baseUrl/tokenized/checkout/execute"), 82 | headers: headers, 83 | body: json.encode(body), 84 | )); 85 | 86 | return data.fold( 87 | (l) => left(l), 88 | (r) => right(PayWithoutAgreementExecuteResponseModel.fromMap(r)), 89 | ); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /lib/src/apis/token_api.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:flutter_bkash/src/utils/api_helper.dart'; 4 | import 'package:fpdart/fpdart.dart'; 5 | import 'package:http/http.dart' as http; 6 | 7 | import '../bkash_credentials.dart'; 8 | import '../utils/failure.dart'; 9 | import 'models/token_response_model.dart'; 10 | 11 | class TokenApi with ApiHelper { 12 | final BkashCredentials _bkashCredentials; 13 | final bool logResponse; 14 | 15 | late String _baseUrl; 16 | 17 | TokenApi( 18 | this._bkashCredentials, { 19 | required this.logResponse, 20 | }) { 21 | _baseUrl = 22 | "https://tokenized.${_bkashCredentials.isSandbox ? "sandbox" : "pay"}.bka.sh/v1.2.0-beta"; 23 | } 24 | 25 | Future> createToken() async { 26 | final headers = { 27 | "accept": 'application/json', 28 | "username": _bkashCredentials.username, 29 | "password": _bkashCredentials.password, 30 | 'content-type': 'application/json' 31 | }; 32 | final body = { 33 | "app_key": _bkashCredentials.appKey, 34 | "app_secret": _bkashCredentials.appSecret, 35 | }; 36 | 37 | final data = await networkCallHelper( 38 | logResponse: logResponse, 39 | function: () => http.post( 40 | Uri.parse("$_baseUrl/tokenized/checkout/token/grant"), 41 | headers: headers, 42 | body: json.encode(body), 43 | ), 44 | ); 45 | 46 | return data.fold( 47 | (l) => left(l), 48 | (r) => right(TokenResponseModel.fromMap(r)), 49 | ); 50 | } 51 | 52 | Future> refreshToken({ 53 | required String refreshToken, 54 | }) async { 55 | final headers = { 56 | "accept": 'application/json', 57 | "username": _bkashCredentials.username, 58 | "password": _bkashCredentials.password, 59 | 'content-type': 'application/json' 60 | }; 61 | final body = { 62 | "app_key": _bkashCredentials.appKey, 63 | "app_secret": _bkashCredentials.appSecret, 64 | "refresh_token": refreshToken, 65 | }; 66 | 67 | final data = await networkCallHelper( 68 | logResponse: logResponse, 69 | function: () => http.post( 70 | Uri.parse("$_baseUrl/tokenized/checkout/token/refresh"), 71 | headers: headers, 72 | body: json.encode(body), 73 | ), 74 | ); 75 | 76 | return data.fold( 77 | (l) => left(l), 78 | (r) => right(TokenResponseModel.fromMap(r)), 79 | ); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/src/bkash_api.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_bkash/src/apis/create_agreement_api.dart'; 2 | import 'package:flutter_bkash/src/apis/pay_with_agreement_api.dart'; 3 | import 'package:flutter_bkash/src/apis/pay_without_agreement_api.dart'; 4 | import 'package:flutter_bkash/src/apis/token_api.dart'; 5 | import 'package:flutter_bkash/src/bkash_credentials.dart'; 6 | import 'package:fpdart/fpdart.dart'; 7 | 8 | import 'apis/models/create_agreement/create_agreement_response_model.dart'; 9 | import 'apis/models/create_agreement/execute_agreement_response.dart'; 10 | import 'apis/models/pay_with_agreement/pay_with_agreement_execute_response_model.dart'; 11 | import 'apis/models/pay_with_agreement/pay_with_agreement_response_model.dart'; 12 | import 'apis/models/pay_without_agreement/pay_without_agreement_execute_response_model.dart'; 13 | import 'apis/models/pay_without_agreement/pay_without_agreement_response.dart'; 14 | import 'apis/models/token_response_model.dart'; 15 | import 'utils/failure.dart'; 16 | 17 | /// The BkashApi class provides an interface to interact with various APIs related to bKash payment integration. 18 | /// 19 | /// This class encapsulates the functionality to create tokens, create agreements, and execute payments with or without agreements. 20 | /// It uses the provided [BkashCredentials] to authenticate API requests. 21 | class BkashApi { 22 | /// This is for printing api response from Bkash 23 | final bool logResponse; 24 | 25 | /// The API for creating tokens to authorize payment operations. 26 | final TokenApi _tokenApi; 27 | 28 | /// The API for creating and executing payment agreements. 29 | final CreateAgreementApi _createAgreementApi; 30 | 31 | /// The API for paying with an existing agreement. 32 | final PayWithAgreementApi _payWithAgreementApi; 33 | 34 | /// The API for paying without an existing agreement. 35 | final PayWithoutAgreementApi _payWithoutAgreementApi; 36 | 37 | /// Creates a new instance of the [BkashApi] with the provided [bkashCredentials]. 38 | /// 39 | /// The [bkashCredentials] contains the necessary authentication information to access the bKash APIs. 40 | BkashApi({ 41 | required BkashCredentials bkashCredentials, 42 | required this.logResponse, 43 | }) : _tokenApi = TokenApi( 44 | bkashCredentials, 45 | logResponse: logResponse, 46 | ), 47 | _createAgreementApi = CreateAgreementApi( 48 | bkashCredentials, 49 | logResponse: logResponse, 50 | ), 51 | _payWithAgreementApi = PayWithAgreementApi( 52 | bkashCredentials, 53 | logResponse: logResponse, 54 | ), 55 | _payWithoutAgreementApi = PayWithoutAgreementApi( 56 | bkashCredentials, 57 | logResponse: logResponse, 58 | ); 59 | 60 | // Token related 61 | 62 | /// Creates a new token for authorizing payment operations. 63 | /// 64 | /// Returns a [TokenResponseModel] if the token creation is successful, 65 | /// or a [BkashFailure] indicating the reason for failure. 66 | Future> createToken() async => 67 | await _tokenApi.createToken(); 68 | 69 | /// Refreshes the token using the provided [refreshToken]. 70 | /// 71 | /// Returns a [TokenResponseModel] if the token is refreshed successfully, 72 | /// or a [BkashFailure] indicating the reason for failure. 73 | Future> refreshToken({ 74 | required String refreshToken, 75 | }) async => 76 | await _tokenApi.refreshToken(refreshToken: refreshToken); 77 | 78 | // create agreement api 79 | 80 | /// Creates a new agreement for the provided [payerReference]. 81 | /// 82 | /// Returns a [CreateAgreementResponseModel] if the agreement creation is successful, 83 | /// or a [BkashFailure] indicating the reason for failure. 84 | Future> createAgreement({ 85 | required String idToken, 86 | required String payerReference, 87 | }) async => 88 | _createAgreementApi.createAgreement( 89 | idToken: idToken, 90 | payerReference: payerReference, 91 | ); 92 | 93 | /// Executes the agreement creation with the provided [paymentId] and [idToken]. 94 | /// 95 | /// Returns an [ExecuteAgreementResponse] if the execution is successful, 96 | /// or a [BkashFailure] indicating the reason for failure. 97 | Future> 98 | executeCreateAgreement({ 99 | required String paymentId, 100 | required String idToken, 101 | }) async => 102 | _createAgreementApi.executeCreateAgreement( 103 | idToken: idToken, 104 | paymentId: paymentId, 105 | ); 106 | 107 | // pay with agreement 108 | 109 | /// Pays with an existing agreement using the provided [idToken], [amount], [agreementId], and [merchantInvoiceNumber]. 110 | /// 111 | /// Returns a [PayWithAgreementResponseModel] if the payment is successful, 112 | /// or a [BkashFailure] indicating the reason for failure. 113 | Future> payWithAgreement({ 114 | required String idToken, 115 | required String amount, 116 | required String agreementId, 117 | required String merchantInvoiceNumber, 118 | }) async => 119 | await _payWithAgreementApi.payWithAgreement( 120 | idToken: idToken, 121 | amount: amount, 122 | agreementId: agreementId, 123 | marchentInvoiceNumber: merchantInvoiceNumber, 124 | ); 125 | 126 | /// Executes the payment with an existing agreement using the provided [paymentId] and [idToken]. 127 | /// 128 | /// Returns a [PayWithAgreementExecuteResponseModel] if the execution is successful, 129 | /// or a [BkashFailure] indicating the reason for failure. 130 | Future> 131 | executePayWithAgreement({ 132 | required String paymentId, 133 | required String idToken, 134 | }) async => 135 | await _payWithAgreementApi.executePayWithAgreement( 136 | paymentId: paymentId, 137 | idToken: idToken, 138 | ); 139 | 140 | // pay without agreement 141 | 142 | /// Pays without an existing agreement using the provided [idToken], [amount], [payerReference], and [merchantInvoiceNumber]. 143 | /// 144 | /// Returns a [PayWithoutAgreementResponse] if the payment is successful, 145 | /// or a [BkashFailure] indicating the reason for failure. 146 | Future> 147 | payWithoutAgreement({ 148 | required String idToken, 149 | required String amount, 150 | required String payerReference, 151 | required String merchantInvoiceNumber, 152 | }) async => 153 | await _payWithoutAgreementApi.payWithoutAgreement( 154 | idToken: idToken, 155 | amount: amount, 156 | payerReference: payerReference, 157 | marchentInvoiceNumber: merchantInvoiceNumber, 158 | ); 159 | 160 | /// Executes the payment without an existing agreement using the provided [paymentId] and [idToken]. 161 | /// 162 | /// Returns a [PayWithoutAgreementExecuteResponseModel] if the execution is successful, 163 | /// or a [BkashFailure] indicating the reason for failure. 164 | Future> 165 | executePayWithoutAgreement({ 166 | required String paymentId, 167 | required String idToken, 168 | }) async => 169 | await _payWithoutAgreementApi.executePayWithoutAgreement( 170 | paymentId: paymentId, 171 | idToken: idToken, 172 | ); 173 | } 174 | -------------------------------------------------------------------------------- /lib/src/bkash_credentials.dart: -------------------------------------------------------------------------------- 1 | class BkashCredentials { 2 | /// Username associated with the merchant account which was shared by bKash during on-boarding. 3 | final String username; 4 | 5 | /// Password associated with the merchant account. 6 | final String password; 7 | 8 | /// Application Key value shared by bKash during on-boarding. 9 | final String appKey; 10 | 11 | /// Application Secret value shared by bKash during on-boarding. 12 | final String appSecret; 13 | 14 | /// Make this false for production credentials 15 | final bool isSandbox; 16 | 17 | const BkashCredentials({ 18 | required this.username, 19 | required this.password, 20 | required this.appKey, 21 | required this.appSecret, 22 | this.isSandbox = true, 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /lib/src/bkash_payment_response.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'dart:developer'; 3 | 4 | class BkashPaymentResponse { 5 | final String trxId; 6 | final String payerReference; 7 | final String paymentId; 8 | final String customerMsisdn; 9 | final String merchantInvoiceNumber; 10 | final String _executeTime; 11 | 12 | BkashPaymentResponse( 13 | this._executeTime, { 14 | required this.trxId, 15 | required this.payerReference, 16 | required this.paymentId, 17 | required this.customerMsisdn, 18 | required this.merchantInvoiceNumber, 19 | }); 20 | 21 | DateTime get executeTime { 22 | try { 23 | return DateTime.parse(_executeTime.replaceAll(" GMT+0600", "")); 24 | } catch (e, st) { 25 | log("DateTime parse Error", error: e, stackTrace: st); 26 | return DateTime.now(); 27 | } 28 | } 29 | 30 | @override 31 | String toString() { 32 | return 'BkashPaymentResponse(trxId: $trxId, payerReference: $payerReference, paymentId: $paymentId, customerMsisdn: $customerMsisdn, merchantInvoiceNumber: $merchantInvoiceNumber, _executeTime: $_executeTime)'; 33 | } 34 | } 35 | 36 | class BkashAgreementResponse { 37 | final String payerReference; 38 | final String paymentId; 39 | final String customerMsisdn; 40 | final String agreementId; 41 | final String _executeTime; 42 | 43 | BkashAgreementResponse( 44 | this._executeTime, { 45 | required this.payerReference, 46 | required this.paymentId, 47 | required this.customerMsisdn, 48 | required this.agreementId, 49 | }); 50 | 51 | DateTime get executeTime { 52 | try { 53 | return DateTime.parse(_executeTime.replaceAll(" GMT+0600", "")); 54 | } catch (e, st) { 55 | log("DateTime parse Error", error: e, stackTrace: st); 56 | return DateTime.now(); 57 | } 58 | } 59 | 60 | @override 61 | String toString() { 62 | return 'BkashAgreementResponse(payerReference: $payerReference, paymentId: $paymentId, customerMsisdn: $customerMsisdn, agreementId: $agreementId, _executeTime: $_executeTime)'; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lib/src/bkash_payment_status.dart: -------------------------------------------------------------------------------- 1 | enum BkashPaymentStatus { 2 | failed, 3 | canceled, 4 | successed, 5 | } 6 | -------------------------------------------------------------------------------- /lib/src/flutter_bkash.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bkash/src/apis/models/token_response_model.dart'; 3 | import 'package:flutter_bkash/src/bkash_api.dart'; 4 | import 'package:flutter_bkash/src/bkash_credentials.dart'; 5 | import 'package:flutter_bkash/src/flutter_bkash_view.dart'; 6 | import 'package:fpdart/fpdart.dart'; 7 | 8 | import 'bkash_payment_response.dart'; 9 | import 'bkash_payment_status.dart'; 10 | import 'utils/failure.dart'; 11 | 12 | class FlutterBkash { 13 | /// For printing Bkash responses 14 | final bool logResponse; 15 | 16 | // All Bkash apis 17 | final BkashApi _bkashApi; 18 | 19 | // Token is invalid after this time 20 | late DateTime _tokenValidity; 21 | 22 | // Token for calling bkash apis 23 | Either? _token; 24 | 25 | FlutterBkash({ 26 | BkashCredentials? bkashCredentials, 27 | this.logResponse = false, 28 | }) : _bkashApi = BkashApi( 29 | bkashCredentials: bkashCredentials ?? 30 | const BkashCredentials( 31 | username: "sandboxTokenizedUser02", 32 | password: "sandboxTokenizedUser02@12345", 33 | appKey: "4f6o0cjiki2rfm34kfdadl1eqq", 34 | appSecret: 35 | "2is7hdktrekvrbljjh44ll3d9l1dtjo4pasmjvs5vl5qr3fug4b", 36 | isSandbox: true, 37 | ), 38 | logResponse: logResponse, 39 | ); 40 | 41 | /// Call this function for Create-Payment (Mentioned in Bkash Doc) 42 | /// 43 | /// Throws [BkashFailure] for error with a user-friendly message 44 | /// 45 | /// Provide User Phonenumber for [payerReference] 46 | Future pay({ 47 | required BuildContext context, 48 | required double amount, 49 | required String merchantInvoiceNumber, 50 | String payerReference = " ", 51 | }) async { 52 | await _validateToken(); 53 | 54 | final paymentResponse = await _token?.fold>( 55 | (l) async => throw l, 56 | (tokenRes) async { 57 | final apiResponse = await _bkashApi.payWithoutAgreement( 58 | idToken: tokenRes.idToken, 59 | amount: amount.toString(), 60 | payerReference: payerReference, 61 | merchantInvoiceNumber: merchantInvoiceNumber, 62 | ); 63 | 64 | return await apiResponse.fold>( 65 | (l) async => throw l, 66 | (apiRes) async { 67 | if (apiRes.statusCode != "0000") { 68 | throw BkashFailure(message: apiRes.statusMessage); 69 | } 70 | 71 | final bkashPaymentStatus = await Navigator.push( 72 | context, 73 | MaterialPageRoute( 74 | builder: (context) => FlutterBkashView( 75 | bkashURL: apiRes.bkashURL, 76 | failureCallbackURL: apiRes.failureCallbackURL, 77 | successCallbackURL: apiRes.successCallbackURL, 78 | cancelledCallbackURL: apiRes.cancelledCallbackURL, 79 | ), 80 | ), 81 | ) ?? 82 | BkashPaymentStatus.canceled; 83 | 84 | if (bkashPaymentStatus == BkashPaymentStatus.successed) { 85 | final result = await _bkashApi.executePayWithoutAgreement( 86 | paymentId: apiRes.paymentID, 87 | idToken: tokenRes.idToken, 88 | ); 89 | 90 | return result.fold( 91 | (l) => throw l, 92 | (r) { 93 | // failed to execute 94 | if (r.statusCode != "0000") { 95 | throw BkashFailure(message: r.statusMessage); 96 | } 97 | return BkashPaymentResponse( 98 | r.paymentExecuteTime, 99 | trxId: r.trxID, 100 | payerReference: r.payerReference, 101 | paymentId: r.paymentID, 102 | customerMsisdn: r.customerMsisdn, 103 | merchantInvoiceNumber: r.merchantInvoiceNumber, 104 | ); 105 | }, 106 | ); 107 | } 108 | if (bkashPaymentStatus == BkashPaymentStatus.canceled) { 109 | throw BkashFailure(message: "Payment Cancelled"); 110 | } 111 | throw BkashFailure(message: "Payment Failed"); 112 | }, 113 | ); 114 | }, 115 | ); 116 | 117 | if (paymentResponse == null) { 118 | throw BkashFailure(); 119 | } 120 | return paymentResponse; 121 | } 122 | 123 | /// Call this function to Create an AgreementId 124 | /// 125 | /// Throws [BkashFailure] for error with a user-friendly message 126 | /// 127 | /// Provide User Phonenumber for [payerReference] 128 | Future createAgreement({ 129 | required BuildContext context, 130 | String payerReference = " ", 131 | }) async { 132 | await _validateToken(); 133 | 134 | final paymentResponse = await _token?.fold>( 135 | (l) async => throw l, 136 | (tokenRes) async { 137 | final agreementResponse = await _bkashApi.createAgreement( 138 | idToken: tokenRes.idToken, 139 | payerReference: payerReference, 140 | ); 141 | 142 | return await agreementResponse.fold>( 143 | (l) async => throw l, 144 | (agrRes) async { 145 | if (agrRes.statusCode != "0000") { 146 | throw BkashFailure(message: agrRes.statusMessage); 147 | } 148 | 149 | final bkashPaymentStatus = await Navigator.push( 150 | context, 151 | MaterialPageRoute( 152 | builder: (context) => FlutterBkashView( 153 | bkashURL: agrRes.bkashURL, 154 | failureCallbackURL: agrRes.failureCallbackURL, 155 | successCallbackURL: agrRes.successCallbackURL, 156 | cancelledCallbackURL: agrRes.cancelledCallbackURL, 157 | ), 158 | ), 159 | ) ?? 160 | BkashPaymentStatus.canceled; 161 | 162 | if (bkashPaymentStatus == BkashPaymentStatus.successed) { 163 | final result = await _bkashApi.executeCreateAgreement( 164 | paymentId: agrRes.paymentID, 165 | idToken: tokenRes.idToken, 166 | ); 167 | 168 | return result.fold( 169 | (l) => throw l, 170 | (r) { 171 | // failed to execute 172 | if (r.statusCode != "0000") { 173 | throw BkashFailure(message: r.statusMessage); 174 | } 175 | return BkashAgreementResponse( 176 | r.agreementExecuteTime, 177 | payerReference: r.payerReference, 178 | paymentId: r.paymentID, 179 | customerMsisdn: r.customerMsisdn, 180 | agreementId: r.agreementID, 181 | ); 182 | }, 183 | ); 184 | } 185 | if (bkashPaymentStatus == BkashPaymentStatus.canceled) { 186 | throw BkashFailure(message: "Agreement creation Cancelled"); 187 | } 188 | throw BkashFailure(message: "Agreement creation Failed"); 189 | }, 190 | ); 191 | }, 192 | ); 193 | 194 | if (paymentResponse == null) { 195 | throw BkashFailure(); 196 | } 197 | return paymentResponse; 198 | } 199 | 200 | /// Call this Fucntion to Pay with AgreementId 201 | /// 202 | /// Throws [BkashFailure] for error with a user-friendly message 203 | Future payWithAgreement({ 204 | required BuildContext context, 205 | required double amount, 206 | required String agreementId, 207 | required String marchentInvoiceNumber, 208 | }) async { 209 | await _validateToken(); 210 | 211 | final paymentResponse = await _token?.fold>( 212 | (l) async => throw l, 213 | (tokenRes) async { 214 | final apiResponse = await _bkashApi.payWithAgreement( 215 | idToken: tokenRes.idToken, 216 | agreementId: agreementId, 217 | amount: amount.toString(), 218 | merchantInvoiceNumber: marchentInvoiceNumber, 219 | ); 220 | 221 | return await apiResponse.fold>( 222 | (l) async => throw l, 223 | (apiRes) async { 224 | if (apiRes.statusCode != "0000") { 225 | throw BkashFailure(message: apiRes.statusMessage); 226 | } 227 | 228 | final bkashPaymentStatus = await Navigator.push( 229 | context, 230 | MaterialPageRoute( 231 | builder: (context) => FlutterBkashView( 232 | bkashURL: apiRes.bkashURL, 233 | failureCallbackURL: apiRes.failureCallbackURL, 234 | successCallbackURL: apiRes.successCallbackURL, 235 | cancelledCallbackURL: apiRes.cancelledCallbackURL, 236 | ), 237 | ), 238 | ) ?? 239 | BkashPaymentStatus.canceled; 240 | 241 | if (bkashPaymentStatus == BkashPaymentStatus.successed) { 242 | final result = await _bkashApi.executePayWithAgreement( 243 | paymentId: apiRes.paymentID, 244 | idToken: tokenRes.idToken, 245 | ); 246 | 247 | return result.fold( 248 | (l) => throw l, 249 | (r) { 250 | // failed to execute 251 | if (r.statusCode != "0000") { 252 | throw BkashFailure(message: r.statusMessage); 253 | } 254 | return BkashPaymentResponse( 255 | r.paymentExecuteTime, 256 | trxId: r.trxID, 257 | payerReference: r.payerReference, 258 | paymentId: r.paymentID, 259 | customerMsisdn: r.customerMsisdn, 260 | merchantInvoiceNumber: r.merchantInvoiceNumber, 261 | ); 262 | }, 263 | ); 264 | } 265 | if (bkashPaymentStatus == BkashPaymentStatus.canceled) { 266 | throw BkashFailure(message: "Payment Cancelled"); 267 | } 268 | throw BkashFailure(); 269 | }, 270 | ); 271 | }, 272 | ); 273 | 274 | if (paymentResponse == null) { 275 | throw BkashFailure(); 276 | } 277 | return paymentResponse; 278 | } 279 | 280 | Future _validateToken() async { 281 | if (_token == null) { 282 | final tokenResponse = await _bkashApi.createToken(); 283 | _token = tokenResponse.fold( 284 | (l) => left(l), 285 | (r) { 286 | if (r.statusCode != "0000") { 287 | return left(BkashFailure(message: r.statusMessage)); 288 | } 289 | _tokenValidity = DateTime.now() 290 | .add(Duration(seconds: r.expiresIn)) 291 | .subtract(const Duration(minutes: 5)); 292 | return right(r); 293 | }, 294 | ); 295 | } else { 296 | if (DateTime.now().isBefore(_tokenValidity)) { 297 | return; 298 | } 299 | _token = await _token?.fold( 300 | (l) async => left(l), 301 | (r) async { 302 | final newToken = 303 | await _bkashApi.refreshToken(refreshToken: r.refreshToken); 304 | 305 | return newToken.fold( 306 | (l) => left(l), 307 | (r) { 308 | if (r.statusCode != "0000") { 309 | return left(BkashFailure(message: r.statusMessage)); 310 | } 311 | _tokenValidity = DateTime.now() 312 | .add(Duration(seconds: r.expiresIn)) 313 | .subtract(const Duration(minutes: 5)); 314 | return right(r); 315 | }, 316 | ); 317 | }, 318 | ); 319 | } 320 | } 321 | } 322 | -------------------------------------------------------------------------------- /lib/src/flutter_bkash_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_bkash/src/bkash_payment_status.dart'; 3 | import 'package:webview_flutter/webview_flutter.dart'; 4 | 5 | typedef PaymentStatus = void Function(BkashPaymentStatus bkashPaymentStatus); 6 | 7 | class FlutterBkashView extends StatefulWidget { 8 | final String bkashURL; 9 | final String successCallbackURL; 10 | final String failureCallbackURL; 11 | final String cancelledCallbackURL; 12 | 13 | const FlutterBkashView({ 14 | super.key, 15 | required this.bkashURL, 16 | required this.successCallbackURL, 17 | required this.failureCallbackURL, 18 | required this.cancelledCallbackURL, 19 | }); 20 | 21 | @override 22 | FlutterBkashViewState createState() => FlutterBkashViewState(); 23 | } 24 | 25 | class FlutterBkashViewState extends State { 26 | late WebViewController _webViewController; 27 | 28 | @override 29 | void initState() { 30 | super.initState(); 31 | 32 | _webViewController = WebViewController() 33 | ..setJavaScriptMode(JavaScriptMode.unrestricted) 34 | ..setBackgroundColor(const Color(0x00000000)) 35 | ..setNavigationDelegate( 36 | NavigationDelegate( 37 | // onProgress: (int progress) { 38 | // log(progress.toString()); 39 | // }, 40 | // onPageStarted: (String url) {}, 41 | // onPageFinished: (String url) {}, 42 | onWebResourceError: (WebResourceError error) => Navigator.of(context).pop(BkashPaymentStatus.failed), 43 | onNavigationRequest: (NavigationRequest request) { 44 | if (request.url.contains("bkash.com")) { 45 | //sendbox starts with sandbox.payment.bkash.com and live starts with payment.bkash.com 46 | return NavigationDecision.navigate; 47 | } 48 | if (request.url.startsWith(widget.successCallbackURL)) { 49 | Navigator.of(context).pop(BkashPaymentStatus.successed); 50 | } else if (request.url.startsWith(widget.failureCallbackURL)) { 51 | Navigator.of(context).pop(BkashPaymentStatus.failed); 52 | } else if (request.url.startsWith(widget.cancelledCallbackURL)) { 53 | Navigator.of(context).pop(BkashPaymentStatus.canceled); 54 | } 55 | return NavigationDecision.prevent; 56 | }, 57 | ), 58 | ) 59 | ..loadRequest(Uri.parse(widget.bkashURL)); 60 | } 61 | 62 | @override 63 | void dispose() { 64 | _webViewController.clearCache(); 65 | _webViewController.clearLocalStorage(); 66 | 67 | super.dispose(); 68 | } 69 | 70 | @override 71 | Widget build(BuildContext context) { 72 | return PopScope( 73 | canPop: false, 74 | onPopInvokedWithResult: (didPop, result) async { 75 | if (!didPop) { 76 | if (await _webViewController.canGoBack()) { 77 | await _webViewController.goBack(); 78 | } else { 79 | if (context.mounted) { 80 | Navigator.of(context).pop(BkashPaymentStatus.canceled); 81 | } 82 | } 83 | } 84 | }, 85 | child: Scaffold( 86 | backgroundColor: Colors.white, 87 | appBar: AppBar( 88 | elevation: 0.0, 89 | backgroundColor: Colors.pink, 90 | automaticallyImplyLeading: true, 91 | leading: IconButton( 92 | icon: const Icon(Icons.arrow_back), 93 | color: Colors.white, 94 | onPressed: () => Navigator.of(context).pop(BkashPaymentStatus.canceled), 95 | ), 96 | title: const Text('bKash Checkout')), 97 | body: WebViewWidget(controller: _webViewController), 98 | ), 99 | ); 100 | } 101 | 102 | void showSnackBar(String message) => ScaffoldMessenger.of(context) 103 | ..hideCurrentSnackBar() 104 | ..showSnackBar(SnackBar(content: Text(message))); 105 | } 106 | -------------------------------------------------------------------------------- /lib/src/utils/api_helper.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:developer'; 3 | import 'dart:io'; 4 | 5 | import 'package:fpdart/fpdart.dart'; 6 | import 'package:http/http.dart'; 7 | 8 | import 'failure.dart'; 9 | 10 | mixin ApiHelper { 11 | Future>> networkCallHelper({ 12 | required bool logResponse, 13 | required Future Function() function, 14 | }) async { 15 | try { 16 | final response = await function.call(); 17 | 18 | switch (response.statusCode) { 19 | case 200: 20 | if (logResponse) { 21 | log(response.body, name: "Flutter Bkash"); 22 | } 23 | 24 | return right(json.decode(response.body) as Map); 25 | case 400: 26 | return left(BkashFailure(message: "Bad Request")); 27 | case 401: 28 | return left(BkashFailure(message: "Unauthorized Access")); 29 | case 403: 30 | return left(BkashFailure(message: "Forbidden")); 31 | case 404: 32 | return left(BkashFailure(message: "Not Found")); 33 | case 500: 34 | return left(BkashFailure(message: "Internal Server Error")); 35 | default: 36 | return left(BkashFailure()); 37 | } 38 | } on SocketException catch (e, st) { 39 | return left(BkashFailure( 40 | message: e.message, 41 | error: e, 42 | stackTrace: st, 43 | )); 44 | } catch (e, st) { 45 | return left(BkashFailure( 46 | error: e, 47 | stackTrace: st, 48 | )); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/src/utils/failure.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | class BkashFailure implements Exception { 4 | final String message; 5 | final Object? error; 6 | final StackTrace? stackTrace; 7 | 8 | BkashFailure({ 9 | String? message, 10 | this.error, 11 | this.stackTrace, 12 | }) : message = message ?? "Something went wrong" { 13 | log( 14 | this.message, 15 | error: error, 16 | stackTrace: stackTrace, 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_bkash 2 | description: Flutter package for payment gateway service bKash (Bangladesh). bKash payment easy to implement through this package on your flutter project. 3 | version: 0.3.1 4 | repository: https://github.com/codeboxrcodehub/flutter-bkash 5 | homepage: https://github.com/codeboxrcodehub/flutter-bkash 6 | 7 | environment: 8 | sdk: ">=2.18.0 <4.0.0" 9 | flutter: ">=1.17.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | webview_flutter: ^4.2.2 15 | http: ^1.0.0 16 | fpdart: ^1.1.1 17 | 18 | dev_dependencies: 19 | flutter_test: 20 | sdk: flutter 21 | flutter_lints: ^5.0.0 22 | 23 | # For information on the generic Dart part of this file, see the 24 | # following page: https://dart.dev/tools/pub/pubspec 25 | 26 | # The following section is specific to Flutter packages. 27 | flutter: 28 | # To add assets to your package, add an assets section, like this: 29 | # assets: 30 | # - images/a_dot_burr.jpeg 31 | # - images/a_dot_ham.jpeg 32 | 33 | # For details regarding assets in packages, see 34 | # https://flutter.dev/assets-and-images/#from-packages 35 | # 36 | # An image asset can refer to one or more resolution-specific "variants", see 37 | # https://flutter.dev/assets-and-images/#resolution-aware 38 | 39 | # To add custom fonts to your package, add a fonts section here, 40 | # in this "flutter" section. Each entry in this list should have a 41 | # "family" key with the font family name, and a "fonts" key with a 42 | # list giving the asset and other descriptors for the font. For 43 | # example: 44 | # fonts: 45 | # - family: Schyler 46 | # fonts: 47 | # - asset: fonts/Schyler-Regular.ttf 48 | # - asset: fonts/Schyler-Italic.ttf 49 | # style: italic 50 | # - family: Trajan Pro 51 | # fonts: 52 | # - asset: fonts/TrajanPro.ttf 53 | # - asset: fonts/TrajanPro_Bold.ttf 54 | # weight: 700 55 | # 56 | # For details regarding fonts in packages, see 57 | # https://flutter.dev/custom-fonts/#from-packages 58 | -------------------------------------------------------------------------------- /test/flutter_bkash_test.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | --------------------------------------------------------------------------------