Skip to main content

Signatures

When using Fondy Gateway to create payments, each request and response must include a signature for validation. This ensures data integrity and prevents unauthorised modification of transaction details. The signature is generated using SHA1 encryption and a specific set of parameters.

Before You Begin

Make sure you have your Payment Key ready from the Fondy portal. This key is required for signature generation.

When to Use Signatures

Signatures are used in two primary cases:

  1. Request Signatures: When sending a request to Fondy, the signature ensures the data is correct and authentic. For example, in a payment request, you must include a signature to verify that your information hasn't been tampered with.
  2. Response Validation: Fondy returns a response with a signature after processing your request. You can validate this signature to confirm that the response data has not been altered in transit.
Signatures in Fondy SDKs

Fondy SDKs automatically handle signature generation and response validation. If you are using an SDK, you do not need to manually create signatures or validate responses - the SDKs handle these tasks for you.

Creating a Signature

Let's walk through creating a signature with a practical example:

Step 1: Prepare Payment Parameters

First, define the parameters for your payment request. These parameters contain essential information about the transaction:

  • order_id: A unique identifier for the payment
  • order_desc: A description of what is being purchased
  • currency: The currency code for the transaction (e.g. GBP, USD, EUR)
  • amount: The payment amount in the smallest currency unit (e.g. cents/pence)
  • merchant_id: Your unique merchant identifier from Fondy
  • sender_email: The customer's email address
{
"order_id": "test12345612122121221",
"order_desc": "test12121order",
"currency": "GBP",
"amount": 125,
"merchant_id": 1396424,
"sender_email": "email@email.com"
}
Payment Key

You can find your Payment Key in the Fondy portal under Merchant Settings.

Step 2: Create the Signature String

To create the signature string:

  1. Take all your payment parameters and sort their names alphabetically
  2. Get the value for each parameter in this sorted order
  3. Join all values with the | (pipe) symbol
  4. Add your Payment Key at the beginning, followed by another | symbol

For example, if your parameters are order_id, amount, and currency, you would:

  1. Sort them: amount, currency, order_id
  2. Get their values in that order
  3. Join with |: value1|value2|value3
  4. Add Payment Key: PaymentKey|value1|value2|value3

The final format will be:

Payment Key|amount|currency|merchant_id|order_desc|order_id|sender_email

Replacing with actual values:

PnguSqqcdmFH5p5UlLxXi5zm2SOdm6zW|125|GBP|1396424|test12121order|test12345612122121221|email@email.com

Step 3: Generate the SHA1 Hash

Using a SHA1 function on the signature string generates the final signature:

caf43947bfa47356214925099304a6b6f7afcc24

Complete Implementation

Here's a Python implementation that handles the entire process:

import hashlib

def generate_signature(data: dict, secret_key: str) -> str:
# Remove empty values and 'signature' parameter
clean_data = {k: str(v) for k, v in data.items()
if v is not None and v != "" and k != "signature"}

# Sort parameters alphabetically
sorted_keys = sorted(clean_data.keys())

# Get values in sorted order
values = [clean_data[k] for k in sorted_keys]

# Create signature string with Payment Key
signature_string = secret_key + "|" + "|".join(values)

# Generate SHA1 hash (lowercase)
return hashlib.sha1(signature_string.encode('utf-8')).hexdigest().lower()

# Example usage
payment_data = {
"order_id": "test12345612122121221",
"order_desc": "test12121order",
"currency": "GBP",
"amount": 125,
"merchant_id": 1396424,
"sender_email": "email@email.com"
}

# Generate signature using your Payment Key
signature = generate_signature(payment_data, "PnguSqqcdmFH5p5UlLxXi5zm2SOdm6zW")

Using the Signature

After generating the signature, include it in your API request to the Accept Purchase (Fondy Checkout) endpoint:

{
"request": {
"order_id": "test12345612122121221",
"order_desc": "test12121order",
"currency": "GBP",
"amount": 125,
"signature": "caf43947bfa47356214925099304a6b6f7afcc24",
"merchant_id": 1396424,
"sender_email": "email@email.com"
}
}

Validating Signatures in Fondy Responses

Fondy responses include a signature parameter that ensures the integrity of the data. When validating a response, you must recreate the signature using the response parameters and compare it with the provided signature.

Step-by-Step Validation Guide

  1. Remove Excluded Parameters Remove these parameters from the response before generating the signature:

    • signature
    • response_signature_string (only appears in test mode)
  2. Create Validation String

    • Sort remaining parameters alphabetically
    • Combine values with the | separator
    • Ensure:
      • Empty parameters are excluded
      • No | is added for empty values
      • UTF-8 encoding is used for non-Latin characters
  3. Generate and Compare Signatures

    def validate_response(response_data: dict, secret_key: str) -> bool:
    # Get the signature from response
    received_signature = response_data.pop('signature', '')

    # Remove response_signature_string if present (test mode)
    response_data.pop('response_signature_string', '')

    # Generate signature from remaining data
    calculated_signature = generate_signature(response_data, secret_key)

    # Compare signatures
    return received_signature == calculated_signature

Example Response Validation

# Example response data
response_data = {
"order_id": "test12345612122121221",
"payment_id": "125",
"status": "approved",
"signature": "6bd069be8a6e2f2bbe176df00ba63cc681ca38aa"
}

# Validate the response
is_valid = validate_response(response_data, "PnguSqqcdmFH5p5UlLxXi5zm2SOdm6zW")
if is_valid:
print("Response signature is valid")
else:
print("Invalid signature - possible data tampering")

Common Issues and Troubleshooting

Invalid Signature Error in API Response

If you receive an invalid signature error, check these common issues:

  1. Payment Key Verification

    # Ensure you're using the correct Payment Key from your Merchant Portal
    secret_key = "YOUR_ACTUAL_PAYMENT_KEY" # Get this from Merchant Settings
  2. UTF-8 Encoding

    # Ensure proper encoding for non-Latin characters
    signature_string = signature_string.encode('utf-8')
  3. Zero Values

    # Ensure zero values are treated correctly
    clean_data = {k: str(v) for k, v in data.items()
    if v is not None and v != "" and k != "signature"}
  4. Debug Signature String

    # Log the signature string for debugging
    print(f"Signature String: {signature_string}")
    # Compare with response_signature_string in test mode

Mismatched Signature in Server Callbacks

When handling server callbacks, verify:

  1. Parameter Exclusion

    # Remove signature and response_signature_string
    callback_data = response_data.copy()
    callback_data.pop('signature', None)
    callback_data.pop('response_signature_string', None)
  2. Parameter Order

    # Ensure correct parameter order
    sorted_keys = sorted(callback_data.keys())
    ordered_values = [callback_data[k] for k in sorted_keys]

Best Practices

  1. Case Sensitivity

    # Always use lowercase for SHA1 output
    signature = hashlib.sha1(signature_string).hexdigest().lower()

    Correct: 6bd069be8a6e2f2bbe176df00ba63cc681ca38aa Incorrect: 6BD069BE8A6E2F2BBE176DF00BA63CC681CA38AA

  2. Endpoint-Specific Parameters

    • Include only the necessary parameters for your specific endpoint
    • Different endpoints may require different parameters:
      • /api/recurring has different requirements than /api/redirect
      • Check the endpoint documentation for required parameters
Testing Mode

When in test mode, use the response_signature_string parameter to debug signature generation. This parameter shows the exact string used to generate the signature.

Following these guidelines and troubleshooting steps, you can effectively implement signature validation and handle any signature-related issues in your integration with Fondy Gateway.