Skip to main content

Changelog

Developer Changelog

We regularly update our API and provide detailed notes on each release. We first release to staging, then to production about a week later. Learn more about our release process.

: Staging

: Production

✨ New

Addresses

Country area code display for address forms

Added the detailedAllowedCountryAreas field to the CountryDisplay model for displaying area codes in address forms. This field replaces the deprecated CountryDisplay.allowedCountryAreas field.

🪲 Fixed

Discounts

Fixed an issue where non-qualifying items were incorrectly counted towards the minimum quantity requirement for voucher eligibility.

Auth

Fixed an issue where using app authentication to query productVariants sometimes triggered an 'App' object has no attribute 'is_anonymous' error.

🚫 Deprecated

Addresses

Deprecated the CountryDisplay.allowedCountryAreas field. This field will be removed after 2024-12-31.

: Staging

: Production

✨ New

Users

Last status changed at field

Added a lastStatusChangedAt field to the User model. This field updates with the current datetime whenever there's a change in the isActive status for any user (customer or staff).

🪲 Fixed

Microsites

Fixed a pagination loop issue caused by identical endCursor and startCursor values when querying microsite.products.

: Staging

: Production

✨ New

Integrations

WorkOS Authentication plugin

Added support to connect to WorkOS authentication, an SSO tool that supports various identity providers.

The existing createCustomerToken mutation has been extended to accept WorkOS as an oauthProviderSource. You can use this mutation to exchange a WorkOS access token for a nauticalToken after activating the plugin.

Mutation
mutation {
createCustomerToken(
oauthProviderSource: WORKOS
oauthProviderToken: "[ACCESS_TOKEN]"
) {
nauticalToken
refreshToken
authErrors {
field
message
}
}
}

💎 Changed

Payouts

NOT_PAID payout status

Updated the OrderPayoutStatusEnum to include the NOT_PAID payout status for orders in the new financial ledgers system.

note

When using the new ledger system for payouts, only the states NOT_PAID, PAID_OUT, PARTIALLY_PAID_OUT, and ERROR will be used.

Integrations

Updated Shopify API version

Migrated Shopify plugin instances to use the latest Shopify API version.

🪲 Fixed

Webhooks

Fixed an issue where the product_updated webhook was not being triggered when an image was added to a product or variant.

Payments

Fixed an issue where successful capture of ACH payments with Stripe were not updating as paid in Nautical.

Emails

Fixed an issue where the "Partial Order Cancel" and "Pending Quote" buyer emails were stored with the Admin Email Templates.

Catalog

Fixed an issue where the productUpdate mutation required the category input even when a category was previously assigned.

: Staging

: Production

✨ New

Payouts

Financial ledgers with queryable journals

Added a new financial modelling system, using double-entry accounting that automatically records data to a balanced ledger through various order and payout related events.

This updated model aligns with ASC 606 revenue recognition standards, providing a clear and auditable financial trail of how revenue is recognized and split between the marketplace and its sellers. Central to this feature is the MarketplaceConfiguration.revenueAccrualStrategy field, which determines how revenue is recognized in alignment with your operational needs.

Feature Enablement

For marketplaces to benefit from this new feature, a Nautical representative must enable it. Contact Nautical Support for assistance.

You can leverage the journalEntries query to view journal entries, using filters like order ID or journal entry type via JournalEntryFilterInput. Here's a sample GraphQL query and response that demonstrates how you can retrieve the first 10 journalEntries related to a marketplace order:

