DigetPay Developer Integration API
  1. Integration Flow
  • Overview & Getting Started
  • Integration Flow
    • 01 - Authentication & Team
    • 02 - End-to-End Integration Flow
    • 03 - Customizing your Marketplace Listing
  • API Reference
    • Auth
      • Refresh access token using a refresh token
      • Logout — revoke the refresh token
      • Get current profile
      • Activate an invited `DEVELOPER` account (set password from invite link)
    • Login
      • Login with email + password (sends OTP via email and SMS)
      • Verify the login OTP and issue access + refresh tokens
      • Resend login OTP via email and SMS
    • Register
      • Self-register a developer company + owner account
      • Verify registration OTP (email + phone)
      • Resend registration OTP
    • Forgot Password
      • Forgot password — send a reset OTP to the email
      • Verify the forgot-password OTP
      • Reset the password using the reset token
    • Team
      • List organization members
      • Invite a `DEVELOPER` into the organization
      • Resend the activation link for a `PENDING` member
      • Remove a member
    • Company
      • Change Requests
        • Submit a company information change request
        • Withdraw a pending change request
        • Upload a document for a company change request
        • Remove a staged document from a change request
        • Get current pending company change request
      • Company profile + verification status + documents
      • Respond to a single information request
      • Update company / verification data (DRAFT or INFO_REQUIRED only)
      • Onboarding readiness for verification submit and marketplace
      • Upload a verification document (pdf/jpeg/png, max 10MB)
      • Signed download URL for an own document
      • Submit company for verification review
      • Verification status only
      • List information requests for the current verification
    • Applications
      • List applications
      • Create application (requires APPROVED verification)
      • Active marketplace categories (for the listing form)
      • Application detail
      • Update application
      • Request production activation (certification must be PASSED)
      • Upload an application logo (icon)
      • Upload an application banner
      • Marketplace orders for the application
      • API request logs (masked metadata only)
      • Orders / transactions for the application
      • Advance a confirmation-required order
      • Submit application for review
    • Listings
      • Marketplace listing for the application
      • Create or partially update the marketplace listing
      • Submit listing for marketplace review
      • Unpublish a live or scheduled marketplace listing
    • Offers
      • List authored marketplace offers (cards)
      • Create a marketplace offer (card)
      • Reorder marketplace offers
      • Update a marketplace offer (card)
      • Delete a marketplace offer (card)
      • Upload a marketplace offer (card) image
      • Upload an offer (card) banner image
    • Panels
      • Upload a panel (section) banner image
      • List marketplace panels (sections)
      • Create a marketplace panel (section)
      • Reorder marketplace panels (sections)
      • Update a marketplace panel (section)
      • Delete a marketplace panel (section)
    • Credentials
      • List credentials (masked)
      • Generate credential for an environment — raw key returned once
      • Rotate API key — new raw key returned once
      • Rotate webhook signing secret — returned once
      • Revoke credential (`isActive=false`)
      • Set optional IP allowlist (IPv4 / CIDR)
    • Webhooks
      • Webhook event catalog
      • List webhook endpoints
      • Add webhook endpoint (**max 5 per environment**)
      • Update webhook endpoint
      • Delete webhook endpoint
      • Send a signed connection test to the endpoint
      • Delivery logs
    • Dashboard
      • Developer portal overview
    • Company
  • Developer Portal
    • Applications
    • Certification
      • Certification progress ("8 of 12 tests completed")
      • Re-evaluate automated certification checks
    • Auth
      • Login
        • Login with email + password (no OTP — non-production only)
  • admin
    • auth
      • Step 1: email + password → email OTP
      • Step 2: verify OTP → admin JWT
      • Resend OTP (re-runs login challenge)
      • Get current admin user profile
      • Update current admin profile (name, phone, avatar)
      • Change password for the current admin user
      • Logout admin user
      • Set password from an invite link token (no auth required)
      • Request password reset via email/SMS OTP (no auth required)
      • Verify password reset OTP and get reset token (no auth required)
      • Reset password using reset token and new password (no auth required)
  • integrity
    • Issue a one-time nonce for Play Integrity attestation
      POST
    • (DEV ONLY) Decode an integrity token and return the verdict
      GET
  • health
    • Liveness probe - basic health check
    • Readiness probe - dependency health check
    • HealthController_getMetrics
  • super-admin-portal
    • impersonate
      • Impersonate a partner or merchant OWNER by targetId + targetType
      • End an active impersonation session
  1. Integration Flow

