{"id":32272753,"url":"https://github.com/youngcet/payfast_web","last_synced_at":"2026-02-22T01:08:32.168Z","repository":{"id":299628874,"uuid":"1003656258","full_name":"youngcet/payfast_web","owner":"youngcet","description":"A Flutter package to integrate Payfast payments into your Flutter web application.","archived":false,"fork":false,"pushed_at":"2025-10-08T15:55:14.000Z","size":3007,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-22T23:11:34.337Z","etag":null,"topics":["flutter","flutter-web","payfast","payment-gateway","payment-gateway-integration","payments"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/youngcet.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-06-17T13:22:57.000Z","updated_at":"2025-10-08T15:55:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"91bda4b3-4b46-4e7a-ba7e-88f3d5c86524","html_url":"https://github.com/youngcet/payfast_web","commit_stats":null,"previous_names":["youngcet/payfast_web"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/youngcet/payfast_web","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/youngcet%2Fpayfast_web","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/youngcet%2Fpayfast_web/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/youngcet%2Fpayfast_web/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/youngcet%2Fpayfast_web/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/youngcet","download_url":"https://codeload.github.com/youngcet/payfast_web/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/youngcet%2Fpayfast_web/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29702056,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T23:35:04.139Z","status":"ssl_error","status_checked_at":"2026-02-21T23:35:03.832Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flutter","flutter-web","payfast","payment-gateway","payment-gateway-integration","payments"],"created_at":"2025-10-22T23:07:10.503Z","updated_at":"2026-02-22T01:08:32.160Z","avatar_url":"https://github.com/youngcet.png","language":"Dart","funding_links":["https://www.buymeacoffee.com/yungcet"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e   \n    \u003ca href=\"https://github.com/youngcet/payfast_web\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/youngcet/payfast_web?style=social\" alt=\"Repo stars\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/youngcet/payfast_web/commits/main\"\u003e\u003cimg src=\"https://img.shields.io/github/last-commit/youngcet/payfast_web/main?logo=git\" alt=\"Last Commit\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/youngcet/payfast_web/pulls\"\u003e\u003cimg src=\"https://img.shields.io/github/issues-pr/youngcet/payfast_web\" alt=\"Repo PRs\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/youngcet/payfast_web/issues?q=is%3Aissue+is%3Aopen\"\u003e\u003cimg src=\"https://img.shields.io/github/issues/youngcet/payfast_web\" alt=\"Repo issues\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/youngcet/payfast_web/graphs/contributors\"\u003e\u003cimg src=\"https://badgen.net/github/contributors/youngcet/payfast_web\" alt=\"Contributors\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/youngcet/payfast_web/blob/main/LICENSE\"\u003e\u003cimg src=\"https://badgen.net/github/license/youngcet/payfast_web\" alt=\"License\"\u003e\u003c/a\u003e\n    \u003cbr\u003e       \n    \u003ca href=\"https://app.codecov.io/gh/youngcet/payfast_web\"\u003e\u003cimg src=\"https://img.shields.io/codecov/c/github/youngcet/payfast_web?logo=codecov\u0026logoColor=white\" alt=\"Coverage Status\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# Payfast Web Flutter Package\n\nA Flutter package to integrate Payfast payments into your Flutter web app. **This package is for Flutter Web only. If you're looking for the mobile package, the documentation is here: [PayFast for mobile](https://github.com/youngcet/payfast)**.\n\n[![Pub Version](https://img.shields.io/pub/v/payfast_web)](https://pub.dev/packages/payfast_web)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/youngcet/payfast_web/blob/main/LICENSE)\n\u003ca href=\"https://pub.dev/packages/payfast_web\"\u003e\u003cimg src=\"https://badgen.net/pub/points/payfast_web\" alt=\"Pub points\"\u003e\u003c/a\u003e\n\u003ca href=\"https://pub.dev/packages/payfast_web\"\u003e\u003cimg src=\"https://badgen.net/pub/likes/payfast_web\" alt=\"Pub Likes\"\u003e\u003c/a\u003e\n\u003ca href=\"https://pub.dev/packages/payfast_web\"\u003e\u003cimg src=\"https://badgen.net/pub/popularity/payfast_web\" alt=\"Pub popularity\"\u003e\u003c/a\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/youngcet/payfast_web/blob/main/doc/sandbox.gif?raw=true\" height=\"400\"\u003e\n  \u003cimg src=\"https://github.com/youngcet/payfast_web/blob/main/doc/live.gif?raw=true\" height=\"400\"\u003e\n\u003c/p\u003e\n\u003cbr/\u003e\n\u003chr/\u003e\n\u003cbr/\u003e\n\n- [Getting Started](#getting-started)\n  * [Usage](#usage)\n  * [Payfast Onsite Activation Script](#payfast-onsite-activation-script)\n    * [Hosting on Gihub](#hosting-on-github)\n    * [Hosting on a different server](#hosting-on-a-different-server)\n  * [Android \u0026 IOS Setup](#android-and-ios-setup)\n- [Features](#features)\n  * [Onsite Payments](#onsite-payments)\n  * [Sandbox or Live Environment integration](#sandbox-or-live-environment-integration)\n  * [Customizable Payment Summary Widget](#customizable-payment-summary-widget)\n  * [Customizable Payment Button](#customizable-payment-button)\n  * [Customizable Waiting Overlay Widget](#customizable-waiting-overlay-widget)\n  * [FlutterFlow Integration](#flutterflow-integration)\n- [Handling And Understanding Errors](#handling-and-understanding-errors)\n- [Properties](#properties)\n  * [passPhrase](#passphrase)\n  * [useSandBox](#usesandbox)\n  * [data](#data)\n  * [onsiteActivationScriptUrl](#onsiteactivationscripturl)\n  * [paymentSumarryWidget](#paymentsumarrywidget)\n  * [defaultPaymentSummaryIcon](#defaultPaymentSummaryIcon)\n  * [paymentSummaryAmountColor](#paymentSummaryAmountColor)\n  * [itemSummarySectionLeadingWidget](#itemSummarySectionLeadingWidget)\n  * [payButtonStyle](#paybuttonstyle)\n  * [payButtonText](#paybuttontext)\n  * [waitingOverlayWidget](#waitingoverlaywidget)\n  * [backgroundColor](#backgroundcolor)\n  * [animatedSwitcherWidget](#animatedswitcherwidget)\n\n\n## Getting Started\n\nThis package uses Payfast's Onsite Payments integration, therefore, you need to host their onsite activiation script. \n\n## Payfast Onsite Activation Script\n\n### Hosting on Github\n\n\u003e **Note:** You can also host the file on Github Pages\n\nBelow are GitHub links that you can use if you prefer not to host the file yourself or need them for development purposes:\n\n- https://youngcet.github.io/sandbox_payfast_onsite_payments/ \u003e use to point to the sandbox\n- https://youngcet.github.io/payfast_onsite_payments/ \u003e use to point to the live server\n\n\u003e **Note:** While these links are hosted on GitHub, accessing them through a browser will result in a 404 error from Payfast. This behavior is expected and not an issue.\n\n\n### Hosting on a different server\n\nCopy the `html` file below and host it on a secure server:\n\n\n```html\n\u003chtml\u003e\n\u003chead\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\"\u003e\n    \u003cscript src=\"https://sandbox.payfast.co.za/onsite/engine.js\"\u003e\u003c/script\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003cscript\u003e\n            // DO NOT MODIFY THE CODE BELOW\n\n            // retrieve the uuid that is passed to this file and send it to PayFast onsite engine\n            const queryString = window.location.search;\n            const urlParams = new URLSearchParams(queryString);\n            const uuid = urlParams.get('uuid');\n            const return_url = urlParams.get('return_url'); \n            const cancel_url = urlParams.get('cancel_url');\n\n            window.payfast_do_onsite_payment({\"uuid\":uuid}, function (result) {\n                if (result === true) {\n                    // Payment Completed\n                    location.href = decodeURIComponent(return_url); \n                }\n                else {\n                    // Payment Cancelled\n                    location.href = decodeURIComponent(cancel_url);\n                }\n            });\n        \u003c/script\u003e\n\u003c/body\u003e\n\n\u003c/html\u003e\n```\n\nAlternatively, you can create your own `html` file but make sure to include the tags below (**do not modify the code**):\n\n\n```html\n\u003cscript src=\"https://sandbox.payfast.co.za/onsite/engine.js\"\u003e\u003c/script\u003e \n\u003cscript\u003e\n    // retrieve the uuid that is passed to this file and send it to PayFast onsite engine\n    const queryString = window.location.search;\n    const urlParams = new URLSearchParams(queryString);\n    const uuid = urlParams.get('uuid');\n    const return_url = urlParams.get('return_url'); \n    const cancel_url = urlParams.get('cancel_url'); \n\n    window.payfast_do_onsite_payment({\"uuid\":uuid}, function (result) {\n        if (result === true) {\n            // Payment Completed\n            location.href = decodeURIComponent(return_url);\n        }\n        else {\n            // Payment Cancelled\n            location.href = decodeURIComponent(cancel_url);\n        }\n    });\n\u003c/script\u003e\n```\n\nYou can also add your URLs like this instead of a callback:\n```html\n...\n\u003cscript\u003e\n    // DO NOT MODIFY THE CODE BELOW\n    \n    // retrieve the url params that are passed to this file and send them to payfast onsite engine\n    const queryString = window.location.search;\n    const urlParams = new URLSearchParams(queryString);\n    const uuid = urlParams.get('uuid');\n    const return_url = urlParams.get('return_url'); \n    const cancel_url = urlParams.get('cancel_url');\n\n    window.payfast_do_onsite_payment({\n      'uuid':uuid,\n      'return_url': decodeURIComponent(return_url),\n      'cancel_url': decodeURIComponent(cancel_url),\n    });\n\u003c/script\u003e \n```\n\n### Payment Confirmation\nPayfast will send a payment confirmation notification to the \"notify_url\" you specified. The full implementation details can be found [here](https://developers.payfast.co.za/docs#step_4_confirm_payment).\n\nTo point to a live server, simply change `\u003cscript src=\"https://sandbox.payfast.co.za/onsite/engine.js\"\u003e\u003c/script\u003e` tag to `\u003cscript src=\"https://www.payfast.co.za/onsite/engine.js\"\u003e\u003c/script\u003e`. Take note of the url where the `html` file is hosted, you're going pass it along in the Payfast package. \n\nWe have to host the file because for security reasons 'Onsite Payments' requires that your application be served over HTTPS. For more detailed documentation, please refer to the official [Payfast Onsite Payments documentation](https://developers.payfast.co.za/docs#onsite_payments). \n\n\u003cp align=\"left\"\u003e\n\u003cimg src=\"https://github.com/youngcet/payfast/blob/main/doc/sandbox.png?raw=true\" alt=\"Sandbox Screenshot\" height=\"600\" width=\"280\" style=\"border:1px solid grey\"/\u003e\n\u003cimg src=\"https://github.com/youngcet/payfast/blob/main/doc/live.png?raw=true\" alt=\"Live Screenshot\" height=\"600\" width=\"280\" style=\"border:1px solid grey\"/\u003e\n\u003c/p\u003e\n\n## Usage\n\nInstall the library to your project by running: \n\n```bash\nflutter pub add payfast_web\n```\n\nor add the following dependency in your `pubspec.yaml` (replace `^latest_version` with the latest version):\n\n\n```yaml\ndependencies:\n  payfast_web: ^latest_version\n```\n\n**Import the package and create a PayFast Widget**\n\n```dart\nimport 'dart:math';\n\nimport 'package:example/payment_cancelled.dart';\nimport 'package:example/payment_completed.dart';\nimport 'package:flutter/cupertino.dart';\nimport 'package:flutter/material.dart';\nimport 'package:payfast_web/payfast_web.dart';\nimport 'package:modal_bottom_sheet/modal_bottom_sheet.dart';\n\nvoid main() {\n  runApp(const MyApp());\n}\n\nclass MyApp extends StatelessWidget {\n  const MyApp({super.key});\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      initialRoute: '/',\n      routes: {\n        '/': (context) =\u003e const MyHomePage(title: 'Flutter Demo Home Page'),\n        '/payment-completed': (context) =\u003e const PaymentCompletedScreen(), // -\u003e add a route for when a payment is completed\n        '/payment-cancelled': (context) =\u003e const PaymentCancelledScreen(), // add a route for when a payment is cancelled\n      },\n      title: 'Flutter Demo',\n      theme: ThemeData(\n        primarySwatch: Colors.blue,\n      ),\n    );\n  }\n}\n\nclass MyHomePage extends StatefulWidget {\n  const MyHomePage({super.key, required this.title});\n\n  final String title;\n\n  @override\n  State\u003cMyHomePage\u003e createState() =\u003e _MyHomePageState();\n}\n\nclass _MyHomePageState extends State\u003cMyHomePage\u003e {\n  @override\n  void initState() {\n    super.initState();\n  }\n\n  String _randomId() {\n    var rng = Random();\n    var randomNumber = rng.nextInt(900000) + 100000;\n\n    return '$randomNumber';\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Material(\n        child: Scaffold(\n          body: CupertinoPageScaffold(\n            navigationBar: CupertinoNavigationBar(\n              transitionBetweenRoutes: false,\n              middle: const Text('Payfast Widget Demo'),\n              trailing: GestureDetector(\n                child: const Icon(Icons.arrow_forward),\n                onTap: () =\u003e Navigator.of(context).pushNamed('/thank-you'),\n              ),\n            ),\n            child: SizedBox.expand(\n              child: SingleChildScrollView(\n                primary: true,\n                child: SafeArea(\n                  bottom: false,\n                  child: Column(\n                    crossAxisAlignment: CrossAxisAlignment.stretch,\n                    mainAxisSize: MainAxisSize.min,\n                    children: \u003cWidget\u003e[\n                      ListTile(\n                        title: const Text('Checkout using PayFast \u003e\u003e'),\n                        onTap: () =\u003e showCupertinoModalBottomSheet(\n                          expand: true,\n                          bounce: true,\n                          enableDrag: true,\n                          context: context,\n                          backgroundColor: Colors.white,\n                          builder: (context) =\u003e PayFast(\n                            data: {\n                              'merchant_id': '00000',\n                              'merchant_key': '000000',\n                              'name_first': 'Yung',\n                              'name_last': 'Cet',\n                              'email_address': 'young.cet@gmail.com',\n                              'm_payment_id': _randomId(),\n                              'amount': '20',\n                              'item_name': 'Subscription',\n                            },\n                            passPhrase: 'xxxxxxxxxx',\n                            useSandBox: true,\n                            payButtonStyle: ElevatedButton.styleFrom(\n                              padding: const EdgeInsets.symmetric(vertical: 16),\n                              backgroundColor: Colors.red,\n                              shadowColor: Colors.transparent,\n                            ),\n                            onsiteActivationScriptUrl:\n                                'https://youngcet.github.io/sandbox_payfast_onsite_payments/',\n                            paymentCancelledRoute: 'payment-cancelled', // -\u003e name of the route as defined in routes:\n                            paymentCompletedRoute: 'payment-completed', // -\u003e name of the route as defined in routes:\n                          ),\n                        ),\n                      ),\n                    ],\n                  ),\n                ),\n              ),\n            ),\n          ),\n        ),\n    );\n  }\n}\n```\n\nThe code above will show you the screen below:\n\n\u003cimg src=\"https://github.com/youngcet/payfast/blob/main/doc/basic_app_screenshot.png?raw=true\" alt=\"Basic App Screenshot\" height=\"600\" width=\"280\"/\u003e\n\n\n\n## Features\n\n### Onsite Payments\n\nIntegrate PayFast's secure payment engine directly into the checkout page. Important: Please note that this is currently in Beta according to PayFast's documentation, however, it works fine.\n\n### Sandbox or Live Environment integration\n\nConfigure whether to use PayFast's sandbox or live server. When you choose to use the sandbox or live server, ensure that the hosted `html` file also points to the server's onsite activation script (`\u003cscript src=\"https://sandbox.payfast.co.za/onsite/engine.js\"\u003e\u003c/script\u003e`) and the PayFast merchant id and key corresponds to the appropiate server.\n\n```dart\nPayFast(\n    ...\n    useSandBox: true, // true to use Payfast sandbox, false to use their live server\n) \n```\n\n### Customizable Payment Summary Widget\n\nProvide a custom widget for displaying the payment summary with the `paymentSumarryWidget` property. This allows for full customization of the payment details display. Only the highlighted section can be replaced with a custom widget.\n\n\u003cimg src=\"https://github.com/youngcet/payfast/blob/main/doc/payment_summary.png?raw=true\" alt=\"Payment Summary\" width=\"280\"/\u003e\n\n\n\nCustom Payment Summary Widget\n\n```dart\nPayFast(\n    ...\n    ...\n    paymentSumarryWidget: Column(\n      crossAxisAlignment: CrossAxisAlignment.start,\n      children: [\n        const Text(\n          'Order Summary',\n          style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, decoration: TextDecoration.none, color: Colors.black),\n        ),\n        const SizedBox(height: 10),\n        Card(\n          elevation: 3,\n          child: Padding(\n            padding: const EdgeInsets.all(16.0),\n            child: Column(\n              children: const [\n                ListTile(\n                  title: Text('Product 1'),\n                  trailing: Text('R20.00'),\n                ),\n                ListTile(\n                  title: Text('Product 2'),\n                  trailing: Text('R15.00'),\n                ),\n                Divider(),\n                ListTile(\n                  title: Text(\n                    'Total',\n                    style: TextStyle(fontWeight: FontWeight.bold),\n                  ),\n                  trailing: Text(\n                    'R35.00',\n                    style: TextStyle(fontWeight: FontWeight.bold),\n                  ),\n                ),\n              ],\n            ),\n          ),\n        ),\n      ],\n    ),\n) \n```\n\n\n\u003cimg src=\"https://github.com/youngcet/payfast/blob/main/doc/payment_summary_widget.png?raw=true\" alt=\"Payment Summary Custom Widget\" width=\"280\"/\u003e\n\n\nOr modify the default widget using the properties below:\n\n**Payment Summary Title \u0026 Icon:** Use the `paymentSummaryTitle` and `defaultPaymentSummaryIcon` properties to customize the title and icon of the payment summary section, ensuring it matches your app's theme.\n\n```dart\nPayFast(\n    ...\n    paymentSummaryTitle: 'Order Summary',\n    defaultPaymentSummaryIcon: const Icon(\n      Icons.shopping_cart,\n      size: 50,\n      color: Colors.grey,\n    ),\n) \n```\n\n\n\u003cimg src=\"https://github.com/youngcet/payfast/blob/main/doc/payment_summary_text_icon.png?raw=true\" alt=\"Payment Summary Custom Text \u0026 Icon\" width=\"280\"/\u003e\n\n\n### Customizable Payment Button\n\nThe `payButtonStyle` and `payButtonText` properties allow you to style the \"Pay Now\" button and change its text and styling, ensuring that it fits seamlessly with your app's design.\n\n```dart\nPayFast(\n    ...\n    payButtonText: 'Checkout \u003e\u003e',\n    payButtonStyle: ElevatedButton.styleFrom(\n      padding: const EdgeInsets.symmetric(vertical: 16),\n      backgroundColor: Colors.black,\n      shadowColor: Colors.transparent,\n      textStyle: TextStyle(backgroundColor: Colors.black)\n    ),\n    payButtonLeadingWidget: const Icon(Icons.payments), // set an icon next to the 'button text'\n) \n```\n\n\n\u003cimg src=\"https://github.com/youngcet/payfast/blob/main/doc/customised_pay_button.png?raw=true\" alt=\"Custom Pay Button\" width=\"280\"/\u003e\n\n\n### FlutterFlow Integration\n\n**PayFast Flutter Package Integration with FlutterFlow**\n\nFlutterFlow Demo:\nhttps://app.flutterflow.io/share/pay-fast-demo-wgqscg\n\nTo integrate with FluterFlow, \n\n1. Create a new Custom Widget under **Custom Code** in FlutterFlow.\n2. Rename the widget to **PayFastWidget**.\n3. Under Widget Settings, add the following parameters:\n\n\u003cimg src=\"https://github.com/youngcet/payfast_web/blob/main/doc/flutterflow_widget_settings.png?raw=true\" alt=\"FlutterFlow Settings\" width=\"280\"/\u003e\n\n\n4. Add **payfast_web: ^latest_version** to the dependencies and refresh the UI (replace latest_version with the latest version).\n\n\u003cimg src=\"https://github.com/youngcet/payfast_web/blob/main/doc/flutterflow_dependency.png?raw=true\" alt=\"FlutterFlow Dependency\" width=\"280\"/\u003e\n\n\n5. Copy and paste the code below (**do not use the boilerplate code provided**):\n\n```dart \n// Automatic FlutterFlow imports\nimport '/flutter_flow/flutter_flow_theme.dart';\nimport '/flutter_flow/flutter_flow_util.dart';\nimport '/custom_code/widgets/index.dart'; // Imports other custom widgets\nimport '/flutter_flow/custom_functions.dart'; // Imports custom functions\nimport 'package:flutter/material.dart';\n// Begin custom widget code\n// DO NOT REMOVE OR MODIFY THE CODE ABOVE!\n\nimport 'package:payfast_web/payfast_web.dart';\n\n// Set your widget name, define your parameter, and then add the\n// boilerplate code using the green button on the right!\n\nclass PayFastWidget extends StatefulWidget {\n  final String passPhrase;\n  final bool useSandBox;\n  final dynamic data;\n  final String onsiteActivationScriptUrl;\n\n  // fields below are required for a FlutterFlow widget\n  final double? width;\n  final double? height;\n\n  const PayFastWidget({\n    required this.useSandBox,\n    required this.passPhrase,\n    required this.data,\n    required this.onsiteActivationScriptUrl,\n    this.width,\n    this.height,\n    Key? key,\n  }) : super(key: key);\n\n  @override\n  State\u003cPayFastWidget\u003e createState() =\u003e _PayFastWidgetState();\n}\n\nclass _PayFastWidgetState extends State\u003cPayFastWidget\u003e {\n  @override\n  Widget build(BuildContext context) {\n    return Material(\n      child: Scaffold(\n          body: Center(\n              child: PayFast(\n              data: widget.data,\n              passPhrase: widget.passPhrase,\n              useSandBox: widget.useSandBox,\n              onsiteActivationScriptUrl: widget.onsiteActivationScriptUrl,\n              paymentCancelledRoute: 'paymentCancelled',\n              paymentCompletedRoute: 'paymentCompleted',\n              paymentSumarryWidget: _paymentSummary(), // pass widget\n              // add other parameters as needed\n      ))),\n    );\n  }\n\n  // modify or remove this widget\n  // this is only for demostration purposes\n  Widget _paymentSummary() {\n    return Column(\n      crossAxisAlignment: CrossAxisAlignment.start,\n      children: [\n        const Text(\n          'Order Summary',\n          style: TextStyle(\n              fontSize: 18,\n              fontWeight: FontWeight.bold,\n              decoration: TextDecoration.none,\n              color: Colors.black),\n        ),\n        const SizedBox(height: 10),\n        Card(\n          elevation: 3,\n          child: Padding(\n            padding: const EdgeInsets.all(16.0),\n            child: Column(\n              children: const [\n                ListTile(\n                  title: Text('Product 1'),\n                  trailing: Text('R20.00'),\n                ),\n                ListTile(\n                  title: Text('Product 2'),\n                  trailing: Text('R15.00'),\n                ),\n                Divider(),\n                ListTile(\n                  title: Text(\n                    'Total',\n                    style: TextStyle(fontWeight: FontWeight.bold),\n                  ),\n                  trailing: Text(\n                    'R35.00',\n                    style: TextStyle(fontWeight: FontWeight.bold),\n                  ),\n                ),\n              ],\n            ),\n          ),\n        ),\n      ],\n    );\n  }\n}\n```\n\nThe widget is designed to accept only the required parameters, making it simple to configure within the 'Widget Palette'. For additional optional parameters, which are more cosmetic, it is recommended to add them directly in the code. This approach is similar to how the `paymentSummaryWidget` was integrated in the example above.\n\n6. Save and Compile the code. There should be no errors.\n7. In the **Widget Palette**, drag and drop the PayFast Widget onto your page. Select the widget and configure the required parameters. For the `onPaymentCancelled` and `onPaymentCompleted` callbacks, add appropriate actions, such as navigating to a specific page or displaying a confirmation message.\n8. Create new pages for Payment Completed and Payment Cancelled, making sure their routes are set to `paymentCompleted` and `paymentCancelled` respectively. You can find the name of the route in the page properties under 'Route Settings'\n\n\u003cimg src=\"https://github.com/youngcet/payfast_web/blob/main/doc/flutterflow_widget_settings.png?raw=true\" alt=\"FlutterFlow Route Settings\" width=\"280\"/\u003e\n\n**Note**: You can update the route names in the widget above to match your chosen routes.\n\n\n**Testing the Payment Flow**\n\nTo test the payment flow, make sure that the useSandBox flag is set to true in the PayFast widget.\n\nUse the provided sandbox URL (https://youngcet.github.io/sandbox_payfast_onsite_payments/) or replace it with your own sandbox testing URL.\n\n\n\u003cp\u003e\n\u003cimg src=\"https://github.com/youngcet/payfast/blob/main/doc/flutterflow_02.png?raw=true\" alt=\"FlutterFlow PayFast Widget\" style=\"width:100%\"/\u003e\n\u003c/p\u003e\n\n\n## How to fix the hash routing conflict:\nIf your app doesn't navigate correctly to payment completion or cancellation pages after a transaction—despite having the correct route names—this issue is likely caused by hash routing conflicts.\n\nIn your `PayFast` Widget, disable the hash routing in the `RouteGenerator`.\n```dart\nPayFast(\n  ...\n  routeGenerator: RouteGenerator(\n     useHashRouting: false  // set to false\n  ),\n)\n```\n\n## Handling And Understanding Errors\n### Payfast Errors\nYou can now handle Payfast errors gracefully by using the `onError` callback. This callback is triggered when Payfast returns an error message.\n\n```dart\nPayFast(\n  onError: (errorMessage) {\n    print('Payfast Error: $errorMessage');\n\n    // Example: show a snackbar or alert dialog\n    ScaffoldMessenger.of(context).showSnackBar(\n      SnackBar(content: Text(errorMessage)),\n    );\n  },\n)\n```\n\nIf the callback is not set, the default error page will be displayed.\n\n### Package Errors\n- Unable to generate a payment reference\n  - Possible cause, downtime on Payfast's servers.\n- Failed to get transaction status from the activation script\n  - Caused by incorrect callbacks on the activation script.\n- This package does not support web\n  - As the error message suggests, the package does not support web.\n\n\n## Properties\n\n### `passPhrase`:  \n  The passphrase provided by Payfast for security.\n\n### `useSandBox`:  \n  A boolean flag to choose between sandbox or live environment.\n\n### `data`:  \n  A `Map\u003cString, dynamic\u003e` containing the required payment data. This includes keys like:\n  - `merchant_id`\n  - `merchant_key`\n  - `name_first`\n  - `name_last`\n  - `amount`\n  - `item_name`\n  - `m_payment_id`\n\n  optional:\n  - `item_description` string, 255 char\n    - The description of the item being charged for, or in the case of multiple items the order description.\n  - `fica_idnumber` integer, 13 char\n    - The Fica ID Number provided of the buyer must be a valid South African ID Number.\n  - `cell_number` string, 100 char\n    - The customer’s valid cell number. If the email_address field is empty, and cell_number provided, the system will use the cell_number as the username and auto login the user, if they do not have a registered account\n  - `email_confirmation` boolean, 1 char\n    - Whether to send an email confirmation to the merchant of the transaction. The email confirmation is automatically sent to the payer. 1 = on, 0 = off\n  - `confirmation_address` string, 100 char\n    - The email address to send the confirmation email to. This value can be set globally on your account. Using this field will override the value set in your account for this transaction.\n  - `payment_method` string, 3 char | Not available in Sandbox\n    - When this field is set, only the SINGLE payment method specified can be used when the customer reaches Payfast. If this field is blank, or not included, then all available payment methods will be shown.\n\n      The values are as follows:\n        - ‘ef’ – EFT\n        - ‘cc’ – Credit card\n        - ‘dc’ – Debit card\n        - ’mp’ – Masterpass Scan to Pay\n        - ‘mc’ – Mobicred\n        - ‘sc’ – SCode\n        - ‘ss’ – SnapScan\n        - ‘zp’ – Zapper\n        - ‘mt’ – MoreTyme\n        - ‘rc’ – Store card\n        - ‘mu’ – Mukuru\n        - ‘ap’ – Apple Pay\n        - ‘sp’ – Samsung Pay\n        - ‘cp’ – Capitec Pay\n\n\n### `onsiteActivationScriptUrl`:  \n  The html file URL used for onsite payment activation.\n\n  Below are GitHub links that you can use if you prefer not to host the file yourself or need them for development purposes:\n\n- https://youngcet.github.io/sandbox_payfast_onsite_payments/ \u003e use to point to the sandbox\n- https://youngcet.github.io/payfast_onsite_payments/ \u003e use to point to the live server\n\n\n### `paymentSumarryWidget`:  \n  A custom widget to display the payment summary before the user proceeds with the payment.\n\n### `defaultPaymentSummaryIcon`:\n  An icon to display next to the payment summary item details.\n\n### `paymentSummaryAmountColor`:\n  The amount text color on the payment summary page\n\n### `itemSummarySectionLeadingWidget`:\n  A custom widget to display next to the payment summary item details.\n\n### `payButtonStyle`:  \n  The style of the \"Pay Now\" button.\n\n### `payButtonText`:  \n  The text displayed on the \"Pay Now\" button.\n\n### `payButtonLeadingWidget`:\n  The widget displayed next to the \"Pay Now\" button.\n\n### `backgroundColor`:  \n  A background color of the payment summary page\n\n## Conclusion\n\nThis package allows you to easily integrate Payfast into your Flutter web project and FlutterFlow. The integration can be fully customized to match your app's payment requirements. For production, ensure that you replace the sandbox configuration with live credentials and URLs.\n\n\n## Contributing\n\n### Github Repository\nIf you have ideas or improvements for this package, we welcome contributions. Please open an issue or create a pull request on our [GitHub repository](https://github.com/youngcet/payfast_web).\n\n### Join Our Community on Discord! 🎮\n\nLooking for support, updates, or a place to discuss the **PayFast Flutter Package**? Join our dedicated Discord channel!\n\n👉 [Join the `#payfast-flutter-package` channel](https://discord.gg/Gh9J5sns)\n\n### What You'll Find:\n- **Help \u0026 Support**: Get assistance with integrating and using the package.\n- **Feature Discussions**: Share ideas for new features or improvements.\n- **Bug Reports**: Report issues and collaborate on fixes.\n- **Community Interaction**: Engage with fellow developers working on Flutter projects.\n\nWe look forward to seeing you there! 🚀\n\n## License\n\nThis package is available under the [MIT License](https://github.com/youngcet/payfast_web/blob/main/LICENSE).\n\nSupport the plugin \u003ca href=\"https://www.buymeacoffee.com/yungcet\" target=\"_blank\"\u003e\u003cimg src=\"https://i.imgur.com/aV6DDA7.png\" alt=\"Buy Me A Coffee\" style=\"height: 41px !important;width: 174px !important; box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\" \u003e \u003c/a\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyoungcet%2Fpayfast_web","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyoungcet%2Fpayfast_web","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyoungcet%2Fpayfast_web/lists"}