Integromat and Apply Payment

I’ve used Integromat with Invoice Ninja and it worked fine on V4. Now that we’ve upgraded to V5, I need to rebuild the Integromat integrations with the new Invoice Ninja modules (V2 vs. V1).

However, I’ve run into an issue with the Payments:
The Create a Payment module has a reference to the Client ID, but not to the Invoice ID. All invoices that are created show up as Drafts, with the balance still due. I have unconnected Payments, too, but I need to go manually into the website and “apply” these payments to the invoices.

What do I need to do to have these payments be applied to the corresponding invoices automatically?
Or how else can I mark these invoices as paid?

Thanks!

Just found another issue:
There used to be a module that was Watching the Payments. Whenever someone paid, the corresponding ticket in our case management tool would be updated with that information.

Now that doesn’t seem to work out of the box anymore?
“Watch New Payment” now just creates a webhook in Integromat, but to trigger that webhook I have to set it up in Invoice Ninja under Account Management, is that right?
But what do I need to enter there?
None of the “Event Types” seems correct. I don’t want to Create, Update, or Delete a Payment, I simply want to get it, then trigger an action in Integromat.

Hi,

We manage the Zapier integration ourselves however for help with the Integromat integration you’ll need to reach out to them directly.

I tried Zapier, but that doesn’t work either, since it allows only Create actions, but no updates.

So now I’m playing around with the API.
I can create an invoice. I can create a Payment.
But howwwww do I apply that payment to an invoice?
How do I update an invoice and mark it as paid?

To create a payment and apply it against an invoice you need to provide an “invoices” property.

{
    "invoices": [
        {
            "amount": 50,
            "invoice_id": "QJ0dN6dLOv",
        }
    ],
}

One approach to figure out how to send specific API requests is to use the admin portal to take the action and inspect the browser console to see the format of the request.

Thank you!

It tried that an I keep getting the same error:
[422] The given data was invalid. “client_id”: The client id field is required.

But here’s the JSON I’m sending: (with dynamic settings):
{
“id”: “{{40.client_id}}”,
“client_id”: “{{40.client_id}}”,
“date”: “{{28.created_at}}”,
“amount”: {{40.amount}},
“paymentables”: {
“client_id”: “{{40.client_id}}”,
“invoice_id”: “{{40.id}}”,
“amount”: 148,
},
“invoices”: [
{
“client_id”: “{{40.client_id}}”,
“invoice_id”: “{{40.id}}”,
“amount”: “147”
}
],
}

the actual JSON (without dynamic fields):
{
“id”: “Vyb841zjbv”,
“client_id”: “Vyb841zjbv”,
“date”: “2021-02-13T15:56:01.000Z”,
“amount”: 149,
“paymentables”: {
“invoice_id”: “GRb4gjOxaB”,
“amount”: 148,
},
“invoices”: [
{
“invoice_id”: “GRb4gjOxaB”,
“amount”: “147”
}
],
}

Method POST

I’m sending three different amounts to see which one is taken.

I also tried to create the Payment through the module first (which works), then updating that payment through PUT. But still I get the same error of 422] The given data was invalid. “client_id”: The client id field is required.

When I try to send the same JSON through Postman, I also get the error.

I actually copied the example JSON from the API doc to create a Payment (changing the IDs), and it still didn’t work.

Any hints?

@david do you have any suggestions?

@markus

Have you see the payments API here:

https://app.swaggerhub.com/apis/invoiceninja/invoiceninja/5.3.25#/payments/storePayment

Something like the below will work.

{
  "id": "Opnel5aKBz",
  "client_id": "Opnel5aKBz",
  "invitation_id": "Opnel5aKBz",
  "client_contact_id": "Opnel5aKBz",
  "user_id": "Opnel5aKBz",
  "type_id": "1",
  "date": "1-1-2014",
  "invoices": [
    {
      "invoice_id": "Opnel5aKBz",
      "amount": "2"
    }
  ],
  "credits": [
    {
      "credit_id": "Opnel5aKBz",
      "amount": "2"
    }
  ]
}


