paywit 0.1.0
paywit: ^0.1.0 copied to clipboard
Accept USDC payments in your Flutter app. Creates a Paywit payment, opens the hosted checkout, and returns the settled result — no native setup required.
paywit #
Accept USDC payments in your Flutter app.
The SDK creates a payment, opens the Paywit hosted checkout in a Custom Tab
(Android) or SFSafariViewController (iOS), waits for it to settle, and returns
the result. No native setup required — no URL schemes, no assetlinks.json,
no AndroidManifest edits.
Install #
flutter pub add paywit
Quick start #
Your API URL and publishable key both come from your Paywit dashboard.
import 'package:paywit/paywit.dart';
final paywit = Paywit(
apiBaseUrl: '<your Paywit API URL>',
publishableKey: '<your publishable key>',
);
final result = await paywit.checkout(
amount: 10,
description: 'Order #1234',
clientReferenceId: 'order_1234',
);
if (result.isPaid) {
confirmOrder();
}
There is no default API URL — pick the environment explicitly so you can't ship against the wrong one by accident.
Or drop in the button:
PaywitButton(
paywit: paywit,
amount: 10,
description: 'Order #1234',
onResult: (result) {
if (result.isPaid) confirmOrder();
},
onError: (error) => showError(error.message),
)
Production: create payments on your server #
checkout() sets the amount on the device, so a buyer can tamper with it.
In production, create the payment on your server with your secret key and pass
the checkout URL it returns to the app. The amount is then fixed server-side and
the app never names a price.
final checkoutUrl = await myBackend.startOrder(1234);
final result = await paywit.checkoutPayment(checkoutUrl: checkoutUrl);
checkoutPayment needs no publishable key.
Handling the result #
An unpaid payment is a result, not an exception:
switch (result.status) {
case PaymentStatus.paid:
confirmOrder();
case PaymentStatus.expired:
showExpired();
case PaymentStatus.canceled:
break;
default:
showFailure();
}
canceleddoes not mean the payment won't happen. It means the buyer came back to your app without completing the checkout — they can still pay from their wallet afterwards. Treat your webhook as the source of truth before releasing goods.
Cross-chain payments pass through PaymentStatus.bridging while funds move
between chains. These never expire, and the SDK keeps waiting.
Errors #
Faults throw PaywitException, a sealed type — the analyzer will tell you when
a case is missing:
try {
final result = await paywit.checkout(amount: 10);
} on PaywitApiException catch (e) {
// e.statusCode, e.message
} on PaywitNetworkException {
// offline or unreachable
} on PaywitConfigException {
// missing key, bad amount
} on PaywitBrowserException {
// no browser available
}
Configuration #
| Parameter | Description |
|---|---|
apiBaseUrl |
Required. From your Paywit dashboard. |
publishableKey |
Required by checkout(). Not needed for checkoutPayment(). |
timeout |
Optional cap on a single checkout. |
Call paywit.dispose() when you're done with an instance.
Platforms #
| Minimum | |
|---|---|
| Android | SDK 23 |
| iOS | 13.0 |
License #
MIT