NAV

Overview

The Curbside SDK allows retailers to integrate the Curbside platform into their existing customer-facing apps to get reliable alerts when customers are on approach to their stores to pick up orders.

The Curbside SDK also supports retail employee-facing apps that run in stores to get alerts when customers are on approach.

The CurbsideSDK has two integration points:

  • Mobile : For the retailer’s customer facing application
  • StoreOps : For the Store Ops order tracking application that run at retail stores

API key and Secret

Before you can use Curbside SDK, you’ll need an API key and secret. The API key and secret is needed to uniquely indentify your app to the Curbside platform. You will need one set of API key and secret for production and another set for development.

Email getcurbside@curbside.com and a Curbside employee will help you set up an API key and secret.

iOS

Add Curbside SDK to Xcode

Add the SDK to your Xcode project using the following steps:

  1. In the Project Navigator, select your project
  2. Select your target
  3. Select General
  4. Scroll to the bottom until you see Embedded Binaries
  5. Drag Curbside.framework into Embedded Binaries

Image of project navigator

Make sure to check the box next to “Copy items if needed” and click Finish

Image of copy if needed

Verify Curbside.framework as been added to your Xcode project.

  • In your Project Navigator. Select your project.
  • Select your target
  • Select Build Phases
  • Under Link Binary With Libraries and Embed Frameworks, you should see Curbside.framework

Image of copy if needed

If Curbside.framework is missing from either build phase. Drag Curbside.framework from your project navigator into the build phase.

Image of copy if needed

Enable background modes

  1. In the Project Navigator, select your project
  2. Select your target
  3. Select Capabilities
  4. Scroll to the bottom until you see Background Modes
  5. Check the box next to Location updates and Remote Notifications

Image of background modes

Integrate the SDK

Import header file

Import the Curbside SDK header file into your app delegate’s .m file and any other place you plan to use it

#import <Curbside/Curbside.h>

Common Curbside SDK Initialization

Now that you have your API key and secret and you have added Curbside SDK framework into your app, it’s time to initialize the SDK in your application.

Add the following to your app delegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    CSSession *sdksession;
    [CSSession setEnvironment:CSEnvironmentProduction];
    sdksession = [CSSession createSessionWithAPIKey:@"YOUR_API_KEY" secret:@"YOUR_SECRET" delegate:self];

    // current application:didFinishLaunchingWithOptions: code

    // Call sessions method application:didFinishLaunchingWithOptions:
    [sdksession application:[UIApplication sharedApplication] didFinishLaunchingWithOptions:nil];

    return YES;
}

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
    [[CSSession currentSession] registerDeviceToken:deviceToken];
    // Do App specific handling if needed
}

- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
    [[CSSession currentSession] handleDidFailToRegisterForRemoteNotifications:error];
    // Do App specific handling if needed
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    if ([[CSSession currentSession] handlePushNotificationDictionary:userInfo])
        completionHandler(UIBackgroundFetchResultNewData);
    else {
        // This means that the CSSession could not handle the notification, which could mean that it is
        // for the application itself. You should handle the notification here. If you currently do not 
        // handle notification then call completionHandler(UIBackgroundFetchResultNoData);
    }
}

Ask for Apple Push Notification and Location service permissions

Curbside SDK makes use of push notifications and location services. If your app has not asked the user for the required permissions, you can use the following code snippets to do so.