Another example from our test suite that will pass:

```php
        $data = [
            'amount' => $this->invoice->amount,
            'client_id' => $client->hashed_id,
            'invoices' => [
                [
                'invoice_id' => $this->invoice->hashed_id,
                'amount' => $this->invoice->amount,
                ],
            ],
            'date' => '2020/12/12',

        ];

There is no “storePayment” section at this page?

I just tried again, with POST to /v1/payments

{
“id”: “pnelG49rdK”
“client_id”: “pnelG49rdK”,
"invitatin_id: “pnelG49rdK”,
“user_id”: “JxboWnYbgw”,
“type”: 1,
“date”: “2021-02-13T15:56:01.000Z”,
“amount”: 149,
“paymentables”: {
“client_id”: “pnelG49rdK”,
“invoice_id”: “y1aKWGzYaQ”,
“amount”: 148,
},
“invoices”: [
{
“client_id”: “pnelG49rdK”,
“invoice_id”: “y1aKWGzYaQ”,
“amount”: “147”
}
],
}

Same error: [422] The given data was invalid. “client_id”: The client id field is required.

Any additional ideas? I’m stumped.

Hi @markus,

This should work although it definitely is not perfect.

  1. Use the module Make an API Call
  • URL: /v1/invoices
  • Method: GET
  • Header: Key: Content-Type, Value: application/json
  • Query String: Key: number, Value: [your invoice number]
  • Body: leave empty

  1. Use the module Make an API Call
  • URL: /v1/payments
  • Method: POST
  • Header: Key: Content-Type, Value: application/json
  • Query String: Key: email_receipt, Value: false
    The query string decides if an email is sent or not (true/false).

Body:

{
  "amount": 1,
  "number": "1234",
  "client_id": "abcdef1234",
  "transaction_reference": "",
  "date": "2021-12-08",
  "private_notes": "bla bla bla",
  "custom_value1": "",
  "custom_value2": "",
  "custom_value3": "",
  "custom_value4": "",
  "invoices": [
    {
      "amount": 1,
      "invoice_id": "abcdef1234"
    }
  ],
  "type_id": "2"
}
  • amount: The amount paid, dot separated value. You can add a payment to a client without applying it to an invoice. In this case you can use this amount.
  • number: can be set but should be unique. Usually InvoiceNinja will set the number.
  • client_id: your client ID from the previous module
  • transaction_reference: any reference like a number, transaction id etc.
  • date: Format YYYY-MM-DD. If date is empty, it will become todays date.
  • invoices: an array with 1 or more invoices
  • invoices - amount: The amount that you want to apply to the invoice, dot separated value. If you use this amount, you can leave the amount at the top empty.
  • invoices - invoice_id: your invoice ID from the previous module
  • type_id: ID of the type of payment, integer. See below.
Mandatory fields are written in bold

Depending on what information you want to enter, you might just need this payload:

{
  "client_id": "xxxxxxxx",
  "invoices": [
    {
      "amount": 2.5,
      "invoice_id": "xxxxxxxx"
    }
  ]
}

See the table below for the ID of the payment types. I am not sure if these IDs are the same in each installation.

label value
Bank Transfer 1
Cash 2
Debit 3
ACH 4
Visa Card 5
MasterCard 6
American Express 7
Discover Card 8
Diners Card 9
EuroCard 10
Nova 11
Credit Card Other 12
PayPal 13
Google Wallet 14
Check 15
Carte Blanche 16
UnionPay 17
JCB 18
Laser 19
Maestro 20
Solo 21
Switch 22
iZettle 23
Swish 24
Venmo 25
Money Order 26
Alipay 27
Sofort 28
SEPA 29
GoCardless 30
Crypto 31
Credit 32

I will contact Integromat so that they update their create a payment module to integrate the invoice id and amount.

@david @hillel a few questions/notes:

  • Via the REST API it is possible to enter the same payment number twice. If you then try to update your payment in the UI, you will get an error 422 because the number already exists. Trying to create a payment via REST with a number that has already been given, should result in an error.
  • It is possible to create payments with amount = 0. This doesn’t really make sense.
  • If a payment can not be made through the API because of an error, it results most of the time in a 302 error (redirect) which doesn’t help finding the error. For example if you try to apply a payment to an invoice that is already fully paid.
  • Whether an email is sent or not is decided by the query string email_receipt. The standard payload in the body does have a key called sendEmail and this can be set to true or false. But in both cases, email notifications will be sent. Why is this done by a query string instead of the key in the body?
  • Which route can be used to get the payment type IDs? /api/v1/company_gateways only results in a list of payment provider set up by the user. I am looking for the list like the table above.
  • It would be nice if you could apply a payment to a client or an invoice using the client number or invoice number instead of their ID. In most cases, the ID is not known by an external programm and thus needs an additional lookup like /api/v1/invoices?number=12345 to recive the ID.
  • What search parameters can be used in the API. I already found out that I can user number to search for an invoice number but I guess there must be more. I couldn’t find anything in the documentation.

Thanks a lot,
Gijs

1 Like

Thanks for your input, Gijs!
I’ll revert back to v4, there are too many issues with V5 as of now. I don’t think the new Integromat modules will work on V4, so I’ll have to make do with what we got.

Hi @david and @hillel

Could one of you give me an anwser on my questions above?

Thanks,
Gijs

@ecomsilio

sorry i missed this, i’ll look into those points and get back to you.

1 Like

@ecomsilio

Via the REST API it is possible to enter the same payment number twice. If you then try to update your payment in the UI, you will get an error 422 because the number already exists. Trying to create a payment via REST with a number that has already been given, should result in an error.

fix checked in for this.

It is possible to create payments with amount = 0. This doesn’t really make sense.

Some scenarios require this. 

If a payment can not be made through the API because of an error, it results most of the time in a 302 error (redirect) which doesn’t help finding the error. For example if you try to apply a payment to an invoice that is already fully paid.

I'll need to look into this.

Whether an email is sent or not is decided by the query string email_receipt. The standard payload in the body does have a key called sendEmail and this can be set to true or false. But in both cases, email notifications will be sent. Why is this done by a query string instead of the key in the body?

Where are you seeing the references for send_email and email_receipt?

Which route can be used to get the payment type IDs? /api/v1/company_gateways only results in a list of payment provider set up by the user. I am looking for the list like the table above.

We bundle all of these in our /statics route - or - you can inspect the payment_types table of the db

It would be nice if you could apply a payment to a client or an invoice using the client number or invoice number instead of their ID. In most cases, the ID is not known by an external programm and thus needs an additional lookup like /api/v1/invoices?number=12345 to recive the ID.

We can look into this, we should be able to support payments by invoice number

What search parameters can be used in the API. I already found out that I can user number to search for an invoice number but I guess there must be more. I couldn’t find anything in the documentation.

We are still working on the docs for the developer API, I have done a spec on the Clients route here:

https://invoiceninja.github.io/docs/api/clients/

Adding search filters are trivial in V5, in the repository you can see in app/Filters the full set of filters that are currently in place for all entities, if you have a specific one you need, just advise and we can add this in. I've added in filtering by payment numbers.
1 Like

Hey @david

Thanks for the quick reply.

I looked these up via the browser console when entering a payment manually in the UI.

Thanks for all other answers. That already helps a lot. Please let me know when a payment can be applied by using an invoice number instead of the id.

I will coordinate with Integromat to update their modules.

Thanks,
Gijs

@ecomsilio

The camelcase sendEmail may be a Flutter reference as I don’t accept this in the API. @hillel can you confirm?

1 Like

That’s correct, anything camel case is just used locally by the Flutter admin portal.

Hi,

Integromat just updated their module. You can now apply a payment directly to one or multiple invoices. You can also determine if an email receipt should be sent or not.

Cheers,
Gijs

Pick you invoice

Invoice added, pick another one if you want.

Instaed of chosing one of the customer’s invoices, you can also enter the ID directly.

Email or not?

2 Likes