{"id":50484741,"url":"https://github.com/programmingwormhole/piprapay-flutter","last_synced_at":"2026-06-01T21:01:33.176Z","repository":{"id":341097509,"uuid":"1168865457","full_name":"programmingwormhole/piprapay-flutter","owner":"programmingwormhole","description":"Secure Flutter SDK for integrating PipraPay payment gateway","archived":false,"fork":false,"pushed_at":"2026-02-27T23:09:42.000Z","size":64,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-28T04:52:55.057Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/programmingwormhole.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","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":"2026-02-27T22:13:47.000Z","updated_at":"2026-02-27T23:09:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/programmingwormhole/piprapay-flutter","commit_stats":null,"previous_names":["programmingwormhole/piprapay-flutter"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/programmingwormhole/piprapay-flutter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programmingwormhole%2Fpiprapay-flutter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programmingwormhole%2Fpiprapay-flutter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programmingwormhole%2Fpiprapay-flutter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programmingwormhole%2Fpiprapay-flutter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/programmingwormhole","download_url":"https://codeload.github.com/programmingwormhole/piprapay-flutter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programmingwormhole%2Fpiprapay-flutter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33793044,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2026-06-01T21:01:30.874Z","updated_at":"2026-06-01T21:01:33.165Z","avatar_url":"https://github.com/programmingwormhole.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🚀 Piprapay Flutter Package\n\n[![Pub Version](https://img.shields.io/pub/v/piprapay)](https://pub.dev/packages/piprapay)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Flutter](https://img.shields.io/badge/Flutter-3.10+-blue.svg)](https://flutter.dev)\n[![Dart](https://img.shields.io/badge/Dart-3.0+-blue.svg)](https://dart.dev)\n[![GitHub](https://img.shields.io/badge/GitHub-programmingwormhole-black.svg)](https://github.com/programmingwormhole/piprapay-flutter)\n\nA **production-ready, type-safe** Flutter package for seamless integration with [Piprapay](https://piprapay.com) payment gateway. Build powerful payment solutions with complete API support (V2 \u0026 V3+), comprehensive error handling, and professional payment UI capabilities.\n\n---\n\n## ✨ Features\n\n### 🌟 Core Features\n- ✅ **Complete Piprapay API Integration** - Full support for V2 and V3+ APIs with automatic version detection\n- ✅ **Payment Creation \u0026 Management** - Create charges, extract checkout URLs, handle payment references\n- ✅ **Real-time Verification** - Verify payment status with detailed transaction information\n- ✅ **Refund Processing** - Process full and partial refunds securely\n- ✅ **Webhook Validation** - Built-in webhook payload validation and signature verification\n- ✅ **Activity Logging** - Optional in-app payment activity tracking and monitoring\n\n### 🔒 Security \u0026 Reliability\n- ✅ **Type-Safe Models** - Null-safe, fully-typed data models with JSON serialization\n- ✅ **Professional Error Handling** - Specific exceptions for different error scenarios\n- ✅ **Flexible Type Conversion** - Handles inconsistent API responses (numeric/string fields)\n- ✅ **API Key Authentication** - Secure API key management and validation\n- ✅ **HTTPS Communication** - All traffic encrypted and secure\n- ✅ **Webhook Signature Verification** - Cryptographic validation of webhook payloads\n\n### 🎯 Developer Experience\n- ✅ **Simple, Intuitive API** - Clean, easy-to-use service interface\n- ✅ **Sandbox \u0026 Production Modes** - Built-in environment switching\n- ✅ **Comprehensive Documentation** - Detailed API references and integration guides\n- ✅ **Example App Included** - Full-featured example showing best practices\n- ✅ **Input Validation Utilities** - Email, mobile number, and payment status validators\n- ✅ **Zero Dependencies** - Minimal external dependencies (only `http` and `crypto`)\n\n### 🎨 UI Enhancements (Built-in)\n- ✅ **WebView Payment Handler** - Built-in WebView for seamless in-app payment execution\n- ✅ **Payment Status Detection** - Automatic detection of success, cancel, and failure states\n- ✅ **Customizable UI** - Configurable app bar title and display duration\n- ✅ **Error Handling** - Comprehensive error detection and reporting\n\n---\n\n## 📦 Installation\n\n### Add to your `pubspec.yaml`:\n\n```yaml\ndependencies:\n  piprapay: ^1.0.0\n```\n\n### Run:\n```bash\nflutter pub get\n```\n\n\u003e **Note:** The package includes `webview_flutter` for in-app payment execution. No additional dependencies needed!\n\n---\n\n## 🚀 Quick Start\n\n### 1️⃣ Initialize the Piprapay Service\n\n#### Basic Initialization\n\n```dart\nimport 'package:piprapay/piprapay.dart';\n\n// Sandbox Mode (Testing) - Minimal configuration\nfinal piprapay = PiprapayService.sandbox(\n  apiKey: 'your_sandbox_api_key',  // ✅ Required\n);\n\n// Production Mode - Minimal configuration\nfinal piprapay = PiprapayService.production(\n  apiKey: 'your_production_api_key',  // ✅ Required\n  baseUrl: 'https://api.piprapay.com/api',  // ✅ Required for production\n);\n```\n\n#### Advanced Initialization (With All Options)\n\n```dart\n// Sandbox with all optional parameters\nfinal piprapay = PiprapayService.sandbox(\n  apiKey: 'your_sandbox_api_key',              // ✅ Required\n  panelVersion: PanelVersion.v3plus,           // ⚙️ Optional (default: V3+)\n  enableLogging: true,                          // ⚙️ Optional (default: false) - Enables request/response logging\n  timeout: Duration(seconds: 30),              // ⚙️ Optional (default: system timeout)\n);\n\n// Production with all optional parameters\nfinal piprapay = PiprapayService.production(\n  apiKey: 'your_production_api_key',           // ✅ Required\n  baseUrl: 'https://api.piprapay.com/api',     // ✅ Required\n  panelVersion: PanelVersion.v3plus,           // ⚙️ Optional (default: V3+)\n  enableLogging: false,                         // ⚙️ Optional (default: false) - Set true for debugging\n  timeout: Duration(seconds: 60),              // ⚙️ Optional (default: system timeout)\n);\n\n// Manual Configuration (Advanced)\nfinal piprapay = PiprapayService(\n  apiKey: 'your_api_key',                      // ✅ Required\n  isSandbox: true,                              // ✅ Required - true for testing, false for production\n  baseUrl: 'https://custom.piprapay.com/api',  // ⚙️ Optional (auto-set if isSandbox: true)\n  panelVersion: PanelVersion.v2,               // ⚙️ Optional - Use V2 for legacy API\n  enableLogging: true,                          // ⚙️ Optional - Logs API calls for debugging\n  timeout: Duration(seconds: 45),              // ⚙️ Optional - Custom timeout duration\n);\n```\n\n#### Initialization Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `apiKey` | String | ✅ Yes | - | Your Piprapay API key from dashboard |\n| `baseUrl` | String | ✅ Yes (Production) | Sandbox URL | API endpoint URL (required when `isSandbox: false`) |\n| `isSandbox` | bool | ✅ Yes (Manual) | - | `true` for testing, `false` for production |\n| `panelVersion` | PanelVersion | ⚙️ Optional | `v3plus` | API version: `PanelVersion.v2` or `PanelVersion.v3plus` |\n| `enableLogging` | bool | ⚙️ Optional | `false` | Enable detailed request/response logging (useful for debugging) |\n| `timeout` | Duration | ⚙️ Optional | System default | Maximum time to wait for API responses |\n\n#### Panel Version Options\n\n```dart\n// For V3+ API (Latest - Recommended)\nfinal piprapay = PiprapayService.sandbox(\n  apiKey: 'your_key',\n  panelVersion: PanelVersion.v3plus,  // Uses pp_id, pp_url, latest features\n);\n\n// For V2 API (Legacy Support)\nfinal piprapay = PiprapayService.sandbox(\n  apiKey: 'your_key',\n  panelVersion: PanelVersion.v2,  // Uses transaction_id, older endpoints\n);\n```\n\n### 2️⃣ Create a Payment Charge\n\n#### For V3+ API (Recommended)\n\n```dart\ntry {\n  final charge = await piprapay.createCharge(\n    // ✅ Required Parameters (V3+)\n    fullName: 'Customer Name',                          // ✅ Required\n    emailAddress: 'customer@example.com',               // ✅ Required (must be valid email)\n    mobileNumber: '+8801700000000',                     // ✅ Required (with country code)\n    amount: '100.00',                                   // ✅ Required (as String)\n    returnUrl: 'https://yourapp.com/payment/return',   // ✅ Required (success redirect)\n    webhookUrl: 'https://yourapp.com/api/webhook',     // ✅ Required (backend notification)\n    \n    // ⚙️ Optional Parameters\n    currency: 'BDT',                                    // ⚙️ Optional (default: BDT)\n    metadata: {'order_id': '12345', 'user_id': '789'}, // ⚙️ Optional (custom data)\n  );\n\n  // Extract payment information\n  String checkoutUrl = piprapay.extractCheckoutUrl(charge)!;\n  String paymentRef = piprapay.extractPaymentReference(charge)!;\n\n  print('✅ Invoice: ${charge.invoiceId}');\n  print('✅ Payment URL: $checkoutUrl');\n  print('✅ Payment Reference (pp_id): $paymentRef');\n  \n} on PiprapayRequestException catch (e) {\n  print('❌ Validation Error: ${e.message}');\n} on PiprapayException catch (e) {\n  print('❌ Error: ${e.message}');\n}\n```\n\n#### For V2 API (Legacy Support)\n\n```dart\ntry {\n  final charge = await piprapay.createCharge(\n    // ✅ Required Parameters (V2)\n    fullName: 'Customer Name',                            // ✅ Required\n    emailOrMobile: 'customer@example.com',                // ✅ Required (email OR mobile)\n    amount: '100.00',                                     // ✅ Required\n    redirectUrl: 'https://yourapp.com/payment/success',  // ✅ Required\n    webhookUrl: 'https://yourapp.com/api/webhook',       // ✅ Required\n    \n    // ⚙️ Optional Parameters\n    cancelUrl: 'https://yourapp.com/payment/cancel',     // ⚙️ Optional (cancel redirect)\n    currency: 'BDT',                                      // ⚙️ Optional (default: BDT)\n    returnType: 'POST',                                   // ⚙️ Optional (default: POST)\n    orderId: 'order_12345',                               // ⚙️ Optional (custom order ID)\n    metadata: {'custom_field': 'value'},                 // ⚙️ Optional\n  );\n\n  String paymentUrl = charge.paymentUrl;\n  print('✅ Payment URL: $paymentUrl');\n  \n} on PiprapayException catch (e) {\n  print('❌ Error: ${e.message}');\n}\n```\n\n#### createCharge() Parameters\n\n**V3+ API Parameters:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `fullName` | String | ✅ Yes | - | Customer's full name |\n| `emailAddress` | String | ✅ Yes | - | Valid email address (validated) |\n| `mobileNumber` | String | ✅ Yes | - | Mobile with country code (e.g., +8801700000000) |\n| `amount` | String | ✅ Yes | - | Payment amount (e.g., \"100.00\") |\n| `returnUrl` | String | ✅ Yes | - | URL to redirect after payment completion |\n| `webhookUrl` | String | ✅ Yes | - | Backend endpoint for payment notifications |\n| `currency` | String | ⚙️ Optional | \"BDT\" | Currency code (BDT, USD, etc.) |\n| `metadata` | Map | ⚙️ Optional | `{}` | Custom data to attach to payment |\n\n**V2 API Parameters:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `fullName` | String | ✅ Yes | - | Customer's full name |\n| `emailOrMobile` | String | ✅ Yes | - | Email OR mobile number (validated) |\n| `amount` | String | ✅ Yes | - | Payment amount |\n| `redirectUrl` | String | ✅ Yes | - | Success redirect URL |\n| `webhookUrl` | String | ✅ Yes | - | Webhook endpoint URL |\n| `cancelUrl` | String | ⚙️ Optional | - | Cancel page redirect URL |\n| `currency` | String | ⚙️ Optional | \"BDT\" | Currency code |\n| `returnType` | String | ⚙️ Optional | \"POST\" | Return method (POST/GET) |\n| `orderId` | String | ⚙️ Optional | - | Custom order identifier |\n| `metadata` | Map | ⚙️ Optional | `{}` | Custom data object |\n\n### 3️⃣ Verify Payment Status\n\n#### For V3+ API\n\n```dart\ntry {\n  final verification = await piprapay.verifyPayment(\n    ppId: 'pp_id_from_redirect',  // ✅ Required (V3+) - Received from payment redirect/webhook\n  );\n\n  if (piprapay.isSuccessfulStatus(verification.status)) {\n    print('✅ Payment Successful!');\n    print('✅ Amount: ${verification.amount} ${verification.currency}');\n    print('✅ Total: ${verification.total}');\n    print('✅ Method: ${verification.paymentMethod}');\n    print('✅ Transaction: ${verification.transactionId}');\n  } else {\n    print('❌ Payment Status: ${verification.status}');\n  }\n  \n} on PiprapayPaymentException catch (e) {\n  print('❌ Verification Error: ${e.message}');\n}\n```\n\n#### For V2 API\n\n```dart\ntry {\n  final verification = await piprapay.verifyPayment(\n    transactionId: 'transaction_id_from_redirect',  // ✅ Required (V2)\n  );\n\n  if (verification.status == 'completed') {\n    print('✅ Payment verified!');\n  }\n  \n} on PiprapayPaymentException catch (e) {\n  print('❌ Error: ${e.message}');\n}\n```\n\n#### verifyPayment() Parameters\n\n| Parameter | Type | Required | API Version | Description |\n|-----------|------|----------|-------------|-------------|\n| `ppId` | String | ✅ Yes | V3+ | Payment reference from redirect (pp_id parameter) |\n| `transactionId` | String | ✅ Yes | V2 | Transaction ID from redirect (V2 legacy) |\n\n\u003e **Note:** Use `ppId` for V3+ API or `transactionId` for V2 API based on your `panelVersion` setting.\n\n### 4️⃣ Execute Payment in WebView (Built-in)\n\nThe package includes a built-in WebView handler - no need to implement it yourself!\n\n```dart\nimport 'package:piprapay/piprapay.dart';\n\ntry {\n  final result = await PiprapayWebView.executePayment(\n    context,\n    paymentUrl: checkoutUrl,                        // ✅ Required - From createCharge()\n    successPageDisplayDuration: Duration(seconds: 2), // ⚙️ Optional (default: 2 seconds)\n    appBarTitle: 'Complete Payment',                // ⚙️ Optional (default: \"Complete Payment\")\n  );\n\n  if (result != null \u0026\u0026 result.isSuccess) {\n    // Verify payment after successful completion\n    final verification = await piprapay.verifyPayment(\n      ppId: result.transactionRef!,  // V3+\n    );\n    \n    ScaffoldMessenger.of(context).showSnackBar(\n      SnackBar(content: Text('✅ Payment verified: ${verification.amount}')),\n    );\n  } else if (result?.isCancelled == true) {\n    ScaffoldMessenger.of(context).showSnackBar(\n      const SnackBar(content: Text('⚠️ Payment cancelled')),\n    );\n  } else if (result?.isFailed == true) {\n    ScaffoldMessenger.of(context).showSnackBar(\n      SnackBar(content: Text('❌ Payment failed: ${result!.message}')),\n    );\n  }\n  \n} catch (e) {\n  print('Error executing payment: $e');\n}\n```\n\n#### PiprapayWebView.executePayment() Parameters\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `context` | BuildContext | ✅ Yes | - | BuildContext for navigation |\n| `paymentUrl` | String | ✅ Yes | - | Payment gateway URL from `createCharge()` |\n| `successPageDisplayDuration` | Duration | ⚙️ Optional | 2 seconds | How long to display success page before closing |\n| `appBarTitle` | String | ⚙️ Optional | \"Complete Payment\" | Custom title for the payment page |\n\n**Returns:** `PaymentResult?` - Contains payment outcome (success/cancelled/failed)\n\n### 5️⃣ Process Refunds\n\n#### For V3+ API\n\n```dart\ntry {\n  final refund = await piprapay.refundPayment(\n    ppId: 'pp_id_value',  // ✅ Required (V3+) - Payment reference to refund\n  );\n\n  if (refund.status == 'refunded') {\n    print('✅ Refund processed successfully');\n    print('✅ Refund Amount: ${refund.refundAmount}');\n    print('✅ Transaction: ${refund.transactionId}');\n  }\n  \n} on PiprapayPaymentException catch (e) {\n  print('❌ Refund failed: ${e.message}');\n}\n```\n\n#### For V2 API\n\n```dart\ntry {\n  final refund = await piprapay.refundPayment(\n    transactionId: 'transaction_id_value',  // ✅ Required (V2)\n  );\n\n  print('✅ Refund initiated');\n  print('Response: $refund');\n  \n} on PiprapayPaymentException catch (e) {\n  print('❌ Refund failed: ${e.message}');\n}\n```\n\n#### refundPayment() Parameters\n\n| Parameter | Type | Required | API Version | Description |\n|-----------|------|----------|-------------|-------------|\n| `ppId` | String | ✅ Yes | V3+ | Payment reference (pp_id) to refund |\n| `transactionId` | String | ✅ Yes | V2 | Transaction ID to refund (V2 legacy) |\n\n\u003e **Note:** Full refund is processed. Partial refunds depend on Piprapay dashboard configuration.\n\n### 6️⃣ Handle Webhooks\n\n#### Using validateWebhook() Method\n\n```dart\n// In your Flutter backend webhook handler\ntry {\n  final webhook = await piprapay.validateWebhook(\n    payload: requestBody,        // ✅ Required - Raw JSON string from request body\n    receivedApiKey: apiKeyHeader, // ✅ Required - API key from request header\n  );\n\n  // Webhook validated successfully\n  if (webhook.status == 'completed') {\n    print('✅ Payment completed: ${webhook.transactionId}');\n    updateDatabase(webhook.transactionId, 'completed');\n  }\n  \n} on PiprapayWebhookException catch (e) {\n  print('❌ Webhook validation failed: ${e.message}');\n  // Return 401 Unauthorized\n}\n```\n\n#### Backend Example (Node.js/Express)\n\n```dart\napp.post('/api/webhook', async (req, res) =\u003e {\n  const apiKey = req.headers['mh-piprapay-api-key'];  // ✅ Required header\n  const payload = JSON.stringify(req.body);           // ✅ Required body\n  \n  // Validate using Piprapay Flutter service\n  const webhook = await piprapay.validateWebhook(\n    payload: payload,\n    receivedApiKey: apiKey,\n  );\n  \n  if (webhook.status === 'completed') {\n    updatePaymentStatus(webhook.transactionId, 'completed');\n  }\n  \n  res.json({ status: true, message: 'Webhook received' });\n});\n```\n\n#### validateWebhook() Parameters\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `payload` | String | ✅ Yes | Raw JSON string from webhook request body |\n| `receivedApiKey` | String | ✅ Yes | API key from `mh-piprapay-api-key` request header |\n\n\u003e **Security Note:** Always validate the API key matches your configured key to prevent unauthorized webhook calls.\n\n---\n\n## 🛡️ Error Handling\n\nThe package provides specific exception types for precise error handling:\n\n```dart\ntry {\n  // Payment operation\n} on PiprapayAuthException catch (e) {\n  // Handle authentication errors (invalid API key)\n  print('🔑 Auth Error: ${e.message}');\n  \n} on PiprapayRequestException catch (e) {\n  // Handle validation/request errors\n  print('📝 Request Error: ${e.message}');\n  print('Status Code: ${e.statusCode}');\n  \n} on PiprapayNetworkException catch (e) {\n  // Handle network errors\n  print('🌐 Network Error: ${e.message}');\n  \n} on PiprapayPaymentException catch (e) {\n  // Handle payment-specific errors\n  print('💳 Payment Error: ${e.message}');\n  print('Transaction: ${e.transactionId}');\n  \n} on PiprapayWebhookException catch (e) {\n  // Handle webhook validation errors\n  print('🔔 Webhook Error: ${e.message}');\n  \n} on PiprapayFailure catch (e) {\n  // Handle simplified payment failures (WebView execution)\n  if (e.isPaymentCancelled) {\n    print('⚠️ Payment cancelled by user');\n  } else if (e.isPaymentFailed) {\n    print('❌ Payment failed: ${e.message}');\n  }\n  \n} on PiprapayException catch (e) {\n  // Handle all other Piprapay errors\n  print('❌ Error: ${e.message}');\n}\n```\n\n---\n\n## 📚 Advanced Usage\n\n### Custom Configuration\n\n#### Full Manual Configuration\n\n```dart\nfinal piprapay = PiprapayService(\n  apiKey: 'your_api_key',                        // ✅ Required - Your Piprapay API key\n  isSandbox: true,                                // ✅ Required - Environment mode\n  baseUrl: 'https://custom.piprapay.com/api',   // ⚙️ Optional (auto-set if sandbox)\n  panelVersion: PanelVersion.v3plus,             // ⚙️ Optional (default: V3+)\n  enableLogging: true,                            // ⚙️ Optional (default: false)\n  timeout: Duration(seconds: 60),                // ⚙️ Optional\n);\n```\n\n#### Configuration Options\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `apiKey` | String | ✅ Yes | - | Piprapay API key |\n| `isSandbox` | bool | ✅ Yes | - | `true` for sandbox, `false` for production |\n| `baseUrl` | String | ⚙️ Optional | Sandbox URL | Custom API endpoint (required if `isSandbox: false`) |\n| `panelVersion` | PanelVersion | ⚙️ Optional | `v3plus` | API version (`PanelVersion.v2` or `PanelVersion.v3plus`) |\n| `enableLogging` | bool | ⚙️ Optional | `false` | Enable request/response logging for debugging |\n| `timeout` | Duration | ⚙️ Optional | System default | Request timeout duration |\n| `httpClient` | http.Client | ⚙️ Optional | - | Custom HTTP client (for testing/mocking) |\n\n\u003e **Tip:** Use `enableLogging: true` during development to see full API request/response details in console.\n\n### Input Validation\n\n```dart\nimport 'package:piprapay/piprapay.dart';\n\n// Validate email\nif (!PiprapayUtils.isValidEmail('test@example.com')) {\n  print('Invalid email format');\n}\n\n// Validate mobile number\nif (!PiprapayUtils.isValidMobileNumber('+8801700000000')) {\n  print('Invalid mobile number');\n}\n\n// Validate email or mobile\nif (PiprapayUtils.isValidEmailOrMobile(userInput)) {\n  print('Valid contact information');\n}\n\n// Check payment status\nif (PiprapayUtils.isPaymentCompleted(status)) {\n  print('Payment completed successfully');\n}\n\n// Verify status helpers\nbool isSuccess = piprapay.isSuccessfulStatus(status);\nbool isFailed = piprapay.isFailedStatus(status);\n```\n\n### Environment Variables\n\n```dart\n// Use environment configuration in main.dart\nconst String PIPRAPAY_API_KEY = String.fromEnvironment(\n  'PIPRAPAY_API_KEY',\n  defaultValue: 'sandbox_key',\n);\n\nconst String PIPRAPAY_ENV = String.fromEnvironment(\n  'PIPRAPAY_ENV',\n  defaultValue: 'sandbox',\n);\n\nfinal piprapay = PIPRAPAY_ENV == 'production'\n    ? PiprapayService.production(apiKey: PIPRAPAY_API_KEY)\n    : PiprapayService.sandbox(apiKey: PIPRAPAY_API_KEY);\n```\n\n### Resource Management\n\n```dart\n@override\nvoid dispose() {\n  piprapay.dispose();\n  super.dispose();\n}\n```\n\n---\n\n## 📊 Data Models\n\n### CreateChargeResponse\n```dart\nclass CreateChargeResponse {\n  final String invoiceId;           // Unique invoice ID\n  final String transactionId;       // Transaction reference (pp_id)\n  final String checkoutUrl;         // Payment gateway URL (V3+)\n  final String paymentUrl;          // Alternative payment URL (V2/V3)\n  final Map\u003cString, dynamic\u003e? metadata; // Custom data\n}\n```\n\n### VerifyPaymentResponse (V2 \u0026 V3+)\n```dart\nclass VerifyPaymentResponse {\n  final String transactionId;       // pp_id\n  final String customerName;\n  final String amount;\n  final double total;               // Total amount\n  final String currency;            // BDT, USD, etc.\n  final String status;              // completed, failed, pending, etc.\n  final String paymentMethod;       // bKash, Nagad, Rocket, etc.\n  final String date;\n  final String? metadata;           // Custom data\n}\n```\n\n### WebhookPayload\n```dart\nclass WebhookPayload {\n  final String transactionId;       // pp_id\n  final String status;              // completed, failed, etc.\n  final String amount;\n  final double total;\n  final String currency;\n  final String paymentMethod;\n  final String customerName;\n  final String customerEmailOrMobile;\n  final Map\u003cString, dynamic\u003e? metadata;\n}\n```\n\n### PaymentResult (WebView)\n```dart\nclass PaymentResult {\n  final bool isSuccess;\n  final bool isCancelled;\n  final bool isFailed;\n  final String? transactionRef;\n  final String? message;\n  \n  // Factory constructors\n  factory PaymentResult.success(String transactionRef);\n  factory PaymentResult.cancelled();\n  factory PaymentResult.failed(String? message, String? transactionRef);\n}\n```\n\n---\n\n## 🧪 Testing\n\n### Run Tests\n\n```bash\nflutter test\n```\n\n### Example Test\n\n```dart\ntest('Create charge request validation', () {\n  final piprapay = PiprapayService.sandbox(apiKey: 'test_key');\n  \n  expect(\n    PiprapayUtils.isValidEmail('valid@example.com'),\n    true,\n  );\n  \n  expect(\n    PiprapayUtils.isValidMobileNumber('+8801700000000'),\n    true,\n  );\n});\n```\n\n### Sandbox Testing\n\n```dart\n// Use sandbox credentials for testing\nfinal piprapay = PiprapayService.sandbox(\n  apiKey: 'pk_test_your_sandbox_key',\n);\n\n// Test credentials\nconst testEmail = 'test@example.com';\nconst testAmount = '100';\nconst testMobile = '+8801700000000';\n\n// All transactions will be simulated\n```\n\n---\n\n## ✅ Best Practices\n\n1. **🔐 API Key Security**\n   - Never hardcode API keys\n   - Use environment variables: `String.fromEnvironment('PIPRAPAY_API_KEY')`\n   - Store sensitive data in secure storage (Flutter Secure Storage)\n\n2. **✔️ Input Validation**\n   - Always validate user input before payment\n   - Use `PiprapayUtils` validators\n   - Show validation errors to users\n\n3. **🛡️ Error Handling**\n   - Implement try-catch for all payment operations\n   - Provide meaningful error messages\n   - Log errors for debugging\n\n4. **🔔 Webhook Verification**\n   - Always validate webhook API keys\n   - Verify webhook signatures\n   - Process payments idempotently (handle duplicate webhooks)\n\n5. **💾 Database Integration**\n   - Store transaction IDs for record-keeping\n   - Update payment status on verification\n   - Log all payment events with timestamps\n\n6. **🧪 Testing Strategy**\n   - Use sandbox environment for testing\n   - Test all payment flows (success, cancel, fail)\n   - Verify webhook handling\n\n7. **📊 Monitoring \u0026 Logging**\n   - Log important payment events\n   - Monitor API response times\n   - Track error rates\n   - Use activity logs for debugging\n\n8. **🚀 Production Deployment**\n   - Switch to production API key\n   - Update base URL for production\n   - Enable webhook endpoint\n   - Monitor payment success rates\n   - Have fallback payment methods\n\n---\n\n## 🔧 API Reference\n\n### PiprapayService Methods\n\n#### `createCharge()`\nCreates a new payment charge.\n\n**V3+ API Parameters:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `fullName` | String | ✅ Yes | - | Customer's full name |\n| `emailAddress` | String | ✅ Yes | - | Valid email address (validated) |\n| `mobileNumber` | String | ✅ Yes | - | Mobile with country code |\n| `amount` | String | ✅ Yes | - | Payment amount (e.g., \"100.00\") |\n| `returnUrl` | String | ✅ Yes | - | Success redirect URL |\n| `webhookUrl` | String | ✅ Yes | - | Backend webhook endpoint |\n| `currency` | String | ⚙️ Optional | \"BDT\" | Currency code |\n| `metadata` | Map | ⚙️ Optional | `{}` | Custom data |\n\n**V2 API Parameters:**\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `fullName` | String | ✅ Yes | - | Customer's full name |\n| `emailOrMobile` | String | ✅ Yes | - | Email OR mobile number |\n| `amount` | String | ✅ Yes | - | Payment amount |\n| `redirectUrl` | String | ✅ Yes | - | Success redirect URL |\n| `webhookUrl` | String | ✅ Yes | - | Backend webhook endpoint |\n| `cancelUrl` | String | ⚙️ Optional | - | Cancel redirect URL |\n| `currency` | String | ⚙️ Optional | \"BDT\" | Currency code |\n| `returnType` | String | ⚙️ Optional | \"POST\" | Return method (POST/GET) |\n| `orderId` | String | ⚙️ Optional | - | Custom order identifier |\n| `metadata` | Map | ⚙️ Optional | `{}` | Custom data |\n\n**Returns:** `CreateChargeResponseV3` (V3+) or `CreateChargeResponseV2` (V2)\n\n#### `verifyPayment()`\nVerifies payment status using transaction ID.\n\n**Parameters:**\n\n| Parameter | Type | Required | API Version | Description |\n|-----------|------|----------|-------------|-------------|\n| `ppId` | String | ✅ Yes | V3+ | Payment reference (pp_id) |\n| `transactionId` | String | ✅ Yes | V2 | Transaction ID (V2 legacy) |\n\n**Returns:** `VerifyPaymentResponseV3` (V3+) or `VerifyPaymentResponseV2` (V2)\n\n#### `refundPayment()`\nProcesses refund for completed payment.\n\n**Parameters:**\n\n| Parameter | Type | Required | API Version | Description |\n|-----------|------|----------|-------------|-------------|\n| `ppId` | String | ✅ Yes | V3+ | Payment reference (pp_id) to refund |\n| `transactionId` | String | ✅ Yes | V2 | Transaction ID to refund (V2) |\n\n**Returns:** `RefundPaymentResponseV3` (V3+) or dynamic (V2)\n\n#### `validateWebhook()`\nValidates webhook payload and signature.\n\n**Parameters:**\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `payload` | String | ✅ Yes | Raw JSON string from webhook request body |\n| `receivedApiKey` | String | ✅ Yes | API key from `mh-piprapay-api-key` header |\n\n**Returns:** `WebhookPayloadV3` (V3+) or `WebhookPayload` (V2)\n\n#### Helper Methods\n\n**`extractCheckoutUrl()`** - Extract payment URL from createCharge response\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `createResponse` | dynamic | ✅ Yes | Response from `createCharge()` |\n\n**Returns:** `String?` - Payment/checkout URL or null\n\n```dart\nString? url = piprapay.extractCheckoutUrl(charge);\n```\n\n---\n\n**`extractPaymentReference()`** - Extract payment reference (pp_id or transaction_id)\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `createResponse` | dynamic | ✅ Yes | Response from `createCharge()` |\n\n**Returns:** `String?` - Payment reference or null\n\n```dart\nString? ppId = piprapay.extractPaymentReference(charge);\n```\n\n---\n\n**`isSuccessfulStatus()`** - Check if payment status indicates success\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `status` | String | ✅ Yes | Payment status from verification |\n\n**Returns:** `bool` - true if status is 'completed'\n\n```dart\nbool isSuccess = piprapay.isSuccessfulStatus(status);\n```\n\n---\n\n**`isFailedStatus()`** - Check if payment status indicates failure\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `status` | String | ✅ Yes | Payment status from verification |\n\n**Returns:** `bool` - true if status is 'failed', 'cancelled', 'expired', or 'rejected'\n\n```dart\nbool isFailed = piprapay.isFailedStatus(status);\n```\n\n---\n\n## 🐛 Troubleshooting\n\n### \"Invalid API Key\" Error\n```\n✗ Verify API key is correct\n✗ Check if API key has required permissions\n✗ Ensure API key matches environment (sandbox/production)\n✗ Regenerate API key in Piprapay dashboard\n```\n\n### \"Request Timeout\" Error\n```\n✗ Check network connectivity\n✗ Verify backend service is running\n✗ Increase timeout: timeout: Duration(seconds: 90)\n✗ Check for network proxy/firewall issues\n```\n\n### \"Invalid Email or Mobile\" Error\n```\n✗ Validate input format before sending\n✗ Use PiprapayUtils validators\n✗ Check phone number includes country code\n✗ Ensure email format is valid\n```\n\n### Webhook Not Received\n```\n✗ Verify webhook URL is publicly accessible\n✗ Ensure webhook URL uses HTTPS\n✗ Check API key in webhook headers\n✗ Verify server logs for errors\n✗ Test webhook endpoint manually\n```\n\n### Payment Verification Fails\n```\n✗ Verify transaction ID (pp_id) is correct\n✗ Wait a few seconds after payment completion\n✗ Check payment status in Piprapay dashboard\n✗ Verify API key has verification permissions\n✗ Check network connectivity\n```\n\n---\n\n## 📖 Documentation\n\n- **[Piprapay Official Docs](https://piprapay.readme.io/reference)**\n- **[API Documentation](https://piprapay.com/api-docs)**\n- **[GitHub Repository](https://github.com/programmingwormhole/piprapay-flutter)**\n- **[Issue Tracker](https://github.com/programmingwormhole/piprapay-flutter/issues)**\n\n---\n\n## 📝 Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for detailed version history and updates.\n\n---\n\n## 🤝 Contributing\n\nContributions are welcome! Please follow these steps:\n\n1. **Fork** the repository\n2. **Create** a feature branch (`git checkout -b feature/amazing-feature`)\n3. **Commit** your changes (`git commit -m 'Add amazing feature'`)\n4. **Push** to the branch (`git push origin feature/amazing-feature`)\n5. **Open** a Pull Request\n\n### Development Setup\n\n```bash\n# Clone repository\ngit clone https://github.com/programmingwormhole/piprapay-flutter.git\ncd piprapay-flutter\n\n# Get dependencies\nflutter pub get\n\n# Run tests\nflutter test\n\n# Run example app\ncd example\nflutter run\n```\n\n---\n\n## 📄 License\n\nThis package is licensed under the **MIT License**. See the [LICENSE](LICENSE) file for details.\n\n---\n\n## 👨‍💻 About the Developer\n\n**Md Shirajul Islam**\n\nA passionate Flutter developer dedicated to building professional, production-ready payment solutions for the Bangladeshi fintech ecosystem.\n\n### Connect with Me\n\n- **GitHub:** [github.com/programmingwormhole](https://github.com/programmingwormhole)\n- **YouTube:** [youtube.com/@programmingwormhole](https://youtube.com/@programmingwormhole)\n- **Facebook:** [facebook.com/no.name.virus](https://facebook.com/no.name.virus)\n- **Email:** programmingwormhole@gmail.com\n\n---\n\n## 🙏 Support\n\nIf you found this package helpful:\n- ⭐ Star the repository on GitHub\n- 📤 Share with your developer friends\n- 🐛 Report issues and suggest improvements\n- 💬 Contribute code and documentation\n\n---\n\n## � Quick Reference\n\n### All Methods \u0026 Parameters Summary\n\n#### Initialization Methods\n\n| Method | Required Parameters | Optional Parameters | Returns |\n|--------|---------------------|---------------------|---------|\n| `PiprapayService.sandbox()` | `apiKey` | `panelVersion`, `enableLogging`, `timeout` | PiprapayService |\n| `PiprapayService.production()` | `apiKey`, `baseUrl` | `panelVersion`, `enableLogging`, `timeout` | PiprapayService |\n\n#### Payment Methods\n\n| Method | Required (V3+) | Required (V2) | Optional | Returns |\n|--------|----------------|---------------|----------|---------|\n| `createCharge()` | `fullName`, `emailAddress`, `mobileNumber`, `amount`, `returnUrl`, `webhookUrl` | `fullName`, `emailOrMobile`, `amount`, `redirectUrl`, `webhookUrl` | `currency`, `metadata`, `cancelUrl` (V2), `returnType` (V2), `orderId` (V2) | CreateChargeResponse |\n| `verifyPayment()` | `ppId` | `transactionId` | - | VerifyPaymentResponse |\n| `refundPayment()` | `ppId` | `transactionId` | - | RefundPaymentResponse |\n| `validateWebhook()` | `payload`, `receivedApiKey` | `payload`, `receivedApiKey` | - | WebhookPayload |\n\n#### Helper Methods\n\n| Method | Required Parameters | Returns | Description |\n|--------|---------------------|---------|-------------|\n| `extractCheckoutUrl()` | `createResponse` | String? | Extract payment URL |\n| `extractPaymentReference()` | `createResponse` | String? | Extract pp_id/transaction_id |\n| `isSuccessfulStatus()` | `status` | bool | Check if status is \"completed\" |\n| `isFailedStatus()` | `status` | bool | Check if status is failed/cancelled/expired |\n\n#### UI Methods (WebView)\n\n| Method | Required Parameters | Optional Parameters | Returns | Description |\n|--------|---------------------|---------------------|---------|-------------|\n| `PiprapayWebView.executePayment()` | `context`, `paymentUrl` | `successPageDisplayDuration`, `appBarTitle` | PaymentResult? | Execute payment in built-in WebView |\n\n#### Utility Methods (PiprapayUtils)\n\n| Method | Required Parameters | Returns | Description |\n|--------|---------------------|---------|-------------|\n| `isValidEmail()` | `email` | bool | Validate email format |\n| `isValidMobileNumber()` | `mobile` | bool | Validate mobile number |\n| `isValidEmailOrMobile()` | `input` | bool | Validate email OR mobile |\n| `isPaymentCompleted()` | `status` | bool | Check if payment completed |\n| `validateWebhookApiKey()` | `receivedApiKey`, `expectedApiKey` | bool | Validate webhook API key |\n\n### Initialization Quick Reference\n\n```dart\n// V3+ Sandbox with logging (Development)\nfinal piprapay = PiprapayService.sandbox(\n  apiKey: 'pk_sandbox_key',\n  panelVersion: PanelVersion.v3plus,  // ⚙️ Optional\n  enableLogging: true,                 // ⚙️ Optional - Helps debugging\n);\n\n// V3+ Production (Live)\nfinal piprapay = PiprapayService.production(\n  apiKey: 'pk_live_key',\n  baseUrl: 'https://api.piprapay.com/api',\n  panelVersion: PanelVersion.v3plus,  // ⚙️ Optional\n  enableLogging: false,                // ⚙️ Optional - Disable in production\n);\n\n// V2 Legacy Support\nfinal piprapay = PiprapayService.sandbox(\n  apiKey: 'pk_sandbox_key',\n  panelVersion: PanelVersion.v2,      // For V2 API\n);\n```\n\n### Payment Flow Quick Reference\n\n```dart\n// 1. Create Charge (V3+)\nfinal charge = await piprapay.createCharge(\n  fullName: 'Name',             // ✅ Required\n  emailAddress: 'email@x.com',  // ✅ Required\n  mobileNumber: '+880170...',   // ✅ Required\n  amount: '100',                // ✅ Required\n  returnUrl: 'https://...',     // ✅ Required\n  webhookUrl: 'https://...',    // ✅ Required\n  currency: 'BDT',              // ⚙️ Optional\n  metadata: {},                 // ⚙️ Optional\n);\n\n// 2. Extract Payment URL\nString url = piprapay.extractCheckoutUrl(charge)!;\n\n// 3. Execute payment in built-in WebView\nfinal result = await PiprapayWebView.executePayment(\n  context,\n  paymentUrl: url,              // ✅ Required\n  successPageDisplayDuration: Duration(seconds: 2), // ⚙️ Optional\n);\n\n// 4. Verify Payment (if successful)\nif (result?.isSuccess == true) {\n  final verification = await piprapay.verifyPayment(\n    ppId: result!.transactionRef!,  // ✅ Required (V3+)\n  );\n  \n  // 5. Check Status\n  if (piprapay.isSuccessfulStatus(verification.status)) {\n    // Payment successful - update your database\n  }\n}\n\n// 6. Refund (if needed)\nfinal refund = await piprapay.refundPayment(\n  ppId: 'pp_id_value',          // ✅ Required (V3+)\n);\n```\n\n---\n\n## �🚀 Quick Links\n\n| Link | Purpose |\n|------|---------|\n| [GitHub Repository](https://github.com/programmingwormhole/piprapay-flutter) | Source code and issue tracking |\n| [pub.dev Package](https://pub.dev/packages/piprapay) | Package page and version history |\n| [Piprapay Official](https://piprapay.com) | Piprapay payment gateway website |\n| [API Documentation](https://piprapay.readme.io) | Official Piprapay API docs |\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n**Made with ❤️ by [Md Shirajul Islam](https://github.com/programmingwormhole)**\n\n*Professional • Secure • Easy to Use • Production Ready*\n\n[⬆ Back to Top](#-piprapay-flutter-package)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprogrammingwormhole%2Fpiprapay-flutter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprogrammingwormhole%2Fpiprapay-flutter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprogrammingwormhole%2Fpiprapay-flutter/lists"}