Points supports three independent earning channels. You can integrate one, two, or all three — each channel is opt-in and shares the same API key, lock, response shape, and pending-customer handling.Documentation Index
Fetch the complete documentation index at: https://docs.papp.sa/llms.txt
Use this file to discover all available pages before exploring further.
| Channel | Trigger | Endpoint |
|---|---|---|
| Order purchase | Customer completes a purchase | POST /v1/orders/earning |
| Store rating | Customer rates your store | POST /v1/orders/earning/store-rating |
| Product rating | Customer rates a product | POST /v1/orders/earning/product-rating |
How earning amounts are decided
The merchant controls the points amount, not the API caller. Each channel reads its configured rate from the merchant’s Points dashboard:- Order purchase — points scale with
total_priceand a per-merchant multiplier. Specific products can be assigned a custom point value that overrides the default. - Store rating — flat amount per accepted store rating.
- Product rating — flat amount per accepted product rating.
A channel must be enabled and funded in the merchant’s dashboard before its endpoint will award points. If the channel is disabled, the API returns
403.Shared behavior across all channels
All three earning endpoints share these guarantees so your integration logic stays uniform:- Authentication. Same
x-api-keyheader (see API keys). - Concurrency. Each merchant is serialized through a distributed lock. Send earning calls sequentially per merchant; retry
429with a short back-off. - Idempotency. Each request carries a merchant-side unique reference (
order_numberfor purchases,review_referencefor ratings). Reuse the same reference on retries — duplicates are rejected, not double-awarded. - Pending customers. If the customer’s Points account is not yet activated, the response returns a
pending_client_activationpayload instead of an approved order. The earning is queued and finalized when the customer activates. - Response shape. Same
data.uuid,data.reference_number,data.order_status, anddata.total_pointsfields. Store theuuidfor later lookups, refunds, and reconciliation.
Pending-customer response (any channel)
Order purchase
Award points to a customer for a completed purchase. This is the most common channel — use it when your checkout system runs entirely on your side and you want to reward the payment.Flow
Required inputs
| Field | Required | Notes |
|---|---|---|
phone_number | Yes | KSA mobile, normalised server-side to 5XXXXXXXX |
total_price | Yes | Total paid amount in SAR |
order_number | Yes | Your merchant-side unique order reference |
products | Yes | Array with at least one item |
metadata | No | Useful for channel, branch, POS context |
Example request
Successful response
When to call the API
CallPOST /v1/orders/earning only after the purchase is actually confirmed in your own system, such as:
- successful PSP callback
- order marked paid in POS
- COD order marked collected
Store rating
Award points when a customer submits a rating for your store overall.Flow
Required inputs
| Field | Required | Notes |
|---|---|---|
phone_number | Yes | KSA mobile, normalised server-side to 5XXXXXXXX |
review_reference | Yes | Your platform’s unique identifier for this rating — used for idempotency |
rating | No | Star value (1–5). Stored for audit only — does not change the points awarded |
comment | No | Free-text review body. Stored for audit only |
metadata | No | Free-form object for channel, branch, source, etc. |
The merchant configures the points amount in the Points dashboard under Earning methods → Store rating. Your request body does not carry the points value.
Example request
Successful response
When to call the API
Call the endpoint only after the rating is accepted in your own system — i.e. it has passed moderation, spam checks, or any minimum-content rules. Do not call it for drafts, deleted reviews, or duplicate submissions. If the customer edits or deletes their rating later, the awarded points are not automatically reversed. Treat the API call as a one-shot reward at submission time.Product rating
Award points when a customer submits a rating for a specific product they purchased.Flow
Required inputs
| Field | Required | Notes |
|---|---|---|
phone_number | Yes | KSA mobile, normalised server-side to 5XXXXXXXX |
review_reference | Yes | Your platform’s unique identifier for this rating — used for idempotency |
product_id | Yes | Your platform’s product identifier (SKU or internal ID) |
product_name | No | Human-readable product name. Stored for audit |
rating | No | Star value (1–5). Stored for audit only |
comment | No | Free-text review body. Stored for audit only |
metadata | No | Free-form object for channel, branch, source, etc. |
The merchant configures the points amount in the Points dashboard under Earning methods → Product rating. Your request body does not carry the points value.
Example request
Successful response
When to call the API
Call the endpoint only after the rating is accepted in your own system — i.e. it has passed moderation, the customer is verified to have purchased the product, and the rating is not a draft. Do not call it for deleted or duplicate submissions. If the customer edits or deletes their rating later, the awarded points are not automatically reversed.Common errors (all channels)
| HTTP status | Meaning | What to do |
|---|---|---|
400 | Missing or invalid API key | Verify x-api-key and environment |
403 | Merchant unverified/unpublished or this earning channel disabled | Ask the merchant to enable the channel in the dashboard |
422 | Validation error | Check required fields for that channel |
429 | Concurrent earning requests for the same merchant | Retry with back-off |
Recommended reconciliation
- Create the earning record after the upstream event (payment / rating) is confirmed on your side.
- Store the returned
uuidagainst your own record. - If your worker crashes between the upstream event and the Points call, use your stored merchant reference (
order_numberorreview_reference) to detect the partially completed step on retry. - For disputes or support, fetch the order later with
GET /v1/orders/{uuid}.
Next
Quick start
Make your first earning call end-to-end.
Refunds & cancellations
What happens when an awarded order is later refunded.
Order lifecycle
State transitions, statuses, and webhooks.
Go-live checklist
Verify production readiness before launch.

