Skip to main content
Before you go live with Mizaniya Pay VTPE, review these practices to keep your integration secure, reliable, and easy to maintain.

Secure Secret Storage

Treat your API Secret and HMAC Secret as credentials:
  • Store them in environment variables or a secrets manager (for example, AWS Secrets Manager or HashiCorp Vault).
  • Never commit secrets to source control or expose them in client-side code.
  • Rotate both secrets immediately if you suspect compromise.

Timestamp Validation

VTPE includes X-Timestamp on every request and webhook. Validate that the timestamp is within plus or minus five minutes of your server’s current time. Reject stale requests to prevent replay attacks.

Idempotent Webhook Processing

VTPE may retry a webhook if the first attempt does not receive an HTTP 200 response. Use paymentId as an idempotency key:
  • Check whether paymentId was already processed before acting on the event.
  • Return HTTP 200 even if the event is a duplicate, as long as your side has already handled it.
  • This protects against duplicate order fulfillment or double crediting.

Logging

Log every incoming webhook for observability and debugging:
  • Log the event type, reference, paymentId, and X-Timestamp on receipt.
  • Log the processing outcome (success, duplicate, or failure).
  • Never log the values of your API Secret or HMAC Secret.

Retry Handling

Return HTTP 200 immediately after validation, then process the event asynchronously via a job queue:
  • Synchronous processing that takes too long can cause VTPE to retry unnecessarily.
  • An async queue lets you retry failed jobs on your own schedule while still acknowledging the webhook promptly.
  • This pattern also helps you recover gracefully from temporary downstream outages.
Use a queue-based async worker (for example, Bull in Node.js, Celery in Python, or a cloud function with a pub/sub trigger) to separate webhook acknowledgment from business logic.

Error Monitoring

Set up alerts for these signals so you catch problems early:
  • Unexpected 4xx or 5xx rates from your Product Information API endpoint.
  • Webhook processing failures (validation errors, queue backlogs, or handler exceptions).
  • Idempotency key collisions that could indicate retry storms or upstream bugs.

Reconciliation with the Payment Status API

Webhook delivery can fail. When it does, you may be holding a locked product with no confirmation of whether the payment went through. Use the Payment Status API as a recovery path in these situations:
  • Before selling a product on-premise that may have been paid through Mizaniya Pay.
  • When reconciling a reference whose webhook never arrived (check payment.webhookDelivery in the response).
  • During periodic reconciliation of open orders past their expected payment window.
Branch on stage or locked when you receive the response. Never branch on payment.status. The rate limit is 60 requests per minute; do not poll in a tight loop.
The Payment Status API is a safety net, not a replacement for webhooks. Keep handling payment.success and payment.fail as your primary signal.

Production Deployment Checklist

Before enabling live traffic, verify every item below:
  • HTTPS only on both the Product Information API and webhook endpoints.
  • Signature verification enabled in production and never skipped.
  • Timestamp window enforced on all incoming requests.
  • Async processing queue set up and monitored.
  • Secrets stored securely outside the codebase.
  • All three event types handled: payment.initialized, payment.success, and payment.fail.
  • Payment Status API tested as a reconciliation fallback for missed webhooks.