Merchant Library Migration Guide on
All Platforms

Merchant Library Migration Guide

Button has created a separate library specifically for Merchants. Some key features:

  • It's open-source
  • No third party dependencies
    • Note: Android uses Support Library and Google Play services
  • 100% functional test coverage
  • Strict semantically versioned releases
  • MIT Licensed

Note: For full documentation on how to integrate the Button Merchant Library, see this guide. See here for the Merchant Library Specs

In this guide, we'll go over how to:

  1. Add Button
  2. Start Button
  3. Handle Post Install Deeplinks
  4. Attribute Users from Incoming Deeplinks
  5. Track Orders in App
  6. Extract the Button Attribution Token

Each section of this guide shows code snippets for the old integration (Sample v5 Configuration) method followed by the new integration (Sample Merchant Library Configuration) method.


Add Button

Sample v5 Configuration

pod "Button", "~>5"
compile 'com.usebutton:android-sdk:5+'

Sample Merchant Library Configuration

pod "ButtonMerchant", "~>1"
implementation 'com.usebutton.merchant:button-merchant:1+'

Start Button

Sample v5 Configuration

import Button

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool

  // Replace YOUR_BUTTON_APP_ID with your App ID from the Button Dashboard https://app.usebutton.com
  Button.shared().configure(withApplicationId: "<#YOUR_BUTTON_APP_ID#>") { error, url in
    if let err = error {
      print("Error: \(err.localizedDescription)")
    }
    else {
      print("Button created a Session successfully 🎉")
    }
  }

  return true
}
@import Button

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  // Replace YOUR_BUTTON_APP_ID with your App ID from the Button Dashboard https://app.usebutton.com
  [[Button sharedButton] configureWithApplicationId:@"<#YOUR_BUTTON_APP_ID#>" completion:^(NSError *error, NSURL *url) {
    if (error) {
      NSLog(@"Error: %@", error.localizedDescription);
    }
    else {
      NSLog(@"Button created a Session successfully 🎉");
    }
  }];

  return YES;
}
// AndroidManifest.xml
<application

    <activity
      <!-- your activities  -->
    </activity>

    <!--Button SDK-->
    <meta-data android:name="com.usebutton.applicationid" android:value="YOUR_APP_ID"/>
</application>

// Application class file
import com.usebutton.sdk.Button

class MyApplication : Application() {
  override fun onCreate() {
    super.onCreate()

    Button.getButton(this).start()
  }
}
// AndroidManifest.xml
<application

    <activity
      <!-- your activities  -->
    </activity>

    <!--Button SDK-->
    <meta-data android:name="com.usebutton.applicationid" android:value="YOUR_APP_ID"/>
</application>

// Application class file
import com.usebutton.sdk.Button;

public class MyApplication extends Application {
  @Override
  public void onCreate() {
      super.onCreate();

      Button.getButton(this).start();
  }
}

Sample Merchant Library Configuration

import ButtonMerchant

func application(_ application: UIApplication,
  didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // Replace app-xxxxxxxxxxxxxxxx with your App ID from the Button Dashboard https://app.usebutton.com
    ButtonMerchant.configure(applicationId: "<#app-xxxxxxxxxxxxxxxx#>")

    return true
}
#import <ButtonMerchant/ButtonMerchant-Swift.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Replace app-xxxxxxxxxxxxxxxx with your App ID from the Button Dashboard https://app.usebutton.com
    [ButtonMerchant configureWithApplicationId:@"app-xxxxxxxxxxxxxxxx"];

    return YES;
}
import com.usebutton.sdk.ButtonMerchant

// Application class
class MyApplication : Application() {
  override fun onCreate() {
    super.onCreate()

    // Replace app-xxxxxxxxxxxxxxxx with your App ID from the Button Dashboard https://app.usebutton.com
    ButtonMerchant.configure(this, "app-xxxxxxxxxxxxxxxx")
  }
}
import com.usebutton.sdk.ButtonMerchant;

// Application class
public class MyApplication extends Application {
  @Override
  public void onCreate() {
      super.onCreate();

      // Replace app-xxxxxxxxxxxxxxxx with your App ID from the Button Dashboard https://app.usebutton.com
      ButtonMerchant.configure(context, "app-xxxxxxxxxxxxxxxx");
  }
}

Handle Post Install Deeplinks

Sample v5 Configuration

import Button

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool

  // Replace YOUR_BUTTON_APP_ID with your App ID from the Button Dashboard https://app.usebutton.com
  Button.shared().configure(withApplicationId: "<#YOUR_BUTTON_APP_ID#>") { error, url in
    if let url = url {
      // Route user to URL.
    }
  }

  return true
}
@import Button

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  // Replace YOUR_BUTTON_APP_ID with your App ID from the Button Dashboard https://app.usebutton.com
  [[Button sharedButton] configureWithApplicationId:@"<#YOUR_BUTTON_APP_ID#>" completion:^(NSError *error, NSURL *url) {
    if (url) {
      // Route user to URL.
    }
  }];

  return YES;
}
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    Button.checkForDeepLink(this, object : Button.DeepLinkListener {
        override fun onDeepLink(intent: Intent) {
            // Deep link received, let's open it.
            startActivity(intent)
        }

        override fun onNoDeepLink() {}
    })

    setContentView(R.layout.activity_main)
    // ...
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Button.checkForDeepLink(new Button.DeepLinkListener() {
        @Override
        public void onDeepLink(final Intent intent) {
            // Deep link received, let's open it.
            startActivity(intent);
        }

        @Override
        public void onNoDeepLink() {}
    });

    setContentView(R.layout.your_activity);
    // ....
}