02 - End-to-End Integration Flow

The definitive path from first register to live in the Super App, plus
the two runtime systems every partner touches: orders (fulfillment) and
signed webhooks (event delivery).
See also:
Getting Started -- quick-start onboarding checklist
Authentication & Team -- registration, login, tokens, and team management

1. Full lifecycle#

Phase gates#

Gate 1 — Create application
Gate 2 — Submit listing

2. Stage-by-stage walkthrough#

Stage A — Onboarding (Days 0–1)#

1
Register + OTP
POST /developer-portal/register → verify OTP → org status ONBOARDING.
2
Complete company profile
PATCH /developer-portal/company — optional until submit; IBAN only ever
returned masked.
3
Upload legal documents
POST /developer-portal/company/documents (multipart, pdf/jpg/png ≤ 10 MB)
for COMMERCIAL_REGISTRATION, TAX_CERTIFICATE, REP_ID (required), plus
BANK_LETTER, AGREEMENT, LOGO, OTHER (optional).
4
Check readiness
GET /developer-portal/company/readiness returns
canSubmitVerification: false until every required field + document is
present.
5
Submit
POST /developer-portal/company/submit → verification SUBMITTED → org
PENDING_VERIFICATION.
Readiness response:
{
  "organizationStatus": "ONBOARDING",
  "verificationStatus": "DRAFT",
  "profileIncomplete": true,
  "missingFields": ["bankName: is required", "iban: is required"],
  "missingDocuments": ["REP_ID"],
  "canSubmitVerification": false,
  "canCreateApplication": false,
  "canPublishListing": false
}

Status enums — organization & verification#

EventOrg statusVerification status
RegisterONBOARDINGDRAFT
Submit KYCPENDING_VERIFICATIONSUBMITTED
Admin reviewPENDING_VERIFICATIONUNDER_REVIEW
Admin approveAPPROVEDAPPROVED
Admin rejectREJECTEDREJECTED
the two runtime systems every partner touches: orders (fulfillment) and
signed webhooks (event delivery).
See also:
Getting Started -- quick-start onboarding checklist
Authentication & Team -- registration, login, tokens, and team management

1. Full lifecycle#

Phase gates#

Gate 1 — Create application
Gate 2 — Submit listing

2. Stage-by-stage walkthrough#

Stage A — Onboarding (Days 0–1)#

1
Register + OTP
POST /developer-portal/register → verify OTP → org status ONBOARDING.
2
Complete company profile
PATCH /developer-portal/company — optional until submit; IBAN only ever
returned masked.
3
Upload legal documents
POST /developer-portal/company/documents (multipart, pdf/jpg/png ≤ 10 MB)
for COMMERCIAL_REGISTRATION, TAX_CERTIFICATE, REP_ID (required), plus
BANK_LETTER, AGREEMENT, LOGO, OTHER (optional).
4
Check readiness
GET /developer-portal/company/readiness returns
canSubmitVerification: false until every required field + document is
present.
5
Submit
POST /developer-portal/company/submit → verification SUBMITTED → org
PENDING_VERIFICATION.
6
Respond to info requests (if any)
Admin may return your submission with INFO_REQUESTED status — either
requesting new information or edits/explanations for existing fields
(e.g. tax number, website URL).
GET /developer-portal/company/info-requests — see what is needed.
POST /developer-portal/company/info-requests/:id/respond — answer each one.
When all requests are answered, verification auto-resubmits
(INFO_REQUESTED → SUBMITTED).
Readiness response:
{
  "organizationStatus": "ONBOARDING",
  "verificationStatus": "DRAFT",
  "profileIncomplete": true,
  "missingFields": ["bankName: is required", "iban: is required"],
  "missingDocuments": ["REP_ID"],
  "canSubmitVerification": false,
  "canCreateApplication": false,
  "canPublishListing": false,
  "pendingInfoRequestCount": 0
}

