Integration API Reference v1.0

Build with the
JadCoins API

Integrate loyalty points, wallets, and JadCoins into your POS system or application. Everything you need to get started.

🔒 API Key Auth
📡 REST / JSON
10 Endpoints
💬 SMS Notifications

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

Header
X-Api-Key: your-api-key-here
ℹ️ The API key is mapped to your company account. All operations will be scoped to your company automatically.

Authentication Errors

StatusErrorDescription
401Missing X-Api-Key headerThe header was not provided in the request.
401Invalid API keyThe provided API key does not match any registered company.
404Company not foundThe 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).

Base URL — API Key endpoints
https://your-domain.com/api/integration
Base URL — Public endpoints
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.

Success — { value, data }

    
Error — { value, msg }

    

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.

422 — FormRequest shape

    
422 — inline-validator shape

    
📞 The 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.

GET /integration/company/check

Parameters

No additional parameters required. Authentication is handled via the X-Api-Key header.

Response 200

    
Error 403

    

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.

POST /integration/customer/check-or-create

Request Parameters

ParameterTypeRequiredDescription
phonestringYesCustomer phone number
phone_codestringYesCountry phone code (e.g., "+972")
namestringYesCustomer full name
emailstringNoCustomer email address
nationalstringNoNational ID or nationality (nullable|string)
birth_datedateNoDate of birth (YYYY-MM-DD). When present, the new customer is created with is_profile_complete = true.
city_idintegerNoCity 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.
Example Request

    
Response 200 — newly created

    
Validation Error 422 (FormRequest shape)

    
Error 422 — Invalid phone code

    

Get Customer Balance

Retrieve the current point balance, wallet balance, and JadCoins balance for a customer.

GET /integration/customer/balance

Query Parameters

ParameterTypeRequiredDescription
phonestringYesCustomer phone number
phone_codestringYesCountry phone code
Example Request
GET /api/integration/customer/balance?phone=0509124719&phone_code=+972
X-Api-Key: your-api-key-here
Response 200

    
Error 403 / 404

    
ℹ️ If loyalty is disabled for the company, this returns 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.

POST /integration/customer/update-profile

Request Parameters

