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

Place this code in your application:didFinishLaunchingWithOptions 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
// First create a configuration and use it to configure the default client.
RCHAPIClientConfig *config = [[RCHAPIClientConfig alloc] initWithAPIKey:@"<api_key>"
                                                         APIClientKey:@"<api_client_key>"];

// Required for logged in users. Leave empty for guest users and temporary users.
config.userID = @"<user ID>";

// Always required.
config.sessionID = @"<session ID>";
[[RCHSDK defaultClient] configure:config];

// Optional: Set the log level to debug so you can observe the API traffic
[RCHSDK setLogLevel:RCHLogLevelDebug];

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 this code in your native view initialization logic, such as viewDidLoad.

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.

#import <RichRelevanceSDK/RichRelevanceSDK.h>

RCHRequestPlacement *placement = [[RCHRequestPlacement alloc] initWithListeningPageType:RCHPlacementPageTypePurchaseComplete];
 RCHPlacementRecsBuilder *builder = [RCHSDK builderForRecsWithPlacement:placement];
NSArray *purchasedProducts = @[
                               [[RCHRequestProduct alloc] initWithIdentifier:@"<product ID 1>" quantity:[NSNumber numberWithInt:<product quantity 1>] priceDollars:[NSNumber numberWithFloat:<single item price 1>]],
                               [[RCHRequestProduct alloc] initWithIdentifier:@"<product ID 2>" quantity:[NSNumber numberWithInt:<product quantity 2>] priceDollars:[NSNumber numberWithFloat:<single item price 2>]],
                               [[RCHRequestProduct alloc] initWithIdentifier:@"<product ID 3>" quantity:[NSNumber numberWithInt:<product quantity 3>] priceDollars:[NSNumber numberWithFloat:<single item price 3>]],
];


for (RCHRequestProduct product in purchasedProducts) {
    [builder addPurchasedProduct:product];
}

[builder setOrderID:@"<order ID>"];
__block RCHRecommendedProduct *product;
[[RCHSDK defaultClient] sendRequest:[builder build] success:^(id responseObject) {
    RCHPlacementsResult *result = responseObject;
    RCHPlacement *placement = result.placements[0];
    product = placement.recommendedProducts[0];
} failure:^(id responseObject, NSError *error) {
    // Use this code block to handle any errors that may occur while loading recommendations.
    NSLog(@"Error encountered: %@", error);
}];

Calling multiple placements

If you want to call multiple placements, simply initialize a builder with a nil placement, then define your placements and pass them to builder:addPlacement. You can also create a list such as a NSArray and iterate with a for..in loop.

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

    NSArray *placements = @[
                            [[RCHRequestPlacement alloc] initWithPageType:RCHPlacementPageTypePurchaseComplete name:@"recs_top"],
                            [[RCHRequestPlacement alloc] initWithPageType:RCHPlacementPageTypePurchaseComplete name:@"recs_middle"]
                            ];
    
    RCHPlacementRecsBuilder *builder = [RCHSDK builderForRecsWithPlacement:nil];
    for (RCHRequestPlacement *placement in placements) {
        [builder addPlacement:placement];
    }
    
    for (RCHRequestProduct product in purchasedProducts) {
        [builder addPurchasedProduct:product];
    }
    
    [[RCHSDK defaultClient] sendRequest:builder success:^(id responseObject) {
        // Add your display logic here
    } failure:^(id responseObject, NSError *error) {
        // Add your error handling logic here
    }];

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 will create a listening placement. Listening placements are a special type of placement that can only log usage data without returning personalization data.

#import <RichRelevanceSDK/RichRelevanceSDK.h>

RCHRequestPlacement *placement = [[RCHRequestPlacement alloc] initWithListeningPageType:RCHPlacementPageTypePurchaseComplete];
RCHPlacementRecsBuilder *builder = [RCHSDK builderForRecsWithPlacement:placement];

NSArray *purchasedProducts = @[
                               [[RCHRequestProduct alloc] initWithIdentifier:@"<product ID 1>" quantity:[NSNumber numberWithInt:<product quantity 1>] priceDollars:[NSNumber numberWithFloat:<single item price 1>]],
                               [[RCHRequestProduct alloc] initWithIdentifier:@"<product ID 2>" quantity:[NSNumber numberWithInt:<product quantity 2>] priceDollars:[NSNumber numberWithFloat:<single item price 2>]],
                               [[RCHRequestProduct alloc] initWithIdentifier:@"<product ID 3>" quantity:[NSNumber numberWithInt:<product quantity 3>] priceDollars:[NSNumber numberWithFloat:<single item price 3>]],
];


for (RCHRequestProduct product in purchasedProducts) {
    [builder addPurchasedProduct:product];
}

[builder setOrderID:@"<order ID>"];
[[RCHSDK defaultClient] sendRequest:[builder build]];

Product Pricing

You can pass product prices in your local currency to RCHRequestProduct initWithIdentifier:quantity:priceDollars:. As an alternative, you can pass prices in cents. Example: one dollar has 100 cents, so the value for USD will be 100. The Yen is the smallest unit in Japan, so the value for JPY will be 1.

/** 
 * In this example we will define a purchased product in Euro (price EUR 29.99).
 * In the first line, we will pass its price using a float.
 * In the second line, we will pass its price using an integer. One Euro has 100 cents, so we need to multiply the original product price by 100.
 *
 * IMPORTANT: Do not use both priceDollars and priceCents in the same request. If you do so, we will only record pricing in local currency.
 */
RCHRequestProduct *productInLocalCurrency =  [[RCHRequestProduct alloc] initWithIdentifier:@"EURPRD192321" quantity:[NSNumber numberWithInt:1] priceDollars:[NSNumber numberWithFloat:29.99]];
RCHRequestProduct *productInCents =  [[RCHRequestProduct alloc] initWithIdentifier:@"EURPRD192321" quantity:[NSNumber numberWithInt:1] priceCents:[NSNumber numberWithInt:2999]];

IMPORTANT Do not use both  initWithIdentifier:quantity:priceDollars: andinitWithIdentifier:quantity:priceCents:in the same request. If you do so, we will only record pricing in local currency.

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 delegate for touch event in your UIViewController for your personalization view.

The following example assumes you are implementing a vertical scroller via a UITableViewController with tableView:didSelectRowAtIndexPath being our delegate for tap events.

@implementation SamplePersonalizationViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // Add your usual initialization logic, for example registerNib. The actual implementation will depend on your code.
    [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([SampleProductCell class]) bundle:nil] forCellReuseIdentifier:[SampleProductCell cellID]];

    // Store an array of personalized product recommendations. You will reference items of this array from your delegate method.
    self.products = @[];
    [self loadData];
}

#pragma mark - TableView

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Reference the current product being selected
    RCHRecommendedProduct *product = self.products[indexPath.row];
    
    // Log a click event
    [product trackClick];
    
    // Initialize your Product Detail view controller. The actual implementation will depend on your code.
    SampleProductDetailScreenViewController *detailVC = [[SampleProductDetailScreenViewController alloc] initWithProduct:product];
    [self.navigationController pushViewController:detailVC animated:YES];
}

@end

 Offline click tracking

In case of poor network connectivity,[product trackClick] will 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.