Status enums — organization & verification#

EventOrg statusVerification status
RegisterONBOARDINGDRAFT
Submit KYCPENDING_VERIFICATIONSUBMITTED
Admin reviewPENDING_VERIFICATIONUNDER_REVIEW
Admin approveAPPROVEDAPPROVED
Admin rejectREJECTEDREJECTED
Admin requests infoPENDING_VERIFICATIONINFO_REQUESTED
Admin suspendSUSPENDEDSUSPENDED
CHECK
Once org = APPROVED you can create an application.

Responding to information requests#

If the admin needs additional details, verification moves to INFO_REQUESTED.
Each requested item appears as a separate info request.
INFO
When all info requests have been responded to, verification is automatically
resubmitted for review. No separate submit step is needed.
TIP
If the admin requests an edit to an existing field (e.g. "wrong tax number"),
use PATCH /developer-portal/company to update the field first, then
respond to the info request with a message like "Tax number corrected to
1234567890". The admin will see both the updated field and your response when
they review.

List info requests#

GET /developer-portal/company/info-requests — Bearer
Response 200
{
  "infoRequests": [
    {
      "id": "1",
      "request": "Company website not working — please verify",
      "response": null,
      "status": "PENDING",
      "requestedAt": "2026-09-01T08:00:00.000Z",
      "respondedAt": null
    }
  ]
}

Respond to an info request#

POST /developer-portal/company/info-requests/:id/respond — Bearer
{
  "response": "https://www.example.com — site is live"
}
Response 200
{
  "id": "1",
  "status": "RESPONDED",
  "respondedAt": "2026-09-01T10:00:00.000Z",
  "verificationStatus": "SUBMITTED"
}
verificationStatus is non-null when all requests are answered and
verification was auto-resubmitted.

Stage B — Build the service (Days 2–5)#

1.
POST /developer-portal/applications → DRAFT application
(integrationModel: "EMBEDDED").
2.
PATCH /developer-portal/applications/:id — set websiteUrl,
redirectUrls, allowedWebOrigins, partnerApiBaseUrl, supportContact.
3.
POST .../credentials/sandbox/generate — raw key shown once.
4.
PATCH .../listing then add offers/panels.
5.
POST .../listing/submit → listing SUBMITTED.

Offers payload#

{
  "titleEn": "Silver top-up",
  "titleAr": "تعبئة فضية",
  "descriptionEn": "Instant digital top-up",
  "design": "banner",
  "linkType": "offer",
  "url": "https://partner.acme.sa/buy/silver",
  "price": "49.99",
  "originalPrice": "79.99",
  "currency": "SAR",
  "inStock": true,
  "perUserLimit": 5,
  "badgeLabel": "Best seller",
  "badgeColor": "#E8553C",
  "fulfillmentMode": "INSTANT"
}
TIP
Offer price is a decimal string (≤ 7 integer + 2 fraction digits); titles are
capped at 200 chars; a listing holds at most 20 offer cards. For composing
panels, card styles, and layout recipes, see
Panels & storefront.

Fulfillment modes#

INSTANT — order completes immediately (PAYMENT_AUTHORIZED → COMPLETED).
PARTNER_CONFIRMATION — you drive fulfillment via
POST .../orders/:orderId/{confirm|start|complete|cancel}
(PAYMENT_AUTHORIZED → PENDING_PARTNER_CONFIRM → CONFIRMED → IN_PROGRESS → COMPLETED).

Stage C — Go live (Day 6)#

1.
Ensure your webhook endpoint is configured and tested in sandbox.
2.
Listing is PUBLISHED → customers can purchase in the Super App.
3.
Monitor order webhooks and fulfill via confirmation endpoints if needed.

3. The purchase moment (customer side)#

Purchases are idempotent via the x-idempotency-key header — a replayed
key returns the original order instead of charging twice.
If the wallet PIN is missing, the API returns 401 PIN_REQUIRED so the app
shows the PIN sheet and retries with pin.

Settlement — the developer's net#

where S_{net} is the amount settled to your payout account, qty is paid
units, and fee_{processing} is DigetPay's processing fee. Settlement events
arrive as webhook settlement.completed.

