Skip to main content
RichRelevance

Purchase Complete

Overview

The Purchase Complete screen is the experience available to customers immediately after they successfully purchased their items.

This is a required integration type. You must include the tracking logic even if you do not serve personalization in this section.

Integration example

Initialization

Make sure your AndroidManifest.xml requests permissions to connect to the Internet.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yourcompany.yourappname">
    
    <!-- Basic internet access permission. You should already have this in your app. -->
    <uses-permission android:name="android.permission.INTERNET" />
    
    <!-- Add this to enable offline click tracking and event throttling. -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

Place this code in your main onCreate method. The SDK configuration must take place once per app load, and there is no need to duplicate this code in other controllers.

Replace the following placeholders:

  • <api key> with your API Key.
  • <api client key> with your API Client Key.
  • <user ID> with a valid User ID, or use an empty string if you do not have a user ID (for example if the user hasn't logged in yet).
  • <session ID> with a valid Session ID

 

public class SampleApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        // First create a configuration and use it to configure the default client.
        ClientConfiguration config = new ClientConfiguration("<api key>", "<api client key>");

        // Required for logged in users. Leave empty for guest users and temporary users.
        config.setUserId("<user ID>");
        
        // Always required.
        config.setSessionId("<session ID>");
        RichRelevance.init(this, config);
        // Optional: Set the log level to debug so you can observe the API traffic
        RichRelevance.setLoggingLevel(RRLog.VERBOSE);
    }
}

User and Session IDs

RichRelevance leverages user and session identifiers to provide product and content personalization. You must always provide a Session ID for the current user. A Session ID can have any format and duration. For example, you can refresh a Session ID by app load, or after 1 hour of idling, depending on how you define sessions.

You must provide a User ID when a user logs into your app (or when you can identify a returning user with a consistent, unique identifier). RichRelevance relies on User IDs to drive personalization and to build personalized user models based on behavioral data. User ID must be unique and consistent for each user, in other words, they must not change upon subsequent sessions and logins.

 

Request and display personalization

Place your code in your fragment's initialization logic, such as onCreate.

Return Personalization

Use this code when you are requesting and serving personalized product recommendations.

Replace the following placeholders in the code:

  • <placement name> with your Placement name. You can find a list of placements in your Dashboard.
  • For each purchased product, replace:
    • <product ID>with the Product ID of the purchased item
    • <product quantity>with the purchased quantity for this product
    • <product single price> with the price for a single unit of this product. For example, if a customer purchased 3 products P12389, and its price was 9.99 per item, the value for this argument will be 9.99.
    • <order ID> with an identifier for this order, such as a Confirmation ID.

Make sure to add all the products in the order. In order to successfully log a purchase you must pass at least one valid product.

In addition to the variadic signature, addPurchasedProducts() can also accept a Collection<Product>.

Placement placement = new Placement(Placement.PlacementType.PURCHASE_COMPLETE, "<placement name>");

RichRelevance.buildRecommendationsForPlacements(placement)
  .addPurchasedProducts(
      new Product("<product ID 1>", <product quantity 1>, <product single price 1>),
      new Product("<product ID 2>", <product quantity 2>, <product single price 2>),
      new Product("<product ID 3>", <product quantity 3>, <product single price 3>)
  ).setOrderId("<order ID>")
  .setCallback(new Callback<PlacementResponseInfo>() {
      @Override
      public void onResult(PlacementResponseInfo result) {          
          int index = 0;
          for(PlacementResponse placement : result.getPlacements()) {
              for(final RecommendedProduct recommendedProduct : placement.getRecommendedProducts()) {
                  // Add your view init logic. The actual implementation will depend on your code.
                  // In this example we will assume items are rendered as TableRows in a TableView.
                  TableRow row = new TableRow(context);
                  row.setId(index);
                  row.addView(detailView);
                  index++;
                  tableView.addLayout(row);
              }
          }
      }
      @Override
      public void onError(Error error) {
          // Use this code block to handle errors
          Log.e(getClass().getSimpleName(), "Error: " + error.getMessage());
      }
  }).execute();

Calling multiple placements

If you want to call multiple placements, simply define your placements and pass them to RichRelevance.buildRecommendationsForPlacements() either as individual arguments or as a Collection<Placement>.

IMPORTANT Placements must always be of the same type per request.

// This example defines placements as individual arguments.
Placement topPlacement = new Placement(Placement.PlacementType.PURCHASE_COMPLETE, "recs_top");
Placement middlePlacement = new Placement(Placement.PlacementType.PURCHASE_COMPLETE, "recs_middle");

RichRelevance.buildRecommendationsForPlacements(topPlacement, middlePlacement)
// Add callback logic
.execute();
// This example defines placements as an ArrayList. It is equivalent to the example above.
ArrayList<Placement> placements = new ArrayList<>(
    Arrays.asList(
        new Placement(Placement.PlacementType.PURCHASE_COMPLETE, "recs_top"),
        new Placement(Placement.PlacementType.PURCHASE_COMPLETE, "recs_middle"))
    );

RichRelevance.buildRecommendationsForPlacements(placements)
// Add callback logic
.execute();

Listening Mode

When you do not render personalization in your Purchase Complete UX, you must still send a tracking request using the SDK. This is required so that RichRelevance can gather usage data in order to train your personalization models. In this specific case, you can use a convenience builder that sets all the configuration parameters (including a listening placement) automatically.

RichRelevance.buildLogPurchase(
    "<order id>",
    new Product("<product ID 1>", <product quantity 1>, <product single price 1>),
    new Product("<product ID 2>", <product quantity 2>, <product single price 2>),
    new Product("<product ID 3>", <product quantity 3>, <product single price 3>)
).execute();

In addition to the variadic signature, buildLogPurchase() can also accept a Collection<Product>.

Tracking Events

The SDK will automatically log a page view event when executing the builder. It will also automatically log a placement impression for each of the placements returned. For example, if you request three placements but only one is returned, the SDK will log a placement impression for this returned placement only.

You can include this logic in the controller for your personalization placement fragment, inside a click listener.

  • // Assuming a list of personalized product recommendations is being stored in memory
    List<RecommendedProduct> products;
    
    tableRow.setOnClickListener(new View.OnClickListener() {                   
        @Override
        public void onClick(View view) {
            RecommendedProduct product = products.get((int)view.getId());
            if (product) {
                product.trackClick();
            }
            
            // Add your logic to render your Product Detail View.
        }
    });
    

Offline click tracking

In case of poor network connectivity,trackClick() can store click data locally and will send these events at a later stage, for example when there is enough bandwidth or when the network becomes available again. To allow this, your app need to request the relevant permission in your AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

If you cannot add this permission to your manifest, you can still flush click events programmatically by accessing the following method:

RichRelevance.flushClickTracking(); 
  • Was this article helpful?