Request
query {
journalEntries(
filter: { nauticalOrderIds: "TmF1dGljYWxPcmRlcjoxNjU4" }
first: 10
sortBy: { direction: ASC, field: DATE }
) {
edges {
node {
id
type
description
createdAt
order {
id
}
ledgerEntries {
ledgerBalance {
baseAmount
}
ledger {
id
type
accountType
balance {
baseAmount
}
}
}
}
}
}
}
Show more ↓
Response
{
"data": {
"journalEntries": {
"edges": [
{
"node": {
"id": "Sm91cm5hbEVudHJ5OjEyNzk=",
"type": "ORDER_PLACED",
"description": "NauticalOrder TmF1dGljYWxPcmRlcjoxNjU4 placed",
"createdAt": "2024-03-12T13:28:47.755267+00:00",
"order": null,
"ledgerEntries": [
{
"ledgerBalance": {
"baseAmount": -9552473
},
"ledger": {
"id": "TGVkZ2VyOjM=",
"type": "DEFERRED_SALES_REVENUE",
"accountType": "REVENUE",
"balance": {
"baseAmount": -10014369
}
}
},
{
"ledgerBalance": {
"baseAmount": -975237
},
"ledger": {
"id": "TGVkZ2VyOjEw",
"type": "SALES_TAX",
"accountType": "LIABILITY",
"balance": {
"baseAmount": -1024184
}
}
},
{
"ledgerBalance": {
"baseAmount": -274000
},
"ledger": {
"id": "TGVkZ2VyOjI=",
"type": "DEFERRED_SHIPPING_REVENUE",
"accountType": "REVENUE",
"balance": {
"baseAmount": -314000
}
}
},
{
"ledgerBalance": {
"baseAmount": 8681638
},
"ledger": {
"id": "TGVkZ2VyOjE1OQ==",
"type": "CUSTOMER_RECEIVABLE",
"accountType": "ASSET",
"balance": {
"baseAmount": 8617168
}
}
}
]
}
},
{
"node": {
"id": "Sm91cm5hbEVudHJ5OjEyODA=",
"type": "PAYMENT_CAPTURED",
"description": "Payment UGF5bWVudDoxMjkx captured",
"createdAt": "2024-03-12T13:29:05.541593+00:00",
"order": null,
"ledgerEntries": [
{
"ledgerBalance": {
"baseAmount": 10050882
},
"ledger": {
"id": "TGVkZ2VyOjU=",
"type": "FUNDS_PAYMENTS",
"accountType": "ASSET",
"balance": {
"baseAmount": 10183826
}
}
},
{
"ledgerBalance": {
"baseAmount": 8362918
},
"ledger": {
"id": "TGVkZ2VyOjE1OQ==",
"type": "CUSTOMER_RECEIVABLE",
"accountType": "ASSET",
"balance": {
"baseAmount": 8617168
}
}
}
]
}
},
{
"node": {
"id": "Sm91cm5hbEVudHJ5OjEyODE=",
"type": "ORDER_ACCRUED",
"description": "OrderLine T3JkZXJMaW5lOjU2MTQ= accrued",
"createdAt": "2024-03-12T13:29:15.517609+00:00",
"order": {
"id": "T3JkZXI6Mjg5NQ=="
},
"ledgerEntries": [
{
"ledgerBalance": {
"baseAmount": -9531073
},
"ledger": {
"id": "TGVkZ2VyOjM=",
"type": "DEFERRED_SALES_REVENUE",
"accountType": "REVENUE",
"balance": {
"baseAmount": -10014369
}
}
},
{
"ledgerBalance": {
"baseAmount": 124120
},
"ledger": {
"id": "TGVkZ2VyOjY0",
"type": "SELLER_PAYABLE",
"accountType": "LIABILITY",
"balance": {
"baseAmount": 181900
}
}
}
]
}
},
{
"node": {
"id": "Sm91cm5hbEVudHJ5OjEyODI=",
"type": "COMMISSION",
"description": "OrderLine T3JkZXJMaW5lOjU2MTQ= commission",
"createdAt": "2024-03-12T13:29:15.517719+00:00",
"order": {
"id": "T3JkZXI6Mjg5NQ=="
},
"ledgerEntries": [
{
"ledgerBalance": {
"baseAmount": 127330
},
"ledger": {
"id": "TGVkZ2VyOjY0",
"type": "SELLER_PAYABLE",
"accountType": "LIABILITY",
"balance": {
"baseAmount": 181900
}
}
},
{
"ledgerBalance": {
"baseAmount": -2939495
},
"ledger": {
"id": "TGVkZ2VyOjc=",
"type": "MARKETPLACE_COMMISSION",
"accountType": "REVENUE",
"balance": {
"baseAmount": -2997415
}
}
}
]
}
},
{
"node": {
"id": "Sm91cm5hbEVudHJ5OjEyODM=",
"type": "SHIPPING_ACCRUED",
"description": "Order T3JkZXI6Mjg5NQ== shipping accrued",
"createdAt": "2024-03-12T13:29:15.517770+00:00",
"order": {
"id": "T3JkZXI6Mjg5NQ=="
},
"ledgerEntries": [
{
"ledgerBalance": {
"baseAmount": -272000
},
"ledger": {
"id": "TGVkZ2VyOjI=",
"type": "DEFERRED_SHIPPING_REVENUE",
"accountType": "REVENUE",
"balance": {
"baseAmount": -314000
}
}
},
{
"ledgerBalance": {
"baseAmount": -541850
},
"ledger": {
"id": "TGVkZ2VyOjk=",
"type": "MARKETPLACE_FEES",
"accountType": "REVENUE",
"balance": {
"baseAmount": -536950
}
}
}
]
}
},
{
"node": {
"id": "Sm91cm5hbEVudHJ5OjEyODQ=",
"type": "ORDER_ACCRUED",
"description": "OrderLine T3JkZXJMaW5lOjU2MTU= accrued",
"createdAt": "2024-03-12T13:29:15.691871+00:00",
"order": {
"id": "T3JkZXI6Mjg5Ng=="
},
"ledgerEntries": [
{
"ledgerBalance": {
"baseAmount": -9256073
},
"ledger": {
"id": "TGVkZ2VyOjM=",
"type": "DEFERRED_SALES_REVENUE",
"accountType": "REVENUE",
"balance": {
"baseAmount": -10014369
}
}
},
{
"ledgerBalance": {
"baseAmount": 978750
},
"ledger": {
"id": "TGVkZ2VyOjY1",
"type": "SELLER_PAYABLE",
"accountType": "LIABILITY",
"balance": {
"baseAmount": 1572500
}
}
}
]
}
},
{
"node": {
"id": "Sm91cm5hbEVudHJ5OjEyODU=",
"type": "COMMISSION",
"description": "OrderLine T3JkZXJMaW5lOjU2MTU= commission",
"createdAt": "2024-03-12T13:29:15.692001+00:00",
"order": {
"id": "T3JkZXI6Mjg5Ng=="
},
"ledgerEntries": [
{
"ledgerBalance": {
"baseAmount": 1020000
},
"ledger": {
"id": "TGVkZ2VyOjY1",
"type": "SELLER_PAYABLE",
"accountType": "LIABILITY",
"balance": {
"baseAmount": 1572500
}
}
},
{
"ledgerBalance": {
"baseAmount": -2980745
},
"ledger": {
"id": "TGVkZ2VyOjc=",
"type": "MARKETPLACE_COMMISSION",
"accountType": "REVENUE",
"balance": {
"baseAmount": -2997415
}
}
}
]
}
},
{
"node": {
"id": "Sm91cm5hbEVudHJ5OjEyODY=",
"type": "SHIPPING_ACCRUED",
"description": "Order T3JkZXI6Mjg5Ng== shipping accrued",
"createdAt": "2024-03-12T13:29:15.692050+00:00",
"order": {
"id": "T3JkZXI6Mjg5Ng=="
},
"ledgerEntries": [
{
"ledgerBalance": {
"baseAmount": -266500
},
"ledger": {
"id": "TGVkZ2VyOjI=",
"type": "DEFERRED_SHIPPING_REVENUE",
"accountType": "REVENUE",
"balance": {
"baseAmount": -314000
}
}
},
{
"ledgerBalance": {
"baseAmount": -547350
},
"ledger": {
"id": "TGVkZ2VyOjk=",
"type": "MARKETPLACE_FEES",
"accountType": "REVENUE",
"balance": {
"baseAmount": -536950
}
}
}
]
}
}
]
}
}
}
Show more ↓

