Skip to content

Instantly share code, notes, and snippets.

@quetool
Last active September 26, 2025 10:15
Show Gist options
  • Select an option

  • Save quetool/33e9a73ff47f4e242a628693aa793bac to your computer and use it in GitHub Desktop.

Select an option

Save quetool/33e9a73ff47f4e242a628693aa793bac to your computer and use it in GitHub Desktop.
POS SDK Example
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:pos_client/pos_client.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const PaymentScreen(),
);
}
}
class PaymentScreen extends StatefulWidget {
const PaymentScreen({super.key});
@override
State<PaymentScreen> createState() => _PaymentScreenState();
}
class _PaymentScreenState extends State<PaymentScreen> {
PosEvent? _event;
String status = '';
late final IPosClient posClient;
// USDC on Arbitrum
final supportedToken = PosToken(
network: PosNetwork(name: 'Arbitrum One', chainId: 'eip155:42161'),
symbol: 'USDC',
standard: 'erc20',
address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
);
@override
void initState() {
super.initState();
// [PosClient SDK API] 1. Construct your PosClient instance
final metadata = Metadata(
merchantName: 'Merchant Name',
description: 'Secure Crypto Payment Terminal',
url: 'https://merchant-url.com',
logoIcon: 'https://merchant-url.com/icon.png',
);
posClient = PosClient(
projectId: '87....', // TODO set your own project ID
deviceId: 'device_id',
metadata: metadata,
);
// [PosClient SDK API] 2. call setTokens to construct namespaces with your supported tokens and network
posClient.setTokens(
tokens: [
supportedToken,
],
);
// [PosClient SDK API] 3. Subscribe to events
posClient.onPosEvent.subscribe(_onPosEvent);
// [PosClient SDK API] 4. initialize PosClient SDK. Can be awaited if needed
posClient.init().then((_) {
// [PosClient SDK API] 5. create a payment intent with the PaymentIntent. Can be awaited if needed
posClient.createPaymentIntent(
paymentIntents: [
PaymentIntent(
token: posClient.configuredTokens.first,
amount: '1.0',
recipient: '0xD6....', // TODO set your own recipient
),
],
);
});
}
void _onPosEvent(PosEvent event) {
setState(() {
if (event is QrReadyEvent) {
status += '1. Scan QR code with your wallet';
} else if (event is ConnectRejectedEvent) {
status += '\n2. User rejected session';
} else if (event is ConnectFailedEvent) {
status += '\n2. Connection failed: ${event.message}';
} else if (event is ConnectedEvent) {
status += '\n2. Connected!';
} else if (event is PaymentRequestedEvent) {
status += '\n3. Requesting payment...';
} else if (event is PaymentRequestRejectedEvent) {
status += '\n3. User rejected payment.';
} else if (event is PaymentBroadcastedEvent) {
status += '\n4. Payment broadcasted, waiting confirmation...';
} else if (event is PaymentFailedEvent) {
status += '\n4. Payment failed: ${event.message}';
} else if (event is PaymentSuccessfulEvent) {
status += '\n4. Payment successful!. Hash: ${event.txHash}';
} else if (event is DisconnectedEvent) {
status += '\n5. Disconnected';
}
_event = event;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Crypto Payment')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
(_event is QrReadyEvent)
? QrImageView(
data: (_event as QrReadyEvent).uri.toString(),
size: 250,
)
: SizedBox.shrink(),
SizedBox(height: 20),
Padding(padding: const EdgeInsets.all(8.0), child: Text(status)),
],
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment