Dart SDK
Use the official Moosyl Dart SDK in Dart and Flutter backends
Overview
Use moosyl to integrate Moosyl payments from Dart or Flutter server-side code using a generated, typed API client built on Dio.
Links
- Pub.dev package (latest stable): https://pub.dev/packages/moosyl
- Source repository: https://github.com/SoftwareSavants/moosyl-dart
Installation
dart pub add moosylOr add it directly:
dependencies:
moosyl: ^1.1.1Initialization
import 'package:moosyl/moosyl.dart';
final client = Moosyl(
basePathOverride: 'https://api.moosyl.com',
);
client.setApiKey('ApiKey', 'sk_test_...');Core Feature 1: Create Payment Request
Use a secret key (sk_...) on backend only. See API Keys.
import 'package:moosyl/moosyl.dart';
import 'package:one_of/any_of.dart';
PaymentRequestCreateAmount amountAsNumber(num value) {
return PaymentRequestCreateAmount(
(b) => b.anyOf = AnyOf2<String, num>(values: {1: value}),
);
}
final paymentRequestApi = client.getPaymentRequestApi();
final created = await paymentRequestApi.postPaymentRequest(
paymentRequestCreate: PaymentRequestCreate(
(b) => b
..transactionId = 'order_123'
..amount.replace(amountAsNumber(1000)),
),
);
final paymentRequestId = created.data?.data.id;For hosted checkout after creating the request, see Checkout Session.
Retry pattern with stable transactionId:
import 'package:dio/dio.dart';
Future<String?> ensurePaymentRequestId(Moosyl client, String transactionId) async {
final api = client.getPaymentRequestApi();
try {
final created = await api.postPaymentRequest(
paymentRequestCreate: PaymentRequestCreate(
(b) => b
..transactionId = transactionId
..amount.replace(amountAsNumber(1000)),
),
);
return created.data?.data.id;
} on DioException catch (_) {
final existing = await api.getPaymentRequestByTransactionByTransactionId(
transactionId: transactionId,
);
return existing.data?.data.id;
}
}Core Feature 2: Send and Check Status
Send
final checkoutApi = client.getCheckoutSessionApi();
final checkout = await checkoutApi.postCheckoutSession(
checkoutSessionCreateBody: CheckoutSessionCreateBody(
(b) => b.paymentRequestId = paymentRequestId!,
),
);
final checkoutUrl = checkout.data?.checkoutUrl;Check
final paymentRequestApi = client.getPaymentRequestApi();
await paymentRequestApi.patchPaymentRequestByTransactionIdRefreshStatus(
transactionId: 'order_123',
);
final latest = await paymentRequestApi.getPaymentRequestByTransactionByTransactionId(
transactionId: 'order_123',
);Full flow
import 'package:moosyl/moosyl.dart';
import 'package:one_of/any_of.dart';
PaymentRequestCreateAmount amountAsNumber(num value) {
return PaymentRequestCreateAmount(
(b) => b.anyOf = AnyOf2<String, num>(values: {1: value}),
);
}
Future<void> runMoosylFlow() async {
final client = Moosyl(basePathOverride: 'https://api.moosyl.com');
client.setApiKey('ApiKey', 'sk_test_...');
final paymentRequestApi = client.getPaymentRequestApi();
final checkoutApi = client.getCheckoutSessionApi();
final created = await paymentRequestApi.postPaymentRequest(
paymentRequestCreate: PaymentRequestCreate(
(b) => b
..transactionId = 'order_789'
..amount.replace(amountAsNumber(1000)),
),
);
final id = created.data?.data.id;
if (id == null) return;
final checkout = await checkoutApi.postCheckoutSession(
checkoutSessionCreateBody: CheckoutSessionCreateBody(
(b) => b.paymentRequestId = id,
),
);
await paymentRequestApi.patchPaymentRequestByTransactionIdRefreshStatus(
transactionId: 'order_789',
);
final current = await paymentRequestApi.getPaymentRequestByTransactionByTransactionId(
transactionId: 'order_789',
);
print(checkout.data?.checkoutUrl);
print(current.data?.data.status);
}Error Handling
The SDK methods throw DioException for network, API, and serialization errors.
import 'package:dio/dio.dart';
try {
await client.getPaymentRequestApi().getPaymentRequestById(id: 'pr_123');
} on DioException catch (e) {
final statusCode = e.response?.statusCode;
final body = e.response?.data;
print('Moosyl request failed: $statusCode');
print(body);
}Reference API status/error responses in the API docs: https://api.moosyl.com/docs
Webhook/Event Verification
import 'dart:convert';
import 'package:crypto/crypto.dart';
String _hexEncode(List<int> bytes) =>
bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join();
bool _constantTimeEqual(String a, String b) {
if (a.length != b.length) return false;
var diff = 0;
for (var i = 0; i < a.length; i++) {
diff |= a.codeUnitAt(i) ^ b.codeUnitAt(i);
}
return diff == 0;
}
bool verifyMoosylWebhook({
required String rawBody,
required String signature,
required String webhookSecret,
}) {
final digest = Hmac(
sha256,
utf8.encode(webhookSecret),
).convert(utf8.encode(rawBody));
return _constantTimeEqual(_hexEncode(digest.bytes), signature);
}For setup details, see Webhooks.
Requirements
- Dart SDK
>=2.18.0 <4.0.0 - Compatible with Dart backend services and Flutter projects
- Optional for SDK contributors:
build_runnerfor local codegen workflows