VulCode

Shopify integration with Allegro, InPost and Polish payments

Shopify works well worldwide, but the Polish market has its own needs: Allegro, parcel lockers, BLIK, wholesalers and KSeF. We connect them to your store through a custom Shopify app built on the GraphQL Admin API.

E-commerce platforms
The Shopify store integration panel: variants matched to Allegro offers by SKU or EAN, gaps to fill in and the custom app's scopes

The Polish market around a Shopify store

Some of these connections have ready apps or plugins. We write the rest as an app for your store.

Shopify storeGraphQL Admin API and webhooks
  • Allegro

    Our code. We match variants to offers by SKU or EAN, and gaps go to a list to fill in.

    • Stock
      AllegroShopify store
      a sale on one channel lowers stock on the other
    • Allegro orders
      AllegroShopify store
      are created in Shopify
  • InPost

    Ready connection. Shopify is on InPost's list of integrated platforms.

    • An order to ship
      Shopify storeInPost
    • Fulfilment and tracking
      InPostShopify store
      once the parcel is dispatched
  • Przelewy24 and BLIK

    Ready connection. Przelewy24 has a ready plugin for Shopify.

    • The order payment
      Przelewy24 and BLIKShopify store
  • Wholesalers

    Products, prices and stock from wholesaler files or APIs.

    • Wholesaler products
      WholesalersShopify store
      a new file or a wholesaler API change
  • KSeF

    Our code. Your invoicing app or ERP issues the invoices. Shopify does not send invoices to KSeF itself.

    • An order to invoice
      Shopify storeKSeF
    • The invoice with its KSeF number
      KSeFShopify store
      a link in the customer account or email
  • BaseLinker

    Shopify can be one of the channels in BaseLinker.

    • Sales channel data
      BaseLinkerShopify store

GraphQL, not REST

We build new integrations on the GraphQL Admin API. An app for one store can still call REST, but there is no reason to start with something Shopify is retiring.

Shopify itself is retiring REST

The REST Admin API is a legacy API as of October 1, 2024. Starting April 1, 2025, all new public apps must be built exclusively with the GraphQL Admin API.

Limits counted by query cost

250

items at most in one input array. In GraphQL each query has a cost, so we fetch only the fields needed and split changes into batches.

  • 25 000objects at most when paginating an array
  • 10 000new variants a day in a store with 500,000 variants

An import planned around the limit

A three-day plan for importing new Shopify variants: batches of 250 variants, at most 10,000 a day

Over 500,000 variants: new ones go in at 10,000 a day, in batches of 250, and the import ends on the third day.

A Shopify webhook verified and handled in time

Shopify waits 5 seconds for a reply and may send the same webhook more than once. Once a day a reconciliation job checks through the API that none was lost.

The Shopify webhook log in the integration panel: delivery headers, time to reply against 5 seconds, queued handling and the delivery list with a skipped duplicate
  • X-Shopify-Hmac-Sha256A signature over the raw bodyHMAC-SHA256 of the raw body, keyed with the app's client secret, compared with the X-Shopify-Hmac-SHA256 header. A mismatch gets a 401.
  • 200A reply well inside 5 secondsThe receiver replies at once, while the order for the warehouse and the Allegro stock go through a queue. After 8 failed tries over 4 hours Shopify deletes a subscription made via the API.
  • X-Shopify-Webhook-IdA duplicate by its delivery idThe same X-Shopify-Webhook-Id a second time gets a 200 without being handled again, so the order never reaches the warehouse twice.

A Shopify variant, an Allegro offer

One item as each system sees it: a variant from the GraphQL Admin API and an offer from the Allegro REST API. SKU or EAN joins them.

Shopify
GraphQL Admin API: productVariantJSON
{
"productVariant": {
"id": "gid://shopify/ProductVariant/4410",
"displayName": "Plecak miejski 20 l - grafit",
"sku": "PLC-20-GRF",
"barcodes": {
"nodes": [
{ "value": "5901234200014", "type": "EAN" }
]
},
"inventoryQuantity": 13
}
}
Allegro
GET /sale/product-offers/{offerId}JSON
{
"id": "17204500118",
"name": "Plecak miejski 20 l, grafit",
"external": { "id": "PLC-20-GRF" },
"productSet": [{
"product": {
"parameters": [
{ "name": "EAN", "values": ["5901234200014"] }
]
}
}],
"stock": { "available": 13 }
}
  • skuexternal.idThe variant SKU and the offer signature: the first shared key.
  • barcodes.nodes.valueparameters: EANEAN when the SKUs differ. Without either key the pair goes to the list to fill in.
  • inventoryQuantitystock.availableA Shopify order lowers the offer's stock, and an Allegro sale lowers the variant's.

What flows which way

  1. ShopifyWarehouse, ERP, channelsOrdersAn order webhook.
  2. Warehouse, ERP, channelsShopifyInventoryA warehouse document or an Allegro sale.
  3. Warehouse, ERP, channelsShopifyWholesaler productsA new file or a wholesaler API change.
  4. Warehouse, ERP, channelsShopifyFulfilment and trackingA parcel dispatched.
  5. Warehouse, ERP, channelsShopifyInvoice with a KSeF numberKSeF acceptance, a link in the customer account or email.

An App Store app or your own

The Shopify App Store is huge. We write a custom app for processes no ready app covers.

The same order: from the Shopify payment to the KSeF invoice and the Allegro stock
Ready apps alone

Payment and labels work at once. A Polish ERP, wholesaler and KSeF usually need an integration.

  1. Payment

    the ready Przelewy24 plugin

  2. Label

    the carrier's app

  3. The order in the ERP

    by hand

    retyped by hand

  4. The KSeF invoice

    only after the retyping

  5. Allegro stock

    from another app

A custom app

An app for your store on the GraphQL Admin API, with webhooks and code in a repository.

  1. Payment

    the same Przelewy24 plugin

  2. Label

    the same carrier app

  3. The order in the ERP

    from the webhook, through a queue

  4. The KSeF invoice

    from the ERP, the number back on the order

  5. Allegro stock

    from one source

Where ready apps alone stall

Polish ERP and wholesalers

The order in the ERP

Without an integration someone retypes every Shopify order into the ERP by hand.

KSeF outside Shopify

The KSeF invoice

Shopify does not send invoices to KSeF itself. The ERP issues the invoice, fed with the store's orders.

Apps overwrite each other

Allegro stock

Several ready apps do the same job and overwrite each other's stock, and each is its own subscription.

A ready app: Install and configure the app or the operator's plugin.

How we will do it: a Shopify store joins Allegro

The rollout, step by step.

Starting point
Store
Shopify, a warehouse in Poland
Goal
Selling on Allegro from one stock level
Problem
Retyping orders by hand and selling items already gone
The integration panel: Shopify variants matched to Allegro offers by SKU and EAN, the custom app's scopes and the offer stock after matching
  1. An app for the store

    We set up a custom app with scopes for products, inventory and orders only. Customers, discounts and the theme stay out of reach.

  2. A shared product key

    We match Shopify variants to Allegro offers by SKU or EAN, and gaps go to a list to fill in.

  3. Stock both ways

    An Allegro sale lowers stock in Shopify, and a Shopify order webhook lowers stock on Allegro offers.

  4. Orders in one place

    Allegro orders are created in Shopify, so the warehouse packs everything from one list.

Result: One stock level for two channels and one list of orders to pack.

Common questions about Shopify

Answers about the Polish market, KSeF, API versions and the quote.

Selling on Shopify in Poland?

Tell us what your store is missing: channels, payments, couriers or invoices. We will reply within an hour with questions and a quote.