Build with the
JadCoins API
Integrate loyalty points, wallets, and JadCoins into your POS system or application. Everything you need to get started.
Introduction
The JadCoins Integration API allows external businesses and POS systems to integrate with the JadCoins loyalty platform. Through this API, partner companies can manage customers, award loyalty points based on purchases, manage wallets, and process JadCoins payments.
Key Features
Customer Management — Register and manage customer accounts linked to your business.
Points System — Award loyalty points automatically based on purchase amounts with configurable rules.
Auto-Redemption — Points are automatically converted to wallet balance when they reach the threshold.
Wallet System — Customers can use their wallet balance as payment at your business.
JadCoins — A cross-platform coin system that customers can spend across integrated businesses.
SMS Notifications — Automatic SMS for welcome, points earned, and wallet used events.
Authentication
All API requests must include an API key in the request header. Each integrated company receives a unique API key.
Required Header
X-Api-Key: your-api-key-here
Authentication Errors
| Status | Error | Description |
|---|---|---|
401 | Missing X-Api-Key header | The header was not provided in the request. |
401 | Invalid API key | The provided API key does not match any registered company. |
404 | Company not found | The API key is valid but the associated company was not found. |
Base URL & General Information
Base URL
There are two path bases. API-key endpoints live under /api/integration; the two public endpoints live directly under /api (no /integration segment).
https://your-domain.com/api/integration
https://your-domain.com/api
your-domain.com is a placeholder. The repository only configures APP_URL=http://localhost; no production domain is committed. Replace it with your actual host.
Request / Response Format
All requests and responses use application/json. The envelope comes from the ApiResponses trait and has exactly two top-level keys per branch — success returns { value, data } (no msg), a manual error returns { value, msg } (no data). value is true only for HTTP 200/201/202.
Validation Errors (422) — two shapes
Validation failures do not share one shape. Endpoints backed by a FormRequest (check-or-create, earn points, use-wallet, verify company by code) return a Laravel-style body with success/message/errors and no value key. Endpoints using an inline validator (update-profile, both jad-coins endpoints) return the standard { value:false, msg:{…} } envelope where msg is the errors object.
phone_code parameter accepts the + prefix or not (e.g. "+972" or "972") only on the endpoints that normalize it: update-profile, get balance, and both jad-coins endpoints. Exact match (no normalization): check-or-create, points/earn, and use-wallet compare phone_code exactly as sent against the stored code — send it with the +, otherwise the lookup fails with 404 "Customer not found".
API Endpoints
Verify Company
Verify that your API key is valid and retrieve your company details and loyalty configuration.
Parameters
No additional parameters required. Authentication is handled via the X-Api-Key header.
Check or Create Customer
Find an existing customer by phone number or create a new one. The customer will be linked to your company automatically. A welcome SMS is sent to new customers.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Customer phone number |
phone_code | string | Yes | Country phone code (e.g., "+972") |
name | string | Yes | Customer full name |
email | string | No | Customer email address |
national | string | No | National ID or nationality (nullable|string) |
birth_date | date | No | Date of birth (YYYY-MM-DD). When present, the new customer is created with is_profile_complete = true. |
city_id | integer | No | City ID (nullable|exists:cities,id) |
is_new_customer is currently inverted in the code (!$customer->wasRecentlyCreated): a customer that was just created returns is_new_customer: false, while an already-existing customer returns true. Treat this flag with care until it is fixed in the API.
Get Customer Balance
Retrieve the current point balance, wallet balance, and JadCoins balance for a customer.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Customer phone number |
phone_code | string | Yes | Country phone code |
GET /api/integration/customer/balance?phone=0509124719&phone_code=+972 X-Api-Key: your-api-key-here
403 { value:false, msg:"Loyalty program is disabled" } before any customer lookup. The success response includes a nested city object ({ id, name, name_en, name_he }) or null when the customer has no city set. jad_coins reflects the customer's total coins across all operators.
Update Customer Profile
Update a customer's profile. Required before the customer can use their wallet balance. The birth_date field is mandatory to complete the profile.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Customer phone number |
phone_code | string | Yes | Country phone code |
name | string | Yes | Customer full name |
email | string | Yes | Customer email address |
national | string | No | National ID or nationality (nullable|string|max:255) |
birth_date | date | Yes | Date of birth (YYYY-MM-DD) |
city_id | integer | No | City ID (nullable|exists:cities,id) |
is_profile_complete = true. The customer must already exist and be linked to your company. Validation uses an inline validator, so a 422 uses the { value:false, msg:{…} } shape (not the FormRequest shape).
{ "value": false, "msg": "Customer not found" }
{ "value": false, "msg": "Customer is not linked to this company" }
{ "value": false, "msg": "Loyalty program is disabled" }
Earn Points from Purchase
Award loyalty points based on a purchase amount. If the customer's point balance reaches the minimum redemption threshold, points are automatically converted to wallet balance.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Customer phone number |
phone_code | string | Yes | Country phone code |
purchase_amount | number | Yes | The total purchase amount (required|numeric|min:0) |
order_id | string | Yes | Required by validation (required|string). Note: this value is validated but not stored on the transaction. |
reference | string | No | Not validated, but this is the value actually saved as the transaction reference. Omit → stored as null. |
msg for the 400 errors is an object { points_earned, message }, not a string. A purchase above max_purchase_amount is rejected with a 400 here (it is not capped). If the customer cannot be found, this endpoint returns 403 "Customer not found" (not 404). Points are floored to a whole number before crediting.
Use Wallet Balance
Deduct from the customer's wallet as payment. Profile must be complete. If allow_points_on_redemption is enabled, points are also earned.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Customer phone number |
phone_code | string | Yes | Country phone code |
amount | number | Yes | Amount to deduct from wallet (required|numeric|min:0.01) |
purchase_amount | number | No | Total purchase amount used to earn points (nullable|numeric|min:0). Only relevant when allow_points_on_redemption is enabled. |
reference | string | No | Your order/invoice reference (nullable|string|max:255) |
earned_points is 0 unless allow_points_on_redemption is enabled for the company; when enabled, points are earned from purchase_amount and the auto-redeem loop may also run. Other errors: 403 "Please complete your profile firstly" (profile incomplete), 404 "Customer not found", 403 "Loyalty program is disabled". Validation failures use the FormRequest 422 shape.
Check JadCoins Balance
Check a customer's JadCoins balance. JadCoins are a cross-platform currency from operators.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customer_id | integer | No | Customer ID (alternative to phone) |
phone | string | No | Customer phone number |
phone_code | string | No | Country phone code |
customer_id OR both phone and phone_code. customer_id takes precedence. Unlike jad-coins/use, this endpoint does not return a 422 for missing identifiers — supplying none simply resolves to 404 Customer not found. (A non-existent customer_id still fails the exists:customers,id rule and returns 422.) Only wallets with a positive balance appear in wallets_detail.
Use JadCoins
Deduct JadCoins as payment. Uses FIFO (oldest wallet first). A settlement transaction is logged automatically.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customer_id | integer | No | Customer ID (alternative to phone) |
phone | string | No | Customer phone number |
phone_code | string | No | Country phone code |
amount | number | Yes | Amount of JadCoins to spend |
reference | string | No | Your order/invoice reference |
Public Endpoints (No API Key)
VerifyIntegrationApiKey middleware and require no X-Api-Key. The company is identified by a unique_code sent in the request. Anyone who knows a company's unique_code can call them — treat that value as semi-sensitive. Their base path is /api (no /integration segment).
Verify Company (public)
Look up a company and its loyalty configuration by its public unique_code. Same response body as the API-key variant.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
unique_code | string | Yes | The company's public unique code (required|string|max:255) |
GET /api/company/check?unique_code=CRISPY01
Check or Create Customer (public)
Find or create a customer and link them to the company identified by company_unique_code. A welcome SMS is sent to newly-linked customers.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
company_unique_code | string | Yes | Identifies the company (required|string|exists:companies,unique_code) |
phone | string | Yes | Customer phone number |
phone_code | string | Yes | Country phone code (e.g. "+972") |
name | string | Yes | Customer full name (max:255) |
email | string | No | Customer email (nullable|email) |
national | string | No | National ID / nationality |
birth_date | date | No | Date of birth (YYYY-MM-DD) |
city_id | integer | No | City ID (nullable|exists:cities,id) |
accept_terms | boolean | No | Terms acceptance flag (nullable|boolean) |
is_new_customer inversion applies here (true = existing customer). This route is the public sibling of /integration/customer/check-or-create; the API-key variant has no company_unique_code or accept_terms fields.
Business Logic Reference
Points Calculation
| Type | Calculation | Example |
|---|---|---|
percent | purchase_amount × percentage_points / 100 | 150 × 10% = 15 points |
fixed | Fixed amount per transaction | 5 points per purchase |
none | No points awarded | N/A |
/points/earn: a purchase below min_purchase_amount or above max_purchase_amount is rejected with a 400 (no points, not capped). On the /use-wallet earn path: below-min earns 0 and above-max is capped to max_purchase_amount. Rounding differs: /points/earn floors earned points to a whole number, whereas the /use-wallet path keeps percent-based points at 2 decimals (rounded, not floored). points_type that is neither fixed nor percent yields 0.
Auto-Redemption
When points reach min_redemption_points, the system automatically:
1. Deducts points in multiples of the threshold.
2. Calculates wallet value: redeemed_points × point_value.
3. Applies redeem cap if configured.
4. Adds the amount to the customer's wallet.
5. Repeats until remaining points are below the threshold.
Redeem Cap
| Cap Type | Behavior | Example |
|---|---|---|
none | No limit | 100 pts × 1.0 = ₪100 |
fixed | Max fixed amount | Cap 80: 100 pts × 1.0 = ₪80 (capped) |
percent | % of wallet value | Cap 20%: 100 × 1.0 × 20% = ₪20 |
Points Expiry Policy
| Policy | Expiration Date |
|---|---|
week | End of current week (Friday) |
month | End of current month |
quarter | End of current quarter |
half_year | Jun 30 or Dec 31 |
year | Dec 31 |
none | Never expires |
Wallet Usage Rules
Customers must have is_profile_complete = true to use their wallet, otherwise /use-wallet returns 403 "Please complete your profile firstly".
In practice is_profile_complete is set to true when a customer is created with a birth_date, or after a successful update-profile (which validates name + email + birth_date). It is not independently enforced as a three-field rule at creation time.
If allow_points_on_redemption is enabled, customers also earn points (from purchase_amount) when paying with their wallet, and the auto-redeem loop may run.
JadCoins (Cross-Platform Currency)
Not tied to a specific company — can be spent at any integrated business.
Distributed by operators — not earned from purchases.
Settlement tracking — spending triggers a settlement transaction.
FIFO deduction — oldest wallet balances are used first.
Typical Integration Flow
The recommended sequence for a typical POS integration:
Verify Company Setup
Call GET /integration/company/check on startup to verify your API key and retrieve loyalty config.
Identify Customer
Call POST /integration/customer/check-or-create with the customer's phone number.
Check Balance
Call GET /integration/customer/balance to display points, wallet, and JadCoins to the cashier.
Process Purchase
Call POST /integration/points/earn with purchase_amount and a (required) order_id. Points are awarded and auto-redeemed if applicable.
Apply Payment (Optional)
Use POST /integration/use-wallet for wallet payment, or POST /integration/jad-coins/use for JadCoins.
Update Profile (If Needed)
If profile is incomplete, call POST /integration/customer/update-profile with the required details.
Error Codes Reference
| Code | Meaning | Common Causes |
|---|---|---|
200 | Success | Request processed. Envelope { value:true, data }. |
400 | Bad Request | /points/earn only: purchase below min_purchase_amount or above max_purchase_amount. msg is an object { points_earned, message }. |
401 | Unauthorized | Missing X-Api-Key header, or invalid API key (API-key endpoints only). |
403 | Forbidden | Loyalty disabled; profile incomplete (use-wallet); customer not linked (update-profile). Note: /points/earn also returns 403 — not 404 — when the customer is not found. |
404 | Not Found | Customer not found (balance / update-profile / use-wallet / jad-coins), or company not found (public check & API-key middleware). |
422 | Validation Error | Two shapes: FormRequest → { success, message, errors }; inline validator → { value:false, msg:{…} }. Also manual strings: "Invalid phone code", "Insufficient wallet balance", "Insufficient jad coins balance. Available: N", "Provide either customer_id or both phone and phone_code". |
500 | Server Error | Caught exception inside a transaction → { value:false, msg:"Failed to …" / "Integration failed: …" }. |