Code snippet to ask for permission to display push notification

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
   UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
   [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
   [[UIApplication sharedApplication] registerForRemoteNotifications];
#else
   UIUserNotificationType types = UIUserNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeNewsstandContentAvailability;
   [[UIApplication sharedApplication] registerForRemoteNotificationTypes:types];
#endif

Code snippet to ask for permission to use location services

    // Authorize LocationManager
    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    if ([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
        [locationManager requestAlwaysAuthorization];

Apple Push Notification Keys

Curbside servers uses Apple Push Notification Service (APNS) to send messages to the Mobile and Store Ops client as needed. In order to get this working, Curbside needs the Push notification Cert and the private key in order to send the push notification to the clients. Steps to generate the keys are :

Obtain the Push Notification Certificate

To download an APNS SSL certificate

  1. On the Apple Developer web site, click Member Center, click Certificates, Identifiers and Profiles, and then click Certificates.
  2. Select the certificate you created for iOS APNS development, click Download, and then save the file, which will have the .cer extension type.

To convert the APNS SSL certificate from .cer format to .pem format

The following steps use the openssl utility.

  • At a command prompt, type the following command. Replace myapnsappcert.cer with the name of the certificate you downloaded from the Apple Developer web site.
openssl x509 -in myapnsappcert.cer -inform DER -out myapnsappcert.pem

Obtain the App Private Key

You use the Keychain Access application on your Mac computer to export the app private key.

To obtain the app private key

The private key associated with the SSL certificate can be exported from the Keychain Access application on your Mac computer. This is based on the assumption that you have already imported the .cer file you downloaded from the Apple Developer web site into Keychain Access. You can do this either by copying the .cer file into Keychain Access or double-clicking the .cer file.

  1. Open Keychain Access, select Keys, and then highlight your app private key.
  2. Click File, click Export Items…, and then enter a name in the Save As: field.
  3. Accept the default .p12 file format and then click Save.

The .p12 file will then be converted to .pem file format.

To convert the app private key from .p12 format to .pem format

  • At a command prompt, type the following command. Replace myapnsappprivatekey.p12 with the name of the private key you exported from Keychain Access.
openssl pkcs12 -in myapnsappprivatekey.p12 -out myapnsappprivatekey.pem -nodes -clcerts

Mobile Client

Here we will talk about what is needed to integrate CurbsideSDK to the customer facing retailer application for tracking customers. Follow the instructions on integrating Curbside SDK to the application in the previous section. Make sure you use CSMobileSession instead of the CSSession in the code snippet. Curbside requires you to provide a unique tracking identifier for a customer. This is a unique value which will be used by Curbside to identify the customer in the Curbside Arrival Detection system. This should be the same across logins from the same customer across multiple devices. Once the customer is logged in you should use the following method to identify the customer in the Curbside AD System.

    [CSMobileSession currentSession].trackingIdentifier = unique_customer_id; 

When the user logs out use the same method and set the value to nil as in :

    [CSMobileSession currentSession].trackingIdentifier = nil; 

Once this is done, tracking will start for the user when there is a store and order(s) for that stores is set for the user. This can be done by first defining the store and the orders for that store using the following method :

    CSUserStoreRegion *storeRegion = [[CSUserStoreRegion alloc] initWithStoreIdentifier:storeID orderIDs:orderIDs];

here storeID is the unique storeID of the retailer store where we are are tracking the user going to pickup the orders defined by the array of orderIDs. Once this is defined, use the CSTracker class to track this user store region using :

    [[CSTracker sharedTracker] startTrackingUserStoreRegion:storeRegion error:&error]

Note this call checks to make sure the app has all the permissions needed in order for the Curbside AD to report locations. If this returns NO, that means it has failed to set the tracking for the store. Inspect the error returned to see what caused the fail. For Curbside AD to work correctly the following needs to be set for the application :

  1. Location Authorization to Always
  2. Background App Refresh Enabled
  3. Push notification enabled

If the order completes all the way through the system, i.e. the Store Ops application is also integrated with Curbside then the tracking for store will be automatically stopped when the order is collected. If the user is cancelling the order in the Customer facing app and there is no pending orders at the given store then call the following

    [[CSTracker sharedTracker] stopTrackingUserStoreRegion:storeRegion];

to stop tracking the user for the store region.

Curbside also gives a way for the user to notify the associate inside the store where they have placed the order when the app is launched/resumed. This happens on the delegate callback from the session delegate :

    - (void)session:(CSMobileSession *)session canNotifyAssociateAtStoreRegion:(CSStoreRegion *)storeRegion;

Here Curbside informs the app that the user can notify the associate in the given storeRegion. The app can decide what to do at this point, it can then call

    - (BOOL)notifyStoreOpsOfCustomerArrivalAtStoreRegion:(CSStoreRegion *)storeRegion error:(NSError **)error;

on the CSMobileSession to notify the associate at the store.

Store Ops Client

Here we will talk about what is needed to integrate CurbsideSDK to the Store Ops application for tracking customers approaching the store to pickup their orders Follow the instructions on integrating Curbside SDK to the application in the previous section. Make sure you use CSStoreOpsSession instead of the CSSession in the code snippet.

CSStoreOpsSession requires a unique tracking identifier to identify the store associate who is logged into the Curbside AD system at the store. This allows Curbside to track and attribute actions to a pickup to the associate handling a customer pickup. First set the trackingIdentifier of the CSStoreOpsSession to the associate’s unique idenditifier using :

    [CSStoreOpsSession currentSession].trackingIdentifier = unique_associate_id; 

The above can be set when the associate logs in to the Store Ops application and should be set to nil when the user logs out.

Once this is done, then setup a store where the associate is tracking the customer arrival. For this setup a CSStoreRegion with the store’s storeID :

    CSStoreRegion *storeRegion = [[CSStoreRegion alloc] initWithStoreIdentifier:storeID];

This region and a location update handler is set to the CSStoreArrivalTracker to start tracking arrivals at the storeRegion and be informed of location updates of customers. Here is the code snippet :

    CSStoreArrivalTracker *storeArrivalTracker = [CSStoreArrivalTracker sharedArrivalTracker];
    storeArrivalTracker.arrivalStoreRegion = storeRegion;
    storeArrivalTracker.locationUpdateHandler = ^(NSArray *userLocationUpdates) {
        // Process User location updates in the app. 
    };

As there are updates to user location system, the update handler is called back with updated information. Each object in the array is a instance of CSUserLocationUpdate which represent information for a customer, this has the customer trackingIdentifier, distance, location, ETA etc. The CSUserLocationUpdate may also have a CSCustomerArrivalNotificationInfo in it if the customer had used notifyAssociate in the application using the [CSMobileSession notifyStoreOpsOfCustomerArrivalAtStoreRegion:] endpoint.

Android

Integrate the SDK

Add the curbside.aar file to your project

  • Add the curbsidesdk-1.x.x.aar file to the libs folder
  • In the build.gradle file for your app add the following to your dependencies section
    repositories{
        flatDir{
            dirs 'libs'
        }
    }

    dependencies {
        // ... other dependencies
        compile(name:'curbsidesdk-1.x.x', ext:'aar')
        compile 'com.squareup.retrofit:retrofit:1.9.0'
        compile 'com.squareup.okhttp:okhttp-urlconnection:2.2.0'
        compile 'com.squareup.okhttp:okhttp:2.2.0'
        compile 'io.reactivex:rxandroid:1.0.1'
        compile 'com.google.android.gms:play-services:8.1.0'
        compile 'com.android.support:support-v4:23'
        compile 'com.google.code.gson:gson:1.7.2'
        compile 'org.altbeacon:android-beacon-library:2.5.1'
    }
  • CurbsideSdk uses GCM. Edit your Android.xml file to include gcm permission, change _package_name to your app package name :
   <permission
       android:name="package_name_.permission.C2D_MESSAGE"
       android:protectionLevel="signature" />

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

CurbsideSdk Initialization

This will initialize the CurbsideSdk for use within the application.

    CurbsideSdk.init(this, AUTH_KEY_PROD, AUTH_SECRET_PROD);
    CurbsideSdk.getInstance().validate();
    CurbsideSdk.getInstance().registerGCMSenderId(gcmSenderId);

Mobile Client

Curbside requires you to provide a unique tracking identifier for a customer. This is a unique value which will be used by Curbside to identify the customer in the Curbside Arrival Detection system. This should be the same across logins from the same customer across multiple devices. Once the customer is logged in you should use the following method to identify the customer in the Curbside AD System. Use the following code snippet to set the tracking identifier.

    CurbsideSdk.getInstance().registerTrackingId(String tracking_identifier);

When the user logs out use the following to unregister

    CurbsideSdk.getInstance().unregisterTrackingId();

Once a tracking id is registered for the user, tracking will start for the user when there is a store and order(s) for that stores is set for the user. This can be done using the following method.

    CurbsideSdk.getInstance().startTracking(storeId, orderIds);

Here storeID is the unique storeID of the retailer store where we are are tracking the user going to pickup the orders defined by the array of orderIDs.

If the order completes all the way through the system, i.e. the Store Ops application is also integrated with Curbside then the tracking for store will be automatically stopped when the order is collected. If the user is cancelling the order in the Customer facing app and there is no pending orders at the given store then call the following

    CurbsideSdk.getInstance().stopTracking(String storeId);

to stop tracking the user to the store defined by storeId.

CurbsideSdk also provides a way to notify the associate inside the store where they have placed the order when the app is launched/resumed. Use the NotifyAssociateManager instance of CurbsideSDK to query. The NotifyAssociateManager allows you to check

  1. If the store associate can be notified at the given location
  2. If #1 is true, then check with Curbside Server to see if there is already a pending notification by the user for the associate at the store.
  3. Notify the store associate that the user is outside.

This can be done using the following code snippet

    // Check if the store associate can be notified for the tracking_id and location. 
    CurbsideSdk.getInstance().getNofifyAssociateManager().checkIfStoreAssociateCanBeNotifiedNow(tracking_id, current_location, new Callback<CanNotifyStoreAssociateStatus>() {
        @Override
        public void success(CanNotifyStoreAssociateStatus response, Response response2) {
            //need to verify the output on both cases
            String errorCode = response.getErrorCode();
            if (errorCode != null && errorCode.length() != 0 || response.getStoreId() == null) {
                return; // We have a errorCode or storeID is null. This means that we cannot notify the associate. 
            }

            // We can notify the associate 
            checkNotification(response.getStoreId());
        }

        @Override
        public void failure(RetrofitError error) {
            // Add code to log the failure
        }
    });

    // Check if there are pending notification for the associate by the given user and act accordingly. 
    public void checkNotification(String storeID){
        CurbsideSdk.getInstance().getNofifyAssociateManager().checkIfAssociateAlreadyNotified(tracking_id, storeID, new Callback<StoreAssociateNotifiedStatus>() {

            @Override
            public void success(StoreAssociateNotifiedStatus response, Response response2) {
                // This means there is a pending notification for this user at the store. 
                // Inform the client of this. 
            }

            @Override
            public void failure(RetrofitError error) {
                if (error.getKind() == Kind.HTTP) {
                    // This means that there is no pending notification, and the associate can be informed
                    // Show UI as needed and then call the notifyAssociate(String trackingId, String storeId) to let the associate know.
                }
            }
        });
    }

References

iOS SDK Reference

Android SDK Reference