A plugin for channel-aware store credit wallets with ledger tracking. Customers can use wallet balance as a payment method at checkout.

Run a migration to add the Wallet entities to the database, then create a Payment Method in the admin using the store-credit handler.
You also need to rebuild the admin dashboard to see the new Store Credit Wallets on the customer detail page.
These functions are available in the admin API.
Each customer can have multiple wallets. This mutation creates a new wallet for the customer. Starting balance is always 0.
An admin can choose to refund any payment to store credit wiht the custom refundPaymentToStoreCredit mutation:
To refund a payment that was made with store credit, you can use the built-in refundOrder mutation supplied by Vendure. In this case it will refund the store credit to the same wallet that was used to make the payment.
Customers can pay for orders using their store credit balance.
Optionally, a customer can choose to partially pay for an order by specifying the amount to pay with store credit.
Logged-in customers can fetch their wallets via activeCustomer:
Or query a single wallet by ID:
You can configure the plugin to automatically create gift card wallets when certain products are ordered. Use the createGiftCardWallet hook in the plugin options:
The hook is called once for each quantity per order line item. For example, if an order has 1 order line with a giftcard, and the quantity is 3, the hook is invoked 3 times, allowing you to return a different cardCode for each individual gift card.
The generated gift card codes are saved to the order line's giftCardCodes custom field, so you can reference them later (e.g. for email delivery or customer notifications).
Customers can pay for an order by providing the gift card code at checkout. The full wallet balance will be applied to the order (up to the outstanding amount).
To only pay a specific amount with the gift card, include the amount in the metadata:
Gift card wallets are identified by their code. Treat this code like cash:
anyone who knows the code can spend the wallet. It is the responsibility of the
consuming project (via the createGiftCardWallet strategy) to make sure the
returned cardCode is sufficiently unguessable — use a cryptographically
secure random generator (e.g. crypto.randomUUID() or generatePublicId()
from @vendure/core) and never derive the code from predictable data like
order id or sequence numbers.
The walletByCode query has a few safeguards to reduce enumeration risk:
UpdateOrder permission;null for unknown codes (instead of throwing) so the API does not
leak whether a given code exists;You can create wallets with a specified balance for all (or given) customers with the following script that is included:
To create a wallet with an initial starting balance, you can create a wallet for a customer on the customer detail page in the admin dashboard. Wallets always start with a balance of 0, but you can adjust the balance to anything you want after creation. Wallets always start with 0, so that you can recalculate the current balance by 'rerunning' all the adjustments.
Currently you can not delete a wallet, because of accountability: you need to be able to see the history of adjustments on the wallet. Future version will allow you to archive a wallet.
WalletAdjustment.mutatedBy optional, allowing gift-card payments to be recorded without an active user (e.g. anonymous/guest customers).NOT NULL constraint on wallet_adjustment.mutatedById so that adjustments can be created without an associated user.createGiftCardWallet hook is now called once per order line quantity instead of once per order line. This allows returning different gift card configurations for each individual item when the quantity of an order line is > 1.giftCardCodes custom field to OrderLine to store generated gift card codes.GiftCardWalletCreatedEvent to GiftCardsCreatedEvent. The old class name is kept as a deprecated alias.Wallet based Gift CardswalletByCode is now channel-scoped, returns null for unknown codes, requires UpdateOrder on the admin API and an active order on the shop API (to prevent enumeration attacks)WalletService.create now throws when neither customerId nor code is provided. The admin CreateWalletInput has a new optional code field; pass a code explicitly when creating a wallet without a customergiftCardWallets query now requires the ReadCustomer permissionwallet.name allows duplicate wallet names across customerswallet.adjustments is now paginated, that means you need to query adjustments { items { ...fields } } instead of adjustments { ...fields };Money to prevent rounding errors.