A basket is a collection of product variants.

There are two types of baskets:

  • Persistent Baskets: The contents of a PersistentBasket are managed by the user and changes to the baskets are saved with the user profile.
  • Temporary Baskets: The contents of a TemporaryBasket cannot be modified by the user and the basket is not saved with the user profile.

Manipulation of PersistentBaskets, such as adding or removing products and changing quantities is performed locally using the BasketsManager.

A TemporaryBasket can only be retrieved from the TemporaryBasketWorkflow and cannot be created or manipulated by the user - the only action you can perform with a TemporaryBasket is to create an invoice for the basket. After 60 minutes the tag associated with the basket will expire.


This page covers:

Note: For those using RxJava, all the methods described below are available in the RxBasketsManager


Managing Baskets


Obtaining the Baskets for a User

The SDK manages the creation and deletion of baskets based on whether there are any product variants added for a specific merchant.
A basket only exists for a merchant if it contains at least one product variant.

There are two situations that result in a basket being deleted:

  • All product variants are removed from the basket.
  • The user purchases the items in a basket.

If a null is returned when retrieving a basket it means that no product variants are currently added for the merchant. In this case just add a product variant using the BasketsManager.

  1. Get the baskets for the current user using the BasketsManager:
BasketsManager basketsManager = ManagerFactory.getInstance().getBasketsManager();
Baskets currentBaskets = basketsManager.getCurrentBaskets();
Set<PersistentBasket> baskets = currentBaskets.getBaskets();
if (!baskets.isEmpty()) {
	// Display baskets to user for selection
}

  1. Get the basket for a specific merchant:
PersistentBasket basket = baskets.GetBasket(merchant);
// If there is no basket for the merchant null is returned
if (basket != null) {
	// manage basket contents
}

Adding a Product Variant to a Basket

There is no need to create a basket for a merchant if one doesn't already exist. Simply follow the steps below and the SDK will create the basket for you.

  1. Add a product variant to the basket for the merchant:
Mechant merchant = workflow.getMerchant();
ProductVariant variant = workflow.getProduct().getVariants().get(0);
basketsManager.addVariant(merchant, variant);

  1. Or you can add a specific quantity of the product variant to the basket:
basketsManager.addVariant(workflow.getMerchant(), variant, 2);

Removing a Product Variant from a Basket

  1. You can remove a single quantity of a variant (this will return true if the quantity of the variant was decreased by 1), if the remaining quantity is 0 the item will be removed from the basket:
boolean singleQuantityRemoved = basketsManager.removeVariant(merchant, variant);

  1. Or you can remove a specific quantity:
// The quantity removed is returned
int quantityRemoved = basketsManager.removeVariant(merchant, variant, 2);

Changing the Quantity of a Product Variant

  1. Set the quantity of a variant:

This will override the existing quantity value.
if you set the quantity to 0 the basket item for that variant will be removed.

basketsManager.setVariantQuantity(merchant, variant, 3);

Basket Items

A basket is made up of multiple line items, one for each unique product variant. A BasketItem records the quantity of each variant (the quantity will always be >= 1):

for (BasketItem item : basket.getItems()) {
	ProductVariant variant = item.getVariant();
	int quantity = item.getQuantity();
}

Saving a Basket to the Server

  1. To make Basket information available on other devices or between logins you need to update the Basket on the server using the BasketsManager:
basketsManager.updateBasket(merchant, new PowaTagCallback<PersistentBasket>() {
	public void onSuccess(PersistenBasket basket) {
		// Basket has been updated on the server and is accessible from other devices
	}
	public void onError(PowaTagException exception) {
	}
});



Preparing The Basket For Checkout

Before creating an invoice you need to ensure that the user's profile has all the information required by the merchant.


Obtaining Fulfillment Options

The merchant may offer multiple fulfillment options for the user's basket.

The two main fulfillment types are:

  • Delivery: The user selects an address where the order should be delivered.
  • Collection: The user selects one of the merchant's locations to collect the items from.

Obtaining Delivery Options

If the user has selected to ship the items to an address.

Use the calculateShippingCosts method to obtain a list of shipping costs for each address in the user's profile.
Each ShippingCost contains a list of fulfillment options available for a single address.
Each FulfillmentOption has a name, description and price that can be shown to the user.

