We are transitioning over to a new forum platform. Please post new issues there. Existing threads will be dealt with here unless you choose to move them over. Visit the new forum

Forum

Thread tagged as: Question, Third-party, Shop

Google Analytics with Perch Shop orders

I'd like to implement Google Analytics' e-commerce tracking on my order completion page with Perch Shop. It seems that they just take a snippet of Javascript on the page, so I had perch_shop_order_items pull a template with the tags injected into their Javascript vars. What I'd like to know is if the solution I did will work, and if this is the cleanest way possible. This is hard to test on a dev copy because it requires so many API moving parts to process an order and the data would get mixed with our live data on Google, so I want to check with someone who understands the system best to see if this is even possible.

My Page:

<?php
    perch_layout('global.top', [
        'title' => perch_page_title(true),
    ]);

    // Has the order been successfully placed?
    if (perch_member_logged_in() && perch_member_has_tag('dealer')) {

        // Dealer order success page
        perch_content('Dealer Order Successful');

        perch_shop_empty_cart();

    } elseif (perch_shop_order_successful()) {

        // Yes! Show a success message and clear the cart
        $email = perch_member_get('email');
        $firstname = perch_member_get('first_name');
        $lastname = perch_member_get('last_name');

        PerchSystem::set_vars([
            'email'      =>  $email,
            'first_name' =>  $firstname,
            'last_name'  =>  $lastname,
        ]);

        perch_content('Order Successful');

        if (perch_member_is_passwordless()) {
            perch_member_form('set_password');
        }

        // Get order info for analytics
        perch_shop_order_items(perch_shop_successful_order_id(), array(
            'template' => 'shop/orders/analytics.html',
        ));

        perch_shop_empty_cart();

    } else {

        // Payment problem! Show instructions to the customer
        perch_content('Payment Unsuccessful');
    }

    perch_layout('global.footer');
?>

My Template:

<script>
    ga('require', 'ecommerce');

    ga('ecommerce:addTransaction', {
        'id': '<perch:shop id="invoice_number" />',
        'revenue': '<perch:shop id="grand_total" />',
    });

    <perch:orderitems>
        ga('ecommerce:addItem', {
            'id': '<perch:shop id="invoice_number" />',
            'name': '<perch:orderitem id="title" type="hidden" />',
            'price': '<perch:orderitem id="price_without_tax" />',
            'quantity': '<perch:orderitem id="quantity" type="hidden" />'
        });
    </perch:orderitems>

    ga('ecommerce:send');
</script>
Kevin Wolff

Kevin Wolff 0 points

  • 9 months ago
Drew McLellan

Drew McLellan 2638 points
Perch Support

Does the output onto the page look correct?

It looks like with some adjustments I can get the script to output info in the source code, but it isn't being sent to Google. I also am noticing that in order to send multiple items, I need to get the order ID for each item using the shop template snippet, but it doesn't work inside the orderitems repeater because it's out of the scope. How do I get the order ID for each item in orderitems? I've been using this site for reference: https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce

<perch:before>
<script>
    ga('require', 'ecommerce');

    ga('ecommerce:addTransaction', {
        'id': '<perch:shop id="invoice_number" />',
        'revenue': '<perch:shop id="grand_total" />',
    });
</perch:before>
    ga('ecommerce:addItem', {
            'id': '<perch:shop id="invoice_number" />',
        <perch:orderitems>
            'name': '<perch:orderitem id="title" type="hidden" />',
            'price': '<perch:orderitem id="price_without_tax" />',
            'quantity': '<perch:orderitem id="quantity" type="hidden" />'
        </perch:orderitems>
    });
<perch:after>
    ga('ecommerce:send');
</script>
</perch:after>

Output:

<script>
    ga('require', 'ecommerce');

    ga('ecommerce:addTransaction', {
        'id': '15264',
        'revenue': '435.59',
    });

    ga('ecommerce:addItem', {
            'id': '15264',

            'name': 'Studio Essentials 100W LED Monolight 2-Light Kit',
            'price': '399.99',
            'quantity': '1'

    });

    ga('ecommerce:send');
</script>
Drew McLellan

Drew McLellan 2638 points
Perch Support

Do you mean the item ID? The order ID would be the same for every item, giving you duplicate IDs.

The "ID" for the additem function should be the same for all items as the invoice number for the transaction, not the specific item ID. That's how Google connects the items to a certain transaction. I got the system to send the info for the transaction, but because of the scope of the orderitems repeater, I can't figure out a way to get the purchased items to send and pair to the invoice number used above. Is there a way to set a JS variable and then use that inside the function instead?

Have you tried using <perch:shop id="parent.invoice_number" /> within perch:orderitems?

Just a guess and this approach works with categories.

Thanks for chiming in Adam! Unfortunately that doesn't seem to work in that tag set. The following code fills out everything except the invoice number for the item ID fields.

<script>
  fbq('track', 'Purchase', {
    value: '<perch:shop id="grand_total" />',
    currency: 'USD',
  });
</script>

<script>
    ga('require', 'ecommerce');

    ga('ecommerce:addTransaction', {
        'id': '<perch:shop id="invoice_number" />',                             // Transaction ID. Required.
        'revenue': '<perch:shop id="grand_total" />',                           // Grand Total.
        'shipping': '<perch:shop id="shipping_without_tax" type="hidden" />',   // Shipping.
        'tax': '<perch:shop id="total_tax" type="hidden" />'                    // Tax.
    });

    <perch:orderitems>
        ga('ecommerce:addItem', {
            'id': '<perch:shop id="parent.invoice_number" />',                  // Transaction ID. Required.
            'name': '<perch:orderitem id="title" type="hidden" />',             // Product name. Required.
            'price': '<perch:orderitem id="price_without_tax" />',              // Unit price.
            'quantity': '<perch:orderitem id="quantity" type="hidden" />'       // Quantity.
        });
    </perch:orderitems>

    ga('ecommerce:send');
</script>

Perhaps <perch:orderitems id="parent.invoice_number" /> might work? Another wild guess I'm afraid but might be worth a try.

No luck :/ I'm not sure what to do... Even setting a global variable with it in JS and then trying to set the other variable in the function to it wasn't working. I just need that one number copied down to the same spot.

Hussein Al Hammad

Hussein Al Hammad 105 points
Registered Developer

Hello Kevin,

Generally when you use parent.originalID you need to also use the attribute scope-parent on the outer tag:

<perch:orderitems scope-parent="true">
  <perch:orderitem id="parent.invoice_number" />
</perch:orderitems>

In case that doesn't work and you don't mind using the order ID instead of the invoice number, I believe orderID is available inside perch:orderitems:

<perch:orderitems>
  <perch:orderitem id="orderID" />
</perch:orderitems>

If none of the above works for you and you must use the invoice number, you might have to call perch_shop_order() twice:

$orderID = perch_shop_successful_order_id();
$order = perch_shop_order($orderID, ['skip-template' => true,]);

PerchSystem::set_var('global_invoice_number', $order[0]['invoice_number']);

perch_shop_order($orderID, [
    'template' => 'shop/orders/analytics.html',
]);

And use global_invoice_number in your template:

<perch:orderitems>
  <perch:orderitem id="global_invoice_number" />
</perch:orderitems>

Hussein, you're always a life saver! I had tried shifting the scope earlier to no avail, and was avoiding using the order ID or running another order function for the var, but in the end that's what solved it. Thank you very much for all of your help.