/** Set custom dimensions and metrics on the hit. */
 void attachCustomDimensionsAndMetrics(CustomHitBuilder hitBuilder, Properties properties) {
   for (Map.Entry<String, Object> entry : properties.entrySet()) {
     String property = entry.getKey();
     if (customDimensions.containsKey(property)) {
       int dimension =
           extractNumber(customDimensions.getString(property), DIMENSION_PREFIX.length());
       hitBuilder.setCustomDimension(dimension, String.valueOf(entry.getValue()));
     }
     if (customMetrics.containsKey(property)) {
       int metric = extractNumber(customMetrics.getString(property), METRIC_PREFIX.length());
       hitBuilder.setCustomMetric(metric, Utils.coerceToFloat(entry.getValue(), 0));
     }
   }
 }
  private void event(String name, Properties properties) {
    JSONObject propertiesJSON = properties.toJsonObject();
    amplitude.logEvent(name, propertiesJSON);
    log.verbose("AmplitudeClient.getInstance().logEvent(%s, %s);", name, propertiesJSON);

    double revenue = properties.getDouble("revenue", -1);
    if (revenue == -1) {
      return;
    }
    String productId = properties.getString("productId");
    int quantity = properties.getInt("quantity", 0);
    String receipt = properties.getString("receipt");
    String receiptSignature = properties.getString("receiptSignature");
    amplitude.logRevenue(productId, quantity, revenue, receipt, receiptSignature);
    log.verbose(
        "AmplitudeClient.getInstance().logRevenue(%s, %s, %s, %s, %s);",
        productId, quantity, revenue, receipt, receiptSignature);
  }
  /** Send a product event. */
  void sendProductEvent(String event, String category, Properties properties) {
    if (!PRODUCT_EVENT_NAME_PATTERN.matcher(event).matches()) {
      return;
    }

    ItemHitBuilder itemHitBuilder = new ItemHitBuilder();
    itemHitBuilder
        .setTransactionId(properties.orderId())
        .setCurrencyCode(properties.currency())
        .setName(properties.name())
        .setSku(properties.sku())
        .setCategory(isNullOrEmpty(category) ? DEFAULT_CATEGORY : category)
        .setPrice(properties.price())
        .setQuantity(properties.getLong(QUANTITY_KEY, 0))
        .build();
    attachCustomDimensionsAndMetrics(itemHitBuilder, properties);
    Map<String, String> itemHit = itemHitBuilder.build();
    tracker.send(itemHit);
    logger.verbose("tracker.send(%s);", itemHit);
  }
  @Override
  public void track(TrackPayload track) {
    Properties properties = track.properties();
    String event = track.event();
    String category = properties.category();

    sendProductEvent(event, category, properties);

    if (COMPLETED_ORDER_PATTERN.matcher(event).matches()) {
      List<Product> products = properties.products();
      if (!isNullOrEmpty(products)) {
        for (int i = 0; i < products.size(); i++) {
          Product product = products.get(i);
          ItemHitBuilder hitBuilder = new ItemHitBuilder();
          hitBuilder
              .setTransactionId(properties.orderId())
              .setName(product.name())
              .setSku(product.sku())
              .setPrice(product.price())
              .setQuantity(product.getLong(QUANTITY_KEY, 0))
              .build();
          attachCustomDimensionsAndMetrics(hitBuilder, properties);
          Map<String, String> hit = hitBuilder.build();
          tracker.send(hit);
          logger.verbose("tracker.send(%s);", hit);
        }
      }
      TransactionBuilder transactionBuilder = new TransactionBuilder();
      transactionBuilder
          .setTransactionId(properties.orderId())
          .setCurrencyCode(properties.currency())
          .setRevenue(properties.total())
          .setTax(properties.tax())
          .setShipping(properties.shipping());
      Map<String, String> transaction = transactionBuilder.build();
      tracker.send(transaction);
      logger.verbose("tracker.send(%s);", transaction);
    }

    String label = properties.getString(LABEL_KEY);
    EventHitBuilder eventHitBuilder = new EventHitBuilder();
    eventHitBuilder
        .setAction(event)
        .setCategory(isNullOrEmpty(category) ? DEFAULT_CATEGORY : category)
        .setLabel(label)
        .setValue((int) properties.value());
    attachCustomDimensionsAndMetrics(eventHitBuilder, properties);
    Map<String, String> eventHit = eventHitBuilder.build();
    tracker.send(eventHit);
    logger.verbose("tracker.send(%s);", eventHit);
  }