Overview
All API requests to Waypay payment endpoints must include a valid signature for security verification. This guide explains how to generate signatures correctly.Quick Reference
Signature Generation Algorithm
Step-by-Step Process
- Collect all request parameters (excluding ‘signature’)
- Remove null values, empty strings, objects, and arrays
- Convert all parameter keys to LOWERCASE
- Sort parameters alphabetically by lowercase key name (ASCII order)
- Build query string:
key1=value1&key2=value2&... - Append your secret key directly (no & prefix)
- Compute MD5 hash of the combined string
- Convert to lowercase hexadecimal
Visual Example
Value Formatting Rules
Important Notes
🔑 ALL Keys Must Be Lowercase
🔑 ALL Keys Must Be Lowercase
orderRef→orderrefcallbackUrl→callbackurlpaymentMethod→paymentmethod
Numbers: Format depends on type
Numbers: Format depends on type
- Integers (int, long): Plain number →
100,1000,20 - Decimals (decimal, double, float): Use .NET ToString() →
1000.50,99.99 - Enums: Convert to integer value →
WalletProvider.JazzCash(2) →"2"
Booleans: Must be lowercase
Booleans: Must be lowercase
true, false❌ Incorrect: True, FALSE, TRUEObjects & Arrays: Handling varies by type
Objects & Arrays: Handling varies by type
- Most objects (like
customerRef): Excluded from signature calculation - Required parameter objects (like
orderRef): Serialized to JSON string and included - Arrays: Always excluded from signature calculation
DateTime Values: Use .NET default ToString()
DateTime Values: Use .NET default ToString()
Code Examples
Testing Your Implementation
Test Endpoint
Use our signature testing API to verify your implementation:Verify Endpoint
Common Mistakes & Troubleshooting
Common Errors
Debugging Checklist
Is your signature 32 characters?
Is your signature lowercase?
abcdef123456... not ABCDEF123456...Are all parameter keys converted to lowercase?
orderRef→orderrefcallbackUrl→callbackurlAmount→amount
Are parameters sorted correctly?
Are numbers formatted correctly?
- Integers: Plain number →
1000,20,5 - Decimals: Use ToString() →
1000.50,99.99 - Enums: Integer value →
2,5
Are you skipping objects and arrays?
customerRef: { name: "..." }→ SKIPorderRef: { orderRef: "..." }→ INCLUDE (serialize to JSON string)items: [...]→ SKIP
Is the secret key appended correctly?
& before secret key. Directly append: ...orderId=123mer_sk_xxxAPI Request Example
Complete Payment Request
Security Best Practices
Protect Your Secret Key
Never expose in client-side code
Never expose in client-side code
Store securely
Store securely
- Use environment variables
- Use secret management services (Azure Key Vault, AWS Secrets Manager)
- Never commit to version control
Rotate if compromised
Rotate if compromised
Use HTTPS only
Use HTTPS only
Secret Key Format
Getting Help
Test Your Implementation
- Use
/api/v1/signature/exampleto see a complete example - Use
/api/v1/signature/generateto generate signatures for testing - Use
/api/v1/signature/verifyto debug signature mismatches
Contact Support
If you continue to have issues:- Email: support@waypay.com
- Include: Your merchant ID, request payload (without signature), and the signature you generated
Migration from v1.1 to v2.0
Breaking Changes
1. All keys are now lowercase in signature calculation
1. All keys are now lowercase in signature calculation
orderRef, callbackUrl, paymentMethodNew: orderref, callbackurl, paymentmethod2. Integer formatting changed
2. Integer formatting changed
1000 → "1000.00"New: 1000 → "1000"3. Enum handling
3. Enum handling
WalletProvider.JazzCash (value: 2) → "2"4. DateTime formatting
4. DateTime formatting
"2024-01-15T10:30:00"New: .NET default ToString() (culture-dependent)Migration Steps
Update your signature generation code
Remove forced 2-decimal formatting for integers
1000 instead of 1000.00).Test your signatures
/api/v1/signature/generate endpoint to verify your implementation.Verify before deploying
/api/v1/signature/verify to validate signatures before deploying to production.Changelog
Document Version: 2.0
Last Updated: 2026-01-26
API Version: v1