Skip to main content
Changes to what your code talks to: routes and their fields, permissions, webhook events, limits, and the scripts and packages. Changes to the dashboard are in the guides. Each line starts with what kind of change it is. Removed and Changed are the ones that can need a change on your side.
APIWebhooksSDK

Email Templates

  • New: seven routes in Email Templates for Email Templates: the emails a store can write listed, one read with its original HTML, its variables and parts, changed, previewed for a sample buyer and put back as Shoply wrote it, and the CSS every email gets read and changed. They need two new permissions, emails.read and emails.write.
  • New: Get an email template answers originalSubjectSource, the original subject written with its variables (Your {{ store.name }} order is delivered ({{ order.id }})), beside originalSubject, which is the same for a sample buyer.
  • Changed: the subjects set by firstSubject, declinedSubject and secondSubject in Change Cart Recovery, and firstSubject and secondSubject in Change Win-Back, are the subjects Email Templates shows for those emails, and may hold their variables, such as {{ store.name }}.

Support Tickets

  • New: seven routes in Support Tickets for Support Tickets: the store’s tickets listed with four figures, one read with its conversation, a reply, resolve and reopen, the feature switched on or off, and a ticket’s picture. They need two new permissions, tickets.read and tickets.write.
  • New: five routes in the Customer API for the buyer’s half: their tickets listed with the orders they can ask about, a ticket opened, read, written on and resolved.
  • New: four webhook events: ticket.opened, ticket.message, ticket.resolved and ticket.reopened. An endpoint that takes every event gets them. See Webhook events.
  • New: emailTicketsEnabled and discordTicketsEnabled in Get email and alert settings.
  • New: @shoplygg/node 0.4.0, shoplygg/shoply-php 0.4.0 and shoply 0.4.0 have the new routes and events, and October 21’s too: 0.3.0 was never published.
  • New: html on each message of a ticket’s conversation, in Get a support ticket and the Customer API’s, and on ticket.message’s message: its body as Markdown draws it, escaped and safe to show as it is. Links go only to the web or an email address and open in a new tab; one whose words are not its address names its host after it; a picture written in Markdown is a link and never loaded. body is still the words as written.

Coupons for one tag

  • New: customerTag in Create a coupon and Update a coupon: empty for anybody with the code, vip, or the ID of one of the store’s tags. A buyer whose email does not wear it is refused the code at checkout and at Pay. Left out of an update, the coupon keeps its own. See A coupon for one tag.
  • New: customerTag on each coupon the API answers: null, or the tag with its name and colour, and live false where nobody can wear it now (VIP switched off, or a tag since deleted).
  • New: coupons on each of the store’s tags in List customer tags: how many coupons are only for it.

Saving the store’s settings

  • New: settingsVersion in Get the store, and expectedVersion taken by Update the store. It moves only when something that route saves changes, where updatedAt moves for every other setting of the store too: Support Tickets switched on, its tax, its payment options. Sent, a save is refused with stale_write only for a real change in between.
  • New: version in Get email and alert settings, the same for those settings.
  • Fixed: a coupon’s updatedAt no longer moves each time a buyer uses one, so Update a coupon sent with expectedUpdatedAt is no longer refused for a sale in between.

The Checkout Kit

  • Changed: kit.js 1.4. Where a product asks the buyer questions (custom fields), the payment piece asks them on a page of their own, with Continue to Payment in the pay piece, and then shows the payment methods with the answers on one line and Edit. The email and billing pieces are empty until then, and the summary piece no longer holds the questions. The line of answers has the class .shoply-kit-answers.

The customer panel’s downloads

  • New: downloads.orders in Get the signed-in buyer: the buyer’s paid orders newest first, each with what it bought, its own files and its own instructions, as the customer panel’s Downloads & Setup page now shows them. downloads.files and downloads.instructions, every order’s together, are answered as before.
  • New: @shoplygg/node 0.4.1, shoplygg/shoply-php 0.4.1 and shoply 0.4.1 type downloads.orders, and html on a ticket’s messages.