Learn more ->

💎 Changed

Webhooks

Voucher data in order webhooks

The voucher field is now part of all order and nauticalOrder webhook payloads, providing the following voucher data: id, name, type, discountValue, and discountValueType.

Emails

Order line metadata in email payloads

Non-private metadata for orderLines and nauticalOrderLines will now be included in all order-related email payloads. Update your email templates to make use of order line metadata.

🪲 Fixed

Discounts

Fixed an issue where vouchers created with the option "Specific products" selected caused items to be discounted automatically without entering the voucher code.

: Staging

: Production

✨ New

Catalog

Visibility field for collections

Added the isVisible boolean field to the collection object.

Vendor mgmt

New seller statuses

Added the following statuses to the SellerStatus enum:

  • SUSPENDED
  • BANNED
  • DEACTIVATED

💎 Changed

Orders

Customer order count

Changed customer.numOrders to resolve the total number of marketplace orders instead of seller orders.

🪲 Fixed

Emails

Fixed an issue preventing the order refund confirmation and CSV export emails from sending.

Integrations

Fixed an issue with Stripe webhook processing to handle webhook errors appropriately.

: Staging

: Production

💎 Changed

Webhooks

Webhook event type and timestamp in payload body

The nautical_event_type and nautical_event_timestamp fields are now part of every webhook payload body, whereas previously this information was only accessible from the header. For example:

  "nautical_event_type": "nautical_order_created",
