Client-Side Order Reporting

You can report orders to Button's Order API via the Merchant Library using ButtonMerchant.reportOrder().

📘

Note

If reporting Orders directly from the client, there is no need to report orders server-side. However, you will need to validate / invalidate orders.

Create Order Object

Construct LineItems(s) and an optional Customer object. Then, assign them to an Order.

// Create line items
let lineItem1 = Order.LineItem(identifier: "unique-line-item-idenifier-1", total: 400, description: "optional description", sku: "optional-sku")
let lineItem2 = Order.LineItem(identifier: "unique-line-item-idenifier-2", total: 500)
lineItem2.attributes = ["custom key": "custom value"]

// Create a customer (optional)
let customer = Order.Customer(id: "unique-customer-id")
customer.email = "1DDDE4A27FA6E869DBC99F25E392F1E1CB84A6FD1D13A9FF65491D8A0ED9BB4E" // SHA 256

// Create the order and add optional properties
let order = Order(id: "unique-order-id", purchaseDate: Date(), lineItems: [lineItem1, lineItem2])
order.customer = customer
// Create line items
LineItem *lineItem1 = [[LineItem alloc] initWithIdentifier:@"unique-line-item-idenifier-1" total:400];
LineItem *lineItem2 = [[LineItem alloc] initWithIdentifier:@"unique-line-item-idenifier-2" total:500];
lineItem1.attributes = @{ @"custom key": @"custom value" };

// Create a customer (optional)
Customer *customer = [[Customer alloc] initWithId:@"unique-customer-id"];
customer.email = @"1DDDE4A27FA6E869DBC99F25E392F1E1CB84A6FD1D13A9FF65491D8A0ED9BB4E"; // SHA 256

// Create the order and add optional properties
Order *order = [[Order alloc] initWithId:@"unique-order-id" purchaseDate:[NSDate date] lineItems:@[lineItem1, lineItem2]];
order.customer = customer;
// Create line items
val lineItem1 = LineItem.Builder("unique-line-item-idenifier-1", 400).build()
val lineItem2 = LineItem.Builder("unique-line-item-idenifier-2", 500)
        .setDescription("Optional description")
        .setCategory(listOf("Optional category"))
        .setQuantity(2)
        .setSku("optional-sku-string")
        .setUpc("optional-upc-string")
        .setAttributes(mapOf("custom-key" to "custom-value"))
        .build()

// Create a customer
val customer = Order.Customer.Builder("unique-customer-id")
        .setEmail("1DDDE4A27FA6E869DBC99F25E392F1E1CB84A6FD1D13A9FF65491D8A0ED9BB4E") // SHA-256
        .setIsNew(false) // optionally indicate if the customer is new
        .build()

// Create the order and add optional properties
val order = Order.Builder("unique-order-id", Date(), listOf(lineItem1, lineItem2))
        .setCustomerOrderId("optional-customer-readable-order-id")
        .setCustomer(customer)
        .setCurrencyCode("USD")
        .build()
// Create line items
Order.LineItem lineItem1 = new Order.LineItem.Builder("unique-line-item-idenifier-1", 400).build();
Order.LineItem lineItem2 = new Order.LineItem.Builder("unique-line-item-idenifier-2", 500)
        .setDescription("Optional description")
        .setCategory(Collections.singletonList("Optional category"))
        .setQuantity(2)
        .setSku("optional-sku-string")
        .setUpc("optional-upc-string")
        .setAttributes(Collections.singletonMap("custom-key", "custom-value"))
        .build();
List<Order.LineItem> lineItems = new ArrayList<>();
lineItems.add(lineItem1);
lineItems.add(lineItem2);

// Create a customer
Order.Customer customer = new Order.Customer.Builder("unique-customer-id")
        .setEmail("1DDDE4A27FA6E869DBC99F25E392F1E1CB84A6FD1D13A9FF65491D8A0ED9BB4E") // SHA-256
        .setIsNew(false) // optionally indicate if the customer is new
        .build();

// Create the order and add optional properties
Order order = new Order.Builder("unique-order-id", new Date(), lineItems)
        .setCustomerOrderId("optional-customer-readable-order-id")
        .setCustomer(customer)
        .setCurrencyCode("USD")
        .build();

The required properties on each of the above objects are passed in the constructor. All optional fields can be set using dot notation.

Line Item Attributes are going to include any additional order data that is typically sent to your marketing partners. You will work closely with your Button representative to determine exactly what data will be needed.

Considerations

order_id should match the format/type that you send to your your digital marketing partners for similar orders. This guarantees deduplication in the event of any double reporting.

Button requires currency nominal values to be reported in cent notation – $1.00 should be reported as 100.

For each line item the value passed in the order.line_items[n].total field must represent the line item's total cost (unit cost x quantity). Button will calculate the unit cost if/when necessary.

Order.total and line_items[n].total should only represent gross merchandise sales (GMS), and should exclude any taxes, fees, or surcharges the brand may collect.

Any discounts for the order should be applied as follows:

  • Order level discounts - evenly distributed across all “order.line_items[n].total”
  • Item level discounts - applied to the item’s specific “order.line_items[n].total”

In each line item below, you’ll see an attributes field, which represents a key/value pair to share additional order metadata that may be relevant to your affiliate program/marketing partners.

Report the Order

After creating one or more LineItem objects, Customer, and Order you can then report your order to Button.

// Report the order directly to Button. The completion is optional.
ButtonMerchant.reportOrder(order) { error in
    // Handle error
}
// Report the order directly to Button. The completion is optional.
[ButtonMerchant reportOrder:order completion:^(NSError * _Nullable error) {
    // Handle error
}];
// Report the order directly to Button
ButtonMerchant.reportOrder(context, order) { throwable ->
    if (throwable == null) {
        // Report order success
        Log.d(TAG, "Report Order Success")
    } else {
        // Report order failed
        Log.e(TAG, "Report Order Failed", throwable)
    }
}
// Report the order directly to Button
ButtonMerchant.reportOrder(context, order, new OrderListener() {
    @Override
    public void onResult(@Nullable Throwable throwable) {
        if (throwable == null) {
            // Report order success
            Log.d(TAG, "Report Order Success");
        } else {
            // Report order failed
            Log.e(TAG, "Report Order Failed", throwable);
        }
    }
});

Validate / Invalidate Orders

To setup a validations or invalidations process for orders reported from the client, reach out to your Button representative.