guavasure_flutter 0.1.5
guavasure_flutter: ^0.1.5 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 #
Path dependency (monorepo / pre-publish):
dependencies:
guavasure_flutter:
path: ../path/to/guavasure/apps/plugins/guavasure_flutter
Or from pub.dev when available:
dependencies:
guavasure_flutter: ^0.1.5
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.5+.
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:
- Request camera permission when the capture screen opens
- Open the system camera on Capture Photo
- Return the image to the embed (chunked base64 when large)
- On permanent deny, open OS Settings via Open Settings
Works on HTTP local-dev embeds where getUserMedia is unavailable.
Quick start #
import 'package:guavasure_flutter/guavasure_flutter.dart';
GuavaSureEmbed(
config: GuavaSureEmbedConfig(
partnerId: 'YOUR_PARTNER_ID',
environment: GuavaSureEnvironment.sandbox,
partnerAuthTokenProvider: () => myBackend.fetchCustomerAuthToken(),
),
// 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.5+, 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
partnerAuthTokenProviderwith short-lived JWTs. - Never put Razorpay Key Secret in the app — only the public Key ID from the
embed
open-paymentpayload.
Docs #
| Guide | Audience |
|---|---|
| Flutter Plugin | Partner apps — native + URL fallback |
| Mobile WebView protocol | Bridge message reference |
| Flutter Plugin Example | Flutter + Node/TypeScript sample |
Monorepo paths: apps/docs/docs/integrations/.
License #
Licensed under GPL-3.0. Intended for authorized GuavaSure integration partners.