Skip to main content

Softlogin Store Credits API

Apply store credits at checkout without full Shopify login. Supports standard storefronts and headless commerce.

Updated over 3 weeks ago

Softlogin Store Credits API

Apply store credits to customer carts from custom storefronts or headless checkouts. This API enables credit redemption without requiring full Shopify login.


Overview

The Softlogin API allows customers to apply store credits during checkout. It supports both standard Shopify storefronts and headless commerce setups.

Deployment Types

Type

API Base URL

Standard Shopify

https://your-store.myshopify.com/apps/subscribfy-api/softlogin

Headless/Custom Domain

https://checkout.your-domain.com/apps/subscribfy-api/softlogin


Authentication

The Softlogin API uses session-based authentication. Customers must be logged into Shopify (verified via cookies) for requests to succeed.


Available Actions

Action

Description

customer-check

Verify customer and retrieve balance/subscription status

discount

Apply or remove store credits from cart


Customer Check

Verify customer identity and retrieve their store credit balance and subscription status.

Request

POST /apps/subscribfy-api/softlogin?action=customer-check&t={timestamp}Parameters:
  customer_email: Customer's email address
  customer_id: Shopify customer ID (optional, for logged-in verification)
  location_origin: window.location.origin
  location_pathname: window.location.pathname
  location_search: window.location.search

Response

{
  "customer_email": "john@example.com",
  "customer_phone_private": "***-***-4567",
  "shopify_customer_id": "7211677024514",
  "current_balance": 50.00,
  "subscription_status": "ACTIVE",
  "membership_status": 1,
  "credits_method": "functions",
  "currency_code": "USD"
}

Response Fields

Field

Type

Description

customer_email

string

Verified customer email

shopify_customer_id

string

Shopify customer GID (numeric)

current_balance

float

Available store credits

subscription_status

string

ACTIVE, PAUSED, CANCELLED, or NONE

membership_status

integer

1 = active VIP, 0 = no membership

credits_method

string

functions, coupon, or giftcard

currency_code

string

Store currency (USD, EUR, etc.)


Apply Store Credits

Apply store credits to the current cart. The cart token must be fetched fresh before each request.

Request

POST /apps/subscribfy-api/softlogin?action=discount&cid={customer_id}&exm={membership_flag}&token={cart_token}&st={amount}&t={timestamp}Parameters:
  customer_email: Customer's email
  customer_id: Shopify customer ID
  cid: Same as customer_id
  email: Same as customer_email
  exm: Membership flag (2 = no membership, 3 = active membership)
  token: Cart token from /cart.js
  st: Amount of store credits to apply (optional, uses max available if not specified)
  cart[...]: Full cart object as flat parameters
  location_origin: window.location.origin
  location_pathname: window.location.pathname
  location_search: window.location.search

Response

{
  "sac": 25.00,
  "sch": "abc123xyz",
  "cdi": 12345
}

Response Fields

Field

Type

Description

sac

float

Store credits amount applied

sch

string

Store credits hash (for verification)

cdi

integer

Store credit transaction ID

dc

string

Discount code (if coupon method)

After Successful Response

Update cart attributes with the store credit information:

POST /cart/update.js{
  "attributes[subscribfy_checkout_storecredits_label]": "Store Credits",
  "attributes[subscribfy_checkout_storecredits_value]": {sac},
  "attributes[subscribfy_checkout_storecredits_hash]": {sch}
}

Remove Store Credits

Remove previously applied store credits from the cart.

Step 1: Clear Cart Attributes

POST /cart/update.js{
  "attributes[subscribfy_checkout_storecredits_label]": "",
  "attributes[subscribfy_checkout_storecredits_value]": "",
  "attributes[subscribfy_checkout_storecredits_hash]": "",
  "attributes[subscribfy_store_credits_code]": "",
  "attributes[subscribfy_store_credits]": "",
  "attributes[subscribfy_store_credits_id]": ""
}

Step 2: Notify API

POST /apps/subscribfy-api/softlogin?action=discount&cid={customer_id}&exm=1&cp={pathname}&t={timestamp}

JavaScript Implementation

Complete Example

