Skip to content
MrIvoryMrIvory
Connect processor Merchant panel

Notifications

Webhooks

Outbound merchant notifications and inbound KYC provider callbacks. JSON bodies. No PAN or CVV. Not live acquiring.

Merchant notification URL

Set on My Profile. Must be http:// or https:// (HTTPS preferred) or blank to disable. The sandbox POSTs Content-Type: application/json and waits up to 5 seconds. There is no retry queue.

Sale captured/declined and refund created use the same sale shape (TXNTYPE=NEWORDER) plus HASH from the merchant secret. See HASH.

Staff email, SMS, and WhatsApp

When a sale becomes Captured, Mr Ivory can also notify merchant staff by email, SMS, and WhatsApp. This is extra fan-out next to the webhook. It fires once per TXN_ID and does not re-send on status refresh. Shopper receipts are out of scope.

Toggles and destinations are on My Profile. Email defaults on (sign-in email). SMS and WhatsApp default off until an E.164 number is saved. Platform env: SENDGRID_API_KEY, TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_SMS_FROM, TWILIO_WHATSAPP_FROM. Missing channel secrets skip that channel and log; they never fail the payment.

Live WhatsApp needs a Meta-approved utility template before production. Delivery is never assumed if the template or messaging credentials are missing. Staff copy is short: You have just been paid USD 1.00. Email subject matches; the body may add the order id in a tiny footer. Never PAN or CVV.

FieldMeaning
APP_IDMerchant id
TXN_ID, ORDER_IDSale or refund ids
STATUS, RESPONSE_CODE, RESPONSE_MESSAGESame success rule as the APIs
AMOUNTMinor units (integer string)
AMOUNT_DECIMALMajor units for display
CURRENCY_CODE / CURRENCY_CODE_ALPHANumeric and alpha
CUST_EMAIL, CUST_NAME, address fieldsFrom the sale — no card number
HASHSigned over the payload fields
JSON
{
  "APP_ID": "1000221129001154",
  "TXN_ID": "16-digit id",
  "ORDER_ID": "S2S-001",
  "STATUS": "Captured",
  "RESPONSE_CODE": "000",
  "AMOUNT": "1000",
  "AMOUNT_DECIMAL": "10.00",
  "CURRENCY_CODE": "784",
  "CURRENCY_CODE_ALPHA": "AED",
  "TXNTYPE": "NEWORDER",
  "CUST_EMAIL": "buyer@example.test",
  "HASH": "…"
}

Recurring events

Same merchant URL. These bodies include EVENT and HASH. They never include PAN.

EVENTWhen
recurring.invoice.paidRecurring charge captured
recurring.invoice.failedRecurring charge declined or failed
subscription.cancelledSubscription cancelled
subscription.pausedSubscription paused

Shared fields: APP_ID, subscriptionId, planId, invoiceId, amount (minor), currency, status, txnId, failureMessage, failCount, RESPONSE_DATE_TIME, HASH.

JSON
{
  "EVENT": "recurring.invoice.paid",
  "APP_ID": "1000221129001154",
  "subscriptionId": "sub_…",
  "planId": "plan_…",
  "invoiceId": "inv_…",
  "amount": 1000,
  "currency": "784",
  "status": "paid",
  "txnId": "16-digit id",
  "HASH": "…"
}

Inbound KYC webhook

Provider → this host, not merchant → this host.

  • POST /pgui/jsp/kycWebhook
  • POST /pgui/services/kyc/webhook (same handler)

JSON body:

JSON
{
  "applicantId": "kyc_sbx_…",
  "status": "approved",
  "checkId": "chk_sbx_…",
  "reason": "optional"
}

status is approved, rejected, or pending (aliases are normalised). If KYC_WEBHOOK_SECRET is set, send x-kyc-signature as hex HMAC-SHA256 of the raw body. Unknown applicantId returns 404. Invalid signature returns 401. Success returns { "ok": true, "status": "Approved", "appId": "…" }.

This updates the KYB pack only. It does not start live acquiring.

Inbound banking / payouts / cards webhook

Partner rail → this host only. Not card eCom. The endpoint must be HTTPS on port 443 on the Mr Ivory origin.

  • POST /webhooks/upp — platform / env signing secret first (white-label rail), then any stored merchant override that verifies
  • POST /webhooks/upp/<APP_ID> — that APP_ID’s ops-override signing_secret first, then platform / env

Required headers: Webhook-Id, Webhook-Timestamp, Webhook-Signature (v1= HMAC-SHA256 of timestamp + "." + raw_body). Invalid signature or a timestamp outside 300 seconds returns 401. A first delivery is persisted under Webhook-Id; a retry of the same id returns { "received": true, "duplicate": true } without re-running side effects. Banking, card issuing, and other unknown event types are stored and acknowledged with 2xx. Known payout status events update a matching payout row when data.id equals that row’s acquirer reference. Verification, KYC, funding-account, and payout events also update status chips on the Banking panel from those stored processor events. No PAN or CVV is stored.

JSON
{
  "received": true
}