How to handle trial periods and notifications of payments

Hi,

I have previously used Stripe for payment process and it has been a dream to work with. The webhook + api technique works really well for payment processing. I am glad this technique is being included for Infusionsoft with the new REST API.

Currently I am trying to use the Infusionsoft API to do the following:

  • Start a subscription on a trial for a contact.

When the trial ends, I want to know if the payment was successful or failed. Its not quite obvious what notification can be used to get this data. I cannot seem to find a page with an explanation of all the webhook types and what type of response we can expect from it.

Thanks

Each resthook will generate a list of record IDs that were add/edited/deleted (based on the subscribed events) inside the processing window as a JSON object, delivered to the verified endpoint at the end of that window. Documentation on them is found in our developer site.

The list of subscribeable events is obtainable via the /hooks/event_keys endpoint, but I pulled our current list for convenience:

[
    "appointment.add",
    "appointment.delete",
    "appointment.edit",
    "company.add",
    "company.delete",
    "company.edit",
    "contact.add",
    "contact.delete",
    "contact.edit",
    "contactGroup.add",
    "contactGroup.applied",
    "contactGroup.delete",
    "contactGroup.edit",
    "contactGroup.removed",
    "invoice.add",
    "invoice.delete",
    "invoice.edit",
    "invoice.payment.add",
    "invoice.payment.delete",
    "invoice.payment.edit",
    "leadsource.add",
    "leadsource.delete",
    "leadsource.edit",
    "note.add",
    "note.delete",
    "note.edit",
    "opportunity.add",
    "opportunity.delete",
    "opportunity.edit",
    "opportunity.stage_move",
    "order.add",
    "order.delete",
    "order.edit",
    "product.add",
    "product.delete",
    "product.edit",
    "subscription.add",
    "subscription.delete",
    "subscription.edit",
    "task.add",
    "task.delete",
    "task.edit"
]

Just to clarify, I am aware of the list and I am subscribed to some webhooks and they work fine.

I was seeking advice on how the developers of the API would suggest going about this scenario.

Trial periods and subscriptions are common place in payment processing systems. Your documentation provides no guidance on scenarios and best practices with your own API, hence why I am asking on these forums.

Here is an example of a the type of info I was hoping for - https://stripe.com/docs/subscriptions/trials

Just clear guidance and suggestions of different approaches.

There are three resthook events that we would throw in that kind of workflow:

subscription.add - When the user is signed up.
invoice.add - When the period of the subscription reaches it’s conclusion.
invoice.payment.add - When the customer successfully submits payment.

If you wanted to provide free trials, I would suggest possibly creating a Subscription Plan that has a 0.00 price, then triggering creating the chargeable subscription plan for them at that time.

Okay, thanks for your advice. What about promotions? I’ve noticed you can use the promotions area to setup a free trial for a subscription. It crated a 0 amount invoice straight away and then setups a later invoice for after the trial period.

Can the workflow support that too?

@TomScott any update on this?

I’m not quite sure what the question is there; the resthook events will fire as described.

@TomScott, can you please provide what kind of data we will get and how we will get on the targeted URL/page once hook hits the page? I want to know sample data for all three events (subscription.add, invoice.add, invoice.payment.add) you have mentioned above.

@swati_prajapati

1 Like

@mike.christianson
We are trying to implement recurring payment flow via infusionsoft from our website and for that we are using these Rest Hooks. I have configured three hooks as mentioned above, subscription.add, invoice.add and invoice.payment.add.
I have given direct link for subscription plan to our customers and whenever someone is using that link, filling all the details and signing up for our subscription plan then two events are firing, subscription.add and invoice.add. If I am not wrong, invoice.payment.add event will fire when customer will be charged automatically after the subscription duration is completed, is that right?
More, I am getting such responses in these hooks,
For subscription.add : {“event_key”:“subscription.add”,“object_type”:“subscription”,“object_keys”:[{“apiUrl”:"",“id”:104,“timestamp”:“2018-04-10T04:40:56Z”}],“api_url”:""}

