Skip to main content

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.

Points issues every merchant two keys per credential pair:
KeyPurposeSent whereSecret?
Public keyIdentifies your merchant on the public Checkout endpoint. Safe to embed in browser/mobile code.Inside the URL path: POST /v1/orders/checkout/{publicKey}No
Private keyAuthenticates server-to-server API calls on behalf of your merchant.x-api-key header on every authenticated requestYes — never expose
The Private key is equivalent to a password for your merchant account. Anyone holding it can create and refund orders. Treat it like a production database password.

Get your keys

1

Sign in

2

Open Settings → API Keys

Both keys for your merchant are listed on this page.
3

Copy the values

Click to copy each key. Store the Private key in your server-side secrets manager (AWS Secrets Manager, HashiCorp Vault, .env — wherever you keep production secrets).
4

(Optional) Rotate

Use Regenerate to rotate a key. The old key is revoked immediately — deploy the new key first.

Using the Private key (authenticated endpoints)

Every endpoint except the public Checkout endpoint requires the x-api-key header:
POST /api/v1/orders/earning HTTP/1.1
Host: business.papp.sa
x-api-key: YOUR_PRIVATE_KEY
Content-Type: application/json
Accept: application/json

{ ... }
If the header is missing or the key is invalid/inactive, the API returns:
{
  "status": false,
  "message": "Invalid or inactive API key",
  "appended_data": {}
}
with HTTP status 400.

Example — earning order

curl -X POST https://business.papp.sa/api/v1/orders/earning \
  -H "x-api-key: $POINTS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "phone_number": "512345678", "total_price": 50, "order_number": "A-1", "products": [{"product_name":"Tea","product_price":50,"quantity":1}] }'

Using the Public key (Checkout endpoint)

The redirect-to-checkout flow uses the Public key embedded in the URL path. No x-api-key header is needed because this endpoint is designed to be called from the customer’s browser:
curl -X POST https://business.papp.sa/api/v1/orders/checkout/YOUR_PUBLIC_KEY \
  -H "Content-Type: application/json" \
  -d '{ "total_price": 150.75, "order_number": "ORD-1", "products": [...] }'
The response returns a checkout_url that you redirect the customer to. See Checkout flow for the full sequence.
The Public key does not grant read access to orders or any other merchant data. It only authorises creating checkout sessions for your merchant.

Active state vs. integration state

Every key carries two independent flags — they answer different questions:
FlagQuestion it answersSet by
statusIs this API key valid for HTTP auth?The dashboard (you, or an admin disabling a leaked key). Driving the ApiKeyAuth.active() scope.
integration_activeHas the merchant currently toggled the Points integration ON in their external platform?External platforms via POST /v1/integration/status (Matajer’s “ربط بوينتس” switch today).
Both must be true for the merchant dot on the admin /merchants listing to be green. The split keeps a leaked-key kill switch separate from the merchant’s day-to-day on/off toggle — disabling a key for security reasons doesn’t pretend the merchant opted out of the integration, and the merchant toggling off doesn’t invalidate the key (so the next toggle-back-on works with the same key).
Pure API integrators (no Matajer / Salla connection) usually have integration_active = true from the moment the key is generated — it defaults to true and there’s nothing to flip it. The flag matters for platforms that gate the integration behind their own UI switch.

Rotating keys

Rotate immediately if you suspect leakage (committed to git, shared in chat, old employee, etc.):
1

Generate a new Private key in the dashboard

Go to Settings → API Keys → Regenerate. The new key is returned once; copy it immediately.
2

Deploy the new key to all production services

Update your secrets store and redeploy. For zero-downtime rotation, dual-write to both keys briefly if your deployment is staggered.
3

Confirm no traffic on the old key

Watch the dashboard API log for a full traffic cycle (e.g. 1 hour) before considering the rotation complete.

Environments

Production and sandbox environments use separate keys. Keys from one environment never authenticate against the other.
EnvironmentDashboardAPI base URL
Productionbusiness.papp.sahttps://business.papp.sa/api/v1
Sandboxsandbox.papp.sahttps://sandbox.papp.sa/api/v1
To request sandbox credentials, email support@papp.sa.

Best practices

Never put it in client-side JavaScript, mobile apps, public repositories, CI logs, or customer-facing config files. Only your backend should ever see it.
Keep the key out of source control. Load it at runtime from environment variables (POINTS_API_KEY) or a managed secret store (AWS Secrets Manager, GCP Secret Manager, Vault).
If multiple internal services call Points, consider provisioning separate keys per service so you can rotate individually and audit traffic by key.
Rotation is cheap and the old key is revoked instantly. When in doubt, rotate.
A sudden spike in Invalid or inactive API key responses can signal a stale key in a newly deployed service, or a leaked key being probed.

Next steps

Security

TLS, IP allow-listing, webhook secrets, and related hardening.

Quick start

Ready with a key? Make your first call.