← Files StripeARCHIVED FILE

skills/stripe-apps/references/publishing.md

5.72 KB · Oct 5, 2026 · 12:04 UTC

↓ Download file

# Publishing — versioning, releases, test vs live mode, marketplace

## Publishing

How to version, release, and publish your Stripe App.

## Test mode vs live mode

**Plain-language:** “Test mode uses fake data so you can try things safely. Live mode uses real customer data. Always build and test in test mode first.”

| Mode | Data | When to use |
| --- | --- | --- |
| Test mode | Fake (test cards, test customers) | Development and QA |
| Live mode | Real customer and payment data | Production |

**Workflow:** Upload → install in test mode → test thoroughly → install in live mode.

**Do not skip test mode testing.** Even if your app looks correct locally with `stripe apps start`, you must install it in test mode and verify it works with the actual install flow before going live.

## Versioning

Bump `version` in `stripe-app.yaml` before each upload:

```yaml
id: com.example.my-app
version: 1.0.1
name: My App
```

Use semantic versioning:

- `1.0.0` — initial release
- `1.0.1` — bug fix
- `1.1.0` — new feature (backward compatible)
- `2.0.0` — breaking change or major feature

**Rules:**

- Versions must be uploaded in order — if you upload `2.0.0` before `1.0.0`, `2.0.0` won’t be available for release
- You can have multiple uploaded versions; you choose which one to install
- Stripe auto-upgrades installed users to the latest release — they don’t need to do anything **unless** you changed permissions

## Upload and release workflow

```bash
# 1. Bump version in stripe-app.yaml, then:
stripe apps upload

# 2. Go to Dashboard → Apps → your app → version history
# 3. Click the version you want to release
# 4. Click "Set as external test version" (test mode) or "Release" (live mode)
```

## When you change permissions

This is a common source of bugs. When you add new permissions:

1. Update `stripe-app.yaml` with the new permissions
2. Bump the version and upload
3. Existing users are notified by email
4. The **“Review Permissions”** button appears — but only on the **Apps workload page** ([dashboard.stripe.com/apps](https://dashboard.stripe.com/apps)), **not on the app itself**
5. The app returns an **invalid-request error** for the new permissions until the user clicks “Review Permissions” and re-authorizes

**Always warn users about this step** when you change permissions. Many users miss the notification and think the app is broken.

**How to notify users:** Consider adding a banner in your app UI that detects when a required permission is missing and guides the user to re-authorize.

## Publishing to the Stripe Apps Marketplace

For public apps — making your app available to all Stripe users.

### Requirements

Before submitting:

- Verified email address on your Stripe account
- Business details filled in (legal name, address)
- App passes [review requirements](https://docs.stripe.com/stripe-apps/review-requirements.md)
- Connect platform accounts cannot publish marketplace apps

### Submission

1. Go to [Dashboard → Apps](https://dashboard.stripe.com/apps)
2. Select your app
3. Click **Submit for review**

Stripe reviews your app for security, functionality, and compliance with their guidelines.

### Review requirements overview

- App must work correctly in test and live mode
- No prohibited content or misleading claims
- Privacy policy URL required
- Support contact required
- App icon and screenshots required

### After approval

Your app appears in the [Stripe Apps Marketplace](https://marketplace.stripe.com/). Any Stripe user can install it.

## Troubleshooting uploads

**Successful upload looks like:**

```
Uploading... Done
Your app has been uploaded to version 0.0.1.
```

**Common upload failures and fixes:**

| Error | Cause | Fix |
| --- | --- | --- |
| `Invalid manifest` / validation failed | Missing required fields or malformed YAML | Check indentation; ensure `id:`, `version:`, `name:` are present |
| `Build failed` / TypeScript errors | UI component has type/import errors | Run `pnpm build` locally first to see the exact error |
| `Version already exists` | Already uploaded this version number | Bump `version` in stripe-app.yaml (e.g. 0.0.1 → 0.0.2) |
| `Permission denied` / `Not authenticated` | CLI not logged in or wrong account | Run `stripe login` and verify with `stripe config --list` |
| `connect-src` / CSP error | App calls a URL not declared in content_security_policy | Add the URL to `content_security_policy.connect-src` in stripe-app.yaml |
| `extensions field required` | Missing `extensions: []` in stripe-app.yaml | Add `extensions: []` even if you have no backend extensions |
| `Component not found` | Viewport references a component name that doesn’t match your export | Ensure `component:` in stripe-app.yaml matches your default export name |

**Debugging steps when upload fails:**

1. Read the full error message — it usually says exactly what’s wrong
2. Run `pnpm build` to check for TypeScript/build errors locally
3. Validate your stripe-app.yaml has all required fields (id, version, name, declarations)
4. Check that file paths match (ui/src/views/App.tsx, not a renamed file)
5. If still stuck: `stripe apps upload --verbose` for detailed output

## Sandboxes for app development

Sandboxes provide isolated environments for safe app development and testing.

**Benefits of using Sandboxes:**

- Isolated from your live account — test destructive operations safely
- Each sandbox has its own app installation and signing secrets
- Useful for testing onboarding flows, uninstall/reinstall cycles, and permission changes

**How to use:**

1. Create a sandbox from Dashboard → Sandboxes
2. Run `stripe apps start` targeting the sandbox
3. Upload and install your app in the sandbox to test the full install flow
4. When ready, upload to your main account for production use

SHA-256: 719e4f2b5aede603bb28fb626f6f2c36f81fd90b25fed91f7fd7e2d9afe78be1