Vendure Flutter SDK
A Flutter SDK for interacting with the Vendure e-commerce framework's GraphQL API. This SDK simplifies the process of connecting to Vendure and performing common operations like authentication, adding items to the cart, and more.
Sponsor
Thanks to ZikZak AI for sponsoring this project!
ZikZak AI is an AI-Powered Price Comparison app that you scan barcodes, and discover amazing savings instantly. Your personal shopping assistant that never sleeps.
Features
- Authenticate users
- Add items to the cart
- Manage orders
- Manage customers
- Access catalog and system information
- Extendable to support custom GraphQL operations
- Global enum conversion toggles:
VendureUtils.convertQueryEnumsandVendureUtils.convertMutationEnums(both default totrue). UseVendureUtils.setConvertEnums({bool? queryEnums, bool? mutationEnums})to change them globally. - Convenience re-export: The utilities are available via a short import (
package:vendure/vendure_utils.dart) and are also exported frompackage:vendure/vendure.dartfor easy access toVendureUtils.
Installation
Add the following to your pubspec.yaml:
dependencies:
vendure: ^2.8.0
Note: Starting with v2.8.0 the SDK exposes global flags to control enum conversion:
- Toggle query/response enum normalization with
VendureUtils.setConvertEnums(queryEnums: true|false). - Toggle mutation input enum normalization with
VendureUtils.setConvertEnums(mutationEnums: true|false).
You can import the helper utilities using the short path:
import 'package:vendure/vendure_utils.dart';
// or import the main library:
import 'package:vendure/vendure.dart';
Usage
First, create an instance of the Vendure class:
import 'package:vendure/vendure.dart';
void main() async {
// Initialize with Native Auth
Vendure vendure = await Vendure.initializeWithNativeAuth(
endpoint: 'http://localhost:3000/shop-api',
username: 'your-username',
password: 'your-password',
sessionDuration: const Duration(days: 1),
customFieldsConfig: {
'User': ['os'],
'Order': ['giftMessage']
},
);
// Initialize with Firebase Auth
vendure = await Vendure.initializeWithFirebaseAuth(
endpoint: 'http://localhost:3000/shop-api',
uid: '8o6CuL3vvceCwjnSxtCTp08vEMr2',
jwt: 'your-jwt-token',
sessionDuration: const Duration(hours: 1),
customFieldsConfig: {
'User': ['os'],
'Order': ['giftMessage']
},
languageCode: 'TR',
channelToken: 'your-channel-token'
);
// Initialize with Token
vendure = await Vendure.initialize(
endpoint: 'http://localhost:3000/shop-api',
token: '9a3d1222ed018701fdd8a7484a7299977507787f5bb22bec898e67939ee453169f8',
);
// Initialize with Custom Auth
vendure = await Vendure.initializeWithCustomAuth(
endpoint: 'http://localhost:3000/shop-api',
fetchToken: (params) async {
// Implement your custom token fetching logic here
return 'custom-token';
},
tokenParams: {
'customParam1': 'value1',
'customParam2': 'value2',
},
sessionDuration: const Duration(days: 1),
customFieldsConfig: {
'User': ['os'],
'Order': ['giftMessage']
},
);
// Use the vendure instance for various operations
Vendure vendure = Vendure.instance;
// Update the authentication token at runtime (e.g., after refresh)
Vendure.setAuthToken('your-new-token');
}
Firebase Authentication
Firebase updates tokens every hour. You should listen and update Vendure client with new token:
Future<void> initializaRepository() async {
FirebaseAuth.instance.idTokenChanges().listen((event) async {
if (event == null) return;
String? idToken = await event.getIdToken();
if (idToken == null) {
throw Exception('idToken is null');
}
// Instead of reinitializing, just update the token:
Vendure.setAuthToken(idToken);
});
}
Order Operations
Add Item to Order
Future<void> addItem() async {
try {
var result = await vendure.order.addItemToOrder(
productVariantId: 79,
quantity: 1,
);
print('Item added: ${result.toJson()}');
} catch (e) {
print('Error adding item to cart: $e');
}
}
Set Shipping Address
Future<void> setShippingAddress() async {
try {
var result = await vendure.order.setOrderShippingAddress(
input: CreateAddressInput(
fullName: 'Abraham Lincoln',
streetLine1: '1600 Pennsylvania Avenue NW',
city: 'Washington',
postalCode: '20500',
countryCode: 'US',
),
);
print('Shipping address set: ${result.toJson()}');
} catch (e) {
print('Error setting shipping address: $e');
}
}
Set Billing Address
Future<void> setBillingAddress() async {
try {
var result = await vendure.order.setOrderBillingAddress(
input: CreateAddressInput(
fullName: 'Abraham Lincoln',
streetLine1: '1600 Pennsylvania Avenue NW',
city: 'Washington',
postalCode: '20500',
countryCode: 'US',
),
);
print('Billing address set: ${result.toJson()}');
} catch (e) {
print('Error setting billing address: $e');
}
}
Get Active Order
Future<void> getActiveOrder() async {
try {
var result = await vendure.order.getActiveOrder();
print('Active order: ${result.toJson()}');
} catch (e) {
print('Error getting active order: $e');
}
}
Add Payment to Order
Future<void> addPayment() async {
try {
var result = await vendure.order.addPaymentToOrder(
input: PaymentInput(
method: 'stripe-payment',
metadata: {'stripeCheckoutSessionId': 'xyz'},
),
);
print('Payment added: ${result.toJson()}');
} catch (e) {
print('Error adding payment to order: $e');
}
}
Get Order by Code
Future<void> getOrderByCode(String code) async {
try {
var result = await vendure.order.getOrderByCode(code: code);
print('Order by code: ${result.toJson()}');
} catch (e) {
print('Error getting order by code: $e');
}
}
Get Payment Methods
Future<void> getPaymentMethods() async {
try {
var result = await vendure.order.getPaymentMethods();
print('Payment methods: ${result.map((e) => e.toJson()).toList()}');
} catch (e) {
print('Error getting payment methods: $e');
}
}
List Shipping Methods
Future<void> getShippingMethods() async {
try {
var result = await vendure.order.getShippingMethods();
print('Shipping methods: ${result.map((e) => e.toJson()).toList()}');
} catch (e) {
print('Error getting shipping methods: $e');
}
}
Set Shipping Method for Order
Future<void> setCustomerForOrder() async {
try {
var result = await vendure.order.setCustomerForOrder(
input: CreateCustomerInput(
emailAddress: 'customer@example.com',
firstName: 'John',
lastName: 'Doe',
),
);
print('Customer set for order: ${result.toJson()}');
} catch (e) {
print('Error setting customer for order: $e');
}
}
Set Customer for Order
Future<void> setOrderShippingMethod({
required String shippingMethodId,
List<String>? additionalMethodIds }) async {
try {
var result = await vendure.order.setOrderShippingMethod(
shippingMethodId: shippingMethodId, additionalMethodIds: additionalMethodIds);;
print('Customer set for order: ${result.toJson()}');
} catch (e) {
print('Error setting customer for order: $e');
}
}
Adjust Order Line
Future<void> adjustOrderLine(String orderLineId, int quantity) async {
try {
var result = await vendure.order.adjustOrderLine(
orderLineId: orderLineId,
quantity: quantity,
);
print('Order line adjusted: ${result.toJson()}');
} catch (e) {
print('Error adjusting order line: $e');
}
}
Remove Order Line
Future<void> removeOrderLine(String orderLineId) async {
try {
var result = await vendure.order.removeOrderLine(orderLineId: orderLineId);
print('Order line removed: ${result.toJson()}');
} catch (e) {
print('Error removing order line: $e');
}
}
Apply Coupon Code
Future<void> applyCouponCode(String couponCode) async {
try {
var result = await vendure.order.applyCouponCode(couponCode: couponCode);
print('Coupon code applied: ${result.toJson()}');
} catch (e) {
print('Error applying coupon code: $e');
}
}
Remove Coupon Code
Future<void> removeCouponCode(String couponCode) async {
try {
var result = await vendure.order.removeCouponCode(couponCode: couponCode);
print('Coupon code removed: ${result.toJson()}');
} catch (e) {
print('Error removing coupon code: $e');
}
}
Transition Order to State
Future<void> transitionOrderToState(String state) async {
try {
var result = await vendure.order.transitionOrderToState(state: state);
print('Order transitioned to state: ${result.toJson()}');
} catch (e) {
print('Error transitioning order to state: $e');
}
}
Set Order Custom Fields
Future<void> setOrderCustomFields(Map<String, dynamic> customFields) async {
try {
var result = await vendure.order.setOrderCustomFields(
input: UpdateOrderInput(customFields: customFields),
);
print('Order custom fields set: ${result.toJson()}');
} catch (e) {
print('Error setting order custom fields: $e');
}
}
Catalog Operations
Get Collections
Future<void> getCollections() async {
try {
var result = await vendure.catalog.getCollections(
options: CollectionListOptions(topLevelOnly: true),
);
print('Collections: ${result.toJson()}');
} catch (e) {
print('Error getting collections: $e');
}
}
Get Collection by ID
Future<void> getCollectionById(int id) async {
try {
var result = await vendure.catalog.getCollectionById(id: id);
print('Collection: ${result.toJson()}');
} catch (e) {
print('Error getting collection: $e');
}
}
Get Collection by Slug
Future<void> getCollectionBySlug(String slug) async {
try {
var result = await vendure.catalog.getCollectionBySlug(slug: slug);
print('Collection: ${result.toJson()}');
} catch (e) {
print('Error getting collection: $e');
}
}
Get Collections With Parent and Children
Future<void> getCollectionsWithParentChildren() async {
try {
CollectionListOptions options = CollectionListOptions(
topLevelOnly: false,
filter: CollectionFilterParameter(
parentId: IdOperators(eq: '2'),
),
);
var result = await vendure.catalog
.getCollectionListWithParentChildren(options: options);
for (var collection in result.items) {
print('Collection: ${result.toJson()}');
if (collection.children.isNotEmpty) {
print(collection.children.first.slug);
}
}
} catch (e) {
print('Error getting collection: $e');
}
}
Get Collection With Parent and Children
Future<void> getCollectionWithParentChildren(String id) async {
try {
var result = await vendure.catalog
.getCollectionWithParentChildren(id:id);
for (var collection in result.items) {
print('Collection: ${result.toJson()}');
if (collection.children.isNotEmpty) {
print(collection.children.first.slug);
}
}
} catch (e) {
print('Error getting collection: $e');
}
}
Get Collection With Parent
Future<void> getCollectionWithParent(String id) async {
try {
var result = await vendure.catalog
.getCollectionWithParent(id:id);
} catch (e) {
print('Error getting collection: $e');
}
}
Get Collection With Children
Future<void> getCollectionWithChildren(String id) async {
try {
var result = await vendure.catalog
.getCollectionWithChildren(id:id);
} catch (e) {
print('Error getting collection: $e');
}
}
Get Products
Future<void> getProducts() async {
try {
var result = await vendure.catalog.getProducts(
options: ProductListOptions(take: 1),
);
print('Products: ${result.toJson()}');
} catch (e) {
print('Error getting products: $e');
}
}
Get Product by ID
Future<void> getProductById(int id) async {
try {
var result = await vendure.catalog.getProductById(id: id);
print('Product: ${result.toJson()}');
} catch (e) {
print('Error getting product: $e');
}
}
Get Product by Slug
Future<void> getProductBySlug(String slug) async {
try {
var result = await vendure.catalog.getProductBySlug(slug: slug);
print('Product: ${result.toJson()}');
} catch (e) {
print('Error getting product: $e');
}
}
Search Catalog
Future<void> searchCatalog(String term) async {
try {
var result = await vendure.catalog.searchCatalog(
input: SearchInput(term: term),
);
print('Search results: ${result.toJson()}');
} catch (e) {
print('Error searching catalog: $e');
}
}
Customer Operations
Get Active Customer
Future<void> getActiveCustomer() async {
try {
var result = await vendure.customer.getActiveCustomer();
print('Active customer: ${result.toJson()}');
} catch (e) {
print('Error getting active customer: $e');
}
}
Get Current User
Future<void> getCurrentUser() async {
try {
var result = await vendure.customer.getCurrentUser();
print('Current user: ${result.toJson()}');
} catch (e) {
print('Error getting current user: $e');
}
}
Get Active Channel
Future<void> getActiveChannel() async {
try {
var result = await vendure.customer.getActiveChannel();
print('Active channel: ${result.toJson()}');
} catch (e) {
print('Error getting active channel: $e');
}
}
Update Customer
Future<void> updateCustomer(String firstName, String lastName) async {
try {
var result = await vendure.customer.updateCustomer(
input: UpdateCustomerInput(
firstName: firstName,
lastName: lastName,
),
);
print('Customer updated: ${result.toJson()}');
} catch (e) {
print('Error updating customer: $e');
}
}
Create Customer Address
Future<void> createCustomerAddress() async {
try {
var result = await vendure.customer.createCustomerAddress(
input: CreateAddressInput(
fullName: 'John Doe',
streetLine1: '123 Main St',
city: 'Springfield',
postalCode: '12345',
countryCode: 'US',
),
);
print('Customer address created: ${result.toJson()}');
} catch (e) {
print('Error creating customer address: $e');
}
}
Update Customer Address
Future<void> updateCustomerAddress(String addressId) async {
try {
var result = await vendure.customer.updateCustomerAddress(
input: UpdateAddressInput(
id: addressId,
fullName: 'John Doe Updated',
streetLine1: '456 Main St',
city: 'Springfield',
postalCode: '12345',
countryCode: 'US',
),
);
print('Customer address updated: ${result.toJson()}');
} catch (e) {
print('Error updating customer address: $e');
}
}
Delete Customer Address
Future<void> deleteCustomerAddress(String addressId) async {
try {
var result = await vendure.customer.deleteCustomerAddress(id: addressId);
print('Customer address deleted: ${result.toJson()}');
} catch (e) {
print('Error deleting customer address: $e');
}
}
System Operations
Get Available Countries
Future<void> getAvailableCountries() async {
try {
var result = await vendure.system.getAvailableCountries();
print('Available countries: ${result.toJson()}');
} catch (e) {
print('Error getting available countries: $e');
}
}
Get Facets
Future<void> getFacets() async {
try {
var result = await vendure.system.getFacets(
options: FacetListOptions(take: 1),
);
print('Facets: ${result.toJson()}');
} catch (e) {
print('Error getting facets: $e');
}
}
Get Facet
Future<void> getFacet(int id) async {
try {
var result = await vendure.system.getFacet(id: id);
print('Facet: ${result.toJson()}');
} catch (e) {
print('Error getting facet: $e');
}
}
Authentication Operations
Authenticate with Username and Password
Future<void> authenticate(String username, String password) async {
try {
var result = await vendure.auth.authenticate(
username: username,
password: password,
);
print('Authentication result: ${result.toJson()}');
} catch (e) {
print('Error authenticating: $e');
}
}
Authenticate with Firebase
Future<void> authenticateFirebase(String uid, String jwt) async {
try {
var result = await vendure.auth.authenticateFirebase(
uid: uid,
jwt: jwt,
);
print('Firebase Authentication result: ${result.toJson()}');
} catch (e) {
print('Error authenticating with Firebase: $e');
}
}
Get Token
Future<void> getToken(String username, String password) async {
try {
var token = await vendure.auth.getToken(
username: username,
password: password,
);
print('Token: $token');
} catch (e) {
print('Error getting token: $e');
}
}
Get Token with Firebase
Future<void> getTokenFirebase(String uid, String jwt) async {
try {
var token = await vendure.auth.getTokenFirebase(
uid: uid,
jwt: jwt,
);
print('Firebase Token: $token');
} catch (e) {
print('Error getting Firebase token: $e');
}
}
Login
Future<void> login(String username, String password) async {
try {
var result = await vendure.auth.login(
username: username,
password: password,
rememberMe: true,
);
print('Login result: ${result.toJson()}');
} catch (e) {
print('Error logging in: $e');
}
}
Logout
Future<void> logout() async {
try {
var result = await vendure.auth.logout();
print('Logout result: ${result.toJson()}');
} catch (e) {
print('Error logging out: $e');
}
}
Register Customer Account
Future<void> registerCustomerAccount() async {
try {
var result = await vendure.auth.registerCustomerAccount(
input: RegisterCustomerInput(
emailAddress: 'test@example.com',
firstName: 'John',
lastName: 'Doe',
),
);
print('Register customer account result: ${result.toJson()}');
} catch (e) {
print('Error registering customer account: $e');
}
}
Verify Customer Account
Future<void> verifyCustomerAccount(String token, String? password) async {
try {
var result = await vendure.auth.verifyCustomerAccount(
token: token,
password: password,
);
print('Verify customer account result: ${result.toJson()}');
} catch (e) {
print('Error verifying customer account: $e');
}
}
Update Customer Password
Future<void> updateCustomerPassword(String currentPassword, String newPassword) async {
try {
var result = await vendure.auth.updateCustomerPassword(
currentPassword: currentPassword,
newPassword: newPassword,
);
print('Update customer password result: ${result.toJson()}');
} catch (e) {
print('Error updating customer password: $e');
}
}
Request Update Customer Email Address
Future<void> requestUpdateCustomerEmailAddress(String password, String newEmailAddress) async {
try {
var result = await vendure.auth.requestUpdateCustomerEmailAddress(
password: password,
newEmailAddress: newEmailAddress,
);
print('Request update customer email address result: ${result.toJson()}');
} catch (e) {
print('Error requesting update customer email address: $e');
}
}
Update Customer Email Address
Future<void> updateCustomerEmailAddress(String token) async {
try {
var result = await vendure.auth.updateCustomerEmailAddress(
token: token,
);
print('Update customer email address result: ${result.toJson()}');
} catch (e) {
print('Error updating customer email address: $e');
}
}
Request Password Reset
Future<void> requestPasswordReset(String emailAddress) async {
try {
var result = await vendure.auth.requestPasswordReset(
emailAddress: emailAddress,
);
print('Request password reset result: ${result.toJson()}');
} catch (e) {
print('Error requesting password reset: $e');
}
}
Reset Password
Future<void> resetPassword(String token, String password) async {
try {
var result = await vendure.auth.resetPassword(
token: token,
password: password,
);
print('Reset password result: ${result.toJson()}');
} catch (e) {
print('Error resetting password: $e');
}
}
Custom Operations
You can also perform custom operations using the custom method.
Custom Mutation
Future<void> customMutation() async {
try {
const String myCustomMutation = r'''
type CustomMutationInput{
customField: String!
}
mutation CustomMutation($input:CustomMutationInput) {
customMethod(input:$input){
__typename
{
customField
}
}
}
''';
var variables = {"customField": 'your-custom-value'};
final result = await vendure.custom.mutate(
myCustomMutation,
variables,
CustomMutationResult.fromJson,
expectedDataType: 'custom',
);
print('Custom result: ${result.customField}');
} catch (e) {
print('Error custom mutation: $e');
}
}
Custom Query
Future<void> customQuery() async {
try {
const String myCustomQuery = r'''
type CustomQueryInput{
customField: String!
}
query CustomQuery($input:CustomQueryInput) {
customMethod(input:$input){
__typename
{
customField
}
}
}
''';
var variables = {"customField": 'your-custom-value'};
final result = await vendure.custom.query(
myCustomQuery,
variables,
CustomQueryResult.fromJson,
expectedDataType: 'custom',
);
print('Custom result: ${result.customField}');
} catch (e) {
print('Error custom query: $e');
}
}
Custom Query List
Future<void> customQueryList() async {
try {
const String myCustomQueryList = r'''
query CustomQueryList {
customListMethod{
__typename
{
customListItem
}
}
}
''';
final result = await vendure.custom.queryList(
myCustomQueryList,
{},
CustomQueryResult.fromJson,
expectedDataType: 'customListItems',
);
for (var item in result) {
print('Custom list item: ${item.customListItem}');
}
} catch (e) {
print('Error custom query list: $e');
}
}
Custom Mutation List
Future<List<ZikZakResponse>> postZikZaks(
{required List<ZikZak> zikZaks, required String userId}) async {
final input = zikZaks
.map((zikZak) => ZikZakToMutationMapper.toMutationInput(zikZak, userId))
.toList();
print(input.map((i) => i.toJson()).toList());
return _vendure.custom.mutateList<ZikZakResponse>(
postZikZaksMutation,
{'input': input.map((i) => i.toJson()).toList()},
ZikZakResponse.fromJson,
expectedDataType: 'postZikZaks',
);
}
Contributing
Contributions are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request on the GitHub repository.
Libraries
- vendure
- vendure_utils
- Convenience re-export for Vendure utilities.


