Loading...
Loading...
Use when connecting Spree 6 to an external system through a provider contract — a tax engine, carrier rate shopping, a WMS/3PL or label provider, a payment gateway, a search engine (Meilisearch, Typesense, Algolia), seller payouts, digital downloads/license keys, SSO/OpenID Connect or a custom JWT issuer, OpenTelemetry/APM, or an ERP/PIM/DAM. Common phrasings - "custom tax provider", "Avalara", "delivery rate provider", "EasyPost", "fulfillment provider", "custom payment method", "search provider", "payout provider", "digital asset provider", "SSO", "Okta/Entra login", "Spree::Integration", "store credentials for a provider", "Spree.integrations", "which registry do I append to". A map of every plug-in point - base class, registration call, where it is selected, and the doc to read.
npx skill4agent add spree/agent-skills spree-providersPaths below use theprefix of aserver/project; on a classic Rails app drop it.create-spree-app
| Concern | Base class | Register | Selected by | Default |
|---|---|---|---|---|
| Tax | | | | |
| Delivery rates | | | | |
| Fulfillment / labels / WMS | | | | |
| Payments | | | Payment method records (Settings → Payments) | Check, StoreCredit, Bogus |
| Search | | | — | |
| Seller payouts | | | store preference | |
| Digital deliverables | | | | |
| Auth strategies (SSO, external JWT) | | | Login request ( | |
| Credentials for any of the above | | | Per store, Settings → Integrations | — |
| Observability | — (gem) | | — | dormant |
SMTP_*spree-deploymentSpree.order_routing.rules.strategiesSpree::OrderRoutingRuleSpree::OrderRouting::Strategy::BaseSpree.stock_splittersSpree.number_generators[:order] = 'My::Numbers'Spree.promotions.rules.actionsSpree.adjustersSpree.tracking_carriers['my_courier'] = { name:, url: }spree-fulfillmentspree-promotionsspree-order-totalsSpree::PricingProvider::BaseSpree::InventoryProvider::BaseSpree.pricing_providersSpree.inventory_providerspricing_providerinventory_provider'internal'payment_methodsfulfillment_providersintegrationsstock_splittersadjusterspromotions.actionstracking_carriersconfig.after_initializeconfig/initializers/spree.rbto_prepareafter_initializeafter_initialize# server/config/initializers/spree.rb
Rails.application.config.after_initialize do
Spree.integrations << 'MyApp::AcmeIntegration'
Spree.delivery_rate_providers << MyApp::AcmeRates
Spree.fulfillment_providers << MyApp::AcmeFulfillment
Spree.payment_methods << MyApp::AcmeGateway
end
Spree.search_provider = 'MyApp::SearchProvider::Typesense' # plain assignment, any timeconfig.after_initializespree-extensionsdelivery_method.rate_providermarket.tax_providerdigital_asset.provider_typeintegration.typeSpree::Integrationmodule MyApp
class AcmeIntegration < Spree::Integration
preference :api_key, :password # :password = masked on read, guarded on write
preference :test_mode, :boolean, default: true
def self.integration_group = 'shipping' # gallery grouping
# Called when the merchant activates it; false blocks activation with the message.
def can_connect?
client.ping
true
rescue StandardError => e
self.connection_error_message = e.message
false
end
def client = @client ||= Acme::Client.new(api_key: preferred_api_key)
end
enddef self.integration_class = 'MyApp::AcmeIntegration'Spree::IntegrationBackedProviderintegrationself.available_for_store?(store)spree-taxesestimate(owner, items = nil, tax_date:, tax_identifier:, exemptions:, context:)Spree::TaxLinecommit(order)void(order)refund(order, return_items, amount:, tax_date:)display_nameavailable_for_store?unsupported_capabilitiesspree-fulfillmentestimates(package)Spree::DeliveryRateProvider::Estimate.new(cost:, currency:, carrier:, service_level:, estimated_delivery_date:, metadata:)estimate(package)nil[]Rails.error.report[]costSpree::Current.provider_cache[key] ||=self.service_catalog(integration)ServiceCatalog.listing/none/unavailablebookreleasegenerates_labels?digital?pickup?can_fulfill?auto_fulfill?requires_address?serves_location?(delivery_method, stock_location)purchase_label(owner)refund_label(label)create_fulfillment(fulfillment)cancel_fulfillmenttracking_urldocumentsspree_easypostSpreeEasyPost::DeliveryRateProviderSpreeEasyPost::FulfillmentProviderSpreeEasyPost::Integrationspree-paymentsSpree::PaymentMethodSpree::PaymentSessionSpree::PaymentSetupSessionSpreeStripe::Gatewaysearch_and_filter(scope:, query:, filters:, sort:, page:, limit:)filters(...)index(product)remove(product)remove_by_id(prefixed_id)index_batch(documents)reindex(scope)self.indexing_required?Spree::Dependencies.search_product_presenterspree_meilisearchSpreeMeilisearch::ProductPresentergem 'spree_meilisearch'MEILISEARCH_URLMEILISEARCH_API_KEYSpree.search_provider = 'SpreeMeilisearch::SearchProvider'spree task search:reindexspree-marketplacetransfer!(seller_transfer)pay!(seller_payout)referenceSpree.seller_payout_complete_workflowreverse!(seller_transfer)onboarding_urlonboarded?onboarding_stateonboarding_messagedisplay_namereference_systemrequires_payout_account?available_for_store?provider_keySpree::Core::AmbiguousGatewayErrorSpree::Core::GatewayErrorSpreeStripe::PayoutProviderdeliver(digital_link, expires_in:)Spree::DigitalDelivery.new(redirect_url:).new(inline_value:, content_type:)setting :pool_name, :stringself.requires_attachment?spree-auth-permissionsRails.application.config.after_initialize do
Spree.admin_authentication_strategies.add(
:entra,
Spree::Authentication::Strategies::OidcStrategy.configure(
issuer: 'https://login.microsoftonline.com/<tenant>/v2.0',
client_id: ENV['ENTRA_CLIENT_ID'],
client_secret: ENV['ENTRA_CLIENT_SECRET'],
redirect_uri: 'https://shop.example.com/api/v3/admin/auth/callback/entra',
label: 'Microsoft Entra ID'
)
)
end.remove(:email)BaseStrategyauthenticateprovidersuccess(user)failure(msg)find_or_create_user_from_oauthspree-deploymentspree-performancegem 'spree_opentelemetry'OTEL_SERVICE_NAMEOTEL_EXPORTER_OTLP_ENDPOINTOTEL_SDK_DISABLED=trueSpreeOpenTelemetry.configure { |c| c.use/skip/with_sdk }OTEL_TRACES_EXPORTER=noneestimateSpree::TaxLineSpree::TaxProvider::Internaldelivery_methoddelivery_rate_providersfulfillment_providers'My::Provider'POST /api/v3/webhooks/{payments,payouts}/:payment_method_id/webhooks/fulfillments/:integration_idSpree::Current.storeSpree::Payments::HandleWebhookJobconstruct_eventcommitrefundnode_modules/@spree/docs/dist/developer/providers/overview.mdnode_modules/@spree/docs/dist/developer/how-to/{custom-delivery-rate-provider,custom-payment-method,custom-search-provider,custom-digital-asset-provider,custom-api-authentication,custom-order-routing,custom-stock-splitter,custom-document-numbers}.mdnode_modules/@spree/docs/dist/developer/providers/{fulfillment,payouts,sso,observability,erp,pim,dam}.mdnode_modules/@spree/docs/dist/integrations/<category>/<name>.mdspree-extensionsspree-taxesspree-fulfillmentspree-paymentsspree-marketplacespree-auth-permissionsspree-customization