1. Alternative Payment Methods
Sipay API Documentation - ZA
  • Overview
    • Getting Started
    • Test Cards
  • Authentication
    • Token Generation
      POST
  • Commission
    • Commission
      POST
  • HASH
    • Hash Creation
    • Hash Validation
  • Non-Secure Payment
    • Non-Secure Payment Flow
    • Non-Secure Card Payment
      POST
    • Non-Secure Pre-Authorization Payment
      POST
    • Confirm Payment
      POST
  • 3D Secure Payment
    • 3D Secure Payment Flow
    • 3D Secure Card Payment
      POST
    • 3D Secure Pre-Authorization Payment
      POST
    • Complete Payment
      POST
    • Confirm Payment
      POST
  • Non-Secure and 3D Payment with Sipay
    • Non-Secure and 3D Secure Payment with Sipay
  • Check Status
    • Check Status
  • Refund
    • Refund
  • Webhook
    • Webhook
  • Status Codes
    • Status Codes
  • Alternative Payment Methods
    • Overview
    • Payment Flow
    • Base URL & Environments
    • Hash Key
    • Client-side SDK handling
    • Status Codes
    • End-to-end example
    • GPay Payment Example
    • Authentication
      POST
    • walletCheckout
      POST
    • walletPay
      POST
  1. Alternative Payment Methods

Hash Key

Every payment request carries a hash_key — an encrypted signature that binds the request to merchant's secret so cannot be forged or replayed against a different order. The hash is built by joining the relevant fields with |, encrypting them with AES-256-CBC using your app_secret , and packaging the IV, salt and ciphertext together.
EndpointSignature Fields
walletCheckouttotal | currency_code | merchant_key | invoice_id
walletPayinvoice_id | merchant_key
Why walletPay's hash omits the amount: the transient token returned by the wallet button is wallet provider-signed and single-use, so it already carries the amount/currency and provides replay protection. The hash only needs to bind the invoice and merchant.

Reference implementation (PHP)#

Amount formatting. When validating, Sipay normalizes total to 4 decimal places (number_format($total, 4, '.', '')). Make sure the total sign matches the total sending in the request body — they only need to be numerically equal (e.g. 10, 10.00 and 10.0000 all match).
Modified at 2026-06-01 13:49:24
Previous
Base URL & Environments
Next
Client-side SDK handling
Built with