Cryptoacquiring: API Docs
  • CRYPTO ACQUIRING API
    • General
    • Glossary
    • API References
      • Authorization
      • Orders
      • Statuses
      • Currencies
      • Callbacks
Powered by GitBook
On this page
  • How to sign requests
  • How to verify responses (Optional)
  1. CRYPTO ACQUIRING API
  2. API References

Authorization

SWAPPLE API uses RSA-1024 keypair to secure requests.

First of all you need to generate RSA-1024 keys and send us your public key. We will send you our public key so that you can verify our response.

How to sign requests

You need to generate SHA512 hash sign based on request body.

Authentication parameters are transmitted in Headers:

  • public-key

  • signature

  • timestamp - current time in milliseconds (used in sign generation)

An example of generating a signature.

Python 3.9
import binascii
import collections
import decimal
import time

from Crypto.Hash import SHA512
from Crypto.PublicKey import RSA
from Crypto.Signature.pkcs1_15 import PKCS115_SigScheme

# Example of private/public keys
PRIVATE_KEY_PEM=-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQC8+WkIRyupart2WnDWSYr8Qz4LOXSft8IxlzfiLkSWL4c0Y9WI\nC4UbKDAH7Som+5gOTTRt9YckHVc3FO+HyGQdmPATKxcJoVk8Bj0nmLSiWN+x6DHL\ne/4E3xqbwGlmCuwVGM1Yg3HDMneJznNGLvfPXAt0ZnpLuRaBdI3cHjm1PwIDAQAB\nAoGAG59LSoH4sFlhEHI01yXF0ozTp1ldIjF+ibgkW4PO07MbzL0hC7M/YBJWPvpc\nNHmHJuQDG2WNvOorAuqk/pB8jZQUquH3exzLmohJy65Sl19EL24K8REx0gsg8+Q3\n+dPwVE3QXAKCUtmRmQPv+WGzWVvi1rDim9Il87u/t72MPY0CQQC/6dilUIirCt32\np6p9j8U9CP09E9nOOd6cehKbyqk8F/8pLb991IoKLdMLAevrdwas8OVxXv75RxcV\ni/kgu0nVAkEA/BRMtFhcGkwWT3+TeHuTtz/AYXTYwVgnCV8g+5NyDPGOM83+rrn0\nfl3SP3RdJSpbl2hqfKee4LaUNxHvP9KYwwJAb9gm7GE85QHWThN05uxM9L8yZtAU\n1X0gYW07PxQjAOSzThpdSUX+lOQT5IxgI8AgYdWawjGswzZNG7+RlyPPaQJBAK9R\nPve+7G+ts2afB+WnrNiqEha1uXre4Gd4LexKY+v0pD4LarICyrSIdA2F1LJgf0sS\nZ91ChxEqanLSml79DRkCQDyD74RrQJB3zFw7zJQI52rTXePXn8IZnf/O+dqCHjQs\no/MO7n1kavb6syDVP2AO0iqnDyB8UNHVlrl5LavjIH0=\n-----END RSA PRIVATE KEY-----
PUBLIC_KEY=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8+WkIRyupart2WnDWSYr8Qz4LOXSft8IxlzfiLkSWL4c0Y9WIC4UbKDAH7Som+5gOTTRt9YckHVc3FO+HyGQdmPATKxcJoVk8Bj0nmLSiWN+x6DHLe/4E3xqbwGlmCuwVGM1Yg3HDMneJznNGLvfPXAt0ZnpLuRaBdI3cHjm1PwIDAQAB


def stringify_value(value: str) -> str:
    """
    Convert the value to a decimal string or a lower case string.

    :param value: The value to be converted.
    :return: The converted value as a string.
    """
    try:
        # Try to convert value to a decimal string.
        decimal_value = Decimal(str(value))
    except decimal.InvalidOperation:
        # If not possible, convert the value to a lower case string.
        return str(value).lower()

    return str(decimal_value)


def request_body_to_str_line(body: dict, timestamp: str) -> str:
    """
    Convert the body of the request to a string line.

    :param body: The body of the request as a dictionary.
    :param timestamp: The timestamp as a string.
    :return: The string line.
    """
    sorted_body = collections.OrderedDict(sorted(body.items())) if isinstance(body, dict) else {}
    line = "".join(f"{key.lower()}{stringify_value(value)}" for key, value in sorted_body.items() if value)
    line += f"timestamp{timestamp}"
    return line.lower()


def request_sign(body: dict, timestamp: str, private_key_pem: bytes) -> str:
    """
    Generate the request signature.

    :param body: The body of the request as a dictionary.
    :param timestamp: The timestamp as a string.
    :param private_key_pem: The private key as a PEM string.
    :return: The request signature as a string.
    """
    line = request_body_to_str_line(body, timestamp)
    new_hash = SHA512.new(line.encode())
    signer = PKCS115_SigScheme(RSA.importKey(private_key_pem))
    sign = signer.sign(new_hash)
    return binascii.hexlify(sign).decode("utf-8")


def get_authorization_headers(private_key_pem: bytes, public_key: str, body: dict) -> dict:
    """
    Get the authorization headers.

    :param private_key_pem: The private key as a PEM string.
    :param public_key: The public key as a string.
    :param body: The body of the request as a dictionary.
    :return: The authorization headers as a dictionary.
    """
    timestamp = str(int(time.time()))
    signature = request_sign(body, timestamp, private_key_pem)

    return {
        "public-key": public_key,
        "signature": signature,
        "timestamp": timestamp,
    }


# Example of signed request
base_url = 'https://test.acquiring.swapple.io'
body = {'currency': 'CARDUAH', 'amount': '10', ...}
requests.post(
    f'{base_url}/public/api/orders/',
    json=body,
    headers=get_authorization_headers(body)
)

How to verify responses (Optional)

We sign our responses the same way you sign a request. Though this step is optional we strongly advise on verifying responses.

You will receive three parameters in headers: public-key, signature and timestamp.

An example of response verification.

import binascii
from Crypto.Hash import SHA512
from Crypto.Signature.pkcs1_15 import PKCS115_SigScheme


def response_body_to_str_line(body, timestamp):
    line = ""
        body = collections.OrderedDict(sorted(body.items()))
        for value, keys in body.items():
            line += value + keys
            
    line += "timestamp" + timestamp
    line = line.lower()
    return line

def verify_signature(body, headers):
    line = response_body_to_str_line(body, headers.get('timestamp'))
    client_sign = headers.get('signature')
    hash = SHA512.new(line.encode())
    verifier = PKCS115_SigScheme(headers.get('public-key'))
    try:
        verifier.verify(hash, binascii.unhexlify(client_sign))
        return True
    except:
        return False
PreviousAPI ReferencesNextOrders

Last updated 1 year ago