qattapay_flutter 1.0.1
qattapay_flutter: ^1.0.1 copied to clipboard
Official QattaPay Flutter SDK — group contribution checkout for Flutter apps.
QattaPay Flutter SDK #
Official QattaPay SDK for Flutter — add group contribution checkout to your app.
dependencies:
qattapay_flutter: ^1.0.0
QattaPay lets groups of people split the cost of a purchase. This package handles:
- Server-side (Dart): creating checkout intents and managing orders with your merchant API key
- Webhooks: verifying and parsing events when a session is funded
- Flutter UI: official branded
QattaPayButton+ hosted checkout opener
Parity with @hadawi/sdk and qattapay/laravel.
Requirements #
- Dart ^3.5 / Flutter ≥ 3.24
- A QattaPay merchant account (qatta.sa)
Architecture (important) #
Flutter app Your backend QattaPay
─────────── ──────────── ────────
QattaPayButton ──POST /intent──► QattaPayClient.intents.create ──► POST /intents
│ │
│◄────────── intentId ─────────────┘
│
└── opens hosted checkout ──────────────────────────────────► /checkout/{id}
Never put your merchant API key or webhook secret in the mobile app. Create intents on your server (Node, Laravel, Dart Frog, etc.), then pass only the intentId to Flutter.
Checkout is the hosted web flow. Do not embed it in a framed WebView — the payment page sends X-Frame-Options: deny and will not render inside a frame. The SDK opens Custom Tabs / SFSafariViewController / the external browser via url_launcher.
Installation #
dependencies:
qattapay_flutter: ^1.0.0
flutter pub get
Platform setup for url_launcher follows the official docs (Android queries / iOS LSApplicationQueriesSchemes as needed).
Quick start #
1 — Create an intent (server) #
Using this package on a Dart backend:
import 'package:qattapay_flutter/qattapay_flutter.dart';
final qattapay = QattaPayClient(
apiKey: Platform.environment['QATTAPAY_API_KEY']!,
mode: QattaPayMode.dev, // or live
webhookSecret: Platform.environment['QATTAPAY_WEBHOOK_SECRET'],
);
final result = await qattapay.intents.create(
CreateIntentParams(
itemSnapshot: [
ItemSnapshot(
name: 'Luxury Watch',
price: 150000, // 1500.00 SAR in halalas
reference: 'watch-001',
),
],
totalAmount: 150000,
currency: 'SAR',
metadata: {'cart_id': 'abc'},
),
);
return {'intentId': result.intent.id};
Or use Node (@hadawi/sdk) / Laravel (qattapay/laravel) — same API.
Amounts are integers in the smallest currency unit (halalas for SAR — e.g. 15000 = 150.00 SAR).
2 — Mount the branded button (Flutter) #
import 'package:qattapay_flutter/qattapay_flutter.dart';
QattaPayButton(
mode: QattaPayMode.live,
variant: QattaPayButtonVariant.primary,
label: QattaPayButtonLabel.split,
locale: QattaPayLocale.en,
getIntentId: () async {
final res = await http.post(Uri.parse('https://api.my-store.com/qattapay/intent'));
final data = jsonDecode(res.body) as Map<String, dynamic>;
return data['intentId'] as String;
},
returnUrl: Uri.parse('myapp://thank-you'),
onError: (err) => debugPrint('QattaPay error: $err'),
)
3 — Verify webhooks (server) #
final event = qattapay.webhooks.constructEvent(
requestBodyBytes,
request.headers['x-qattapay-signature']!,
);
if (event.type == WebhookEventType.orderFunded) {
final orderId = event.payload.orderId;
if (orderId != null) {
await qattapay.orders.fulfill(orderId);
}
}
Event types: order.funded, order.partially_funded, order.cancelled, order.expired.
API surface #
QattaPayClient (server) #
| API | Methods |
|---|---|
intents |
create, get |
orders |
list, get, fulfill, deliver |
webhooks |
verifySignature, constructEvent |
Config: apiKey, mode (dev | live), optional baseUrl (disables host fallback), optional webhookSecret.
Host fallback when using mode: qatta.sa → hadawi.sa (same as the Node / Laravel SDKs).
QattaPayButton / QattaPayCheckout (mobile) #
| Option | Values |
|---|---|
variant |
primary, dark, light, outline |
size |
sm, md, lg |
label |
split, splitCart, pay (or labelText) |
locale |
en, ar |
showBadge / showIcon |
booleans |
returnUrl |
deep link / https URL appended to hosted checkout |
Imperative open:
final checkout = QattaPayCheckout(mode: QattaPayMode.live);
await checkout.open(intentId, returnUrl: Uri.parse('myapp://thank-you'));
Exceptions #
QattaPayApiException— HTTP / API errors (status,code)QattaPayWebhookException— invalid signature or payload
Links #
- Docs: https://qatta.sa/docs/sdk
- Node SDK: https://www.npmjs.com/package/@hadawi/sdk
- Laravel SDK: https://packagist.org/packages/qattapay/laravel
- Issues: https://github.com/Hadawi-Engineering/qattapay-flutter/issues
License #
MIT © Hadawi Engineering