# Shopify Integration

The Gamopanda Shopify app adds three **Shopify Flow actions** and a **theme block** to your store. Flow actions let you trigger streak and challenge progress from any Shopify automation — order paid, checkout completed, loyalty event — without writing backend code. The theme block embeds the Gamopanda loyalty widget directly into your storefront, surfacing progress and rewards to logged-in customers in real time.

---

## Installation

Install the Gamopanda app from the Shopify App Store. Once installed, the Flow actions are immediately available in Shopify Flow and the theme block is available in your theme editor.

:::info
After installation, the app will store your `account_id` in a shop metafield (`gamopanda.account_id`) and `organization_id` in a shop metafield (`gamopanda.organization_id`). This is used automatically by the storefront widget — you do not need to configure it manually.
:::

---

## Floating widget

The Gamopanda **Storefront Script** is a theme block that embeds the loyalty widget into your storefront. It handles customer authentication automatically and renders the floating widget on every page where it is active.

### Adding the block to your theme

1. In your Shopify admin, go to **Online Store → Themes → Edit Theme**.
2. In the theme editor, open **App embeds**.
3. Find **Storefront Script** in the Gamopanda app blocks.
4. Configure the widget (see [Settings](#widget-settings) below).
5. Enable the **Storefront Script**
6. Save your theme.

#### Storefront Script block configuration

![Storefront Script block in the Shopify theme editor showing Template Id, Theme Id, and Floating Widget Id fields](/shopify-storefront-script-configuration.png)

---

### Widget settings

Configure the widget appearance and behaviour by entering the IDs from your Gamopanda dashboard:

| Setting | Description |
|---|---|
| **Template Id** | Controls the widget's copy and localisation. Find this in **Gamopanda → Templates**. See [Template](/template) for field details. |
| **Theme Id** | Controls the widget's colours and typography. Find this in **Gamopanda → Themes**. See [Theme](/theme) for field details. |
| **Floating Widget Id** | Controls the launcher button style and position. Find this in **Gamopanda → Floating Widgets**. See [Floating Widget](/floating_widget) for field details. |

All three fields are compulsory.

---

### How authentication works

The storefront block detects whether a customer is logged in and handles authentication accordingly:

**Logged-in customers**
The block calls the Gamopanda API server-side and fetches the user `accessToken`. The widget is initialised with the `accessToken`, giving the customer full access to their progress, milestones, and rewards.

**Guest visitors**
If no customer is logged in, the widget is initialised without an `accessToken`. The widget renders in guest mode — public content (e.g. how the programme works, available streaks and challenges) is visible, but personal progress is not shown until the customer logs in.

The locale of the storefront (`request.locale.iso_code`) is passed automatically — no extra configuration needed for multilingual stores.

---

### Rendered widget

#### Floating widget on storefront
![Floating Widget on Storefront](/floating-widget.png)

#### End User Display on storefront (logged-in customer)
![Logged In End User Display on Storefront](/loggedin-eud.png)

#### End User Display on storefront (guest visitor)
![Logged Out End User Display on Storefront](/loggedout-eud.png)

---

## Flow actions

:::note
Not on Shopify Plus?
The Flow actions below are custom app extensions that require Shopify Plus on some plans. If you're on a standard Shopify plan, you can achieve the same result using Flow's built-in **HTTP Request** action. [Jump to the HTTP Request guide](#using-http-request-in-flow-non-shopify-plus).
:::

### Execute Streak

**Logs a customer activity event that contributes to a streak.** Use this action in any Flow that tracks repeating behaviour — daily purchases, weekly visits, monthly workouts.

Internally, this action calls `POST /schema/streak_log/record` on your customer's behalf. See [Streak Logs](/streak-log) for field details.

#### Action fields

| Field | Required | Description |
|---|---|---|
| Customer | ✅ | The Shopify customer performing the activity. Resolved to a Gamopanda member automatically. |
| Streak Id | ✅ | The ID of the Gamopanda streak to log against. Found in your Gamopanda dashboard. |
| Activity Id | ✅ | The type of activity — e.g. `order_paid`, `visited_store`. |
| Activity Value | ✅ | The numeric value of the activity. Use `1` for `count` streaks. For `sum` streaks, pass the relevant value (e.g. order total). |
| Activity At | ✅ | The datetime the activity occurred. Used to determine the aggregation period. |
| Unique Identifier | The idempotency key so that duplicate requests are rejected. |

#### Action output

The action returns the created `StreakLog` record along with `streakProgress`, `achievedMilestone`(if any), `nextMilestone`(if any), `taskProgress` for the current period and `achievedMilestoneRewardLog`. You can use these output fields in downstream Flow steps. See [Streak Logs](/streak-log) for field details.

:::tip
If you are managing coupons on your own, use the `achievedMilestoneRewardLog.id` output to chain directly into the **Update Milestone Reward Log with Coupon** action — no extra lookup needed.
:::

#### Execute Streak Flow Action
![Execute Streak Flow Action](/execute-streak-flow-action.png)

---

### Execute Challenge

**Logs a customer activity event that contributes to a challenge.** Use this action to track cumulative progress toward a spend, visit, or activity target — for example, a monthly $500 spend challenge.

Internally, this action calls `POST /schema/challenge_log/record` on your customer's behalf. See [Challenge Logs](/challenge-log) for field details.

#### Action fields

| Field | Required | Description |
|---|---|---|
| Customer | ✅ | The Shopify customer performing the activity. Resolved to a Gamopanda member automatically. |
| Challenge Id | ✅ | The ID of the Gamopanda challenge to log against. Found in your Gamopanda dashboard. |
| Activity Id | ✅ | The type of activity — e.g. `order_paid`, `order_created`. |
| Activity Value | ✅ | The numeric value of the activity. Use `1` for `count` challenges. For `sum` challenges, pass the spend amount, step count, or other measurable value. |
| Activity At | ✅ | The datetime the activity occurred. |
| Unique Identifier | The idempotency key so that duplicate requests are rejected. |

#### Action output

The action returns the created `ChallengeLog` record along with `challengeProgress`, `achievedMilestone`(if any), `nextMilestone`(if any) for the current period and `achievedMilestoneRewardLog`. You can use these output fields in downstream Flow steps. See [Challenge Logs](/challenge-log) for field details.

:::tip
If you are managing coupons on your own, connect the `achievedMilestoneRewardLog.id` output directly to the **Update Milestone Reward Log with Coupon** action to issue a coupon in the same Flow, with no additional API calls.
:::

#### Execute Challenge Flow Action
![Execute Challenge Flow Action](/execute-challenge-flow-action.png)

---

### Execute Mission

**Logs a customer activity event that contributes to a mission.** Use this action to track cumulative progress toward a mission target — for example, a monthly $500 spend mission.

Internally, this action calls `POST /schema/mission_log/record` on your customer's behalf. See [Mission Logs](/mission-log) for field details.

#### Action fields

| Field | Required | Description |
|---|---|---|
| Customer | ✅ | The Shopify customer performing the activity. Resolved to a Gamopanda member automatically. |
| Mission Id | ✅ | The ID of the Gamopanda mission to log against. Found in your Gamopanda dashboard. |
| Activity Id | ✅ | The type of activity — e.g. `order_paid`, `order_created`. |
| Activity Value | ✅ | The numeric value of the activity. Use `1` for `count` missions. For `sum` missions, pass the spend amount, step count, or other measurable value. |
| Activity At | ✅ | The datetime the activity occurred. |
| Unique Identifier | The idempotency key so that duplicate requests are rejected. |

#### Action output

The action returns the created `MissionLog` record along with `missionProgress`, `achievedMilestone`(if any), `nextMilestone`(if any) for the current period and `achievedMilestoneRewardLog`. You can use these output fields in downstream Flow steps. See [Mission Logs](/mission-log) for field details.

:::tip
If you are managing coupons on your own, connect the `achievedMilestoneRewardLog.id` output directly to the **Update Milestone Reward Log with Coupon** action to issue a coupon in the same Flow, with no additional API calls.
:::

#### Execute Mission Flow Action
![Execute Mission Flow Action](/execute-mission-flow-action.png)

---

### Update Milestone Reward Log with Coupon

:::info
Gamopanda comes with rewards and coupons management.
If you have set `handleCoupon` to `true` on the parent Reward configuration, you don't need this action.
:::

**Stamps a coupon code and issuance timestamps onto a Reward Log.** Use this action immediately after **Execute Streak** or **Execute Challenge** detects a milestone crossing — it fulfils the reward by writing the coupon code back to the Reward Log record.

#### Action fields

| Field | Required | Description |
|---|---|---|
| Customer | ✅ | The Shopify customer who earned the reward. |
| Reward Log Id | ✅ | The ID of the Reward Log to update. Use the `achievedMilestoneRewardLog.id` output from **Execute Streak** or **Execute Challenge**. |
| Coupon Code | ✅ | The discount code issued to the customer. Generate this via Shopify's built-in discount actions before this step. |
| Reward Issued At | ✅ | The datetime the reward was issued. |
| Reward Expiry At | ✅ | The datetime the reward expires. |

#### Typical Flow pattern

```
Trigger: Order paid
  → Execute Streak / Execute Challenge
    → Condition: achievedMilestoneRewardLog.id is not empty
      → Create Discount Code (Shopify native)
        → Update Milestone Reward Log with Coupon
```

#### Update Milestone Reward Log with Coupon Flow Action
![Update Milestone Reward Log with Coupon Flow Action](/update-milestone-reward-log.png)

---

## Using HTTP Request in Flow (non-Shopify Plus)

The Gamopanda Flow actions above are **custom app extensions** — on some Shopify plans these require Shopify Plus. If your store is on a standard plan and cannot use custom app actions, you can replicate the same behaviour using Shopify Flow's built-in **HTTP Request** action to call the Gamopanda API directly.

:::info
The HTTP Request action is available on all Shopify plans that include Flow. You will need your Gamopanda `x-api-key` and `x-api-secret` to authenticate requests.
:::

---

### Logging a streak activity

Use the **HTTP Request** action to call `POST /schema/streak_log/record`. See [Streak Logs](/streak-log) for the full list of fields, required parameters, and response structure.

**HTTP Request configuration:**

| Setting | Value |
|---|---|
| URL | `/api/v1.0/schema/streak_log/record` |
| Method | `POST` |
| Headers | `x-api-key: <your-api-key>` · `x-api-secret: <your-api-secret>` · `Content-Type: application/json` |

**Request body** (map Flow variables to these fields):

```json
{
  "streakId": "your-streak-id",
  "ownedBy": {
    "externalId": "{{ order.customer.id }}"
  },
  "activityId": "order_paid",
  "uniqueIdentifier": "your-streak-id_{{ order.id }}",
  "activityAt": "{{order.processedAt}}",
  "activityValue": "{{order.currentSubtotalPriceSet.shopMoney.amount}}",
  "status": "live"
}
```

See [Streak Logs](/streak-log) for the full field reference and response details, including how to read `achievedMilestoneRewardLog` from the response to chain into a coupon update step.

:::tip
If you are managing coupons on your own, check `achievedMilestoneRewardLog.id` in the HTTP response body. If it is not empty, a milestone was just crossed — use it as the `Reward Log Id` in a follow-up **HTTP Request** to [update the reward log with a coupon](#updating-a-reward-log-with-a-coupon).
:::

### Logging a challenge activity

Use the **HTTP Request** action to call `POST /schema/challenge_log/record`. See [Challenge Logs](/challenge-log) for the full list of fields, required parameters, and response structure.

**HTTP Request configuration:**

| Setting | Value |
|---|---|
| URL | `/api/v1.0/schema/challenge_log/record` |
| Method | `POST` |
| Headers | `x-api-key: <your-api-key>` · `x-api-secret: <your-api-secret>` · `Content-Type: application/json` |

**Request body** (map Flow variables to these fields):

```json
{
  "challengeId": "your-challenge-id",
  "ownedBy": {
    "externalId": "{{ order.customer.id }}"
  },
  "activityId": "order_paid",
  "uniqueIdentifier": "your-streak-id_{{ order.id }}",
  "activityAt": "{{order.processedAt}}",
  "activityValue": "{{order.currentSubtotalPriceSet.shopMoney.amount}}",
  "status": "live"
}
```

See [Challenge Logs](/challenge-log) for the full field reference and response details, including how to read `achievedMilestoneRewardLog` from the response to trigger a reward.

:::tip
If you are managing coupons on your own, check `achievedMilestoneRewardLog.id` in the HTTP response body. If it is not empty, a milestone was just crossed — use it as the `Reward Log Id` in a follow-up **HTTP Request** to [update the reward log with a coupon](#updating-a-reward-log-with-a-coupon).
:::

### Logging a mission activity

Use the **HTTP Request** action to call `POST /schema/mission_log/record`. See [Mission Logs](/mission-log) for the full list of fields, required parameters, and response structure.

**HTTP Request configuration:**

| Setting | Value |
|---|---|
| URL | `/api/v1.0/schema/mission_log/record` |
| Method | `POST` |
| Headers | `x-api-key: <your-api-key>` · `x-api-secret: <your-api-secret>` · `Content-Type: application/json` |

**Request body** (map Flow variables to these fields):

```json
{
  "missionId": "your-mission-id",
  "ownedBy": {
    "externalId": "{{ order.customer.id }}"
  },
  "activityId": "order_paid",
  "uniqueIdentifier": "your-mission-id_{{ order.id }}",
  "activityAt": "{{order.processedAt}}",
  "activityValue": "{{order.currentSubtotalPriceSet.shopMoney.amount}}",
  "status": "live"
}
```

See [Mission Logs](/mission-log) for the full field reference and response details, including how to read `achievedMilestoneRewardLog` from the response to trigger a reward.

:::tip
If you are managing coupons on your own, check `achievedMilestoneRewardLog.id` in the HTTP response body. If it is not empty, a milestone was just crossed — use it as the `Reward Log Id` in a follow-up **HTTP Request** to [update the reward log with a coupon](#updating-a-reward-log-with-a-coupon).
:::

### Updating a reward log with a coupon

:::info
If you have set `handleCoupon` to `true` on the parent Reward configuration, you don't need this action.
:::

Once a milestone is crossed (detected from the `achievedMilestoneRewardLog` in the streak or challenge log response), use a second **HTTP Request** action to stamp the coupon. See [Reward Log](/reward_log) for field details.

**HTTP Request configuration:**

| Setting | Value |
|---|---|
| URL | `/api/v1.0/schema/reward_log/record/{{ achievedMilestoneRewardLog.id }}` |
| Method | `PATCH` |
| Headers | `x-api-key: <your-api-key>` · `x-api-secret: <your-api-secret>` · `Content-Type: application/json` |

**Request body:**

```json
{
  "couponCode": "{% for codes_item in sendAdminApiRequest.codeDiscountNode.codeDiscount.DiscountCodeBasic.codes %}{{codes_item.code}}{% endfor %}",
  "rewardIssuedAt": "{{sendAdminApiRequest.codeDiscountNode.codeDiscount.DiscountCodeBasic.createdAt}}",
  "rewardExpiryAt": "{{sendAdminApiRequest.codeDiscountNode.codeDiscount.DiscountCodeBasic.endsAt}}"
}
```

See [Reward Log](/reward_log) for the full field reference

#### Typical HTTP Request chain

```
Trigger: Order paid
  → HTTP Request: POST streak_log / challenge_log
    → Condition: body.achievedMilestoneRewardLog.id is not empty
      → Create Discount Code (Shopify native)
        → HTTP Request: PATCH reward_log with coupon
          → Send email to customer with coupon
```

| Resource | Description |
|---|---|
| [Streak](/streak) | Configure the streaks your Flow actions log against |
| [Challenge](/challenge) | Configure the challenges your Flow actions log against |
| [Milestone](/milestone) | Reward checkpoints that trigger the reward log |
| [Reward Log](/reward_log) | The reward record updated by **Update Milestone Reward Log with Coupon** |
| [Template](/template) | Widget copy and localisation settings |
| [Theme](/theme) | Widget visual styling |
| [Floating Widget](/floating_widget) | Launcher button configuration |