Order status enum#

StatusMeaning
CREATEDDraft order row created
PENDING_PAYMENTCharge initiated against the card
PAYMENT_AUTHORIZEDCharge captured, awaiting fulfillment
PENDING_PARTNER_CONFIRMWaiting for partner confirm
CONFIRMEDPartner acknowledged the order
IN_PROGRESSPartner is fulfilling (start)
COMPLETEDFulfilled (complete) / instant
CANCELLEDPartner cancelled
FAILEDPayment failed / expired
REFUND_PENDING / REFUNDEDRefund underway / completed

4. Orders endpoints#

MethodEndpointPurpose
GET/developer-portal/applications/:id/ordersMarketplace orders for your app
GET/developer-portal/applications/:id/transactionsSame data as a sales ledger
POST/developer-portal/applications/:id/orders/:orderId/:actionAdvance an order

4.1 List application orders#

Response 200 — { items, meta }
{
  "id": "1024",
  "status": "COMPLETED",
  "fulfillmentStatus": "COMPLETED",
  "fulfillmentMode": "INSTANT",
  "offer": { "offerId": "12", "titleEn": "Silver top-up", "price": "49.99", "currency": "SAR", "quantity": 1 },
  "fulfillment": { "type": "deeplink", "url": "https://partner.acme.sa/redeem/7f3a…", "token": null, "allowedOrigins": [] },
  "createdAt": "2026-08-18T10:04:12.000Z"
}

4.2 Advance an order (partner-confirmation models)#

ActionMeaningAllowed from
confirmAccept the orderPENDING_PARTNER_CONFIRM
startBegin fulfillmentCONFIRMED
completeFinish fulfillmentIN_PROGRESS
cancelCancel (money refund flows separately)PENDING_PARTNER_CONFIRM
DANGER
cancel does not itself move money back. Refunds are driven by the refund
workflow / gateway and surface via the payment.refunded webhook.
CAUTION
Order actions are validated transitions — an illegal transition returns 400.
Take the order status from the webhook, not from a local cache.

5. Webhook endpoints#

MethodEndpointPurpose
GET.../applications/:appId/webhooks/catalogRead the event catalog
GET.../applications/:appId/webhooksList endpoints
POST.../applications/:appId/webhooksCreate an endpoint
PATCH.../applications/:appId/webhooks/:endpointIdUpdate URL/events/active
DELETE.../applications/:appId/webhooks/:endpointIdRemove an endpoint
POST.../applications/:appId/webhooks/:endpointId/testSend a signed test delivery
GET.../applications/:appId/webhooks/deliveriesDelivery log for an app

5.1 Create an endpoint#

{
  "environment": "SANDBOX",
  "url": "https://api.acme.sa/webhooks/digetpay",
  "events": ["payment.completed", "order.completed"],
  "retryLimit": 3
}
environment ∈ SANDBOX | PRODUCTION
url must be https
events ≤ 20, chosen from the catalog below
retryLimit ∈ 1–5 (default 3)

5.2 Event catalog#

EventRaised when
application.approvedCompany verification approved
application.rejectedVerification rejected
payment.createdCard charge initiated
payment.completedCharge captured
payment.failedCharge declined / failed
payment.refundedRefund finalized
order.confirmation_requiredWaiting for partner confirm
order.confirmedPartner confirmed
order.in_progressPartner started fulfillment
order.completedFulfillment complete (or INSTANT)
order.cancelledOrder cancelled
order.expiredOrder auto-expired
order.failedOrder failed
service.completedEnd-service milestone completed
settlement.completedA settlement batch was paid out
webhook.connection_testEndpoint /test button (not subscribable)

6. Delivery envelope & signatures#

Every delivery is a POST (10 s timeout) with JSON body:
{
  "event": "payment.completed",
  "environment": "SANDBOX",
  "applicationId": "42",
  "createdAt": "2026-08-18T10:04:12.000Z",
  "data": { "orderId": "1024", "amount": "49.99", "currency": "SAR" }
}
The outer fields (event, environment, applicationId, createdAt) are
always present; the business object lives in data. Prefer the
X-DigetPay-Event header for routing and the event body field for
verification.

