# Store Credit Import From File

The **Store Credit Import from File** feature adjusts Shopify store credit balances for multiple customers from a CSV file. Each row becomes one transaction — positive amounts **add** credit, negative amounts **subtract** credit — and you can configure amount, currency, and expiry independently per row. Positive and negative rows can be mixed in the same file. Optionally, the app can send a notification email per transaction.

> **When to use this vs other store credit operations:**
>
> * Use this when amounts, currencies, or expiry dates differ per customer.
> * Use [**Store Credit Bulk Add**](/bulk-operations/store-credit-bulk-add.md) when every recipient should receive the same amount and configuration.

{% hint style="warning" %}
**Prerequisite: new customer accounts.** Per Shopify, store credit can only be redeemed at checkout when the customer is authenticated via [**new customer accounts**](https://shopify.dev/docs/api/admin-graphql/latest/objects/StoreCreditAccount). If your store uses classic customer accounts, recipients won't be able to spend the credit. Check or switch under **Shopify Admin → Settings → Customer accounts**.
{% endhint %}

### 💡 **Common Use Cases**

* **Bulk refunds** — issue store credit to many customers from a refund report.
* **Loyalty rewards** — different credit amounts per customer tier.
* **Compensation campaigns** — credits sized per affected order.
* **Account migrations** — bring in credit balances from another platform.
* **Migration corrections** — subtract amounts customers redeemed on your old system after the initial import.
* **Bulk debits / clawbacks** — remove credit from many customers at once (e.g. after a promotional error or refund reversal).
* **Multi-currency stores** — different currencies per customer market.
* **Referral / affiliate payouts** — credit referrers based on a tracked list.

### **🪜 Step-by-Step Instructions**

<figure><img src="/files/Y1RUQOfe7abjCEOQcp8b" alt=""><figcaption></figcaption></figure>

1. **Download a template.**

{% file src="/files/JIDqhHSlSejV82cAjBYd" %}

{% file src="/files/vA2q3lSlNKIj2JglXitZ" %}

2. **Fill in your data.** See [CSV Columns](#csv-columns) below.
3. **Upload the file.** The form accepts `.csv`, `.tsv`, and `.txt` files up to **10 MB**. After upload, a summary shows the detected separator, row count, and column names. Validation errors (if any) are listed.
4. **Resolve ambiguous dates.** If `expires_at` contains dates like `01/05/2026`, the form asks whether the first number is the day or month and applies it to all rows.
5. **Configure customer notification (optional).** When the file contains an `email` or `customer_id` column, a **Send store credit notification** checkbox appears. Enable it and choose a sending method.
6. **Choose internal delivery options.** Allow data download and / or send yourself a summary email.
7. **Click Import now or Schedule.**

### **📋 CSV Columns**

#### Required

* **`amount`** — The transaction value. Use a **positive number** (e.g. `25.50`) to add store credit, or a **negative number** (e.g. `-25.50`) to subtract from the customer's existing balance. Use a dot as the decimal separator. Commas are auto-converted to dots, but more than two decimal places are rejected. See [Subtracting Store Credit (Debits)](#subtracting-store-credit-debits) for details on how negative rows are processed.

#### Identifying the customer (one of these is needed)

* **`email`** — Customer email. If a customer with this email exists, store credit is added to them. **If no matching customer exists, a new customer record is created with that email and the credit is issued to them.**
* **`customer_id`** — Numeric Shopify customer ID. Use this to avoid creating a new customer when an existing one matches the email.

> Rows with neither `email` nor `customer_id` are skipped (logged as errors in the operation report).

#### Optional

* **`currency_code`** — 3-letter ISO 4217 currency code (e.g. `USD`, `EUR`, `GBP`). If omitted, the store's default currency is used. The currency must be enabled in your Shopify store.
* **`expires_at`** — Expiry date for the credit. Supported formats: `YYYY-MM-DD` (recommended), `DD/MM/YYYY`, `MM/DD/YYYY`, `DD-MM-YYYY`, `MM-DD-YYYY`. If omitted, the credit never expires.

### **👤 Customer Lookup & Creation**

The import uses the following resolution order per row:

1. If `customer_id` is present, look up that customer.
2. Otherwise, search by `email`.
3. If no customer matches by email, create a new customer with that email and issue the credit to them.

> Creating a customer here is the same Shopify operation as adding a customer manually — Shopify's standard "welcome" behavior applies based on your store's settings.

### **➖ Subtracting Store Credit (Debits)**

Any row with a **negative** `amount` subtracts from the customer's existing store credit balance instead of adding to it. The same file can mix positive (credit) and negative (debit) rows freely — each row is processed independently.

**How debit rows are processed:**

1. The customer is looked up via `email` or `customer_id`. If no customer exists, the row is logged as an error (debits cannot create new customers — there'd be nothing to debit).
2. The customer's store credit account in the requested `currency_code` is fetched.
3. **If the customer has no store credit balance in that currency**, the row is logged as an error and skipped.
4. **If the requested debit is greater than the available balance** (e.g. row says `-50` but the customer only has `30` left), the account is **zeroed out** and an info-level message is logged. The row is counted as a success — over-debit never fails the row.
5. The amount actually debited and the new balance are written to the result CSV. Debits show as negative numbers in the **Balance Change** column.

> Debit rows ignore the `expires_at` column — debits don't have an expiry date.

### **✉️ Customer Notification (Optional)**

When the file contains an `email` or `customer_id` column, you can choose to email each customer about their transaction. Enable **Send store credit notification** and pick a sending method. Notifications are sent for **both increases and decreases** when opted in.

* **Shopify Email** — uses Shopify's built-in **Store credit issued** notification email. (Note: Shopify's built-in template only covers credits; for debit notifications use App Email, Flow, or Klaviyo.)
* **App Email** — uses Gift Card Factory's email infrastructure with a customizable template (built from the **Store credit import from file** or **Custom** template type). Preview before sending.
* **Shopify Flow** — fires a Flow trigger; you configure the action that sends the email.
* **Klaviyo** — fires a Klaviyo metric; you configure a flow that responds to the metric.

To differentiate copy for credits vs debits in your App Email / Klaviyo template, branch on `{{ issued_store_credit.transaction_type }}` — its value is either `"credit"` or `"debit"`. Example:

```liquid
{% if issued_store_credit.transaction_type == "debit" %}
  We've adjusted your store credit balance down by {{ issued_store_credit.amount | format_money: shop.currency_formats.money_format }}.
{% else %}
  We've added {{ issued_store_credit.amount | format_money: shop.currency_formats.money_format }} of store credit to your account.
{% endif %}
Your new balance is {{ issued_store_credit.balance_after_transaction | format_money: shop.currency_formats.money_format }}.
```

[Read more about each sending option](/misc/sending-customer-notifications.md).

### **📤 Internal Delivery Options**

Independent of customer notifications:

* **Allow store credits data download**: Creates a download link in the **Bulk Operations** section. Expires after **3 days**.
* **Send internal email with all generated store credits**: Sends a list of credit transactions to an email address you specify (multiple addresses allowed, comma-separated).

### **▶️ Running the Operation**

* **Import now**: Runs the operation immediately.
* **Schedule**: Runs the entire operation at a future date and time you select.

> Per-row scheduling via a `scheduled_on` column is **not** supported for store credit imports — only for [gift card imports](/bulk-operations/import-from-file/multiple-imports-from-a-single-file.md).

### **🧪 Examples**

#### Simple credits

```csv
amount,email
25.00,customer1@example.com
50.00,customer2@example.com
10.00,customer3@example.com
```

#### Credits with expiry

```csv
amount,email,expires_at
25.00,customer1@example.com,2027-12-31
50.00,customer2@example.com,2027-06-30
```

#### Multi-currency credits

```csv
amount,email,currency_code,expires_at
25.00,us-customer@example.com,USD,2027-12-31
20.00,uk-customer@example.com,GBP,2027-12-31
30.00,eu-customer@example.com,EUR,2027-12-31
```

#### Using customer IDs

```csv
amount,customer_id,currency_code
25.00,123456789,USD
50.00,987654321,USD
```

#### Mixed credits and debits (e.g. migration corrections)

```csv
amount,email,currency_code
-25.00,jane@example.com,USD
-10.50,john@example.com,USD
50.00,sarah@example.com,USD
```

### **📄 Result File Output**

After the operation finishes, a result CSV is generated with one row per transaction:

| Column              | Description                                                             |
| ------------------- | ----------------------------------------------------------------------- |
| **Id**              | Store credit account ID.                                                |
| **Customer Name**   | First + last name (if available).                                       |
| **Email**           | Customer email.                                                         |
| **Currency**        | Currency code of the transaction.                                       |
| **Balance Change**  | Amount applied. **Positive** for credits, **negative** for debits.      |
| **Current Balance** | Customer's store credit balance in that currency after the transaction. |

### **🚫 Limitations**

* **File size**: 10 MB maximum.
* **Currency must be enabled** in your Shopify store settings to be valid for that customer.
* **Debits require an existing store credit account** in the requested currency — debit rows for customers with no balance are skipped.
* **Debits ignore `expires_at`** — only credit transactions can have an expiry date.
* **No per-row scheduling** — use the Schedule button to run the whole import later, but every row runs together.

### **FAQ**

**My CSV has decimals like `25,50` and they're being rejected.**\
The decimal separator must be a dot (`.`). Commas are auto-converted, but check for currency symbols (`$`, `€`) or thousands separators in the same field — those are rejected.

**A row was skipped — why?**\
Rows are skipped if `amount` is missing or invalid, or if neither `email` nor `customer_id` resolves to (or creates) a customer. Check the operation log under Bulk Operations → details.

**A customer didn't get a notification email.**\
Confirm **Send store credit notification** was enabled, the row had an `email` or `customer_id` column with a valid value, and your sending method is configured (Shopify Email's Store credit issued template enabled / App Email domain validated / Flow configured / Klaviyo flow listening on the metric).

**I imported the same file twice — did customers get double credit?**\
Yes — the import always processes each row as a new transaction, it doesn't deduplicate. If you re-ran an import, each customer in the file will have been credited (or debited) twice. To reverse a duplicate run, re-upload the same file with the `amount` values negated.

**Can I use this to remove (debit) store credit?**\
Yes. Use a negative number in the `amount` column (e.g. `-25.00`) to subtract from a customer's existing balance. See [Subtracting Store Credit (Debits)](#subtracting-store-credit-debits).

**What happens if I try to debit more than the customer has?**\
The customer's account is zeroed out — only the available balance is debited — and the over-debit is recorded in the operation log. The row is counted as a success, not an error.

**Can I debit a customer who has never had store credit?**\
No. Debits require an existing store credit account in the requested currency. Rows trying to debit a customer with no balance in that currency are logged as errors and skipped.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.giftcardfactory.app/bulk-operations/store-credit-import-from-file.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