Sample Merchant Library Configuration

import ButtonMerchant

func application(_ application: UIApplication,
  didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // Replace app-xxxxxxxxxxxxxxxx with your App ID from the Button Dashboard https://app.usebutton.com
    ButtonMerchant.configure(applicationId: "<#app-xxxxxxxxxxxxxxxx#>")

    ButtonMerchant.handlePostInstallURL { (url, error) in
        if let url = url {
            // Route user to URL.
        }
    }

    return true
}
#import <ButtonMerchant/ButtonMerchant-Swift.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Replace app-xxxxxxxxxxxxxxxx with your App ID from the Button Dashboard https://app.usebutton.com
    [ButtonMerchant configureWithApplicationId:@"app-xxxxxxxxxxxxxxxx"];

    [ButtonMerchant handlePostInstallURL:^(NSURL * _Nullable url, NSError * _Nullable error) {
        if (url) {
            // Route user to URL.
        }
    }];

    return YES;
}
// Activity started on first launch
class MainActivity : Activity() {
  override fun onCreate() {
    super.onCreate()

    ButtonMerchant.handlePostInstallIntent(this) { intent, t ->
            if (intent != null) {
                startActivity(intent)
            } else if (t != null) {
                Log.e(TAG, "Error checking post install intent", t)
            }
        }
    })

  }
}
// Activity started on first launch
public class MainActivity extends Activity {
  @Override
  public void onCreate() {
      super.onCreate();

      ButtonMerchant.handlePostInstallIntent(this, new PostInstallIntentListener() {
          @Override
          public void onComplete(@Nullable Intent intent, @Nullable Throwable t) {
              if (intent != null) {
                  startActivity(intent);
              } else if (t != null) {
                  Log.e(TAG, "Error checking post install intent", t);
              }
          }
      });
  }
}

Attribute Users from Incoming Deeplinks (new addition to Merchant Library)

Sample Merchant Library Configuration

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool {

    ButtonMerchant.trackIncomingURL(url)

    return true
}

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {

    ButtonMerchant.trackIncomingUserActivity(userActivity)

    return true
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {

    [ButtonMerchant trackIncomingURL:url];

    return YES;
}

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {

    [ButtonMerchant trackIncomingUserActivity:userActivity];

    return YES;
}
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Handle custom scheme deep links and App Links
    ButtonMerchant.trackIncomingIntent(this, intent)
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Handle custom scheme deep links and App Links
    ButtonMerchant.trackIncomingIntent(this, getIntent());
}

Track Orders in App (new addition to Merchant Library)

Sample Merchant Library Configuration

let order = Order(id: "order_id", amount: 5000, currencyCode: "USD") // amount is in cents (i.e. $50 is 5000)
ButtonMerchant.trackOrder(order, nil)
Order *order = [[Order alloc] initWithId:@"order_id" amount:5000 currencyCode:@"USD"]; // amount is in cents (i.e. $50 is 5000)
[ButtonMerchant trackOrder:order completion:nil];
val order = Order.Builder("order-id-123")
        .setAmount(8999)
        .setCurrencyCode("USD")
        .build()

ButtonMerchant.trackOrder(context, order, object : UserActivityListener() {
    override fun onSuccess() {
        // Track order success
    }

    override fun onError(t: Throwable?) {
        // Track order error
    }
})
Order order = new Order.Builder("order-id-123")
        .setAmount(8999)
        .setCurrencyCode("USD")
        .build();

ButtonMerchant.trackOrder(context, order, new UserActivityListener() {
    @Override
    public void onSuccess() {
        // Track order success
    }

    @Override
    public void onError(@Nullable Throwable t) {
        // Track order error
    }
});

Extract the Button Attribution Token

Sample v5 Configuration

if let btn_ref = Button.shared().referrerToken() {
    // referred token is present
}
NSString *btn_ref = [[Button sharedButton] referrerToken] ?: @"No Referrer Token";
val btnRef = Button.getButton(this).referrerToken
final String btnRef = Button.getButton(this).getReferrerToken();

Sample Merchant Library Configuration

// Obtain Attribution Token
if let btn_ref = ButtonMerchant.attributionToken {
    // referred token is present
}
NSString *token = [ButtonMerchant attributionToken];
if (token) {
    // referred token is present
}
val btnRef = ButtonMerchant.getAttributionToken(context)
final String btnRef = ButtonMerchant.getAttributionToken(context);