Signature construction#

Headers every delivery carries:
HeaderExample value
Content-Typeapplication/json
User-AgentDigetPay-Webhooks/1.0
X-DigetPay-Timestamp1784544252 (Unix seconds)
X-DigetPay-Signaturesha256=… (hex HMAC over {ts}.{rawBody})
X-DigetPay-Eventpayment.completed
🔐
Verify the signature and check X-DigetPay-Timestamp is fresh (e.g. within
±5 minutes) before trusting any payload.
TIP
The webhook is signed with the application's webhook secret, not the API
key. Rotate it via POST .../credentials/{env}/rotate-webhook-secret.

Retry & backoff policy#

AttemptWait before nextTrigger
Any—success = HTTP 2xx
1st~250 msnetwork error, 429, 5xx
2nd~500 mssame
3rd~1 ssame
4th~2 ssame
laststopfailure logged to deliveries
retryLimit caps attempts at 1–5 (default 3).
Non-retryable 4xx responses (e.g. 400) are not retried.
Every attempt is recorded in the deliveries log with httpStatus, attempts,
lastError, and success.

Endpoint test#

POST .../webhooks/:endpointId/test sends a one-shot webhook.connection_test
delivery with data.message = "DigetPay webhook connection test" (no retries)
and returns { httpStatus, success, errorMessage }.

Sample payloads#

payment.failed
settlement.completed

7. Deliveries log#

GET .../webhooks/deliveries?page=1&pageSize=25 returns delivery attempts:
FieldTypeMeaning
endpointIdstringWebhook endpoint that received it
eventTypestringDelivered event
httpStatusnumber?Last HTTP status (null = network error)
successbooleanWhether the last attempt was 2xx
attemptsintegerHow many attempts were made
lastErrorstring?Last failure reason
NOTE
Use the deliveries log to debug silent misses — check that events[]
subscription, active, and retryLimit all look right first.

8. Testing flow (staging walkthrough)#

Register → login → dashboard shows ONBOARDING
Company profile + CR/TAX/REP uploads → readiness clears → submit SUBMITTED
Admin APPROVED → create application (gate removed)
Sandbox credentials generated (raw key captured once)
Webhook endpoint created + /test returns signed delivery
Listing submitted → admin APPROVED/PUBLISHED
Customer purchase → payment.completed + order.completed

9. Go-live checklist#

Endpoint created for PRODUCTION with the full event set you rely on
X-DigetPay-Signature verified on staging
Timestamp freshness (+/-5 min) enforced
Retry handling + deliveries monitoring in place
payment.refunded handled (money can always come back)
Order PARTNER_CONFIRMATION actions tested through complete
CHECK
Orders + signed webhooks cover the runtime contract. Integration is complete
once your endpoint verifies signatures and your fulfillment actions move orders
to COMPLETED.
| Admin suspend | SUSPENDED | SUSPENDED |
CHECK
Once org = APPROVED you can create an application.

Stage B — Build the service (Days 2–5)#

1.
POST /developer-portal/applications → DRAFT application
(integrationModel: "EMBEDDED").
2.
PATCH /developer-portal/applications/:id — set websiteUrl,
redirectUrls, allowedWebOrigins, partnerApiBaseUrl, supportContact.
3.
POST .../credentials/sandbox/generate — raw key shown once.
4.
PATCH .../listing then add offers/panels.
5.
POST .../listing/submit → listing SUBMITTED.

Offers payload#

{
  "titleEn": "Silver top-up",
  "titleAr": "تعبئة فضية",
  "descriptionEn": "Instant digital top-up",
  "design": "banner",
  "linkType": "offer",
  "url": "https://partner.acme.sa/buy/silver",
  "price": "49.99",
  "originalPrice": "79.99",
  "currency": "SAR",
  "inStock": true,
  "perUserLimit": 5,
  "badgeLabel": "Best seller",
  "badgeColor": "#E8553C",
  "fulfillmentMode": "INSTANT"
}
TIP
Offer price is a decimal string (≤ 7 integer + 2 fraction digits); titles are
capped at 200 chars; a listing holds at most 20 offer cards. For composing
panels, card styles, and layout recipes, see
Panels & storefront.