Order IDs

  • Changed: a new order’s ID is no longer a UUID. It reads a2855h0p1y4-71329ed4d95-1000427, 31 characters, and ends in a number that counts every order on Shoply. Orders made before keep their UUIDs, and every route and webhook answers either. Code that checks an order’s ID is a UUID has to stop: treat it as text of up to 36 characters. See IDs.
  • Changed: an order is named by its whole ID wherever it was named by the first eight characters: on its invoice PDF and the file’s name, in a dispute’s evidence, in {order} for a custom payment method, and in label on the orders a buyer’s support ticket can be about.
  • Fixed: shoply.js 1.26.1 empties the basket after a payment whose order has an ID of the new shape. 1.26.0 kept only a UUID as the checkout it remembered.
APIWebhooksSDK

Email Marketing and customer tags

  • New: nine routes in Email Marketing: Win-Back’s settings and figures, the buyers it writes to and one buyer, the subscribers’ figures, asking at checkout switched on or off, and the subscribers listed, exported and unsubscribed. They need two new permissions, marketing.read and marketing.write.
  • New: eight routes in Customers for tags: the store’s own listed, added, changed and deleted, VIP and Disputed Before changed, and a customer’s tags set, one put on and one taken off. Changing them needs a new permission, customers.tags; listing them is customers.read.
  • New: tags on a customer, in List customers, Get a customer and every customer. webhook. List customers and Export customers take tag, and only takes subscribed. The export has two more columns at its end, Tags and Subscribed.
  • New: six webhook events: customer.tagged, customer.untagged, winback.email_sent, winback.won_back, subscriber.subscribed and subscriber.unsubscribed. An endpoint that takes every event gets them. See Webhook events.
  • New: marketing_consent and won_back among the kinds in an order’s timeline.
  • Changed: a buyer who unsubscribes from a Win-Back email, or whom the store takes off its subscribers, gets no Cart Recovery emails either, and cart.unsubscribed and subscriber.unsubscribed are both sent for a Cart Recovery unsubscribe of a subscriber.
  • New: kit.js 1.3. The box asking for leave to email the buyer has the class .shoply-kit-consent.
  • New: the SDKs have the new routes from 0.4.0 (0.3.0, which was to carry them, was never published).

Apps and OAuth

  • New: apps that any seller connects to their store by OAuth’s authorization code flow, with PKCE. A seller approves an app on Shoply’s approval page, and the app’s server swaps the code at POST /v1/oauth/token for a token, shoply_at_..., which is a key of that store with the permissions approved. It works until the seller disconnects the app. POST /v1/oauth/revoke gives one up.
  • New: app in Get the current key, the app a token is for, or null for the store’s own keys.
  • New: two webhook events, app.connected and app.disconnected. An endpoint that takes every event gets them. See Webhook events.
  • Changed: a webhook endpoint made with an app’s token is deleted when the app is disconnected. One made with the store’s own key, or in the dashboard, is not.
  • New: @shoplygg/node 0.2.0, shoplygg/shoply-php 0.2.0 and shoply 0.2.0 take an app’s token as their key, and have oauth to get one: the approval address, a PKCE pair, the code swapped, a token given up.

