# Printify Integration Research > Research notes from investigating Printify API integration, product syncing, and order submission risks. This document captures findings for future implementation work. ## Product Identity & Matching ### What identifiers exist? | Field | Stable? | Notes | |-------|---------|-------| | `id` (provider_product_id) | ❌ | Changes if product deleted & recreated | | `sku` (variant level) | ❌ | Auto-generated per product creation | | `blueprint_id` | ✅ | The base product type (e.g., Gildan 5000) | | `print_provider_id` | ✅ | The fulfillment provider | | `title` | ✅ | User-defined, stable unless edited | ### Our matching strategy 1. **Primary**: Match by `provider_product_id` 2. **Fallback**: Match by `slug` (derived from title) 3. **Potential improvement**: Match by `blueprint_id + print_provider_id + title` The slug fallback handles cases where Printify product IDs change (e.g., product deleted and recreated with same title). ### How Shopify/Printify official integration works - SKU is generated once when first published to Shopify - SKU becomes the stable link for future updates - Republishing matches by SKU - The "publish lock" prevents editing after publishing ## Duplicate Products ### When duplicates occur - Mock/test product generators run multiple times - User accidentally creates products twice in Printify - Migration scenarios with orphaned products - Using multiple POD providers on same store ### How we detect duplicates Same `title` (and therefore same `slug`) but different `provider_product_id`. In our test case, Printify returned 30 products but only 16 unique titles - every product existed twice with different IDs but identical: - `title` - `blueprint_id` - `print_provider_id` ### How we handle duplicates Our `upsert_product/2` function matches by slug when provider_product_id lookup fails, treating them as the same product and updating the provider_product_id to the latest value. ### Is this a common real-world issue? Research suggests **no** - duplicate products aren't commonly reported. Main sync issues are: - Orders not syncing - Store connection expiring - Publishing failures - Product info being overwritten on republish The official Shopify integration handles product identity well through SKUs. ## Sales Channel Integration Options ### Option 1: Personal API Token (current) - Pull products via API - Works immediately, no approval needed - We don't appear in Printify's "Publish to..." UI - Products not "locked" after sync ### Option 2: OAuth Platform Integration - Apply at printify.com/printify-api - ~1 week approval process - Merchants authorize SimpleShop via OAuth - We appear in Printify's publishing UI alongside Shopify/Etsy - Products get "published" TO us with lock - Webhooks for real-time updates **How publishing works in Option 2:** 1. Merchant clicks "Publish to SimpleShop" in Printify 2. Printify sends `product:publish:started` webhook 3. We create the product on our side 4. We call `publishing_succeeded.json` to confirm 5. Product locked in Printify, shows as "Published to SimpleShop" **Benefits of official integration:** - Publish lock prevents editing after publishing (data consistency) - Real-time webhooks - "Official" feel for merchants - Better UX in Printify dashboard **Downsides:** - Approval process - More complex OAuth auth - Ongoing partnership relationship ## Order Submission Risks ### How order submission works We send to Printify: ```elixir %{ product_id: "printify_product_id", variant_id: 12345, quantity: 2 } ``` We **do not send price**. Printify charges their current wholesale cost. ### Risk scenarios | Scenario | Result | Who bears cost? | |----------|--------|-----------------| | Wholesale cost increased | Order succeeds | Shop owner (you) | | Wholesale cost decreased | Order succeeds | Shop owner profits more | | Variant discontinued | Order **fails** | Customer experience | | Product deleted | Order **fails** | Customer experience | | Design changed | Order succeeds with new design | Customer gets wrong item | ### Why the publish lock matters In official integrations, the publish lock prevents merchants from editing products after publishing. This ensures: - Price consistency between storefront and fulfillment cost - Variant availability guaranteed - Design matches what customer saw Without the lock (our current approach), products can change between sync and order. ### Recommended mitigations 1. **Webhooks / frequent polling** - Subscribe to `product:updated`, `product:deleted` events - Or poll every N minutes for changes - Update local product data immediately 2. **Pre-checkout validation** - Before completing checkout, call Printify API - Verify variant still exists - Get current cost, compare to stored cost - Alert or block if significant difference 3. **Cost monitoring** - Store `cost` from Printify on each variant - During sync, compare old vs new cost - Alert shop owner if cost increased significantly - Consider auto-adjusting retail price 4. **Graceful order failure handling** - Catch "variant not found" errors - Notify customer immediately - Offer refund or alternative - Don't leave order in limbo 5. **Stale data warnings** - Track `last_synced_at` per product - Warn in admin if product not synced recently - Consider blocking orders for very stale products ## API Rate Limits From Printify documentation: - 600 requests/minute global - 100 requests/minute for catalog endpoints - 50 products per page max - Product publishing: 200 requests per 30 minutes ## Implementation Status ### Completed - [x] Product sync with pagination - [x] Parallel processing (5 concurrent) - [x] Slug-based fallback matching - [x] Error recovery (try/rescue) - [x] Checksum-based change detection ### Not yet implemented - [ ] Webhook endpoint for real-time updates - [ ] Pre-checkout variant validation - [ ] Cost change monitoring/alerts - [ ] OAuth platform integration (requires Printify approval) - [ ] `blueprint_id + print_provider_id` matching ## Open Source vs Managed Hosting Considerations ### The core tension SimpleShop exists in two forms: 1. **Open source** - self-hosted by anyone 2. **Managed hosting** - SaaS service run by us Printify's integration options have different implications for each. ### Personal API Token (current approach) **How it works:** - Each merchant creates their own Printify API token - Token entered in SimpleShop admin - Direct API access, no intermediary **Open source:** ✅ Works perfectly - Each self-hosted instance uses merchant's own token - No central service required - Full functionality **Managed hosting:** ✅ Works perfectly - Same as self-hosted - Each tenant uses their own token - No special relationship with Printify needed **Downsides:** - Merchants must manually create/manage API tokens - No "Connect with Printify" button UX - Products not locked after sync (data consistency risk) - No real-time webhooks (must poll or manual sync) ### OAuth Platform Integration **How it works:** - Register SimpleShop as an app with Printify - Get OAuth client ID/secret - Merchants click "Connect" and authorize - We receive access tokens, appear in Printify UI **Open source:** ❌ Problematic - OAuth requires registered callback URLs - Can't register infinite self-hosted domains - Would need to proxy through a central service - Defeats the "fully self-hosted" value proposition **Managed hosting:** ✅ Works well - Single registered callback URL - "Connect with Printify" button - Appears as official integration - Real-time webhooks - Publish lock for data consistency ### Hybrid approach possibilities **Option A: Token for open source, OAuth for managed** - Open source uses personal API tokens (current) - Managed hosting uses OAuth integration - Two code paths, more maintenance - Clear value differentiation **Option B: Webhook proxy service** - Register OAuth app - Self-hosted instances connect through managed webhook proxy - Proxy forwards webhooks to self-hosted URLs - Adds dependency on central service - Could be free tier for open source users **Option C: OAuth with self-registration** - Document how to register own OAuth app with Printify - Self-hosters go through Printify approval themselves - Complex, unlikely many would do this - Each instance is independent ### Business model implications | Approach | Open Source | Managed Hosting | |----------|-------------|-----------------| | Personal API Token | Full feature parity | No differentiation | | OAuth (managed only) | Basic sync only | Premium "official" integration | | Webhook proxy | Depends on proxy | Full features | **Potential differentiation for managed hosting:** - Official "Publish to SimpleShop" in Printify UI - Real-time sync via webhooks - Publish lock (data consistency guarantee) - Pre-checkout validation (verify before order) - No token management for merchants **What open source keeps:** - Full product sync (polling-based) - Order submission - All admin features - Self-hosted independence ### Printify partnership considerations **What registering as an app might require:** - Application/approval process (~1 week) - Technical integration review - Ongoing partnership relationship - Support obligations? - Usage/volume commitments? **Questions to research:** - [ ] What are Printify's requirements for app partners? - [ ] Are there fees or revenue sharing? - [ ] Can we register once for managed hosting only? - [ ] What support/SLA obligations exist? - [ ] Can app be limited to specific redirect URIs (managed only)? ### Recommendation **Phase 1 (now):** Personal API tokens for both versions - Works everywhere - No partnership dependencies - Validates product-market fit first **Phase 2 (if managed hosting gains traction):** OAuth for managed only - Apply for Printify app registration - Implement OAuth flow for managed platform - Keep token-based flow for open source - Use as value differentiator **Phase 3 (optional):** Webhook proxy for open source - If demand exists for real-time sync in self-hosted - Could be free or paid add-on - Maintains open source independence while adding capability ## References - [Printify API Reference](https://developers.printify.com/) - [Printify Help - Sales Channels](https://help.printify.com/hc/en-us/articles/4483630572945-Which-sales-channels-does-Printify-integrate-with) - [Printify Partner Application](https://printify.com/become-a-partner/) - [Shopify Product Status](https://community.shopify.com/t/what-is-the-difference-of-unpublished-product-draft-product/30964)