Fulfillment modes#

INSTANT — order completes immediately (PAYMENT_AUTHORIZED → COMPLETED).
PARTNER_CONFIRMATION — you drive fulfillment via
POST .../orders/:orderId/{confirm|start|complete|cancel}
(PAYMENT_AUTHORIZED → PENDING_PARTNER_CONFIRM → CONFIRMED → IN_PROGRESS → COMPLETED).

Stage C — Go live (Day 6)#

1.
Ensure your webhook endpoint is configured and tested in sandbox.
2.
Listing is PUBLISHED → customers can purchase in the Super App.
3.
Monitor order webhooks and fulfill via confirmation endpoints if needed.

3. The purchase moment (customer side)#

Purchases are idempotent via the x-idempotency-key header — a replayed
key returns the original order instead of charging twice.
If the wallet PIN is missing, the API returns 401 PIN_REQUIRED so the app
shows the PIN sheet and retries with pin.

Settlement — the developer's net#

where S_{net} is the amount settled to your payout account, qty is paid
units, and fee_{processing} is DigetPay's processing fee. Settlement events
arrive as webhook settlement.completed.

Order status enum#

StatusMeaning
CREATEDDraft order row created
PENDING_PAYMENTCharge initiated against the card
PAYMENT_AUTHORIZEDCharge captured, awaiting fulfillment
PENDING_PARTNER_CONFIRMWaiting for partner confirm
CONFIRMEDPartner acknowledged the order
IN_PROGRESSPartner is fulfilling (start)
COMPLETEDFulfilled (complete) / instant
CANCELLEDPartner cancelled
FAILEDPayment failed / expired
REFUND_PENDING / REFUNDEDRefund underway / completed

4. Orders endpoints#

MethodEndpointPurpose
GET/developer-portal/applications/:id/ordersMarketplace orders for your app
GET/developer-portal/applications/:id/transactionsSame data as a sales ledger
POST/developer-portal/applications/:id/orders/:orderId/:actionAdvance an order

4.1 List application orders#

Response 200 — { items, meta }
{
  "id": "1024",
  "status": "COMPLETED",
  "fulfillmentStatus": "COMPLETED",
  "fulfillmentMode": "INSTANT",
  "offer": { "offerId": "12", "titleEn": "Silver top-up", "price": "49.99", "currency": "SAR", "quantity": 1 },
  "fulfillment": { "type": "deeplink", "url": "https://partner.acme.sa/redeem/7f3a…", "token": null, "allowedOrigins": [] },
  "createdAt": "2026-08-18T10:04:12.000Z"
}

4.2 Advance an order (partner-confirmation models)#

ActionMeaningAllowed from
confirmAccept the orderPENDING_PARTNER_CONFIRM
startBegin fulfillmentCONFIRMED
completeFinish fulfillmentIN_PROGRESS
cancelCancel (money refund flows separately)PENDING_PARTNER_CONFIRM
DANGER
cancel does not itself move money back. Refunds are driven by the refund
workflow / gateway and surface via the payment.refunded webhook.
CAUTION
Order actions are validated transitions — an illegal transition returns 400.
Take the order status from the webhook, not from a local cache.

5. Webhook endpoints#

MethodEndpointPurpose
GET.../applications/:appId/webhooks/catalogRead the event catalog
GET.../applications/:appId/webhooksList endpoints
POST.../applications/:appId/webhooksCreate an endpoint
PATCH.../applications/:appId/webhooks/:endpointIdUpdate URL/events/active
DELETE.../applications/:appId/webhooks/:endpointIdRemove an endpoint
POST.../applications/:appId/webhooks/:endpointId/testSend a signed test delivery
GET.../applications/:appId/webhooks/deliveriesDelivery log for an app

5.1 Create an endpoint#

{
  "environment": "SANDBOX",
  "url": "https://api.acme.sa/webhooks/digetpay",
  "events": ["payment.completed", "order.completed"],
  "retryLimit": 3
}
environment ∈ SANDBOX | PRODUCTION
url must be https
events ≤ 20, chosen from the catalog below
retryLimit ∈ 1–5 (default 3)