// Configuration
const SUBSCRIBFY = {
    apiPrefix: 'https://your-store.myshopify.com/apps/subscribfy-api',
    customerEmail: null,
    customerId: null,
    membershipStatus: 0,
    balance: 0,
    cart: null,
    cartToken: null
};// API Helper
const subscribfyApi = {
    async post(url, data = {}) {
        const response = await fetch(url, {
            method: 'POST',
            body: new URLSearchParams(data),
            credentials: 'include',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        });
        return response.json();
    },    async getCart() {
        const response = await fetch('/cart.js');
        SUBSCRIBFY.cart = await response.json();
        SUBSCRIBFY.cartToken = SUBSCRIBFY.cart.token;
        return SUBSCRIBFY.cart;
    },    flattenObject(obj, prefix = '') {
        const result = {};
        for (const [key, value] of Object.entries(obj)) {
            const newKey = prefix ? `${prefix}[${key}]` : key;
            if (typeof value === 'object' && value !== null) {
                Object.assign(result, this.flattenObject(value, newKey));
            } else {
                result[newKey] = value;
            }
        }
        return result;
    }
};// Check customer and get balance
async function checkCustomer(email) {
    const response = await subscribfyApi.post(
        `${SUBSCRIBFY.apiPrefix}/softlogin?action=customer-check&t=${Date.now()}`,
        {
            customer_email: email,
            location_origin: window.location.origin,
            location_pathname: window.location.pathname,
            location_search: window.location.search
        }
    );    if (response.status_code) {
        throw new Error('Customer not found');
    }    SUBSCRIBFY.customerEmail = response.customer_email;
    SUBSCRIBFY.customerId = response.shopify_customer_id;
    SUBSCRIBFY.balance = response.current_balance;
    SUBSCRIBFY.membershipStatus = response.membership_status;    return response;
}// Apply store credits
async function applyStoreCredits(amount) {
    await subscribfyApi.getCart();    const exm = SUBSCRIBFY.membershipStatus ? 3 : 2;
    const cartFlat = subscribfyApi.flattenObject(SUBSCRIBFY.cart, 'cart');    const data = {
        customer_email: SUBSCRIBFY.customerEmail,
        customer_id: SUBSCRIBFY.customerId,
        email: SUBSCRIBFY.customerEmail,
        cid: SUBSCRIBFY.customerId,
        exm: exm,
        token: SUBSCRIBFY.cartToken,
        st: amount,
        location_origin: window.location.origin,
        location_pathname: window.location.pathname,
        location_search: window.location.search,
        ...cartFlat
    };    const url = `${SUBSCRIBFY.apiPrefix}/softlogin?action=discount&cid=${SUBSCRIBFY.customerId}&exm=${exm}&token=${encodeURIComponent(SUBSCRIBFY.cartToken)}&st=${amount}&t=${Date.now()}`;    const response = await subscribfyApi.post(url, data);    if (response.error || response.status_code) {
        throw new Error(response.error || 'Failed to apply credits');
    }    // Update cart attributes
    await fetch('/cart/update.js', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            attributes: {
                'subscribfy_checkout_storecredits_label': 'Store Credits',
                'subscribfy_checkout_storecredits_value': response.sac,
                'subscribfy_checkout_storecredits_hash': response.sch
            }
        })
    });    return response;
}// Remove store credits
async function removeStoreCredits() {
    // Clear cart attributes
    await fetch('/cart/update.js', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            attributes: {
                'subscribfy_checkout_storecredits_label': '',
                'subscribfy_checkout_storecredits_value': '',
                'subscribfy_checkout_storecredits_hash': '',
                'subscribfy_store_credits_code': '',
                'subscribfy_store_credits': '',
                'subscribfy_store_credits_id': ''
            }
        })
    });    // Notify API
    await subscribfyApi.post(
        `${SUBSCRIBFY.apiPrefix}/softlogin?action=discount&cid=${SUBSCRIBFY.customerId}&exm=1&cp=${window.location.pathname}&t=${Date.now()}`
    );
}// Usage Example
async function init() {
    try {
        // Check customer
        const customer = await checkCustomer('john@example.com');
        console.log(`Balance: $${customer.current_balance}`);        // Apply $25 in credits
        if (customer.current_balance >= 25) {
            const result = await applyStoreCredits(25);
            console.log(`Applied: $${result.sac}`);
        }
    } catch (error) {
        console.error('Error:', error.message);
    }
}

Error Handling

Error

Cause

Solution

{"status_code": -4}

Customer email not found

Verify email is registered

{"status_code": -5}

No balance and no active subscription

Customer has no credits to use

{"status_code": -12}

Shopify customer not found

Customer not logged in properly

{"error": "Something went wrong..."}

Not logged into Shopify

Ensure customer is logged in


Cart Attributes Reference

Attribute

Description

subscribfy_checkout_storecredits_label

Display label ("Store Credits")

subscribfy_checkout_storecredits_value

Credit amount applied

subscribfy_checkout_storecredits_hash

Verification hash

subscribfy_store_credits_code

Legacy: discount code

subscribfy_store_credits

Legacy: credit amount

subscribfy_store_credits_id

Legacy: transaction ID


Customer Metafield

The customer's store credit balance is also available via Liquid:

##{{ customer.metafields.exison.exison_st }}

Best Practices

  • Always fetch fresh cart - Call /cart.js before each credit application

  • Include timestamp - Add &t={timestamp} to prevent caching

  • Handle login state - Check if customer is logged in before API calls

  • Validate amounts - Don't request more credits than available balance

  • Clear on cancel - Always remove credits if customer cancels checkout


Did this answer your question?