Enhance security using signed URLs

Protecting your sensitive data

MoonPay is highly committed to security. For this reason, whenever sensitive information such as email or wallet addresses are transmitted to the widget, you are required to use the signature parameter, otherwise, the MoonPay widget will not load. This measure makes it more difficult for unauthorized third parties to misuse the the widget's pre-fill feature.

A signed URL helps limit access from unauthorized third parties by providing limited permissions and time to make a request. Passing the signature parameter is mandatory if you're using the walletAddress or walletAddresses parameter and it must be appended at the end of the URL. If your widget URL contains sensitive information, we strongly recommend using the signature parameter.

You can generate a signature of the URL server-side and append it to the end of the URL. If the signature is provided, we'll check the validity of the query string to make sure it has not been altered. If the signature is invalid for any reason the MoonPay widget will fail to load.

How to sign URLs

When using the SDK, you'll need to

  1. Send your widget URL to your backend server.
  2. Your backend will add a special signature to the URL using the secret key found in your MoonPay dashboard.
  3. Return the signature and update the SDK with it.
  4. Use this signed URL to show the widget.

How to generate signatures

  1. Use a tool to create an HMAC (Hash-based Message Authentication Code) using the SHA-256 hash function.
  2. Use your secret API key as the key and the original URL's query string as the message.
  3. Make sure all query parameter values are URL encoded before creating the signature.

All query parameter values including the signature (not the entire query string) need to be URL encoded before generating the signature in order for it to be valid.

import crypto from 'crypto';

const originalUrl = 'https://buy-sandbox.moonpay.com?apiKey=pk_test_key&currencyCode=eth&walletAddress=0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae';

const signature = crypto
  .createHmac('sha256', 'sk_test_key')  // Use your secret key here
  .update(new URL(originalUrl).search)  // Use the query string part of the URL
  .digest('base64');  // Convert the result to a base64 string

const urlWithSignature = `${originalUrl}&signature=${encodeURIComponent(signature)}`;  // Add the signature to the URL

console.log(urlWithSignature);  // Print the signed URL
<?php
$host = 'https://buy-sandbox.moonpay.com';  // Base URL
$query = '?apiKey=pk_test_key&currencyCode=eth&walletAddress=0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae';  // Query parameters

$secretKey = 'sk_test_key';  // Your secret key

// Create the HMAC SHA-256 hash and encode it in base64
$signature = base64_encode(hash_hmac('sha256', $query, $secretKey, true));

// URL encode the signature
$encodedSignature = urlencode($signature);

// Combine the base URL, query parameters, and the signature
$signedUrl = $host . $query . "&signature=" . $encodedSignature;

echo $signedUrl;  // Print the signed URL
?>

⚠️

Attention

The API gateway of some cloud providers change your parameter's order, resulting in a failed signature validation.