5.2 Event catalog#

EventRaised when
application.approvedCompany verification approved
application.rejectedVerification rejected
payment.createdCard charge initiated
payment.completedCharge captured
payment.failedCharge declined / failed
payment.refundedRefund finalized
order.confirmation_requiredWaiting for partner confirm
order.confirmedPartner confirmed
order.in_progressPartner started fulfillment
order.completedFulfillment complete (or INSTANT)
order.cancelledOrder cancelled
order.expiredOrder auto-expired
order.failedOrder failed
service.completedEnd-service milestone completed
settlement.completedA settlement batch was paid out
webhook.connection_testEndpoint /test button (not subscribable)

6. Delivery envelope & signatures#

Every delivery is a POST (10 s timeout) with JSON body:
{
  "event": "payment.completed",
  "environment": "SANDBOX",
  "applicationId": "42",
  "createdAt": "2026-08-18T10:04:12.000Z",
  "data": { "orderId": "1024", "amount": "49.99", "currency": "SAR" }
}
The outer fields (event, environment, applicationId, createdAt) are
always present; the business object lives in data. Prefer the
X-DigetPay-Event header for routing and the event body field for
verification.

Signature construction#

Headers every delivery carries:
HeaderExample value
Content-Typeapplication/json
User-AgentDigetPay-Webhooks/1.0
X-DigetPay-Timestamp1784544252 (Unix seconds)
X-DigetPay-Signaturesha256=… (hex HMAC over {ts}.{rawBody})
X-DigetPay-Eventpayment.completed
🔐
Verify the signature and check X-DigetPay-Timestamp is fresh (e.g. within
±5 minutes) before trusting any payload.
TIP
The webhook is signed with the application's webhook secret, not the API
key. Rotate it via POST .../credentials/{env}/rotate-webhook-secret.

Retry & backoff policy#

AttemptWait before nextTrigger
Any—success = HTTP 2xx
1st~250 msnetwork error, 429, 5xx
2nd~500 mssame
3rd~1 ssame
4th~2 ssame
laststopfailure logged to deliveries
retryLimit caps attempts at 1–5 (default 3).
Non-retryable 4xx responses (e.g. 400) are not retried.
Every attempt is recorded in the deliveries log with httpStatus, attempts,
lastError, and success.

Endpoint test#

POST .../webhooks/:endpointId/test sends a one-shot webhook.connection_test
delivery with data.message = "DigetPay webhook connection test" (no retries)
and returns { httpStatus, success, errorMessage }.

Sample payloads#

payment.failed
settlement.completed

7. Deliveries log#

GET .../webhooks/deliveries?page=1&pageSize=25 returns delivery attempts:
FieldTypeMeaning
endpointIdstringWebhook endpoint that received it
eventTypestringDelivered event
httpStatusnumber?Last HTTP status (null = network error)
successbooleanWhether the last attempt was 2xx
attemptsintegerHow many attempts were made
lastErrorstring?Last failure reason
NOTE
Use the deliveries log to debug silent misses — check that events[]
subscription, active, and retryLimit all look right first.

8. Testing flow (staging walkthrough)#

Register → login → dashboard shows ONBOARDING
Company profile + CR/TAX/REP uploads → readiness clears → submit SUBMITTED
Admin APPROVED → create application (gate removed)
Sandbox credentials generated (raw key captured once)
Webhook endpoint created + /test returns signed delivery
Listing submitted → admin APPROVED/PUBLISHED
Customer purchase → payment.completed + order.completed

9. Go-live checklist#

Endpoint created for PRODUCTION with the full event set you rely on
X-DigetPay-Signature verified on staging
Timestamp freshness (+/-5 min) enforced
Retry handling + deliveries monitoring in place
payment.refunded handled (money can always come back)
Order PARTNER_CONFIRMATION actions tested through complete
CHECK
Orders + signed webhooks cover the runtime contract. Integration is complete
once your endpoint verifies signatures and your fulfillment actions move orders
to COMPLETED.
Modified at 2026-09-02 09:20:21
Previous
01 - Authentication & Team
Next
03 - Customizing your Marketplace Listing
Built with