For invoice.add :
{“event_key”:“invoice.add”,“object_type”:“invoice”,“object_keys”:[{“apiUrl”:"",“id”:376,“timestamp”:“2018-04-10T04:40:56Z”}],“api_url”:""}

None of them have apiUrl or none of such object types are available to be used with Retrieve api such as “GET https://api.infusionsoft.com/crm/rest/v1/tasks/6006?access_token=ejazxxxxt7e7gj7xxxxxxxx” as per the documents I am referring here, https://developer.infusionsoft.com/docs/rest/#!/Account_Info/getAccountProfileUsingGET

How do I get more details on such objects based on their IDs? I need Contact details or at-least ContactID basically.

1 Like

@swati_prajapati Looks like you’ve found a gap in our REST API. We don’t yet have a resource for subscriptions. But, I’m working on it as I write this!

1 Like

We don’t currently have an invoice endpoint in REST, but you can get the invoice record from the Legacy XMLRPC DataService with the same token you are using for REST. The table schema for fields you can query can be found here, but this is an example of what you would be looking to do:

<?xml version='1.0' encoding='UTF-8'?>
<methodCall>
  <methodName>DataService.load</methodName>
  <params>
    <param>
      <value><string>oauth-access-token-goes-here</string></value>
    </param>
    <param>
      <value><string>Invoice</string></value>
    </param>
    <param>
      <value><int>1</int></value>
    </param>
    <param>
      <value><array>
        <data>
          <value><string>ContactId</string></value>
          <value><string>Description</string></value>
          <value><string>PayStatus</string></value>
          <value><string>InvoiceTotal</string></value>
          <value><string>DateCreated</string></value>
          <value><string>LastUpdated</string></value>
        </data>
      </array></value>
    </param>
  </params>
</methodCall>

Returns something like this:

<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
    <params>
        <param>
            <value>
                <struct>
                    <member>
                        <name>Description</name>
                        <value>Shopping Cart</value>
                    </member>
                    <member>
                        <name>PayStatus</name>
                        <value>
                            <i4>1</i4>
                        </value>
                    </member>
                    <member>
                        <name>InvoiceTotal</name>
                        <value>
                            <double>1.0000</double>
                        </value>
                    </member>
                    <member>
                        <name>DateCreated</name>
                        <value>
                            <dateTime.iso8601>20170814T11:41:01</dateTime.iso8601>
                        </value>
                    </member>
                    <member>
                        <name>ContactId</name>
                        <value>
                            <i4>5</i4>
                        </value>
                    </member>
                    <member>
                        <name>LastUpdated</name>
                        <value>
                            <dateTime.iso8601>20170814T11:42:16</dateTime.iso8601>
                        </value>
                    </member>
                </struct>
            </value>
        </param>
    </params>
</methodResponse>
1 Like

Thanks for the info on this xml request, I will use it if required. In fact, I found one another small glitch in your flow. When I got response on invoice.payment.add event on my php page, I got response like this : {“event_key”:“invoice.payment.add”,“object_type”:“invoice.payment”,“object_keys”:[{“apiUrl”:“https://api.infusionsoft.com/crm/rest/v1/transactions/230",“id”:230,“timestamp”:“2018-04-10T11:22:33Z”}],“api_url”:"”}
In this response you can see, object_type is payment and ID returned in response is also payment_id, I have cross verified it in my account. However, you have returned apiUrl for transactions which is incorrect. I also tried this ID to get payment details like this https://api.infusionsoft.com/crm/rest/v1/payments/230 but it seems that end point does not exist yet.
So if you can please correct the above response and send back the correct TransactionID in response then it will fix my issue.

Hi @swati_prajapati, the invoice.payment.add rest hook sending the wrong id is a known issue and is currently being worked on. A fix should be released in the coming weeks!

1 Like