basketsManager.calculateShippingCosts(basket, new PowaTagCallback<List<ShippingCost>> () {
	public void onSuccess(List<ShippingCost> shippingCosts) {
		for (ShippingCost shippingCost : shippingCosts) {
			if(selectAddress == shippingCost.getAddress()) {
				fulfillmentOptions = shippingCost.getFulfillmentOptions();
				// Display fulfillment options for selected address to user for selection
				displayInitialFulfillmentOptions(fulfillmentOptions);
			}
		}
	}
	public void onError(PowaTagException exception) {
	}	
}

Obtaining Collection Options

Not all merchants allow in-store collection so always check before offering this option to a user.

  1. Determine if in-store collection is available:
List<FulfillmentOption> fulfillmentOptions = basket.getMerchant().getFulfillmentOptions();
for (FufillmentOption fulfillmentOption : fulfillmentOptions) {
	if (fulfillmentOption.getType() == DeliveryType.COLLECTION) {
		// The merchant offers in-store collection
		// Add to collection to display to user for selection.
		collectionFulfillmentOptions.add(fulfillmentOption);
	} else {
		// Do not offer in-store collection to user
	}
}

  1. Obtain pickup locations for the merchant:
MerchantManager merchantManager = ManagerFactory.getInstance().getMerchantManager();
GeoLocation geoLocation = new GeoLocation(.0, .0);
Page page = new Page(20);
page.setPage(1);
merchantManager.getMerchantPickupLocations(merchant, geoLocation, page, new PowaTagCallback<List<MerchantLocation>>() {
    public void onSuccess(List<MerchantLocation> merchantLocations) {
        //Retrieves a list of merchant locations based on their distance from a specified GeoLocation. The list is sorted from closest to furthest.
    }

    public void onError(PowaTagException exception) {
    }
});

Creating an Invoice for a Basket

  1. Select a Payment Instrument from the Profile that is accepted by the Merchant:
ProfileManager profileManager = ManagerFactory.getInstance().getProfileManager();
List<PaymentInstrument> acceptedPaymentInstruments = profileManager.getAcceptedPaymentInstruments(merchant);
// Get the user to select a payment instrument
PaymentInstrument selectedPaymentInstrument = acceptedPaymentInstruments.get(0);

  1. Redeem coupons

Use the CouponPicker to help the user select an available discount for this basket. (see Coupons)

List<Coupon> selectedCoupons;
List<Dicount> availableDiscounts = ManagerFactory.getInstance().getCouponManager().getAvailableDiscounts(basket, new PowaTagCallback<List<Discount>>() {
	public void onSuccess(List<Discount> discounts) {
		// Get the user to select the discount they want
		CouponPicker couponPicker = new CouponPicker(availableDiscounts);
		// Use Coupon picker to get the user to select a discount to apply
		
		// Obtain the discount the user has selected.
		Discount discount = couponPicker.getSelectedDiscount();
		if (discount != null) {
			selectedCoupons = discount.getAppliedCoupons();
		}
	}
	public void onError(PowaTagException exception) {
	}
}

  1. Create the Payment Invoice Details:

Create the PaymentInvoiceDetails using one of the two constructors depending on the fullfilment type.

PaymentInvoiceDetails paymentInvoiceDetails;
if (userSelectedDeliveryOption) {
	// Use the shipping address selected by the user
	paymentInvoiceDetails = new PaymentInvoiceDetails(selectedPaymentInstrument, shippingAddress, selectedFulfillmentOption, selectedCoupons);
} else {
	// Use the merchant location selected by the user
	paymentInvoiceDetails = new PaymentInvoiceDetails(selectedPaymentInstrument, merchantLocation, selectedFulfillmentOption, selectedCoupons);
}

  1. Use the BasketsManager to create the invoice for the basket:
basketsManager.createInvoice(basket, paymentInvoiceDetails, new PowaTagCallback<PaymentInvoice>() {
	public void onSuccess(PaymentInvoice invoice) {
		// obtain the invoice cost
		Cost cost = invoice.getCost();
	}
	public void onError(PowaTagException exception) {
	}
});

Paying for a Payment Invoice

Now that you have an invoice for the basket, the next step is to process the payment.