flutter_payment_plugin 1.0.16
flutter_payment_plugin: ^1.0.16 copied to clipboard
A Flutter plugin for Omniware Payment Gateway integration.
Flutter Payment Plugin — Step‑by‑Step Integration #
This guide explains how to add and use flutter_payment_plugin in any Flutter app.
1) Add the Package #
- Run:
flutter pub add flutter_payment_plugin - Import:
import 'package:flutter_payment_plugin/flutter_payment_plugin.dart';
2) Android Setup #
- No additional Android changes are required.
3) Web Setup #
- Copy
payment_return.htmlfrom the example app into your app’sweb/folder. - Set
return_urlin payment params to your hosted page, e.g.https://your-app.com/payment_return.html. This URL must be included when you generate the payment hash. - Allow popups for your site in the browser; the plugin opens a new tab and POSTs directly to the gateway.
- After payment, the gateway redirects to
payment_return.html, which notifies your Flutter app viapostMessage/BroadcastChannel.
Optional: add a redirect file web/payment_return (no extension) that forwards to payment_return.html if your gateway omits .html in redirects.
4) iOS Setup #
- To make the deep links to open payment apps, add these URL schemes to
ios/<YourAppName>/Info.plist:
<key>LSApplicationQueriesSchemes</key>
<array>
<!-- Add the schemes you plan to support -->
<string>upi</string>
<string>gpay</string>
<string>phonepe</string>
<string>paytm</string>
<!-- etc. -->
</array>
5) Prepare Your Inputs #
url: your payment gateway base domain (e.g.,https://your-gateway.example)paramsmust include at least:api_key,order_id,salt,hash,mode,amount,name,phone,email,return_url- Optional fields as required by your gateway:
description,currency,country,city,state,address_line_1,address_line_2,zip_code,enable_auto_refund,udf1–udf5,split_info(JSON string for vendor settlement splits)
Hashing Logic (Recommended on Backend) #
While it is highly recommended to generate the secure hash on your backend, here is the Dart logic for reference. The hash generation requires camelCase keys for sorting, even though the final request uses snake_case.
import 'dart:convert';
import 'package:crypto/crypto.dart'; // Add crypto: ^3.0.0 to pubspec.yaml
String generateHash({
required String salt,
required String apiKey,
required Map<String, String> camelCaseInputs,
}) {
// 1. Prepare map with REQUIRED camelCase keys
final Map<String, String> params = {
"aaaasalt": salt,
"apiKey": apiKey,
"mode": camelCaseInputs["mode"] ?? "",
"amount": camelCaseInputs["amount"] ?? "",
"name": camelCaseInputs["name"] ?? "",
"phone": camelCaseInputs["phone"] ?? "",
"email": camelCaseInputs["email"] ?? "",
"returnURL": camelCaseInputs["returnURL"] ?? "",
"description": camelCaseInputs["description"] ?? "",
"currency": camelCaseInputs["currency"] ?? "",
"country": camelCaseInputs["country"] ?? "",
"city": camelCaseInputs["city"] ?? "",
"state": camelCaseInputs["state"] ?? "",
"addressLine1": camelCaseInputs["addressLine1"] ?? "",
"addressLine2": camelCaseInputs["addressLine2"] ?? "",
"zipCode": camelCaseInputs["zipCode"] ?? "",
"enable_auto_refund": camelCaseInputs["enable_auto_refund"] ?? "",
"orderID": camelCaseInputs["orderID"] ?? "",
"splitInfo": camelCaseInputs["splitInfo"] ?? "", // when using split_info
};
// 2. Sort keys alphabetically
final entries = params.entries.toList()..sort((a, b) => a.key.compareTo(b.key));
// 3. Join non-empty values with '|'
final buffer = StringBuffer();
for (final e in entries) {
final v = e.value.trim();
if (v.isNotEmpty) buffer.write('|$v');
}
if (buffer.isEmpty) return "";
// 4. Remove leading '|'
final toHash = buffer.toString().substring(1);
// 5. Generate SHA-512 and convert to Uppercase Hex
final digest = sha512.convert(utf8.encode(toHash));
return digest.bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join().toUpperCase();
}
6) Trigger the Payment #
Future<void> startPayment() async {
final params = <String, String>{
'api_key': 'YOUR_API_KEY',
'order_id': 'YOUR_ORDER_ID',
'salt': 'YOUR_SALT',
'hash': 'YOUR_GENERATED_HASH',
'mode': 'LIVE',
'amount': '100',
'name': 'Buyer Name',
'phone': '9999999999',
'email': 'buyer@example.com',
'return_url': 'https://your.domain/return',
// optional fields...
};
final result = await FlutterPaymentPlugin.openPayment(
url: 'https://your-gateway.example',
params: params,
title: 'Payment',
);
if (result.cancelled) {
// Handle cancellation
} else if (result.success) {
// Handle success, check result.data if provided
} else {
// Handle failure, inspect result.data
}
}
7) Integration Tips #
- Ensure all required fields are set and trimmed.
- Use a reachable
return_urlprovided by your gateway. - Prefer generating
hashsecurely on your backend. - Provide only the base
url; the plugin handles the payment endpoint internally.
8) Common Issues #
- Wrong base URL: ensure your
urlpoints to the correct gateway domain. - Network errors: check device connectivity and the base
url. - iOS deep links: add URL schemes for the apps your flow targets.
- Web popups blocked: allow popups; result
datamay bePOPUP_BLOCKED. - Web timeout: ensure
return_urlpoints to your same-originpayment_return.htmland the hash was generated with that exact URL.