guavasure_flutter 0.1.6 copy "guavasure_flutter: ^0.1.6" to clipboard
guavasure_flutter: ^0.1.6 copied to clipboard

Embed GuavaSure pet insurance in Flutter via WebView.

guavasure_flutter #

Flutter package that embeds the hosted GuavaSure insurance flow in a WebView and implements GuavasureBridge for native Razorpay Checkout (primary), payment-link fallback (Custom Tab / Safari / external browser), native camera capture (nose photos + just-in-time permissions), native file pick, logout, and optional partner-collected payment.

Requirements: Dart >=3.6.0, Flutter >=3.24.0 · Android & iOS

Installation #

Add from pub.dev:

flutter pub add guavasure_flutter

Or in pubspec.yaml:

dependencies:
  guavasure_flutter: ^0.1.6

Then:

flutter pub get
cd ios && pod install && cd ..

Transitive packages: webview_flutter, url_launcher, file_selector, image_picker, permission_handler, razorpay_flutter.

Platform setup #

Android #

URL fallback (Custom Tabs) on Android 11+ — inside <queries> in AndroidManifest.xml:

<queries>
  <intent>
    <action android:name="android.support.customtabs.action.CustomTabsService" />
  </intent>
</queries>

Camera (nose photo capture) — inside <manifest>:

<uses-permission android:name="android.permission.CAMERA" />

Native Razorpay Checkout uses the official Android SDK via razorpay_flutter (Internet permission is included by the SDK).

iOS #

Run pod install after adding the package so the Razorpay iOS SDK is linked.

URL fallback uses SFSafariViewController — no additional manifest entries.

Camera — add to ios/Runner/Info.plist:

<key>NSCameraUsageDescription</key>
<string>GuavaSure needs camera access to capture your pet’s nose photo.</string>

Also enable the camera permission macro in ios/Podfile (required by permission_handler):

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',
        'PERMISSION_CAMERA=1',
      ]
    end
  end
end

Then re-run pod install.

Payment cascade #

When the embed posts open-payment, the plugin runs strategies in order:

open-payment
   ├─ 1. Native Razorpay SDK     key + orderId | subscriptionId
   ├─ 2. Custom Tab / Safari     url (Razorpay allowlist)
   └─ 3. External browser        url if in-app browser fails
Strategy Customer sees
Native SDK (primary) Razorpay modal inside the app
Custom Tab / Safari (fallback) Razorpay hosted page in system browser
External browser (last resort) Razorpay in Chrome / Safari app
  • Native cancel / failure does not open a URL (no double checkout).
  • Native success reloads the embed with a fresh partner JWT.
  • Browser fallback reloads on app resume after the customer closes the tab.

The hosted embed sends key, orderId (annual) or subscriptionId (monthly), amountPaise, prefill, and url in every open-payment message — native checkout is the default on mobile when using current embed + 0.1.6+.

Partners using GuavaSureEmbed get this automatically. Custom WebView hosts can call:

final result = await launchGuavaSurePayment(request);

Native camera (nose photos) #

When the embed posts camera-permission / capture-photo / open-camera-settings, GuavaSureEmbed handles them automatically:

  1. Request camera permission when the capture screen opens
  2. Open the system camera on Capture Photo
  3. Return the image to the embed (chunked base64 when large)
  4. On permanent deny, open OS Settings via Open Settings

Quick start #

import 'package:guavasure_flutter/guavasure_flutter.dart';

GuavaSureEmbed(
  config: GuavaSureEmbedConfig(
    partnerId: 'YOUR_PARTNER_ID',
    environment: GuavaSureEnvironment.sandbox,
    partnerAuthTokenProvider: () => myBackend.fetchCustomerAuthToken(),
    // Optional: same externalId as customer-auth-token pet upserts
    // partnerExternalId: 'pet-001',
  ),
  // Only when GuavaSure enables partner-collected payment on your account:
  partnerPaymentHandler: (request) async {
    // Charge your PSP, confirm server-side, return confirmed or cancelled
    return PartnerPaymentResult.confirmed;
  },
)

Verify native checkout (debug) #

After tapping Pay, debug logs should include:

GuavaSureEmbed payment native=true quote=… order=order_…
GuavaSure native Razorpay open order=order_… amount=…

If you see I/chromium / api.razorpay.com/v1/checkout/public instead, the app is on URL fallback — upgrade to 0.1.6+, run pod install, and cold-start the app (avoid hot restart with an active WebView).

Two payment paths #

Path Bridge message Use when
Standard (default) open-payment GuavaSure-managed Razorpay — native SDK first
Partner-collected COLLECT_PAYMENT GuavaSure enabled enablePartnerCollectedPayment; you charge your PSP

Standard checkout does not require partnerPaymentHandler. Partner-collected is annual-only and separate from the Razorpay cascade above.

Security #

  • Bridge messages are only handled on the configured embed origin.
  • Razorpay payment URLs are allowlisted (rzp.io, razorpay.me, *.razorpay.com).
  • Prefer partnerAuthTokenProvider with short-lived JWTs.
  • Never put Razorpay Key Secret in the app — only the public Key ID from the embed open-payment payload.

Docs #

Guide Audience
Flutter Plugin Partner apps — native + URL fallback
Mobile WebView protocol Bridge message reference
Flutter Plugin Example Flutter + Node/TypeScript sample

License #

Licensed under GPL-3.0. Intended for authorized GuavaSure integration partners.