Modulr authorization using Python

Modulr is a service that replaces bank functionality for payments. They provide an API, that you can implement anywhere you want, to get access to a 24/7 payment service. Some of the things you can do with Modulr, as taken from their website:

Well, that’s what it says. Now let’s look how to implement it in Python.

How to authorize using Python

The API is Restful, so we won’t bother explaining how exactly it works. You can go through the documentation to see what are the endpoints you can access. The hard part of this API is the authorization, as it’s quite elaborate. You can see nodejs and java samples in their official (taken from website) github repository… but again, we want to do it in Python! Let’s see how.

Add the following imports:

import re
import base64
import hashlib
import hmac
import uuid
from datetime import datetime
from wsgiref.handlers import format_date_time
import requests  # pip install requests

Now we will create some variables to store values you need for authorization from Modulr:

API_KEY = 'YOUR_API_KEY'
HMAC_SECRET = 'YOUR_SECRET'
BASE_URL = 'https://api-sandbox.modulrfinance.com/api-sandbox'

To access the API, you will have to generate HMAC Signatures/Authorization headers. The process is described here. We will try implementing it in Python:

# Create the date value
date = format_date_time(datetime.now().timestamp())

# Create the nonce value
nonce = uuid.uuid4().hex + str(int(datetime.now().timestamp()))

# Create the signature
message = 'date: ' + date + '\n' + 'x-mod-nonce: ' + nonce
message = bytes(message, 'UTF-8')
key = bytes(HMAC_SECRET, 'UTF-8')
digester = hmac.new(key, message, hashlib.sha1)
signature_dig = digester.digest()

signature = base64.urlsafe_b64encode(signature_dig)
signature = str(signature, 'UTF-8')

Although this looks good, when we try to use that with Modulr, we can see that they can’t parse some symbols. I found a solution writen by one of the team members, that replaced some of the symbols using regex. Add to the ending of the above code:

MODULR_URL_SAFE_HMAC = {
    '_': '%5F',
    '=': '%3D',
    '-': '%2D',
}
RE_FIND_PATTERN = '=|\\-|_'

signature = re.sub(
    RE_FIND_PATTERN,
    lambda m: MODULR_URL_SAFE_HMAC.get(m.group(0)),
    signature,
)

Let’s gather the headers into a dictionary, so it’s usable:

headers = {
    'Authorization': (
        f'Signature keyId="{API_KEY}",'
        'algorithm="hmac-sha1",'
        'headers="date x-mod-nonce",'
        f'signature="{signature}"'
    ),
    'date': date,
    'x-mod-nonce': nonce,
    'x-mod-retry': '1',
    'Content-type': 'application/json',
}

Now you can use the created headers dictionary in your requests going to Modulr. A simple example on how to do it for gathering customers:

response = requests.get(
    BASE_URL + '/customers',
    headers=headers,
)

Tell me what you think!