Customer has active subscriptions: yes or no?

Hey guys,

We are building the logic for our email marketing (Klaviyo software) and we need to be able to segment our inactive customers.

To make this happen, we need to know if the customer has any active subscriptions, which might be segmented like this in Klaviyo:

image

In the Foxycart API docs, I don't see any such property for customers or users that says if they have active/inactive subscriptions (e.g., True/False). Under the API properties for subscriptions I see a True/False for is_active but a customer could have multiple active/inactive subscriptions. We just need to know if a customer has any active subscriptions, and if not, we mark them inactive.

Do you guys have any suggestions on how we can get this data via the API or datafeed for our purposes?

Thanks!
Comments
  • fc_adamfc_adam FoxyCart Team
    edited February 2
    @Epotratz,

    We don't currently have any boolean attached to customers to say if they have subscriptions or not. What you can do though is filter subscriptions in the API based on the customer, and only search for active subscriptions. That way, if there are any results, then you know that that customer has at least one active subscription.

    In terms of the datafeed - if one comes through that is related to an active subscription, then you could update the customers record within Klaviyo to mark them as having an active subscription.
  • EpotratzEpotratz Member
    edited February 2
    @fc_adam,

    So it sounds like we need to do some intermediate data processing before sending to Klaviyo.

    Klaviyo is already receiving all the order details from each order. We now just need to make a custom property that's shows "has active subscriptions" : true or false, like this...

    image



    Hopefully Jacob can figure it out!
  • @fc_adam,

    Are subscribers only considered "active" in FC if the "start date" is in the past?
  • fc_adamfc_adam FoxyCart Team
    @Epotratz,

    As far as FoxyCart is concerned, a subscription is active if it's allowed to charge a customer, either today or in the future. So if a subscription is purchased with a future start date - so it hasn't charged a subscription yet - it's still "active" in that on that date the customer will be attempted to be charged. If a subscription is made inactive, then it won't be included in any of our normal subscription billing runs.
  • Hey @fc_adam,

    This setup is working about 95% using your new API. Here's our code: https://gist.github.com/jacobdubail/6e8bbdb84a8fd3472c080f54b3ac1837 If you'd like to see how some of the API calls are setup, let me know. I'll paste one below.

    function jtd_bc_has_active_sub($customer_id = null, $store_url = null) {

    $subs = jtd_bc_foxy_subscription('get', $customer_id, $store_url);

    if ( $subs['total_items'] == 0 ) return false;

    $subs = $subs['_embedded']['fx:subscriptions'];
    $has_active_sub = false;

    foreach ( $subs as $sub ) {
    if ( $sub['is_active'] )
    $has_active_sub = true;
    }

    return $has_active_sub;
    }


    What I'm finding is that looping through all of the customers via the $store_links['_links']['fx:customers']['href'] endpoint, everyone appears except 4 customers. I can't for the life of me figure out why. I can view their customer records when I browse to them manually. Here are the 4 customer IDs:

    22230962
    22245244
    22229365
    22249413

    They don't appear when I loop through the customers pages or the subscriptions pages, yet all 4 have active subs.

    Thanks!

    -Jacob
  • fc_adamfc_adam FoxyCart Team
    @jacobdubail,

    That's very strange! We'll do some digging and see if we can spot what might be preventing these customers from appearing. To confirm - you're not applying any additional filters when fetching all the customers for the store? You're just using the URI as it's returned on the API homepage, or are you appending additional parameters there?
  • Thanks @fc_adam. No extra search parameters. Just the uri from the API. In each do loop, I grab the next page link for the paginated results. The one place I filter is for the customer-specific subscriptions: $store_url . "/subscriptions?customer_id=$customer_id", but I never get that far for these 4 customers.
  • lukeluke FoxyCart Team
    Hey @jacobdubail. I'm going to temporarily add a test oauth client to this store so I can run through some code and see what's going on here. The data seems okay, but maybe there's an issue with pagination. We'll let you know when we know more. Glad to see you rocking the new API. :)
  • Thanks @luke. Took me a while to wrap my head around the new API, but now that I've mostly figured it out, I love it!
  • @luke. In case I didn't make this clear previously, I can navigate to these customers manually via the API. It's just an issue with them not appearing in the paginated results.
  • lukeluke FoxyCart Team
    I love it!
    I love to hear that! :)

    Yeah, I'm thinking there may be something strange going on with pagination. We may need to specify a sort order or something. I feel like we had a similar issue with transaction pagination before. I'll keep you posted.
  • lukeluke FoxyCart Team
    @jacobdubail okay, I think I found the problem.

    You have a do while which skips the last 13 records. In my testing with similar code to what you have, I only got the first 180 records. Once } while ( $customers_next != $customers_last ); is no longer true, we're done and that creates a problem as you never get the last 13 records.

    I'd change that to a while loop instead of a do/while and you should be good to go.

    Also, I find it really helpful in situations like this to use the HAL Browser here: https://api.foxycart.com/hal-browser/browser.html

    Just plugin a valid access token after the Bearer part of that header (replace the one that is there) and you should be able to navigate the data quite easily to see what's going on. Here's the code I was using and noticed it ends on customer 22214729 which is the second to last page according to the HAL Browser.


    $store = $fc->get($fc->getLink("fx:store"));
    $store_url = $store['_links']['fx:store']['href'];
    $store_links = $fc->get( $store_url );
    $customers_next = $store_links['_links']['fx:customers']['href'];

    do {
    $customers_result = $fc->get($customers_next);
    if ( ! $customers_result ) exit;
    $customers_next = $customers_result['_links']['next']['href'];
    $customers_last = $customers_result['_links']['last']['href'];

    if (isset($customers_result['_embedded']['fx:customers'])) {
    foreach ( $customers_result['_embedded']['fx:customers'] as $customer ) {
    print 'id: ' . $customer['id'] . ' ' . $customer['first_name'] . ' ' . $customer['last_name'] . '<br />';
    }
    }

    } while ( $customers_next != $customers_last );


    But this works:

    $store = $fc->get($fc->getLink("fx:store"));
    $store_url = $store['_links']['fx:store']['href'];
    $store_links = $fc->get( $store_url );
    $customers_next = $store_links['_links']['fx:customers']['href'];

    $has_more_records = true;
    $get_last = true;
    while($has_more_records || $get_last) {

    $customers_result = $fc->get($customers_next);
    if ( ! $customers_result ) exit;
    $customers_next = $customers_result['_links']['next']['href'];
    $customers_last = $customers_result['_links']['last']['href'];

    if (isset($customers_result['_embedded']['fx:customers'])) {
    foreach ( $customers_result['_embedded']['fx:customers'] as $customer ) {
    print 'id: ' . $customer['id'] . ' ' . $customer['first_name'] . ' ' . $customer['last_name'] . '<br />';
    }
    }

    // base case
    if ($customers_next == $customers_last) {
    if (!$has_more_records) {
    $get_last = false;
    }
    $has_more_records = false;
    }
    }


    I'm a little uncomfortable with using the link hrefs as the basis for the loop instead of parsing though the actual numeric values like so to keep track of your loop:


    {
    "total_items": "193",
    "returned_items": 13,
    "limit": 20,
    "offset": 180
    }


    But if it works, I guess you're okay.

    Hope that helps.
  • Thanks @luke. That's really nice to know about updating the token in the HAL browser. That'll be very convenient for testing. I'll update my code. I really should have been able to figure this one out. Guess I just needed an extra set of eyes. I appreciate it!
  • lukeluke FoxyCart Team
    No problem!

    Also, you may want to consider adding a limit of 300 (that's the max) to avoid making multiple calls to the API. The default limit is 20 records at a time, but as the customer count grows, that might end up being quite a few calls and be slow. The limit is mentioned here: https://api.foxycart.com/docs/cheat-sheet
Sign In or Register to comment.