Server SDKs

  • New: shoply 0.1.0 on PyPI, the API for your own server in Python 3.9 or later, as the Node.js and PHP packages are: every route as a method named after it, its fields as keyword arguments, TypedDict answers for mypy and your editor, retries with an Idempotency-Key, lists a page at a time or all with for, shoply.webhooks.verify, and shoply.Customer for the Customer API. Each route’s page shows its call in Python too.
  • New: shoplygg/shoply-php 0.1.0, the API for your own server in PHP 8.1 or later, as the Node.js package is: every route as a method named after it, array shapes for PhpStorm and PHPStan, retries with an Idempotency-Key, lists a page at a time or all with foreach, Shoply\Webhooks::verify, and Shoply\Customer for the Customer API. Each route’s page shows its call in PHP too.
  • Fixed: @shoplygg/node 0.1.1 sends kind with Add a file to a dispute’s answer. 0.1.0 left it out, so every file went as other and took the place of the one before.
  • Changed: @shoplygg/node 0.1.1 names its source, github.com/shoplygg/shoply-node, where issues can be filed.
  • New: @shoplygg/node 0.1.0, the API for your own server: every route as a typed method named after it, retries with an Idempotency-Key so a change is never made twice, lists a page at a time or all with for await, webhooks.verify for a delivery’s signature, and ShoplyCustomer for the Customer API. Each route’s page shows its call.

Customer API

  • New: the Customer API, 18 routes for a buyer’s own browser or app. A buyer signs in with a code emailed to them (Send a sign-in code, Sign in with the code) and gets a token, shoply_ct_..., for their own orders and keys, subscriptions and affiliate page at one store. No API key reaches these routes, and a buyer’s token reaches no other.

Disputes

  • Changed: Submit a dispute’s answer and Accept a dispute work for Revolut, Adyen, and PayPal connected with API keys, as well as Stripe: answeredFrom is here for those. Two new codes: provider_key (502) where the provider will not let the store’s key or app answer disputes, and file_not_taken (409) for a file the provider does not take (Adyen takes no PNG, and a PDF of up to 2 MB). See Disputes.
  • Changed: an Adyen chargeback that Adyen says can still be defended is needs_response, not lost, until Adyen says it was lost or its defense period ends.
  • New: 16 routes in Disputes: list and read a store’s disputes with what Shoply recorded about each order, save an answer, submit or accept a Stripe dispute, mark one as answered in its provider’s own dashboard, add files, get the answer as a PDF, hide what a disputed order delivered, and the dispute settings.
  • New: two permissions for them, disputes.read and disputes.write. A key made before today has neither.
  • New: five webhook events: dispute.opened, dispute.updated, dispute.won, dispute.lost and dispute.closed. An endpoint that takes every event gets them. See Webhook events.
  • New: disputes on an order in Get an order, its disputes newest first, and dispute_answered among the kinds in its timeline.
  • New: emailDisputeOpenedEnabled, emailDisputeClosedEnabled and discordDisputesEnabled in Get email and alert settings. They are the same three switches as emailOpened, emailClosed and discord in the dispute settings, which answer as before.

More of the dashboard through a key

Webhook events

  • New: order.payment_submitted, order.rerouted, review.removed, review.flag_declined, affiliate.balance_changed, cart.email_sent, cart.recovered, cart.unsubscribed, routing.processor_paused, routing.processor_resumed and fraud.checkout_blocked. An endpoint that takes every event gets them. Webhook events now says what data is for each group of events.
  • New: a cart has emailedAt, secondEmailAt, couponCode, recoveredOrderId and recoveredAt.
APIWebhooksSDKPayments

Subscriptions

  • New: 13 routes in Subscriptions. List and read subscriptions, their settings and the options sold by subscription, and cancel, undo a cancellation, pause, resume, add free days or email the renewal again.
  • New: two permissions for them, subscriptions.read and subscriptions.write. A key made before today has neither. Give it them with Edit Key in Developers, API Keys.
  • New: seven webhook events: subscription.started, subscription.renewed, subscription.cancelled, subscription.ended, subscription.paused, subscription.resumed and subscription.charge_failed. See Webhook events.
  • New: subscriptionId on an order, and runningSubscriptions on a product, the number of running subscriptions that deleting it would end.
  • New: shoply.js 1.26.0. Every variant in the catalogue has renews ({ every, unit }, or null for one sold once), and renews(variant) reads it.
  • New: @shoplygg/js and @shoplygg/react 0.1.1, with renews in their types.