ParameterTypeRequiredDescription
phonestringYesCustomer phone number
phone_codestringYesCountry phone code
namestringYesCustomer full name
emailstringYesCustomer email address
nationalstringNoNational ID or nationality (nullable|string|max:255)
birth_datedateYesDate of birth (YYYY-MM-DD)
city_idintegerNoCity ID (nullable|exists:cities,id)
ℹ️ On success the customer is force-set to 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).
Response 200

    
Error 422 — inline-validator shape

    
Error 403 / 404
{ "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.

POST /integration/points/earn

Request Parameters

ParameterTypeRequiredDescription
phonestringYesCustomer phone number
phone_codestringYesCountry phone code
purchase_amountnumberYesThe total purchase amount (required|numeric|min:0)
order_idstringYesRequired by validation (required|string). Note: this value is validated but not stored on the transaction.
referencestringNoNot validated, but this is the value actually saved as the transaction reference. Omit → stored as null.
Example Request

    
Response 200 — Points Only

    
Response 200 — With Auto-Redemption

    
Error 400 — below minimum

    
Error 400 — above maximum

    
⚠️ On this endpoint, 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.

POST /integration/use-wallet

Request Parameters

ParameterTypeRequiredDescription
phonestringYesCustomer phone number
phone_codestringYesCountry phone code
amountnumberYesAmount to deduct from wallet (required|numeric|min:0.01)
purchase_amountnumberNoTotal purchase amount used to earn points (nullable|numeric|min:0). Only relevant when allow_points_on_redemption is enabled.
referencestringNoYour order/invoice reference (nullable|string|max:255)
Response 200

    
Error 422 — insufficient balance

    
ℹ️ 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.

GET /integration/jad-coins/check-balance

Query Parameters

ParameterTypeRequiredDescription
customer_idintegerNoCustomer ID (alternative to phone)
phonestringNoCustomer phone number
phone_codestringNoCountry phone code
ℹ️ Provide either 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.
Response 200

    
Error 404

    

Use JadCoins

Deduct JadCoins as payment. Uses FIFO (oldest wallet first). A settlement transaction is logged automatically.

POST /integration/jad-coins/use

Request Parameters

ParameterTypeRequiredDescription
customer_idintegerNoCustomer ID (alternative to phone)
phonestringNoCustomer phone number
phone_codestringNoCountry phone code
amountnumberYesAmount of JadCoins to spend
referencestringNoYour order/invoice reference
Example Request

    
Response 200

    
Error 422

    

Public Endpoints (No API Key)

⚠️ These two routes are registered outside the 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.

GET /company/check

Query Parameters

ParameterTypeRequiredDescription
unique_codestringYesThe company's public unique code (required|string|max:255)
Example Request
GET /api/company/check?unique_code=CRISPY01
Response 200

    
Error 404 / 403

    

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.

POST /customer/check-or-create

Request Parameters

ParameterTypeRequiredDescription
company_unique_codestringYesIdentifies the company (required|string|exists:companies,unique_code)
phonestringYesCustomer phone number
phone_codestringYesCountry phone code (e.g. "+972")
namestringYesCustomer full name (max:255)
emailstringNoCustomer email (nullable|email)
nationalstringNoNational ID / nationality
birth_datedateNoDate of birth (YYYY-MM-DD)
city_idintegerNoCity ID (nullable|exists:cities,id)
accept_termsbooleanNoTerms acceptance flag (nullable|boolean)
Example Request

    
Response 200

    
Validation Error 422 (FormRequest shape)

    
ℹ️ The same 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

TypeCalculationExample
percentpurchase_amount × percentage_points / 100150 × 10% = 15 points
fixedFixed amount per transaction5 points per purchase
noneNo points awardedN/A
⚠️ Behaviour differs by endpoint. On /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 TypeBehaviorExample
noneNo limit100 pts × 1.0 = ₪100
fixedMax fixed amountCap 80: 100 pts × 1.0 = ₪80 (capped)
percent% of wallet valueCap 20%: 100 × 1.0 × 20% = ₪20

Points Expiry Policy

PolicyExpiration Date
weekEnd of current week (Friday)
monthEnd of current month
quarterEnd of current quarter
half_yearJun 30 or Dec 31
yearDec 31
noneNever 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:

1

Verify Company Setup

Call GET /integration/company/check on startup to verify your API key and retrieve loyalty config.

2

Identify Customer

Call POST /integration/customer/check-or-create with the customer's phone number.

3

Check Balance

Call GET /integration/customer/balance to display points, wallet, and JadCoins to the cashier.

4

Process Purchase

Call POST /integration/points/earn with purchase_amount and a (required) order_id. Points are awarded and auto-redeemed if applicable.

5

Apply Payment (Optional)

Use POST /integration/use-wallet for wallet payment, or POST /integration/jad-coins/use for JadCoins.

6

Update Profile (If Needed)

If profile is incomplete, call POST /integration/customer/update-profile with the required details.

Error Codes Reference

CodeMeaningCommon Causes
200SuccessRequest processed. Envelope { value:true, data }.
400Bad Request/points/earn only: purchase below min_purchase_amount or above max_purchase_amount. msg is an object { points_earned, message }.
401UnauthorizedMissing X-Api-Key header, or invalid API key (API-key endpoints only).
403ForbiddenLoyalty disabled; profile incomplete (use-wallet); customer not linked (update-profile). Note: /points/earn also returns 403 — not 404 — when the customer is not found.
404Not FoundCustomer not found (balance / update-profile / use-wallet / jad-coins), or company not found (public check & API-key middleware).
422Validation ErrorTwo 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".
500Server ErrorCaught exception inside a transaction → { value:false, msg:"Failed to …" / "Integration failed: …" }.