SADAD Integration Cheatsheet
1. SADAD Overview
Section titled “1. SADAD Overview”SADAD is the national Electronic Bill Presentment and Payment (EBPP) system for Saudi Arabia, operated under the Saudi Central Bank (SAMA). It provides a centralized platform for presenting and paying bills (utilities, government fees, taxes, telecom, etc.) via all Saudi banks and selected digital channels.
SADAD works with all Saudi banks and digital wallets, allowing customers to pay bills through ATMs, internet banking, phone banking, mobile apps, and other electronic channels, while billers interact with SADAD via their sponsoring bank.
SADAD Account (also called SADAD Online Payment or OLP) is a related service that enables real‑time, non‑card e‑commerce payments by debiting a designated “light account” at the issuing bank during online checkout, typically using an alias or SADAD ID instead of a card number.
SADAD Bills vs SADAD Account
Section titled “SADAD Bills vs SADAD Account”| Aspect | SADAD Bills (EBPP) | SADAD Account (OLP / SADAD Number) |
|---|---|---|
| Primary use case | Recurring and one‑off bills (utilities, government, telecom, etc.) | E‑commerce checkout, direct online payments |
| Payment channel | Bank channels (ATM, online banking, mobile app, IVR, branch) | Merchant checkout flows via SADAD platform and bank portals |
| Flow | Biller uploads bills to SADAD via bank; customers query and pay via bank; SADAD settles and reconciles daily | Customer selects SADAD at checkout, authenticates via bank, funds debited in real time to merchant |
| Identifier | Biller ID + bill/invoice reference | SADAD Account ID / alias or SADAD Number code |
| Settlement | Batch settlement via SARIE and daily reports | Typically real‑time or near real‑time settlement to merchant account |
Role in the Saudi payments ecosystem
Section titled “Role in the Saudi payments ecosystem”- Core rail for bill payments and government fees; cabinet resolutions require government entities collecting revenues electronically to integrate via SADAD.
- Complements other rails like MADA (domestic card network), credit/debit cards, and newer wallets by giving a familiar alternative that uses existing bank accounts, not cards.
When to use SADAD vs MADA / card payments
Section titled “When to use SADAD vs MADA / card payments”- Use SADAD when:
- Dealing with government, utilities, or regulated bill‑like payments.
- Customers are used to paying via their bank channels (billers list, SADAD Number) rather than card entry.
- You need guaranteed funds from the customer’s bank account with low fraud risk and strong customer authentication.
- Use MADA/cards when:
- Classic e‑commerce with cardholder experience optimization (one‑click, saved cards).
- International cards or non‑Saudi customers.
- You rely on PSP risk tools and card‑network chargebacks.
⚠️ SADAD is strongly regulated; any integration must follow the sponsoring bank/PSP’s onboarding, security, and certification processes.
2. Integration Models
Section titled “2. Integration Models”Because SADAD itself does not expose a single public API, integration is typically via banks or PSPs that provide their own REST/SOAP interfaces.
2.1 Direct integration via bank (EBPP / SADAD Bills)
Section titled “2.1 Direct integration via bank (EBPP / SADAD Bills)”- You onboard as a biller with a specific bank (or multiple banks) that sponsors you into SADAD.
- The bank exposes:
- File‑based or API‑based bill upload interface (batch or real time).
- Payment notification / settlement reports (often files or SFTP + portal).
- Optional online APIs for inquiry and payment notifications.
- Common tech characteristics:
- VPN or leased line connectivity, mutual TLS, sometimes SOAP or ISO‑8583 with bank‑specific schemas.
- Strict change control, long lead times for onboarding and certification.
2.2 Integration via PSP (HyperPay, PayTabs, others)
Section titled “2.2 Integration via PSP (HyperPay, PayTabs, others)”- PSP exposes a unified REST API and/or hosted payment page that includes SADAD as a payment option; under the hood, PSP connects to banks/SADAD.
- Typical features:
- PSP‑managed SADAD onboarding.
- One contract and settlement channel for multiple payment methods (MADA, cards, SADAD, wallets).
- Sandbox/testing environments and developer documentation for integration.
2.3 Hosted vs API‑based flows
Section titled “2.3 Hosted vs API‑based flows”| Model | Description | Pros | Cons |
|---|---|---|---|
| Hosted page (PSP) | Customer is redirected (or embedded iFrame) to PSP page that offers SADAD, cards, etc. Payment result sent via redirect + webhook | Fast to integrate, PSP handles UX, security, and certifications | Less control over UX, PSP‑specific limitations |
| API‑based (server‑to‑server) | Your backend calls PSP/bank APIs to create SADAD bills or payment sessions; front‑end uses bank/PSP URLs or SADAD references | More control, easier multi‑channel flows (web, app, POS) | Higher responsibility for security, error handling, PCI‑adjacent concerns |
2.4 Trade‑offs
Section titled “2.4 Trade‑offs”- Direct‑via‑bank: ✅ deeper control, potentially better fees; ⚠️ higher complexity, slower onboarding, multi‑bank differences.
- Via PSP: ✅ faster time‑to‑market, unified API, better documentation; ⚠️ PSP lock‑in, extra fees, need abstraction layer to switch providers.
3. Key Concepts & Terminology
Section titled “3. Key Concepts & Terminology”- Biller ID: Unique numeric identifier assigned by SADAD to each biller (e.g., utility company, government agency, private merchant).
- SADAD Account / OLP ID: Alias‑based online payment account for e‑commerce (light account) that customers register with their bank; used at checkout instead of card number.
- Invoice/Bill ID (Customer Reference): Biller‑side reference for a specific bill; combined with Biller ID to uniquely identify the obligation in SADAD.
- SADAD Number / Payment Reference:
- For SADAD Bills: reference number exposed to customer for bank payment (may be customer number or invoice reference, depending on biller design).
- For PSP‑style SADAD: PSP often generates a SADAD Number code which the customer uses in their bank app to complete payment.
- Reconciliation:
- Process of matching SADAD‑reported paid bills with internal invoices, based on Biller ID, reference number, amount, value date, and banking transaction IDs.
4. End‑to‑End Payment Flow
Section titled “4. End‑to‑End Payment Flow”4.1 SADAD Bills (EBPP) – High‑level steps
Section titled “4.1 SADAD Bills (EBPP) – High‑level steps”- Biller sends summary bill information to SADAD at a pre‑determined schedule via its sponsoring bank.
- SADAD validates and loads bills into its database, notifies biller of any discrepancies.
- Customer queries and views bills through bank channels (ATM, online banking, mobile app, etc.).
- Bank forwards inquiry to SADAD; SADAD returns bill details from its database.
- Customer selects bill(s) and confirms payment; bank debits customer account and confirms transaction.
- SADAD updates its database and notifies relevant biller(s) of successful payments.
- At end of day, SADAD initiates settlement via SARIE and sends reconciliation reports to billers.
4.2 Text‑based sequence diagram – Direct bill flow
Section titled “4.2 Text‑based sequence diagram – Direct bill flow”Participant Merchant SystemParticipant Sponsor BankParticipant SADADParticipant Customer BankParticipant Customer
Merchant System->Sponsor Bank: Upload bills (batch/API) with Biller ID + Bill RefSponsor Bank->SADAD: Forward billsSADAD->Sponsor Bank: Validation resultSponsor Bank->Merchant System: Acknowledgement / rejections
Customer->Customer Bank: Open channels (ATM / online / mobile) and list billsCustomer Bank->SADAD: Request bills for Biller ID / customerSADAD->Customer Bank: Bill list + amounts + due datesCustomer->Customer Bank: Select bill(s) and confirm paymentCustomer Bank->SADAD: Confirm payment(s)SADAD->Customer Bank: Payment status OKSADAD->Sponsor Bank: Notify paymentsSponsor Bank->Merchant System: Payment notification(s)SADAD->SARIE: Settlement instructions (batch)SARIE->Sponsor Bank: Settlement to biller account4.3 Text‑based sequence – PSP‑style SADAD Number flow (e‑commerce)
Section titled “4.3 Text‑based sequence – PSP‑style SADAD Number flow (e‑commerce)”Participant CustomerParticipant Merchant FrontendParticipant Merchant BackendParticipant PSP (e.g., PayTabs)Participant SADAD / Bank
Customer->Merchant Frontend: Place order, select "SADAD" as payment methodMerchant Frontend->Merchant Backend: Create orderMerchant Backend->PSP: Create SADAD payment (amount, orderId, callback URLs)PSP->Merchant Backend: Payment session + SADAD Number (code)Merchant Backend->Merchant Frontend: SADAD Number + redirect URLMerchant Frontend->Customer: Show SADAD Number and instructionsCustomer->Bank App: Enter SADAD Number and confirm paymentBank App->SADAD/Bank: Debit customer and confirm SADAD paymentSADAD/Bank->PSP: Notify payment successPSP->Merchant Backend (webhook): Payment status = PAIDMerchant Backend->Merchant Frontend: Update UI (order paid)5. API Design & Integration Pattern
Section titled “5. API Design & Integration Pattern”Because bank and PSP APIs are heterogeneous, design your internal interface as an abstraction with provider‑specific adapters.
5.1 Internal REST API (example)
Section titled “5.1 Internal REST API (example)”Assume an internal PaymentService that exposes generic endpoints independent of bank/PSP:
POST /api/payments/sadad/billsGET /api/payments/sadad/bills/{billId}GET /api/payments/sadad/bills/{billId}/statusPOST /api/payments/sadad/webhooks/{provider}Payload example for bill creation (internal representation):
{ "orderId": "ORD-2026-000123", "customerId": "CUST-1001", "amount": 150.75, "currency": "SAR", "description": "Electricity Bill March 2026", "expiryDate": "2026-04-15T23:59:59Z", "channel": "SADAD_NUMBER", "provider": "PAYTABS"}5.2 Provider adapter pattern
Section titled “5.2 Provider adapter pattern”- Define a
SadadProviderClientinterface:createBill(...)– returns provider bill/payment reference (e.g., SADAD Number, bank bill ID).queryStatus(...)– returns normalized status (PENDING, PAID, EXPIRED, FAILED).handleWebhook(...)– maps provider‑specific webhook to internal event.
- Implement
PayTabsSadadClient,HyperPaySadadClient,BankXSadadClient, each mapping internal DTOs to provider‑specific payloads and endpoints.
5.3 Sync vs async flows
Section titled “5.3 Sync vs async flows”- Sync:
createBillreturns SADAD Number/URL immediately.- Status remains PENDING until customer pays via bank.
- Async:
- PSP/bank sends webhook/notification when payment is completed (or failed).
- Your system updates invoice/order status and emits domain events.
⚠️ Never assume payment is completed synchronously at checkout; SADAD is inherently async when customer must complete payment in their bank app/portal.
5.4 Sample curl for internal gateway
Section titled “5.4 Sample curl for internal gateway”curl -X POST https://merchant.example.com/api/payments/sadad/bills \ -H "Content-Type: application/json" \ -d '{ "orderId": "ORD-2026-000123", "customerId": "CUST-1001", "amount": 150.75, "currency": "SAR", "description": "Order #123", "expiryDate": "2026-04-15T23:59:59Z", "channel": "SADAD_NUMBER", "provider": "PAYTABS" }'6. Java Spring Boot Implementation
Section titled “6. Java Spring Boot Implementation”6.1 Module architecture
Section titled “6.1 Module architecture”applicationlayer (REST controllers): exposes payment APIs to front‑ends and internal services.domainlayer:- Aggregates:
Payment,SadadBill,ReconciliationEntry. - Services:
SadadPaymentService,ReconciliationService.
- Aggregates:
infrastructurelayer:- Provider clients:
PayTabsSadadClient,BankXSadadClient. - HTTP clients (WebClient), persistence repositories (JPA), outbox/event publisher.
- Provider clients:
6.2 DTOs
Section titled “6.2 DTOs”public record CreateSadadBillRequest( String orderId, String customerId, BigDecimal amount, String currency, String description, Instant expiryDate, String channel, String provider) {}
public record CreateSadadBillResponse( String paymentId, String provider, String providerReference, String sadadNumber, URI bankPaymentUrl, String status) {}6.3 Service interface
Section titled “6.3 Service interface”public interface SadadPaymentService { CreateSadadBillResponse createSadadBill(CreateSadadBillRequest request); PaymentStatusResponse getPaymentStatus(String paymentId); void handleProviderWebhook(String provider, String payload, Map<String, String> headers);}6.4 Spring WebClient configuration
Section titled “6.4 Spring WebClient configuration”@Configurationpublic class HttpClientConfig {
@Bean public WebClient payTabsWebClient(@Value("${paytabs.base-url}") String baseUrl) { return WebClient.builder() .baseUrl(baseUrl) .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .build(); }
@Bean public WebClient bankXWebClient(@Value("${bankx.base-url}") String baseUrl) { return WebClient.builder() .baseUrl(baseUrl) .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .build(); }}6.5 Provider client example (PSP)
Section titled “6.5 Provider client example (PSP)”@Componentpublic class PayTabsSadadClient implements SadadProviderClient {
private final WebClient webClient; private final String profileId; private final String serverKey;
public PayTabsSadadClient( @Qualifier("payTabsWebClient") WebClient webClient, @Value("${paytabs.profile-id}") String profileId, @Value("${paytabs.server-key}") String serverKey) { this.webClient = webClient; this.profileId = profileId; this.serverKey = serverKey; }
@Override public ProviderCreateResponse createBill(ProviderCreateRequest request) { return webClient.post() .uri("/payment/request") .header("authorization", serverKey) .bodyValue(toPayTabsPayload(request)) .retrieve() .onStatus(HttpStatusCode::isError, response -> response.bodyToMono(String.class) .map(body -> new ProviderException("PayTabs error: " + body))) .bodyToMono(ProviderCreateResponse.class) .block(); }
// map to/from PSP payloads...}6.6 Controller example
Section titled “6.6 Controller example”@RestController@RequestMapping("/api/payments/sadad")public class SadadPaymentsController {
private final SadadPaymentService sadadPaymentService;
public SadadPaymentsController(SadadPaymentService sadadPaymentService) { this.sadadPaymentService = sadadPaymentService; }
@PostMapping("/bills") public ResponseEntity<CreateSadadBillResponse> createBill(@RequestBody CreateSadadBillRequest request) { CreateSadadBillResponse response = sadadPaymentService.createSadadBill(request); return ResponseEntity.status(HttpStatus.CREATED).body(response); }
@GetMapping("/bills/{paymentId}/status") public PaymentStatusResponse getStatus(@PathVariable String paymentId) { return sadadPaymentService.getPaymentStatus(paymentId); }}6.7 Exception handling strategy
Section titled “6.7 Exception handling strategy”- Use
@ControllerAdviceto map provider/bank errors to standardized error responses. - Distinguish between:
- Business errors (e.g., bill already paid, expired) → 409 / 422.
- Technical errors (timeouts, 5xx) → 502 / 503.
- Log all provider responses with correlation IDs, but never log sensitive data.
✅ Implement circuit breakers and retries at the provider client level (see section 11).
7. Webhooks / Notifications
Section titled “7. Webhooks / Notifications”7.1 Asynchronous confirmation
Section titled “7.1 Asynchronous confirmation”- PSPs and some banks send webhooks or notifications when SADAD payments are completed.
- Design a single
/api/payments/sadad/webhooks/{provider}endpoint that delegates to provider‑specific handlers.
@PostMapping("/webhooks/{provider}")public ResponseEntity<Void> handleWebhook( @PathVariable String provider, @RequestHeader Map<String, String> headers, @RequestBody String payload) { sadadPaymentService.handleProviderWebhook(provider, payload, headers); return ResponseEntity.ok().build();}7.2 Security
Section titled “7.2 Security”- IP whitelisting: restrict webhook source IPs to PSP/bank ranges (enforced at network or WAF level).
- Signatures: verify HMAC or signature headers if PSP/bank supports it (e.g.,
X-Signatureor similar). - TLS: enforce HTTPS with strong ciphers.
⚠️ Never trust only the redirect/return URL for payment success; always rely on webhook+server‑to‑server status confirmation.
7.3 Idempotency & retries
Section titled “7.3 Idempotency & retries”- Webhooks may be delivered multiple times; implement idempotent processing:
- Use unique provider transaction ID as idempotency key.
- Persist processed events with status; ignore duplicates.
- Retry‑safe processing steps:
- Use transactional outbox: update payment state and publish domain events atomically.
8. Reconciliation & Reporting
Section titled “8. Reconciliation & Reporting”8.1 Daily reconciliation
Section titled “8.1 Daily reconciliation”- SADAD provides reconciliation reports to billers via sponsoring banks, typically daily, with detailed breakdown of processed transactions.
- PSPs provide transaction reports for SADAD payments via portals and APIs.
8.2 Matching algorithm
Section titled “8.2 Matching algorithm”- Match items based on:
- Biller ID (if available in reports).
- Internal
orderIdorbillRefvs SADAD reference. - Amount, value date, customer ID where available.
- Use a three‑way match when possible: internal invoice, SADAD/PSP transaction, and bank statement.
8.3 Handling mismatches & disputes
Section titled “8.3 Handling mismatches & disputes”- Mismatches:
- Payment in SADAD but not in internal system → create suspense entries and investigate.
- Internal
PAIDbut missing in SADAD report → escalate to bank/PSP.
- Disputes and refunds:
- SADAD Account supports refund and dispute flows via consumer portal and bank; merchants often trigger refunds via bank/PSP portals or APIs.
8.4 Reporting
Section titled “8.4 Reporting”- Build internal reports for:
- Collected amount per day per channel (SADAD vs MADA/cards).
- Ageing of unpaid SADAD bills.
- Failure reasons (expired, customer cancelled, technical errors).
9. Error Handling & Edge Cases
Section titled “9. Error Handling & Edge Cases”- Duplicate bill IDs:
- Detect in your domain (unique constraint on
orderId+channel). - If provider reports duplicate, map to
409 CONFLICTfor callers.
- Detect in your domain (unique constraint on
- Delayed payments:
- SADAD allows payments as long as bills are not expired; customers may pay close to expiry.
- Design logic to accept late but valid payments and adjust fulfilment flows accordingly.
- Partial payments:
- Many government/utility bills are full‑amount only; partial payment rules are biller‑specific.
- Explicitly model whether a SADAD bill supports partial or full payment only; validate before creating bills.
- Timeouts and retries:
- For provider calls, use timeouts (e.g., 3–5 seconds) and limited retries with backoff.
- Do not retry non‑idempotent operations (e.g.,
createBill) without idempotency keys.
⚠️ Never assume bank/PSP guarantees single delivery or exactly‑once semantics; design for at‑least‑once notifications and at‑least‑once execution.
10. Security & Compliance
Section titled “10. Security & Compliance”Saudi regulatory considerations
Section titled “Saudi regulatory considerations”- SADAD is under SAMA; government entities collecting revenues must use SADAD for e‑payments, and SADAD is considered a critical national payment system.
- Banks and PSPs will require security assessments, penetration tests, and possibly SAMA‑aligned controls.
Data protection
Section titled “Data protection”- Treat SADAD identifiers and bank account references as sensitive.
- Avoid storing unnecessary PII; tokenize where possible.
Communication security
Section titled “Communication security”- Use VPN or dedicated links with banks; mutual TLS in all server‑to‑server APIs.
- Enforce strong TLS configuration and regular certificate rotation.
Audit logging
Section titled “Audit logging”- Log all payment lifecycle events (creation, status changes, webhook receipts) with correlation IDs.
- Separate audit logs from application logs for integrity and retention.
⚠️ Avoid logging full bank account numbers, SADAD Account passwords, or any authentication factors.
11. Production Best Practices
Section titled “11. Production Best Practices”11.1 Idempotency keys
Section titled “11.1 Idempotency keys”- For
createBilland similar operations, use a deterministic idempotency key:idempotencyKey = sha256(orderId + channel + provider).- Send this key in a custom header to PSPs that support it; otherwise, enforce idempotency in your own persistence layer.
11.2 Retry and backoff
Section titled “11.2 Retry and backoff”- Implement exponential backoff with jitter for transient provider errors.
- Use different retry policies for read vs write operations.
11.3 Circuit breakers (Resilience4j)
Section titled “11.3 Circuit breakers (Resilience4j)”@Configurationpublic class ResilienceConfig {
@Bean public Customizer<Resilience4JCircuitBreakerFactory> defaultCustomizer() { return factory -> factory.configure(builder -> builder .slidingWindowSize(50) .failureRateThreshold(50) .waitDurationInOpenState(Duration.ofSeconds(30)), "sadadProvider"); }}- Wrap provider client calls with circuit breakers and time limiters to avoid cascading failures.
11.4 Observability
Section titled “11.4 Observability”- Logging:
- Structured logs with
paymentId,orderId,provider,providerTxnId,status.
- Structured logs with
- Metrics:
- Success/failure rates per provider, latency histograms, open circuit counts.
- Tracing:
- Use OpenTelemetry to trace from customer request through your system to PSP/bank and back.
11.5 High availability
Section titled “11.5 High availability”- Run payment services as stateless microservices with horizontal scaling.
- Use a robust database with HA (e.g., managed PostgreSQL with multi‑AZ).
- Design webhook handling and reconciliation jobs to be horizontally scalable (e.g., partition by provider or date).
12. Testing Strategy
Section titled “12. Testing Strategy”12.1 Sandbox and staging
Section titled “12.1 Sandbox and staging”- PSPs usually provide sandbox environments and test credentials for SADAD and other methods.
- Banks may provide certification environments over VPN.
12.2 Mocking SADAD flows
Section titled “12.2 Mocking SADAD flows”- Use provider mocks for:
- Bill creation responses (e.g., fixed SADAD Number for given order IDs).
- Status queries with programmable transitions (PENDING → PAID → SETTLED).
- Simulate webhook calls with
curlto local/staging endpoints.
curl -X POST http://localhost:8080/api/payments/sadad/webhooks/paytabs \ -H "Content-Type: application/json" \ -H "X-Signature: test-signature" \ -d '{ "transaction_reference": "TXN-123", "order_id": "ORD-2026-000123", "payment_method": "SADAD", "result": "SUCCESS" }'12.3 Integration testing
Section titled “12.3 Integration testing”- Contract tests for provider adapters (using WireMock or MockWebServer).
- End‑to‑end tests in staging with real PSP sandbox accounts.
12.4 Failure simulation
Section titled “12.4 Failure simulation”- Simulate:
- PSP/bank timeouts and 5xx errors.
- Duplicate webhooks.
- Late payments (beyond internal reservation time but before SADAD expiry).
✅ Automate replay of reconciliation files or PSP transaction reports into test environments to validate matching logic.
13. Common Pitfalls
Section titled “13. Common Pitfalls”- Misunderstanding async nature:
- Treating SADAD payment as immediate at checkout instead of pending until bank payment completes.
- Incorrect reconciliation:
- Not handling timing differences between SADAD settlement and bank statements.
- Ignoring adjustment/rollback records in reconciliation reports.
- Tight coupling with bank/PSP APIs:
- Hard‑coding provider payloads deep in business logic instead of adapter layer.
- No abstraction for switching providers or adding a second bank.
- Missing idempotency:
- Creating multiple SADAD bills for same order on retries.
- Processing same webhook multiple times.
⚠️ These issues typically surface only at scale during production spikes; design for them from the beginning.
14. Quick Reference
Section titled “14. Quick Reference”14.1 Key fields & formats (generic)
Section titled “14.1 Key fields & formats (generic)”| Field | Example | Notes |
|---|---|---|
| Biller ID | 123 | Assigned by SADAD; numeric. |
| Bill / Customer Ref | 2026-03-INV-0001 | Unique per bill within biller. |
| SADAD Number | 1234567890 | Generated by PSP/bank, used by customer in bank app. |
| Currency | SAR | Saudi Riyal. |
| Amount | 150.75 | Typically up to 2 decimal places. |
| Status | PENDING, PAID, EXPIRED, FAILED | Internal normalized statuses. |
14.2 Sample internal REST payloads
Section titled “14.2 Sample internal REST payloads”Create SADAD bill:
curl -X POST https://merchant.example.com/api/payments/sadad/bills \ -H "Content-Type: application/json" \ -d '{ "orderId": "ORD-2026-000123", "customerId": "CUST-1001", "amount": 150.75, "currency": "SAR", "description": "Order #123", "expiryDate": "2026-04-15T23:59:59Z", "channel": "SADAD_NUMBER", "provider": "PAYTABS" }'Get payment status:
curl -X GET https://merchant.example.com/api/payments/sadad/bills/{paymentId}/status14.3 Flow summary table
Section titled “14.3 Flow summary table”| Scenario | Channel | Core actions | Outcome |
|---|---|---|---|
| EBPP bill payment | Bank ATM/online | Biller uploads bills → Customer selects bill in bank channel → Bank debits account → SADAD settles → Biller receives reports | Bill marked as paid in SADAD and internal system, funds settled next day. |
| E‑commerce SADAD Number | PSP hosted/API | Merchant creates SADAD payment via PSP → Customer gets SADAD Number → Pays via bank app → PSP webhook confirms | Order updated to PAID once webhook processed, fulfilment triggered. |
✅ Keep this cheatsheet alongside bank/PSP‑specific integration manuals to quickly map generic concepts and flows to concrete endpoints and payloads for each provider.