iVendNextDevelopers Request a sandbox

S25 — Gift card on spend (a big sale earns the shop's own gift card, spendable after a hold)

What the shop does

A customer's sale reaches the shop's threshold. Within the next half a minute the app gives them the shop's own gift card, of the value the shop chose, from the shop's own gift card item. The card can be spent once the hold has passed (24 hours by default), at the till, like any other gift card. Nothing changes at the till: the cashier rings the sale as before.

What happens When
A gift card is made, at a balance of 0, and listed under the customer and the sale (Gift cards) as Held a booked sale whose spend reaches the threshold, for a customer who may earn one
The card is raised to its value by a Gift Card Balance entry (GC-BAL-…) and listed as Released the hold has passed
The till refuses the card: "Insufficient balance: R 0.00 left." (the bench's words, in its currency) a customer tries it during the hold
A held card is never released; a released card never used at the till is set to 0 by a Gift Card Balance entry; both are listed as Voided the sale is cancelled, or its returns take its spend below what earned the card (the last card first). The service reads the sale again just before each release, so this holds whichever event comes first
Nothing is taken from the card; it is listed as Review for the shop to decide the card was already used at the till before that cancellation or return
Nothing a sale under the threshold, a walk-in, a customer group the shop excludes, a sale in another currency, a layaway, an order or a quotation, or a gift card item that could turn into money (rechargeable, paid out as cash, store credit) or expires inside the hold

Spend is what the customer paid for the sale, tax included, less any gift card sold, recharged or paid out on it, less anything paid on it with a gift card, store credit, a partner's wallet, loyalty points or on account, and less a tender discount, so stored value and credit never earn a gift card. An exchange earns on the net the customer paid. Each return takes off what it refunded (its whole value, less its share of a tender discount). Cards per sale: 1 gives one card per sale; a higher number gives one card for each full threshold, up to that number.

What it costs the shop. Each card is a promotion: no sale credits the shop's gift card account when the card is issued, so when it is spent the gift card payment method's account is debited for value the shop gave away. Book it as you book any promotion.

How the customer learns the number. Staff read it under the customer (or the sale) in Desk, Gift cards. Nothing sends it to the customer yet: an e-mail or a message is a later version (it needs the product to give the framework's e-mail call an iVendNext name, or a message gateway).

Bounds, said plainly.

What the shop does to set it up

  1. Install manifest.json (the shop's administrator, on the install screen; on your sandbox, tools/deploy/deploy.py). It adds PP GCS Settings, PP GCS Card, the Gift cards links under Customer and POS Invoice, the feed registration PP GCS Sales (switched off) and the role PP GCS Integration (empty).
  2. In Role Permissions, give PP GCS Integration read on POS Invoice, Customer and Item; read and create on Gift Card; read, create and submit on Gift Card Balance. A manifest can grant rights only on its own record types (the integration user recipe). ⚠ With these rights the key can make a gift card and set the balance of any gift card in the shop, not only this app's: give the role to this app's user alone.
  3. Make the app's integration user with that role and generate its API key.
  4. Open PP GCS Settings, record Default: the currency, the threshold, each card's value, the gift card item (a gift card item that is not rechargeable, not paid out as cash and not store credit), the cards per sale, the hold in hours, and the walk-in customers and customer groups that never earn. Tick Enabled — before step 5, so no sale is booked while the app is off.
  5. Choose the integration user on the feed registration PP GCS Sales and tick POS Invoice. For a hosted service, press Connect again on the app's package record now: the site hands the service the user's key only once the user has its key and is chosen here.
  6. Run the service with the integration user's key (below). Staff see each card under the customer and the sale.

What leaves the shop. The shop calls nothing outside but the service's own address (allowed_urls: the hosted handshake, which carries the integration user's key). The service reads the shop with that key: each booked, returned or cancelled sale from the event feed, the sale itself, its returns, the customer's group and the gift card item. It writes: gift cards, gift card balances and the app's own Card records.

Run it

python3 -m unittest discover -s samples/s25_gift_on_spend/tests -p 'test_*.py'
python3 samples/s25_gift_on_spend/tests/canaries.py

On a sandbox, with the integration user's key in service/.env.local (never committed: PP_BASE, PP_KEY, PP_SECRET, PP_STATE, GCS_PREFIX=PP GCS):

python3 samples/s25_gift_on_spend/service/worker.py run samples/s25_gift_on_spend/service/.env.local --watch 30
#   or the service with its /health beside the worker:
python3 samples/s25_gift_on_spend/service/app.py samples/s25_gift_on_spend/service/.env.local

Many shops (the app template's handshake, chapter 14b): set IVN_LIBRARY_APP and a shops store; each shop's site connects itself to the app's one *.ivendnext.app address in allowed_urls after its install (the site connects to no other address, and refuses a manifest naming two) and hands over its integration user's key (once the shop has made it and pressed Connect again, step 5), and the worker reads each shop's feed with that shop's key, each on its own thread. It is background work, so it runs as a container, never a function:

docker build --platform linux/arm64 -f samples/s25_gift_on_spend/Dockerfile -t gift-card-on-spend:1.0.0 .

Technical notes

What was proven where

Needs this serves

This page in the kit