Other changes

  • New: totals.recovered in Get the overview: the orders and revenue Cart Recovery brought back.
  • New: meta.routing.providers in List payment methods: the payment methods Payment Routing is choosing between.
  • New: autoReviews in Get email and alert settings.
  • Removed: couponTint from the email settings. It was added on October 13.
APISDK
  • New: eight routes in Storefront code. Read a storefront’s files, add, save, rename and delete one, give a storefront files of its own, and publish them. They use storefronts.read and storefronts.write, which keys already had.
  • New: the Shoply CLI, @shoplygg/cli, and the npm packages @shoplygg/js and @shoplygg/react, all at 0.1.0.
  • New: custom payment methods. An order paid with one has its ID in gateway (custom_ and 16 hex characters) and has customPayment, which says what the buyer was told and what they sent.
  • New: meta.order in List payment methods: connected and custom methods in the one order the checkout shows them.
  • New: emailCustomPaidEnabled and discordCustomPaidEnabled in the email settings.
APIPayments
  • New: custom fields. A variant has customFields and customFieldsOn, which the product routes read and write. An order has customFields, the buyer’s answers.
  • New: payment providers shopify, skrill, pandabase, tagada, rewarble, adyen, mercadopago and monei, as values of an order’s gateway.
  • New: authorizeUrl and copies on a payment method: where to send the seller to connect it, and what to copy into the provider’s own dashboard.
APISDKPayments
  • New: requests on an order: every webhook delivery and dynamic delivery Shoply sent your servers about it, newest first.
  • New: deliveryInstructions on a product, sent with whatever variant was bought. The create, update and bulk update routes take it.
  • New: unpaidHours on each payment method, and meta.unpaid with the store’s own time and its limits: how long an unpaid order is kept before it is cancelled.
  • New: Export blacklist rules and Export fraud events, under fraud.read.
  • New: checks on the store’s domain: whether it points at Shoply, is proved yours, and is secure.
  • New: payment providers skinloop, square, revolut, lemonsqueezy and amazonpaymentservices. A payment method’s field can have max, its own length limit.
  • New: kit.js 1.2. A cart line takes addons and offer, and kit.set() changes them.
  • Changed: Send an order’s email again is limited to five times an hour for one customer, across all their orders. It was five an hour for each order.
  • Changed: an upsell’s hideOwned is false unless you send it. It was true.
APISDK
  • New: seven routes in Upsells, with two permissions, upsells.read and upsells.write. An order line has addonOf and upsellId.
  • New: shoply.js 1.25.0: addons, together, setAddons, cartOffers, takeOffer and offersSeen.
  • New: blacklistedBy on a customer, every rule that refuses them. Clear a customer from the blacklist takes addresses.
  • Fixed: a category’s products are in the store’s own order. They came in no set order.
API
  • New: Export customers.
  • Changed: Export orders takes rows, orders or lines, and has every field an order’s page shows after its first thirteen columns, which are as they were.
  • New: both exports take check=1, which answers how many rows there are without sending the file. A file can be any length. Exports count toward 30 every 10 minutes a store.
  • Changed: a sale in Finance is what the buyer paid. Get profit has commission, affiliate commission counted as a cost. Get profit, Get the books and Export the books count toward 20 every 10 minutes a store, shared with the dashboard’s Generate Report.
APIWebhooksPayments
  • Changed: an endpoint that keeps refusing deliveries is held. From the second refusal in a row nothing more is sent to it until the hold ends, and then one delivery is tried. Up to 5,000 deliveries wait for one endpoint. See Webhooks.
  • New: payment providers whop, cryptomus, heleket, oxapay, nmi, mollie and sumup. A payment method’s switches have group and needs.
  • Removed: emailTint from the email settings. emailAccent is in its place.
API
APIWebhooks
  • New: the API, at https://api.shoply.gg/v1, behind a secret key for each store. 188 routes, 43 permissions, and a key can be held to addresses and domains of your own. See the introduction.
  • New: webhooks, 21 events, signed with X-Shoply-Signature. See Webhooks.