Skip to main content

Key setup

Generate the key pair on your own machine. The platform never receives or stores your private key; you register only the public key in the merchant portal, and the portal walks you through the one-time proof signature that shows you hold the matching private key.

Use OpenSSL 3.0 or later. Older OpenSSL versions and the LibreSSL that ships with macOS may not support the commands below. On Windows use PowerShell 5.1 or later; on macOS and Linux use Bash or Zsh. Run every step in the same terminal, in the directory where priv.pem and pub.pem are saved.

1. Install OpenSSL​

winget install --id ShiningLight.OpenSSL.Light --exact --source winget --accept-source-agreements --accept-package-agreements
$opensslDirs = Get-ChildItem "$env:ProgramFiles\OpenSSL*\bin", "${env:ProgramFiles(x86)}\OpenSSL*\bin" -Directory -ErrorAction SilentlyContinue
$env:Path = ($opensslDirs.FullName -join ";") + ";" + [Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [Environment]::GetEnvironmentVariable("Path", "User") + ";" + $env:Path
openssl version

Approve the system prompt if one appears. If winget is unavailable, install or update App Installer from the Microsoft Store, or install OpenSSL Light manually from Shining Light Productions.

Confirm the output shows OpenSSL 3.x or later before continuing. If it still shows 1.x or LibreSSL, check the installation and PATH first.

2. Generate the key pair​

The commands are the same on every system.

openssl genpkey -algorithm ed25519 -out priv.pem
openssl pkey -in priv.pem -pubout -out pub.pem

Paste pub.pem into the merchant portal to register the credential. Keep priv.pem on your side.

3. Convert the private key for the SDK​

The SDK does not read PEM. Strip the ASN.1 headers and join the 32-byte seed with the 32-byte public key into the 64-byte form, then base64-encode it. The PKCS8 private key DER is 48 bytes (16-byte fixed header + 32-byte seed); the SPKI public key DER is 44 bytes (12-byte fixed header + 32-byte key).

& {
# Strip the ASN.1 header to get raw bytes
openssl pkey -in priv.pem -outform DER -out private.der
if ($LASTEXITCODE -ne 0) { throw "OpenSSL: private key export failed" }
openssl pkey -pubin -in pub.pem -outform DER -out public.der
if ($LASTEXITCODE -ne 0) { throw "OpenSSL: public key export failed" }
$privateDer = [IO.File]::ReadAllBytes((Join-Path $PWD.Path "private.der"))
$publicDer = [IO.File]::ReadAllBytes((Join-Path $PWD.Path "public.der"))
if ($privateDer.Length -ne 48 -or $publicDer.Length -ne 44) { throw "Expected Ed25519 keys" }

# Concatenate seed + public key into the 64-byte form and base64-encode
[Convert]::ToBase64String([byte[]]($privateDer[16..47] + $publicDer[12..43]))
Remove-Item -LiteralPath private.der, public.der
}

The output is the value for the merchant private key setting (MerchantPrivateKeyBase64 in Go; see SDK configuration for the other languages). It is a secret: store it like any other credential, and do not paste it into the portal. The proof signature the portal asks for during registration is a different value.