"nautical_event_timestamp": "2024-02-22T15:24:19.374608-05:00",

: Staging

: Production

✨ New

Integrations

Firebase Authentication plugin

Added support to connect to Firebase authentication, a tool that supports various sign-in methods, including social logins and email/password combinations. This plugin leverages Firebase's secure user token to authenticate users within Nautical, proving a seamless sign-on experience.

Learn more ->

Integrations

Available shipping methods API field

Added the availableShippingStrategy field to the MarketplaceConfiguration model. This field determines how available shipping methods are calculated for price-based shipping rates.

  • When SELLER_LINES (default), the calculation of available shipping methods for each seller is based solely on that seller's order total.
  • When MARKETPLACE_LINES, the calculation includes the entire marketplace order total for determining available shipping methods for each seller.

🪲 Fixed

Emails

Fixed an issue where the vendor_payout_confirmation email was not being sent after processing payouts.

Vendor mgmt

Fixed an issue where you could not filter sellers with the PAUSED status.

Orders

Fixed an issue where a customer user could use another customer's order token to access details of that order via the API.

: Staging

: Production

🚫 Deprecated

Payouts

Deprecated the payout.penalties field in favor of negative adjustments. This field is scheduled for removal after July 1, 2024.

: Staging

: Production

✨ New

Refunds

Generate refund receipts

Added the ability to generate refund receipts with the invoiceRequest mutation. You must provide the refundId as an argument, for example:

mutation {
invoiceRequest(refundId: "UmVmdW5kOjUzOA==") {
invoice {
id
url
}
}
}
Integrations

PayPal payout plugin

Added the nautical.payments.paypal plugin for using PayPal as the payout gateway.

Integrations

Trolley payout plugin

Added the nautical.payments.trolley plugin for using Trolley as the payout gateway.

💎 Changed

Webhooks

Webhook queue manager logging improvements

Improved the logging of webhook events for queue management plugins, such as Google PubSub. Whereas previously logs were only created for failed transmissions, we now also capture and log successful webhook events.

Webhooks

Seller order number in webhooks

Order webhooks now include the number field, which is populated with the seller order number.

🪲 Fixed

Discounts

Fixed an issue where voucher discounts requiring a minimum order value were applied based on the gross total, including tax, rather than the net order total.

: Staging

: Production

✨ New

Refunds

Order line refunds API

Refund lines can now be scoped to an OrderLine, allowing you to target refunds to specific individual order lines. To achieve this, use the refundLinesAdd mutation and set the refundScope to the id of the desired order line. Additionally, specify the quantity of the order line that should be included in the refund.

Learn more ->

Orders

Draft order lines CSV upload API fields

Added the following mutations for uploading a CSV file to create draft order lines:

  • nauticalOrderLinesCsvUpload
  • orderLinesCsvUpload

The CSV file must have at least three columns: id_type, id, and quantity. See the following sample format:

Example CSV
id_type, id, quantity
NSN, 5669abb7-8c4f-477f-8662-4540af3bcdac, 5
ID, UHJvZHVjdFZhcmlhbnQ6MjEx, 5
SKU, 998323573, 5
ID, UHJvZHVjdFZhcmlhbnQ6MjEz, 5
Taxes

Test taxes plugin

Added a "Nautical Test Taxes" plugin, which can be used for development and testing with taxes.

Within the plugin settings, you can input a single tax percentage, which should fall within the range of 0 to 100%. This plugin respects tax settings such as "Charge taxes on shipping rates" and "All products prices are entered with tax included."

caution

This plugin is intended solely for development and testing and is not for use in production environments.

💎 Changed

Refunds

Tax changes on manual fixed-amount refunds

When processing a manual refund for a fixed amount, taxes are no longer added separately. The fixed amount entered is the after-tax amount.

Fixed amount refunds do not automatically adjust records in the tax engine, such as Avalara. If you need to modify the amount of tax to remit, you must manually create a tax adjustment within Avalara.

Was this page helpful?