Insert from URL to Revolut APi - not working from FileMaker

I would like to be able to trigger payment orders through the Revolut Merchant API from FileMaker. I have the merchant account set up and have a simple working code that triggers a new payment order on the account (see below). This works just fine from Postman and Terminal, but when I run this from an Insert from URL script set in Filemaker, I simply get back '404 Not Found' in the result.

curl --location 'https://merchant.revolut.com/api/orders' \
--header 'Revolut-Api-Version: 2023-09-01' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <<APIkey>>' \
--data '{
"amount": 10000,
"currency": "GBP"
}'

FileMaker Scripting:
Set Variable $json [```
JSONSetElement ("";
["amount"; 60000; JSONNumber];
["currency"; "EUR"; JSONString]
)


Set Variable cURL [

Substitute (
List (
"-X POST";
"-L " & Quote( "https://merchant.revolut.com/api/orders" );
"-H " & Quote( "Revolut-Api-Version: 2023-09-01" );
"-H " & Quote( "Accept: application/json" );
"-H " & Quote( "Content-Type: application/json" );
"-H " & Quote( "Authorization: Bearer {apikey}" );
"-d @$json" );
[ "{apikey}"; $secretKey ])


Insert using URL [Select ; With dialog: Off ; Target: $result ; $url ; cURL options: cURL] 

I have tried numerous variations and even tried accessing other APIs with similar scripting with success. But I just can't get the Revolut API to play if I script it from FileMaker. 

Any ideas?

P.s. I have no idea how to use --trace - is it possible to see what is actually being posted by FileMaker?

Try putting the location into the Specify URL field.

Insert from URL [ Select ; With dialog: Off ; Target: $result ; "https://merchant.revolut.com/api/orders" ; cURL options: ]

where the cURL options look like this.

List (
"-X POST";
"-H Revolut-Api-Version: " & Quote( "2023-09-01" );
"-H Accept: " & Quote( "application/json" );
"-H Content-Type: " & Quote( "application/json" );
"-H Authorization: " & Quote( "Bearer " & $secretKey );
"-d @$json" 
)
3 Likes

Thanks so much for your reply - I wrote it that way to begin with, but that doesn't work either.

Malcolm is correct that the URL should be entered into the 'Specify URL' option of the Insert from URL script step rather than in the cURL Options. However, your use of the List function in your cURL options calculation results in the each cURL option/header being on a separate line numbers, whereas the cURL options should be a single line.

So instead of:

-X POST
-H "Revolut-Api-Version: 2023-09-01"
-H "Accept: application/json"
-H "Content-Type: application/json"
-H "Authorization: Bearer 1234512345"
-d @$json

... it should be:

-X POST -H "Revolut-Api-Version: 2023-09-01"  -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer 1234512345" -d @$json

To make the cURL options calc a bit simpler I would probably specify it as:

 "-X POST
-H \"Revolut-Api-Version: 2023-09-01\" 
-H \"Accept: application/json\"
-H \"Content-Type: application/json\"
-H \"Authorization: Bearer " & $secretKey & "
-d @$json"

Note that although I have each option on a new line in the Specify Calculation dialog, these new lines actually evaluate as single spaces, so results in the desired single line... Here it is in Data Viewer:

3 Likes

thanks for clarifying my error @skywillmott.

I know that in the places I'm POSTing I haven't used the List function but I didn't realise it would interfere. I assumed that white space was not significant.

1 Like

Thanks for that. I have put the URL into the Insert from URL script step, but put it here too for comepleteness. It makes no difference if I take it out.

Get (Last Error) shows [1631] Connection Failed

Get(LastExternalErrorDetail) shows nothing

--location "https://merchant.revolut.com/api/orders"
--header “Revolut-Api-Version: 2023-09-01”
--header “Accept: application/json”
--header “Content-Type: application/json”
--header “Authorization: Bearer <<APIkey>>”
--data @$json
--trace $$trace
--show-error

$json

JSONSetElement ( "{}"; ["amount"; 60000 ; 2]; ["currency"; "EUR"; 1])

I just noticed something - you are using smart quotes, e.g.
--header “Revolut-Api-Version: 2023-09-01”
which is not the same as regular quotes:
--header "Revolut-Api-Version: 2023-09-01"

When i try this using proper quoting, like this:

"--header \"Revolut-Api-Version: 2023-09-01\" 
 --header \"Accept: application/json\" 
 --header \"Content-Type: application/json\" 
 --header \"Authorization: Bearer 1234567890\" 
 --data @$json
 --trace $$trace
 --show-error
"

I get this message:

{"code":"unauthenticated","message":"Authentication failed","timestamp":1714584976753}

And error is
1627 - FileMaker error: 1627

And since I don't have an API key (I'm just using 1234567...) the failure seems expected and normal.

2 Likes

Thanks Xoxhi - the quotes seem to make no difference (I have tried both). As far as I can make out, the handshaking is all working fine - al though from FileMaker I get the same result with a bogus API key and a correct one, so maybe there is something in this that is not working.

Thanks again

Currently I am testing with this code loaded into a text field for using as the cURLoptions:

--header 'Revolut-Api-Version: 2023-09-01' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer @$APIkey' \
--trace $$trace
--data @$json

One question I have Xochi if you would be so kind - how do you get your error response?

I can read the trace, but the only error I get when using a with or without a legitimate APIkey is "Connection Failed", Error 1631.

Thanks very much

Hi, have you tried the following tools to translate the curl?

or use this one if you are familiar with JSON.

1 Like

Download my sample project here

1 Like

Thanks so much for your help.

Just worked out the difference between your code and mine - I put an extra '/' at the end of the URL!

I added the APIkey to your version and my corrected code and it still fails authentication. I will take this up with Revolut as I think it should be working now. There is still something peculiar about the actual output of FileMaker that the Revolut server doesn't agree with. It may just be one of the odd characters in the APIkey or something daft like that.

I will let you know how it goes. Thanks so much for your help - it is encouraging that I am so close.

1 Like

Oh - brilliant. Thanks very much.

I will give these a go too.

At the moment, the cURL script in its simplest form is failing on the authentication.

Tried the fmParser from Solent. Took working code from Terminal and pasted into fmParser. But it still fails authentication from FileMaker!

Ok, I don't have a business account so it is difficult for me to help.
I have created a sample file referencing other APIs, could you fill in the API Key in the script step and execute the script once, and see the result, headers, and trace?

RevolutAPISample.fmp12 (284 KB)

3 Likes

Thanks for everyones help here. At last I have it working.

I have at last located the issue(s) with the formatting of my cURL from FileMaker and the Revolut API is now accepting my authentication and responding correctly. It was just a peculiar bit of formatting that was holding the whole thing up.

I have been assembling the Insert from URL script step with variables holding url, cURL options (header) and data (JSON formatted). Adding the APIkey to the cURL options from a variable was not giving a result that was being accepted. By storing the APIkey in a text field and substituting it into the header cURL, it is now being accepted.

3 Likes

Ah - one issue still that won't play ball. As before the working code in postman & terminal, just doesn't translate to work in FileMaker:

To cancel a payment, I have to submit the following:

curl --location --request POST 'https://merchant.revolut.com/api/1.0/orders/663fcc98-348e-a7af-89be-9fff6ade2c86/cancel?=' \
--header 'Authorization: ••••••'

In FileMaker I just receive a length error in the result**:

$UUID = GetAsURLEncoded ("<<UUID from record>>")
$APIkey = GetAsURLEncoded ("<<apikey>>")
$url = "https://merchant.revolut.com/api/1.0/orders/" & $UUID & "/cancel?="
$header = "-X POST --header \"Revolut-Api-Version: 2023-09-01\" --header \"Accept: application/json\" --header \"Content-Type: application/json\" --header \"Authorization: Bearer TempToken\" -D $header"
$curl_options = Substitute ( $header ; "TempToken" ; $APIkey
 )
Insert from URL [ Select; With dialog: Off; Target: $results; $url; Verify SSL Certificates; cURL options: $curl_options ]

P.s. Substituting 'TempToken' for the API key was the only way I could get any of this to work. The only difference here is in the url query script containing the UUID and the lack of payload data. The $header and $curl_options work for other functions (create and retrieve payments). Postman put the "?=" on the end of the URL, which seems to make no difference. Should I be posting a blank data payload - and if so what?

Note: the payment ID shown here is an example from a record successfully cancelled. I am not trying to cancel records again that are already cancelled.

** the error reporting seems to tell me nothing. Trace shows nothing that I can decipher either.

It might be complaining that you're doing a POST but not passing any content via the -d option.

But to more quickly get to the bottom of it, I recommend installing ngrok on your computer, and then you can use that to create a temporary http server and inspect web requests. ngrok http 5000

Once running you can open the web interface in your browser at http://localhost:4040 and inspect web requests made to the temporary url that ngrok provisioned for you. You can make the "same" request from postman and filemaker, and look for differences.

Another tool I like for this kind of stuff, which you can easily run in docker is: https://httpbin.org/

3 Likes

Bingo!

Thanks so much. I knew it was something stupid. And sure enough it was just objecting to not being sent any data.

I added ---data @$json to the header, where $json = JSONSetElement ( "{}"; [""; 0 ; 2])

... and it loved it.

So thanks so much for the nudge in the right direction. I had already tried it, but not in quite the right way.

1 Like