### GET /shop Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk/public-api-get-methods Retrieves configuration and settings for the current shop. ```APIDOC ## GET /shop ### Description Fetches shop-specific settings including currency, plan status, and branding preferences. ### Method GET ### Endpoint joyInstance.shop() ### Response #### Success Response (200) - **plan** (string) - Current subscription plan - **currency** (string) - Shop currency code - **disableWatermark** (boolean) - Whether the watermark is disabled #### Response Example { "disableWatermark": true, "plan": "free", "currency": "VND" } ``` -------------------------------- ### Perform Authenticated GET Request via cURL Source: https://devdocs.joy.so/joy-rest-api-v2/rest-api-v2 An example of how to authenticate and fetch customer data using the cURL command-line tool. It demonstrates the inclusion of required headers and content-type. ```bash curl -X GET "https://dev-api.joy.so/rest_api/v2/customers" \ -H "X-Joy-Loyalty-App-Key: your_app_key" \ -H "X-Joy-Loyalty-Secret-Key: your_secret_key" \ -H "Content-Type: application/json" ``` -------------------------------- ### cURL Authentication Example Source: https://devdocs.joy.so/webhook-api/authentication Demonstrates how to make an authenticated GET request to the Joy Loyalty API's webhooks endpoint using cURL. It includes the necessary authentication headers and content type. ```bash curl -X GET "https://joy.avada.io/app/api/v1/webhooks" \ -H "X-Joy-Loyalty-App-Key: your_app_key" \ -H "X-Joy-Loyalty-Secret-Key: your_secret_key" \ -H "Content-Type: application/json" ``` -------------------------------- ### Implement Joy Loyalty Webhook Server and API Client Source: https://devdocs.joy.so/webhook-api/integration-examples A complete implementation for handling Joy Loyalty webhooks with HMAC signature verification and managing API resources. Includes examples for both Express (Node.js) and Flask (Python) frameworks. ```javascript const express = require('express'); const crypto = require('crypto'); const axios = require('axios'); const app = express(); const joyApi = axios.create({ baseURL: 'https://joy.avada.io/app/api/v1', headers: { 'X-Joy-Loyalty-App-Key': process.env.JOY_APP_KEY, 'X-Joy-Loyalty-Secret-Key': process.env.JOY_SECRET_KEY } }); function verifyWebhook(req, res, next) { const hmac = req.get('X-Joy-Loyalty-Hmac-Sha256'); const calculatedHmac = crypto .createHmac('sha256', process.env.JOY_SECRET_KEY) .update(req.rawBody, 'utf8') .digest('base64'); if (!crypto.timingSafeEqual(Buffer.from(calculatedHmac), Buffer.from(hmac))) { return res.status(401).send('Invalid signature'); } next(); } app.use('/webhook', express.raw({type: 'application/json'}), (req, res, next) => { req.rawBody = req.body; req.body = JSON.parse(req.body); next(); }); app.post('/webhook/points-earned', verifyWebhook, (req, res) => { const {customer, oldPoint, newPoint} = req.body; res.status(200).send('OK'); }); ``` ```python import hmac, hashlib, base64, requests from flask import Flask, request class JoyWebhookClient: def __init__(self, app_key, secret_key): self.secret_key = secret_key self.base_url = 'https://joy.avada.io/app/api/v1' self.session = requests.Session() self.session.headers.update({'X-Joy-Loyalty-App-Key': app_key, 'X-Joy-Loyalty-Secret-Key': secret_key}) def verify_webhook(self, raw_body, hmac_header): calculated_hmac = base64.b64encode( hmac.new(self.secret_key.encode('utf-8'), raw_body, hashlib.sha256).digest() ).decode() return hmac.compare_digest(calculated_hmac, hmac_header) def list_webhooks(self): response = self.session.get(f'{self.base_url}/webhooks') return response.json().get('webhooks', []) ``` -------------------------------- ### GET /customer Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk/public-api-get-methods Retrieves information for the currently logged-in customer on the store. ```APIDOC ## GET /customer ### Description Retrieves the customer profile information for the currently authenticated user. ### Method GET ### Endpoint joyInstance.customer() ### Response #### Success Response (200) - **id** (string) - Unique customer identifier - **shopifyCustomerId** (number) - Shopify customer ID - **email** (string) - Customer email address - **point** (number) - Current loyalty point balance #### Response Example { "id": "avsu0TQoHYd4Zq5TZ123", "shopifyCustomerId": 123123123, "name": "admin super", "point": 100 } ``` -------------------------------- ### GET /redeemPrograms Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk/public-api-get-methods Retrieves the list of active redemption programs available to customers. ```APIDOC ## GET /redeemPrograms ### Description Fetches all configured redemption programs, including point requirements and reward types. ### Method GET ### Endpoint joyInstance.redeemPrograms() ### Response #### Success Response (200) - **programs** (array) - List of redemption program objects #### Response Example [ { "id": "MuvzQblxTj4b7jsUUJzM", "title": "Free product", "spendPoint": 200 } ] ``` -------------------------------- ### Get Earning Programs List Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk/public-api-get-methods Retrieves a list of available earning programs from the public API. This method is asynchronous and returns a Promise that resolves with the program data. ```javascript joyInstance.earnPrograms().then(function(resp){ console.log(resp) }); ``` -------------------------------- ### GET /translation Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk/public-api-get-methods Retrieves the translation dictionary for the store's loyalty program interface. ```APIDOC ## GET /translation ### Description Returns a dictionary of key-value pairs used for localizing the loyalty program UI. ### Method GET ### Endpoint joyInstance.translation() ### Response #### Success Response (200) - **dictionary** (object) - Key-value pairs of translation strings #### Response Example { "Earn": "Earn", "Spend": "Spend", "Back": "Back" } ``` -------------------------------- ### Webview Authentication for Joy Loyalty SDK (KoaJS Example) Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk This JavaScript code provides a KoaJS example for rendering the Joy widget in a webview. It generates a customer hash secret using Node.js crypto and embeds the necessary shop and customer information into an HTML structure for the Joy SDK. ```javascript const { shopId, // App ID shopifyCustomerId, // Shopify customer ID email, // Email of the customer secretKey // Secret key of Joy } = ... const prepareEmailCustomer = email?.toLowerCase() || ''; const hash = crypto .createHmac('sha256', secretKey) .update(`${shopifyCustomerId}-${prepareEmailCustomer}-${shopId}`) .digest('hex'); try { return (ctx.body = ` Joy Loyalty SDK - Mobile WebView `); ``` -------------------------------- ### GET /app/api/v1/widgets/points-calculator/product Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk/public-api-get-methods Calculates the number of points a customer will earn for purchasing a specific product variant. ```APIDOC ## GET /app/api/v1/widgets/points-calculator/product ### Description Retrieves the loyalty points calculation for a specific product variant based on the customer's context. ### Method GET ### Endpoint https://joy.avada.io/app/api/v1/widgets/points-calculator/product ### Parameters #### Query Parameters - **domain** (string) - Required - The Shopify shop domain. - **productId** (string) - Required - The ID of the product. - **variantId** (string) - Required - The ID of the product variant. - **q** (number) - Optional - Quantity of the item. - **customerId** (string) - Optional - The ID of the current customer. ### Response #### Success Response (200) - **html** (string) - Pre-rendered HTML snippet for the widget. - **points** (number) - Calculated point value. - **pointCurrencyName** (object) - Singular and plural labels for the currency. - **fromCache** (boolean) - Indicates if the result was served from cache. ### Response Example { "html": "Receive 699 points...", "points": 699, "pointCurrencyName": { "singular": "point", "plural": "points" }, "fromCache": false } ``` -------------------------------- ### Get Customer Coupon List Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk/public-api-get-methods Retrieves a list of customer coupons that have been redeemed. This method supports pagination using 'before' and 'after' parameters and can filter for available coupons. ```javascript joyInstance.rewardList({before: '', after: '', isAvailableCoupon: true}).then(function(resp){ console.log(resp) }); ``` -------------------------------- ### GET /loyalty/config Source: https://devdocs.joy.so/joy-rest-api-v2/tiers Retrieves the current loyalty program configuration, including point earning tiers and rounding logic. ```APIDOC ## GET /loyalty/config ### Description Retrieves the configuration settings for the loyalty points system. ### Method GET ### Endpoint /loyalty/config ### Parameters None ### Request Example GET /loyalty/config ### Response #### Success Response (200) - **earnPointsTiers** (array) - List of objects containing earnPoint (integer) and rateMoney (number). - **roundingMethod** (string) - The method used for rounding points (round, floor, ceil). - **skipEarnPointGuest** (boolean) - Whether guests are excluded from earning points. #### Response Example { "earnPointsTiers": [{"earnPoint": 1, "rateMoney": 10.0}], "roundingMethod": "floor", "skipEarnPointGuest": true } ``` -------------------------------- ### GET /rewards Source: https://devdocs.joy.so/joy-rest-api-v2/tiers Retrieves the configuration details for loyalty rewards, including points, priority, and localization settings. ```APIDOC ## GET /rewards ### Description Retrieves the current loyalty reward configuration and status metadata. ### Method GET ### Endpoint /rewards ### Parameters #### Query Parameters - **id** (string) - Optional - The unique identifier for the reward. ### Request Example GET /rewards?id=123 ### Response #### Success Response (200) - **bonusPoints** (string) - Bonus points awarded - **priority** (integer) - Reward priority - **showLoyaltyPage** (boolean) - Whether to show on loyalty page - **translateTitle** (object) - Translated titles for different languages - **expired** (boolean) - Whether reward has expired - **createdAt** (string) - Reward creation timestamp - **updatedAt** (string) - Last update timestamp #### Response Example { "bonusPoints": "500", "priority": 1, "showLoyaltyPage": true, "translateTitle": { "en": "Gold Reward" }, "expired": false, "createdAt": "2023-10-01T12:00:00Z", "updatedAt": "2023-10-01T12:00:00Z" } ``` -------------------------------- ### Set up local webhook testing environment with ngrok Source: https://devdocs.joy.so/webhook-api/troubleshooting Instructions for installing ngrok and exposing a local development server to the internet for webhook testing. ```bash # Install ngrok npm install -g ngrok # Start your local server node webhook-server.js # Create secure tunnel ngrok http 3000 ``` -------------------------------- ### Initialize Joy API Node.js SDK Source: https://devdocs.joy.so/joy-rest-api-v2/rest-api-v2 Shows how to initialize the official Joy API client and fetch shop information. Requires app and secret keys for authentication. ```javascript import JoyApi from 'joy-api-node'; const joy = new JoyApi({ appKey: 'your-app-key', secretKey: 'your-secret-key', baseUrl: 'https://dev-api.joy.so', timeout: 30000, maxRetries: 3 }); // Get shop information const shop = await joy.shop.whoami(); console.log(shop.data); ``` -------------------------------- ### Initialize Announcement Logic Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk/js-sdk-tutorial/how-to-make-a-coupon-reminder-using-joy-sdk Handles the conditional rendering of the announcement bar based on the environment (editor vs. live) and user authentication status. It includes event listeners for Shopify section updates and session-based dismissal tracking. ```javascript window.addEventListener('joy:ready', async () => { if (IN_EDITOR) return; if (!IS_CUSTOMER) return; try { if (document.getElementById('joy-announce-wrap')) return; if (sessionStorage.getItem('joy_announcement_dismissed') === '1') return; const ji = window.joyInstance || window.joy; if (!ji) return; const appliedCodes = await getAppliedDiscountCodes(); const resp = await ji.rewardList({ isAvailableCoupon: true }); const rewards = Array.isArray(resp?.data) ? resp.data : []; const unused = rewards.filter(r => r?.couponCode && !r?.isUsedCode); if (!unused.length) return; const latest = unused[0]; const { wrap, bar } = createBar(latest.couponCode, latest.eventRule, latest.programDescription, TEMPLATE_MSG, BUTTON_TEXT); document.body.appendChild(wrap); const restorePad = addBottomPaddingWhileVisible(); bar.querySelector('.joy-dismiss')?.addEventListener('click', () => { sessionStorage.setItem('joy_announcement_dismissed','1'); wrap.remove(); restorePad(); }); } catch(e) { console.error(e); } }); ``` -------------------------------- ### Navigate Paginated Data with Cursors Source: https://devdocs.joy.so/joy-rest-api-v2/rest-api-v2 Demonstrates how to navigate through large datasets using cursor-based pagination. It shows how to request the first page and subsequent pages using the 'before' and 'after' parameters. ```bash # First page curl "https://dev-api.joy.so/rest_api/v2/customers?limit=20&hasCount=true" # Next page (using last item's ID from previous response) curl "https://dev-api.joy.so/rest_api/v2/customers?after=abc123&limit=20" # Previous page (using first item's ID) curl "https://dev-api.joy.so/rest_api/v2/customers?before=abc123&limit=20" ``` -------------------------------- ### Verify and Handle Webhooks Source: https://devdocs.joy.so/webhook-api/integration-examples Demonstrates how to verify incoming webhook requests using HMAC-SHA256 signatures and process event payloads. This implementation ensures data integrity before executing business logic. ```python webhook_client = JoyWebhookClient(os.getenv('JOY_APP_KEY'), os.getenv('JOY_SECRET_KEY')) @app.route('/webhook/points-earned', methods=['POST']) def handle_points_earned(): hmac_header = request.headers.get('X-Joy-Loyalty-Hmac-Sha256') if not webhook_client.verify_webhook(request.data, hmac_header): return 'Invalid signature', 401 payload = request.get_json() # Process payload logic here return 'OK', 200 ``` ```php $rawBody = file_get_contents('php://input'); $hmacHeader = $_SERVER['HTTP_X_JOY_LOYALTY_HMAC_SHA256'] ?? ''; if (!$webhookClient->verifyWebhook($rawBody, $hmacHeader)) { http_response_code(401); exit('Invalid signature'); } $payload = json_decode($rawBody, true); // Process payload logic here echo 'OK'; ``` -------------------------------- ### Manage Webhooks via API Source: https://devdocs.joy.so/webhook-api/integration-examples Provides methods to create and list webhooks using the Joy Loyalty API. Requires valid App and Secret keys for authentication. ```php public function createWebhook($topic, $url) { $data = json_encode(['topic' => $topic, 'url' => $url]); $context = stream_context_create([ 'http' => [ 'method' => 'POST', 'header' => [ 'Content-Type: application/json', 'X-Joy-Loyalty-App-Key: ' . $this->appKey, 'X-Joy-Loyalty-Secret-Key: ' . $this->secretKey ], 'content' => $data ] ]); return json_decode(file_get_contents($this->baseUrl . '/webhooks', false, $context), true); } ``` -------------------------------- ### GET /rest_api/v2/programs/redemption Source: https://devdocs.joy.so/joy-rest-api-v2/programs Retrieves a list of all point spending and redemption programs available for the shop. ```APIDOC ## GET /rest_api/v2/programs/redemption ### Description Retrieve all point spending/redemption programs configured for the shop. This endpoint supports filtering by customer ID and event type. ### Method GET ### Endpoint https://api.joy.so/rest_api/v2/programs/redemption ### Parameters #### Header Parameters - **X-Joy-Loyalty-App-Key** (string) - Required - App ID of your shop retrieved from the Settings page - **X-Joy-Loyalty-Secret-Key** (string) - Required - Secret Key of your shop retrieved from the Settings page #### Query Parameters - **shopifyCustomerId** (string) - Optional - Shopify customer ID for program limitations - **event** (string) - Optional - Filter by program event type (amount_discount, percentage_discount, free_shipping, free_gift) ### Request Example GET /rest_api/v2/programs/redemption?event=amount_discount ### Response #### Success Response (200) - **success** (boolean) - Indicates if the request was successful - **data** (array) - List of redemption programs - **meta** (object) - Metadata including the count of items returned #### Response Example { "success": true, "data": [ { "id": "prog_123", "title": "10% Off", "type": "spending", "event": "percentage_discount" } ], "meta": { "count": 1 } } ``` -------------------------------- ### GET /rest_api/v2/rewards/{rewardId} Source: https://devdocs.joy.so/joy-rest-api-v2/rewards-1 Retrieves the details of a specific reward by its unique identifier. Requires authentication via shop-specific headers. ```APIDOC ## GET /rest_api/v2/rewards/{rewardId} ### Description Retrieve detailed information about a specific reward using its unique ID. This endpoint returns the reward status, associated program details, and customer information. ### Method GET ### Endpoint /rest_api/v2/rewards/{rewardId} ### Parameters #### Path Parameters - **rewardId** (string) - Required - The unique identifier of the reward. #### Headers - **X-Joy-Loyalty-App-Key** (string) - Required - App ID of your shop retrieved from the Settings page. - **X-Joy-Loyalty-Secret-Key** (string) - Required - Secret Key of your shop retrieved from the Settings page. ### Request Example GET /rest_api/v2/rewards/reward_12345 Headers: { "X-Joy-Loyalty-App-Key": "your_app_key", "X-Joy-Loyalty-Secret-Key": "your_secret_key" } ### Response #### Success Response (200) - **success** (boolean) - Indicates if the request was successful. - **data** (object) - The reward object containing id, customerId, email, couponCode, and status. - **message** (string) - Status message. - **timestamp** (string) - ISO 8601 timestamp of the response. #### Response Example { "success": true, "data": { "id": "reward_12345", "email": "customer@example.com", "couponCode": "SAVE20", "discountStatus": "active", "createdAt": "2023-10-01T10:00:00Z" }, "message": "Success", "timestamp": "2023-10-27T12:00:00Z" } ``` -------------------------------- ### Listen for Joy SDK Ready Event Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk This JavaScript code demonstrates how to listen for the 'joy:ready' event, which fires once the Joy SDK has finished loading. This is useful for executing code that depends on the SDK being fully initialized. ```javascript window.addEventListener('joy:ready', () => { }); ``` -------------------------------- ### GET /rest_api/v2/rewards Source: https://devdocs.joy.so/joy-rest-api-v2/rewards-1 Retrieve a list of customer rewards. You must provide either `customerId` or `shopifyCustomerId`. Supports filtering by status, type, creation date, and pagination. ```APIDOC ## GET /rest_api/v2/rewards ### Description Retrieve customer rewards with optional filtering and pagination. Customer Identifier Required: Must provide either `customerId` or `shopifyCustomerId` parameter. ### Method GET ### Endpoint /rest_api/v2/rewards ### Parameters #### Query Parameters - **X-Joy-Loyalty-App-Key** (string) - Required - App ID of your shop which retrieved from the Settings page - **X-Joy-Loyalty-Secret-Key** (string) - Required - Secret Key of your shop which retrieved from the Settings page - **customerId** (string) - Required - Joy internal customer ID - **shopifyCustomerId** (string) - Required - Shopify customer ID - **status** (string) - Optional - Filter by reward status (active, used, expired) - **typeReward** (string) - Optional - Filter by reward type - **before** (string) - Optional - Cursor for pagination (before) - Firestore document ID of reward to paginate before - **after** (string) - Optional - Cursor for pagination (after) - Firestore document ID of reward to paginate after - **limit** (integer) - Optional - Number of rewards per page (default: 10, min: 1, max: 1000) - **created_at_min** (string) - Optional - Filter rewards created after this date (ISO 8601 format) - **created_at_max** (string) - Optional - Filter rewards created before this date (ISO 8601 format) - **order** (string) - Optional - Sort order for results (createdAt_desc, createdAt_asc, updatedAt_desc, updatedAt_asc, default: createdAt_desc) - **hasCount** (boolean) - Optional - Include total count in response (may increase response time, default: false) ### Response #### Success Response (200) - **success** (boolean) - Indicates if the request was successful. - **data** (array) - An array of reward objects. - **id** (string) - Reward ID - **customerId** (string) - Internal customer ID - **email** (string) - Customer email address - **couponCode** (string) - Generated coupon/discount code - **programTitle** (string) - Program title - **shopifyCustomerId** (integer) - Shopify customer ID - **programDescription** (string) - Program description - **orderReqAmount** (string) - Minimum order amount required - **expiredAt** (string) - Reward expiration date (nullable) - **discountStatus** (string) - Status of the discount - **meta** (object) - Pagination metadata. - **pagination** (object) - Pagination details. - **hasNext** (boolean) - True if more results exist after current page. - **hasPre** (boolean) - True if results exist before current page. - **total** (integer) - Total count of all matching results (when available). - **totalPage** (integer) - Total number of pages calculated as ceil(total/limit) (when available). #### Error Response (404) - **success** (boolean) - Indicates if the request was successful. - **data** (object) - Empty object. - **message** (string) - Error message (e.g., "Customer not found"). - **timestamp** (string) - Timestamp of the error. ### Request Example ```json { "headers": { "X-Joy-Loyalty-App-Key": "YOUR_APP_KEY", "X-Joy-Loyalty-Secret-Key": "YOUR_SECRET_KEY" }, "query": { "customerId": "cust_12345", "limit": 20, "status": "active" } } ``` ### Response Example (200 OK) ```json { "success": true, "data": [ { "id": "rew_abcde", "customerId": "cust_12345", "email": "customer@example.com", "couponCode": "SUMMER20", "programTitle": "Summer Sale Discount", "shopifyCustomerId": 123456789, "programDescription": "Get 20% off on your next order.", "orderReqAmount": "50.00", "expiredAt": "2024-12-31T23:59:59Z", "discountStatus": "active" } ], "meta": { "pagination": { "hasNext": true, "hasPre": false, "total": 150, "totalPage": 8 } } } ``` ### Response Example (404 Not Found) ```json { "success": false, "data": {}, "message": "Customer not found", "timestamp": "2023-10-27T10:00:00Z" } ``` ``` -------------------------------- ### Implement Asynchronous Webhook Processing (JavaScript) Source: https://devdocs.joy.so/webhook-api/best-practices This example shows how to handle long-running webhook processes by responding immediately and queuing the task for background processing. This improves responsiveness and avoids timeouts. ```javascript app.post('/webhook', async (req, res) => { // Respond immediately res.status(200).send('OK'); // Queue for background processing await addToQueue('webhook-processing', req.body); }); ``` -------------------------------- ### GET /rest_api/v2/programs/{programId} Source: https://devdocs.joy.so/joy-rest-api-v2/programs Retrieve the details of a specific loyalty program by its unique identifier. This endpoint supports optional filtering based on a Shopify customer ID. ```APIDOC ## GET /rest_api/v2/programs/{programId} ### Description Retrieve a specific loyalty program by its ID. This returns the full configuration of the program, including earning or spending rules. ### Method GET ### Endpoint /rest_api/v2/programs/{programId} ### Parameters #### Path Parameters - **programId** (string) - Required - The unique identifier of the program. #### Query Parameters - **shopifyCustomerId** (string) - Optional - Shopify customer ID used to check program limitations for a specific user. ### Request Example GET https://api.joy.so/rest_api/v2/programs/prog_12345 ### Response #### Success Response (200) - **success** (boolean) - Indicates if the request was successful. - **data** (object) - The program object containing configuration details. - **message** (string) - Status message. - **timestamp** (string) - ISO 8601 timestamp of the response. #### Response Example { "success": true, "data": { "id": "prog_12345", "title": "Summer Sale Earning", "type": "earning", "status": true }, "message": "Success", "timestamp": "2023-10-27T10:00:00Z" } ``` -------------------------------- ### Theme Editor Preview Logic (JavaScript) Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk/js-sdk-tutorial/how-to-make-a-coupon-reminder-using-joy-sdk Handles the rendering of the announcement bar within the Shopify theme editor preview. It listens for section load and select events to re-render the preview, ensuring dynamic updates. Dependencies include the `mountBar` function and a global `inEditor` flag. ```javascript (function editorPreview() { try { if (!inEditor) return; const renderPreview = () => { try { document.getElementById('joy-announce-wrap')?.remove(); mountBar('JOY-PREVIEW10', 'reward', '10% off', { respectDismiss: false }); } catch (e) { console.log('renderPreview error', e); } }; if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', renderPreview); } else { renderPreview(); } document.addEventListener('shopify:section:load', renderPreview); document.addEventListener('shopify:section:select', renderPreview); } catch (e) { console.log('editorPreview error', e); } })(); ``` -------------------------------- ### Retrieve Shop Configuration via Joy API Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk/public-api-get-methods Retrieves the store's current configuration settings from the Joy API. Returns a Promise resolving to an object containing plan details, currency settings, and watermark preferences. ```javascript joyInstance.shop().then(function(resp){ console.log(resp) }); ``` -------------------------------- ### GET /rest_api/v2/programs/earning Source: https://devdocs.joy.so/joy-rest-api-v2/programs Retrieve all earning programs for the authenticated shop. This endpoint allows you to fetch a list of all active and inactive earning programs configured for your loyalty system. ```APIDOC ## GET /rest_api/v2/programs/earning ### Description Retrieve all earning programs for the authenticated shop. ### Method GET ### Endpoint /rest_api/v2/programs/earning ### Parameters #### Header Parameters - **X-Joy-Loyalty-App-Key** (string) - Required - App ID of your shop which retrieved from the Settings page - **X-Joy-Loyalty-Secret-Key** (string) - Required - Secret Key of your shop which retrieved from the Settings page ### Response #### Success Response (200) - **success** (boolean) - Indicates if the request was successful. - **data** (array) - A list of earning program objects. - **id** (string) - The unique identifier for the program. - **title** (string) - The name of the earning program. - **type** (string) - The type of program (e.g., "earning"). - **status** (boolean) - Indicates if the program is currently active. - **createdAt** (string) - The timestamp when the program was created. - **updatedAt** (string) - The timestamp when the program was last updated. - **earnBy** (string) - The method by which points are earned (e.g., "price", "order"). - **rateMoney** (number) - The monetary value associated with earning points. - **earnPoint** (integer) - The number of points earned. - **startDate** (string) - The start date for the program. - **endDate** (string) - The end date for the program. #### Error Response (403) - **success** (boolean) - Indicates if the request was successful. - **message** (string) - Error message describing the issue (e.g., "Plan upgrade required"). #### Error Response (500) - **success** (boolean) - Indicates if the request was successful. - **message** (string) - Error message describing the internal server error. ### Response Example ```json { "success": true, "data": [ { "id": "prog_12345", "title": "10% Back on Orders", "type": "earning", "status": true, "createdAt": "2023-10-27T10:00:00Z", "updatedAt": "2023-10-27T10:00:00Z", "earnBy": "order", "rateMoney": 0.10, "earnPoint": 100, "startDate": "2023-10-27T00:00:00Z", "endDate": "2023-12-31T23:59:59Z" } ], "meta": { "count": 1 } } ``` ``` -------------------------------- ### Get Customer Activity History Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk/public-api-get-methods Fetches a list of customer activity history, supporting pagination via 'before' and 'after' parameters. The response includes activity data and pagination information. ```javascript joyInstance.customerHistory({before: '', after: ''}).then(function(resp){ console.log(resp) }); ``` -------------------------------- ### Live Joy Announcement Logic (JavaScript) Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk/js-sdk-tutorial/how-to-make-a-coupon-reminder-using-joy-sdk Manages the dynamic display of available coupon rewards on the live website. It fetches available rewards, checks against applied codes, and mounts the announcement bar if a new, unused coupon is found. It also includes logic to auto-hide the bar if the code is applied later. Dependencies include `getAppliedDiscountCodes`, `joyInstance` (or `joy`), and `mountBar`. ```javascript window.addEventListener('joy:ready', async () => { if (inEditor) return; // preview handles editor try { const ji = window.joyInstance || window.joy; if (!ji) return; if (document.getElementById('joy-announce-wrap')) return; if (sessionStorage.getItem('joy_announcement_dismissed') === '1') return; const appliedCodes = await getAppliedDiscountCodes(); let resp; try { resp = await ji.rewardList({ isAvailableCoupon: true }); } catch (e) { console.log('rewardList error', e); return; } const rewards = Array.isArray(resp?.data) ? resp.data : []; const unused = rewards .filter(r => r && r.couponCode && !r.isUsedCode) .sort((a, b) => { try { return new Date(b.createdAt) - new Date(a.createdAt); } catch (_) { return 0; } }); if (!unused.length) return; const latest = unused[0]; const code = String(latest?.couponCode || ''); const label = String(latest?.eventRule || 'reward').replace(/_/g, ' '); const benefit= latest?.programDescription || 'your coupon'; if (!code) return; if (appliedCodes.includes(code.toUpperCase())) return; const mounted = mountBar(code, label, benefit, { respectDismiss: true }); if (!mounted) return; const maybeHide = async () => { try { const nowCodes = await getAppliedDiscountCodes(); if (nowCodes.includes(code.toUpperCase())) { try { sessionStorage.setItem('joy_announcement_dismissed', '1'); } catch (_) {} mounted.cleanup(); } } catch (e) { console.log('maybeHide error', e); } }; try { mounted.bar.querySelector('.joy-cta')?.addEventListener('click', () => { try { setTimeout(maybeHide, 1200); } catch (_) {} }); } catch (e) { console.log('cta binding error', e); } let checks = 0; const iv = setInterval(async () => { try { checks++; await maybeHide(); if (checks > 10 || !document.getElementById('joy-announce-wrap')) clearInterval(iv); } catch (e) { clearInterval(iv); console.log('interval error', e); } }, 1000); } catch (e) { console.log('joy:ready handler error', e); } }); ``` -------------------------------- ### Get Shop Information (OpenAPI) Source: https://devdocs.joy.so/joy-rest-api-v2/shop Retrieves safe shop information for the authenticated shop. This OpenAPI definition specifies the endpoint, parameters, and response structure for the 'whoami' GET request. ```json { "openapi": "3.0.0", "info": { "title": "Joy Loyalty Program - REST API v2", "version": "2.0.0" }, "tags": [ { "name": "Shop", "description": "Shop information and authentication" } ], "servers": [ { "url": "https://dev-api.joy.so" }, { "url": "https://api.joy.so" } ], "paths": { "/rest_api/v2/whoami": { "get": { "tags": [ "Shop" ], "summary": "Get shop information", "description": "Retrieve safe shop information for the authenticated shop", "parameters": [ { "$ref": "#/components/parameters/AppKeyHeader" }, { "$ref": "#/components/parameters/SecretKeyHeader" } ], "responses": { "200": { "description": "Shop information", "content": { "application/json": { "schema": { "allOf": [ { "$ref": "#/components/schemas/SuccessResponse" }, { "type": "object", "properties": { "data": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "domain": { "type": "string" }, "email": { "type": "string" }, "plan": { "type": "string" }, "currency": { "type": "string" }, "timezone": { "type": "string" }, "countryCode": { "type": "string" }, "isInstalled": { "type": "boolean" }, "createdAt": { "type": "string", "format": "date-time" }, "updatedAt": { "type": "string", "format": "date-time" } } } } } ] } } } } } } } }, "components": { "parameters": { "AppKeyHeader": { "name": "X-Joy-Loyalty-App-Key", "in": "header", "required": true, "schema": { "type": "string" }, "description": "App ID of your shop which retrieved from the Settings page" }, "SecretKeyHeader": { "name": "X-Joy-Loyalty-Secret-Key", "in": "header", "required": true, "schema": { "type": "string" }, "description": "Secret Key of your shop which retrieved from the Settings page" } }, "schemas": { "SuccessResponse": { "type": "object", "properties": { "success": { "type": "boolean" }, "data": { "type": "object" }, "meta": { "type": "object", "description": "Additional metadata such as counts and pagination" }, "message": { "type": "string" }, "timestamp": { "type": "string", "format": "date-time" } } } } } } ``` -------------------------------- ### Optimize API Requests with Pagination and Filters Source: https://devdocs.joy.so/joy-rest-api-v2/rest-api-v2 Demonstrates efficient data fetching using cursor-based pagination and disabling count metadata to improve performance. Also shows how to filter results using ISO 8601 date strings. ```javascript // Use hasCount sparingly to avoid performance impact const customers = await fetch('/rest_api/v2/customers?hasCount=false'); // Navigate using document IDs, not page numbers const nextPage = await fetch(`/rest_api/v2/customers?after=${lastCustomerId}`); // Use proper ISO 8601 format for dates const recentCustomers = await fetch( '/rest_api/v2/customers?created_at_min=2023-07-01T00:00:00Z' ); ``` -------------------------------- ### GET /rest_api/v2/programs/earning/eligibility Source: https://devdocs.joy.so/joy-rest-api-v2/programs Retrieves earning programs for a specific customer. Single earn event programs include an 'isEarned' field to indicate if the customer has already completed the action. ```APIDOC ## GET /rest_api/v2/programs/earning/eligibility ### Description Retrieve earning programs for a specific customer. Single earn event programs (like social media follows, sign up, birthday) will include an `isEarned` field indicating whether the customer has already earned points from that program. ### Method GET ### Endpoint /rest_api/v2/programs/earning/eligibility ### Parameters #### Query Parameters - **shopifyCustomerId** (string) - Optional - Shopify customer ID. Required if customerId is not provided. - **customerId** (string) - Optional - Internal customer ID. Required if shopifyCustomerId is not provided. ### Request Example GET /rest_api/v2/programs/earning/eligibility?shopifyCustomerId=12345 ### Response #### Success Response (200) - **success** (boolean) - Indicates if the request was successful. - **data** (array) - List of earning programs with eligibility status. - **meta** (object) - Metadata including the count of programs returned. #### Response Example { "success": true, "data": [ { "id": "prog_001", "title": "Sign up bonus", "isEarned": true } ], "meta": { "count": 1 } } ``` -------------------------------- ### GET /webhooks Source: https://devdocs.joy.so/webhook-api/api-reference Retrieve a list of all registered webhooks associated with the shop. ```APIDOC ## GET /webhooks ### Description Get a list of all registered webhooks for your shop. ### Method GET ### Endpoint https://joy.avada.io/app/api/v1/webhooks ### Parameters #### Header Parameters - **X-Joy-Loyalty-App-Key** (string) - Required - Your Joy app key from settings - **X-Joy-Loyalty-Secret-Key** (string) - Required - Your Joy secret key from settings ### Response #### Success Response (200) - **success** (boolean) - Status of the request - **webhooks** (array) - List of webhook objects - **timestamp** (string) - ISO 8601 timestamp #### Response Example { "success": true, "webhooks": [ { "id": "wh_123", "topic": "order/created", "url": "https://example.com/webhook", "isEnabled": true, "createdAt": "2023-10-01T12:00:00Z" } ], "timestamp": "2023-10-01T12:05:00Z" } ``` -------------------------------- ### Retrieve Branding Settings Source: https://devdocs.joy.so/joy-javascript-api/joy-loyalty-sdk/public-api-get-methods Fetches the current branding and configuration settings for the floating widget. This includes color schemes, font settings, and localized labels for the rewards program interface. ```javascript joyInstance.settingsBranding().then(function(resp){ console.log(resp) }); ```