guiziweb / sylius-agentic-commerce-protocol-plugin
Sylius plugin implementing the Agentic Commerce Protocol (ACP) for AI agent checkout integration with ChatGPT, supporting Stripe delegate payment and seamless order processing.
Installs: 5
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Type:sylius-plugin
pkg:composer/guiziweb/sylius-agentic-commerce-protocol-plugin
Requires
- php: ^8.2
- sylius/sylius: ^2.0
Requires (Dev)
- behat/behat: ^3.16
- dmore/behat-chrome-extension: ^1.4
- dmore/chrome-mink-driver: ^2.9
- doctrine/cache: ^2.2
- friends-of-behat/mink: ^1.11
- friends-of-behat/mink-browserkit-driver: ^1.6
- friends-of-behat/mink-debug-extension: ^2.1
- friends-of-behat/mink-extension: ^2.7
- friends-of-behat/page-object-extension: ^0.3
- friends-of-behat/suite-settings-extension: ^1.1
- friends-of-behat/symfony-extension: ^2.6
- friends-of-behat/variadic-extension: ^1.6
- nyholm/psr7: ^1.8
- phpstan/phpstan: ^1.12
- phpstan/phpstan-doctrine: ^1.3
- phpstan/phpstan-webmozart-assert: ^1.2
- phpunit/phpunit: ^10.5
- robertfausk/behat-panther-extension: ^1.1
- sylius-labs/coding-standard: ^4.4
- sylius-labs/suite-tags-extension: ~0.2
- sylius/sylius-rector: ^2.0
- sylius/test-application: ^2.0.0@alpha
- symfony/browser-kit: ^6.4 || ^7.1
- symfony/debug-bundle: ^6.4 || ^7.1
- symfony/dotenv: ^6.4 || ^7.1
- symfony/http-client: ^6.4 || ^7.1
- symfony/intl: ^6.4 || ^7.1
- symfony/runtime: ^6.4 || ^7.1
- symfony/web-profiler-bundle: ^6.4 || ^7.1
- symfony/webpack-encore-bundle: ^2.2
This package is auto-updated.
Last update: 2025-11-04 07:41:29 UTC
README
A Sylius plugin implementing OpenAI's Agentic Commerce Protocol (ACP) specification, enabling AI agents like ChatGPT to browse products, create checkout sessions, and complete purchases through your Sylius store.
Table of Contents
- What is ACP?
- Overview
- Requirements
- Installation
- Configuration
- Product Feed
- API Endpoints
- Webhooks
- Usage Flow
- Communication Flows
- Security Considerations
- Extension Points
- Development
- Troubleshooting
What is ACP?
The Agentic Commerce Protocol (ACP) is OpenAI's standardized protocol for AI-driven commerce interactions. It defines how AI agents (like ChatGPT) communicate with e-commerce platforms to:
- Browse product catalogs
- Create and manage shopping sessions
- Collect buyer and shipping information
- Process payments securely
- Receive order status updates via webhooks
Specification version: 2025-09-29
Official spec: Agentic Commerce Protocol
Overview
This plugin transforms your Sylius store into an ACP-compliant merchant, allowing AI agents to interact with your catalog and checkout flow through a standardized REST API.
Key Features
- Product Feed Push Command - Synchronize your Sylius catalog with OpenAI's product feed endpoint
- Checkout Session Management - Create, update, retrieve, cancel checkout sessions
- Delegate Payment - Secure payment processing via PSP tokens (currently supports Stripe only)
- HMAC Signature Validation - Authenticate incoming requests from ChatGPT
- Webhook Notifications - Notify ChatGPT of order status changes (
order_create,order_update) - Idempotency Support - Handle duplicate requests safely with
Idempotency-Keyheaders - Channel-Aware - Full support for Sylius multi-channel architecture
Architecture
This plugin acts as a bridge between OpenAI's ACP protocol and Sylius's e-commerce entities:
- ACP Checkout Session → Wraps a Sylius Order (state:
cart) - ACP Line Items → Sylius Order Items
- ACP Fulfillment Options → Sylius Shipping Methods
- ACP Payment → Sylius Payment via PSP delegate payment
- ACP Webhooks → Notify ChatGPT when orders are created/updated
Requirements
- PHP ^8.2
- Sylius ^2.0
- Symfony ^6.4
Installation
Quick Installation (Recommended)
The plugin uses Symfony Flex for automatic configuration:
composer require guiziweb/sylius-agentic-commerce-protocol-plugin
This will automatically:
- Register the bundle in
config/bundles.php - Create configuration file in
config/packages/guiziweb_sylius_agentic_commerce_protocol.yaml - Create routes file in
config/routes/guiziweb_sylius_agentic_commerce_protocol.yaml
Configuration Requirements
To enable Symfony Flex recipes from this repository, add the custom recipe endpoint to your composer.json:
{
"extra": {
"symfony": {
"allow-contrib": true,
"endpoint": [
"https://api.github.com/repos/Guiziweb/SyliusRecipes/contents/index.json?ref=flex/main",
"https://api.github.com/repos/Sylius/SyliusRecipes/contents/index.json?ref=flex/main",
"flex://defaults"
]
}
}
}
Note: You also need to set "minimum-stability": "dev" and "prefer-stable": true in your composer.json until a stable release is tagged.
Post-Installation
After installation, run the database migrations:
php bin/console doctrine:migrations:migrate -n
Configuration
1. Create an ACP Payment Method
Navigate to Sylius Admin → Configuration → Payment Methods and create a new payment method:
- Code:
acp(or any code you prefer) - Name:
ACP Payment(visible in admin only - not shown to customers) - Gateway: Select ACP
- Enabled: Yes
- Channels: Select your channel(s)
2. Configure Gateway Settings
Fill in the following fields in the payment method configuration:
Note: While the Agentic Commerce Protocol supports multiple Payment Service Providers (PSPs), this plugin currently implements Stripe only. Future versions may add support for additional payment providers (PayPal, Adyen, etc.).
Stripe Configuration (PSP)
- PSP URL: URL of your Payment Service Provider (e.g.,
https://api.stripe.com) - PSP Merchant Secret Key: Your PSP secret key for payment processing (e.g., Stripe secret key)
ChatGPT Webhook Configuration
- ChatGPT Webhook URL: URL provided by OpenAI to receive order events
Example:
https://openai.example.com/agentic_checkout/webhooks/order_events - Webhook Secret: Shared secret for HMAC signature of outgoing webhooks
Authentication
- Bearer Token: Token used by ChatGPT to authenticate API requests to your store
- Signature Secret (optional): Shared secret for HMAC signature verification of incoming requests from ChatGPT
3. Configuration Examples
Development/Testing Setup
PSP URL: https://api.stripe.com
PSP Merchant Secret Key: sk_test_xxxxxxxxxxxxx
ChatGPT Webhook URL: https://openai-dev.example.com/webhooks
Webhook Secret: whsec_dev_xxxxxxxxxxxxxxxx
Bearer Token: dev_token_xxxxxxxxxxxxx
Signature Secret: sig_secret_dev_xxxxxxxxxxxx
Production Setup
PSP URL: https://api.stripe.com
PSP Merchant Secret Key: sk_live_xxxxxxxxxxxxx
ChatGPT Webhook URL: https://api.openai.com/agentic_checkout/webhooks/order_events
Webhook Secret: whsec_live_xxxxxxxxxxxxxxxx
Bearer Token: prod_token_xxxxxxxxxxxxx
Signature Secret: sig_secret_prod_xxxxxxxxxxxx
API Endpoints
Once installed, your Sylius store exposes the following ACP endpoints:
Product Catalog
The ACP specification does not include a product catalog endpoint. Instead, merchants push their product catalog directly to OpenAI using the Product Feed Push Command.
Checkout Session Management
POST /acp/checkout_sessions
Create a new checkout session with items, buyer info, and shipping address.
GET /acp/checkout_sessions/{checkoutSessionId}
Retrieve the current state of a checkout session.
POST /acp/checkout_sessions/{checkoutSessionId}
Update an existing session (add/remove items, change address, select shipping method).
POST /acp/checkout_sessions/{checkoutSessionId}/complete
Finalize the order by providing payment data (PSP token).
POST /acp/checkout_sessions/{checkoutSessionId}/cancel
Cancel a checkout session (transitions order to cancelled state).
Authentication
All ACP endpoints require authentication via the Bearer Token configured in the payment method:
Authorization: Bearer your_bearer_token_here
HMAC Signature Validation
If Signature Secret is configured, incoming requests from ChatGPT must include a valid HMAC signature in the Signature header:
Signature: sha256=<hmac_signature_of_request_body> Timestamp: 2025-01-01T12:00:00+00:00
The signature is computed as: HMAC-SHA256(request_body, signature_secret)
Webhooks
The plugin automatically sends webhook notifications to ChatGPT when order events occur.
Event Types
order_create- Sent when an order is successfully created (after payment completion)order_update- Sent when an order status changes (e.g., shipped, fulfilled)
Webhook Payload
{
"type": "order_create",
"data": {
"type": "order",
"checkout_session_id": "ses_xxxxxxxxxxxxx",
"permalink_url": "https://yourstore.com/order/xxxx",
"status": "created",
"refunds": []
}
}
Webhook Signature
Outgoing webhooks are signed with HMAC-SHA256 using the Webhook Secret:
Merchant-Signature: sha256=<hmac_signature> Request-Id: acp_xxxxxxxxxxxxx Timestamp: 2025-01-01T12:00:00+00:00 Content-Type: application/json
ChatGPT will verify the signature before processing the webhook.
Usage Flow
Typical AI Shopping Journey
-
Browse Products ChatGPT retrieves product catalog from OpenAI's product feed (merchant pushes via batch command)
-
Create Session User selects items → ChatGPT calls
POST /acp/checkout_sessionswith items -
Collect Shipping Info User provides address → ChatGPT calls
POST /acp/checkout_sessions/{id}withfulfillment_address -
Select Shipping Method Store returns
fulfillment_options→ User selects method → ChatGPT callsPOST /acp/checkout_sessions/{id}withfulfillment_option_id -
Complete Payment ChatGPT obtains PSP token via delegate payment → calls
POST /acp/checkout_sessions/{id}/complete -
Webhook Notification Store sends
order_createwebhook to ChatGPT with order details -
Order Confirmation ChatGPT displays order confirmation with permalink to user
Product Feed
Pushing Your Catalog to OpenAI
The ACP specification requires merchants to push their product catalog directly to OpenAI. This plugin provides a command to synchronize your Sylius products with OpenAI's product feed system.
Prerequisites
Before using this plugin, you must:
- Register as a merchant at chatgpt.com/merchants
- Submit a sample feed to OpenAI's indexing team for validation
- Receive your feed endpoint URL and authentication token from OpenAI after approval
- Configure allowed formats with OpenAI (TSV, CSV, XML, or JSON)
OpenAI will provide you with a secure HTTPS endpoint and credentials during the onboarding process.
Configuration
After completing OpenAI's merchant registration, configure the Product Feed settings for your channel in Sylius Admin:
- Navigate to Marketing → Product Feed Configuration
- Select your channel
- Configure the following fields:
- Feed Endpoint: Secure HTTPS endpoint provided by OpenAI during registration
- Feed Bearer Token: Authentication token provided by OpenAI
- Default Brand: Fallback brand name for products without one
- Default Weight: Fallback weight for products (e.g.,
"1 kg") - Default Material: Fallback material for products (e.g.,
"Cotton") - Return Policy URL: URL to your return policy page
- Return Window Days: Number of days for returns (e.g.,
30) - Privacy Policy URL: URL to your privacy policy page
- Terms of Service URL: URL to your terms of service page
Command Usage
php bin/console guiziweb:acp:push-product-feed <channel-code>
Usage Examples
# Push products for WEB-US channel php bin/console guiziweb:acp:push-product-feed WEB-US # Dry run (see what would be sent without actually sending) php bin/console guiziweb:acp:push-product-feed WEB-US --dry-run
The command will:
- Fetch all enabled products for the specified channel
- Include variants with available inventory
- Format data according to OpenAI's product feed schema
- Send the catalog to the configured feed endpoint
- Display progress and summary
Scheduling Automatic Sync
To keep your catalog synchronized with OpenAI, schedule the command to run periodically.
Update Frequency: OpenAI accepts product feed updates every 15 minutes, allowing you to keep pricing and availability current in near real-time.
# config/packages/sylius_cron.yaml (if using SchedulerBundle) scheduler_tasks: push_product_feed: expression: '*/15 * * * *' # Every 15 minutes (maximum frequency) command: 'guiziweb:acp:push-product-feed WEB-US'
Or use a system cron job:
# crontab -e # Every 15 minutes (maximum frequency supported by OpenAI) */15 * * * * cd /path/to/sylius && php bin/console guiziweb:acp:push-product-feed WEB-US # Alternative: Every hour (recommended for most stores) 0 * * * * cd /path/to/sylius && php bin/console guiziweb:acp:push-product-feed WEB-US
Recommendation: For most stores, hourly updates are sufficient unless you have highly volatile pricing or inventory. High-frequency updates (every 15 minutes) are best for flash sales or time-sensitive promotions.
Extension Points
Custom Order Processing
The plugin dispatches Symfony events during the order lifecycle:
ACPOrderCompleted- Dispatched after order is finalized (triggers webhook)
Subscribe to these events to add custom business logic:
use Guiziweb\SyliusAgenticCommerceProtocolPlugin\Event\ACPOrderCompleted; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class CustomOrderHandler implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ACPOrderCompleted::class => 'onOrderCompleted']; } public function onOrderCompleted(ACPOrderCompleted $event): void { // Your custom logic here } }
Custom Webhook Events
To send additional webhook events (e.g., order_update when order ships), inject ACPWebhookNotifier:
use Guiziweb\SyliusAgenticCommerceProtocolPlugin\Service\ACPWebhookNotifier; class ShipmentHandler { public function __construct(private ACPWebhookNotifier $webhookNotifier) {} public function onOrderShipped(Order $order): void { $session = $order->getAcpCheckoutSession(); // Your custom mapping $this->webhookNotifier->notify($session, $order, 'order_update', 'shipped'); } }
Development
Running Tests
# PHPUnit vendor/bin/phpunit # Behat vendor/bin/behat # PHPStan vendor/bin/phpstan analyse # Code Style vendor/bin/ecs check
Docker Environment
# Initialize test application make init # Setup database make database-init # Load fixtures make load-fixtures # Run tests make phpunit make behat
Database Schema
The plugin creates two tables:
-
guiziweb_acp_checkout_session- Stores ACP session metadata Links to:sylius_order(one-to-one) - The underlying Sylius ordersylius_channel(many-to-one) - Channel context
-
guiziweb_product_feed_config- Stores Product Feed configuration per channel Links to:sylius_channel(many-to-one) - Channel context
Communication Flows
The plugin orchestrates three distinct communication flows as defined by the ACP specification:
Complete Purchase Flow
sequenceDiagram
participant User
participant ChatGPT
participant YourStore as Your Sylius Store
participant PSP as Payment Provider (Stripe)
Note over User,PSP: 1️⃣ BROWSING & CHECKOUT
User->>ChatGPT: "I want to buy a shirt"
Note right of ChatGPT: ChatGPT retrieves products<br/>from OpenAI's product feed<br/>(merchant pushes via batch)
ChatGPT-->>User: Show products
User->>ChatGPT: "Add blue shirt to cart"
ChatGPT->>YourStore: POST /acp/checkout_sessions<br/>(Bearer Token + Signature)
YourStore-->>ChatGPT: Session created (ses_xxx)
User->>ChatGPT: "Ship to 123 Main St"
ChatGPT->>YourStore: POST /acp/checkout_sessions/ses_xxx<br/>(fulfillment_address)
YourStore-->>ChatGPT: Updated session + shipping options
Note over User,PSP: 2 DELEGATE PAYMENT
User->>ChatGPT: "Pay with card 4242..."
ChatGPT->>PSP: POST /agentic_commerce/delegate_payment<br/>(card data + allowance)
PSP-->>ChatGPT: Vault token (vt_abc123)
Note over User,PSP: 3 COMPLETE ORDER
ChatGPT->>YourStore: POST /acp/checkout_sessions/ses_xxx/complete<br/>(token: vt_abc123)
YourStore->>PSP: POST /agentic_commerce/create_and_process_payment_intent<br/>(PSP Secret Key + vt_abc123)
PSP-->>YourStore: Payment confirmed
YourStore-->>ChatGPT: Order completed
Note over User,PSP: 4 WEBHOOK NOTIFICATION
YourStore->>ChatGPT: POST /webhooks/order_events<br/>(HMAC Signature)
ChatGPT-->>YourStore: 200 OK
ChatGPT-->>User: "Order confirmed"
Loading
Important Notes:
- Your Sylius Store (this plugin) implements:
/acp/checkout_sessions/*+ Product Feed Push Command - PSP (Stripe) implements:
/agentic_commerce/delegate_payment,/agentic_commerce/create_and_process_payment_intent - ChatGPT (OpenAI) implements:
/agentic_checkout/webhooks/order_events+ Product Feed storage
The delegate payment flow (step 2) is handled entirely between ChatGPT and the PSP. Your store never sees the raw card data.
Security Considerations
The plugin handles three distinct communication flows, each with its own authentication mechanism:
| Flow | Direction | Authentication | Header | Required | Notes |
|---|---|---|---|---|---|
| API Requests | ChatGPT → Your Store | Bearer Token | Authorization: Bearer <token> |
✅ Yes | Rotate regularly. Used for all /acp/checkout_sessions/* calls |
| Request Signature | ChatGPT → Your Store | HMAC-SHA256 | Signature: sha256=<hmac>Timestamp: <RFC3339> |
⚠️ Recommended | Prevents unauthorized access even with leaked Bearer Token |
| Webhooks | Your Store → ChatGPT | HMAC-SHA256 | Merchant-Signature: sha256=<hmac> |
✅ Yes | OpenAI verifies webhook authenticity. Min. 32 characters secret |
| PSP Payment | Your Store → PSP | Secret Key | Authorization: Bearer <psp_key> |
✅ Yes | Stripe secret key. Stored encrypted in database |
Security Best Practices
- Rotate tokens regularly - Change Bearer Tokens and Signature Secrets every 90 days
- Use different secrets per environment - Never reuse dev/staging secrets in production
- Enable signature validation - Configure Signature Secret to prevent Bearer Token abuse
- Secure webhook endpoints - Ensure ChatGPT Webhook URL is HTTPS and validate
Merchant-Signature - Protect PSP credentials - Ensure proper database encryption and access controls
Troubleshooting
"Payment method not configured for this channel"
Ensure the ACP payment method is:
- Created in Sylius Admin
- Enabled
- Assigned to the correct channel
"Invalid signature" errors
Verify that:
- Signature Secret matches what ChatGPT is using
- Request body is being hashed correctly (raw body, no modifications)
- HMAC algorithm is SHA256
Webhooks not received by ChatGPT
Check that:
- Webhook URL is correct and accessible from your server
- Webhook Secret is configured
ACPOrderCompletedevent is being dispatched (check logs)
Product feed push fails
Ensure:
- Product Feed Configuration is set up for the channel
- Feed Endpoint and Feed Bearer Token are configured correctly
- Products are Enabled in Sylius Admin
- Products have at least one variant with inventory
- Products have channel pricing configured for the current channel
- Network connectivity to OpenAI's feed endpoint is available
License
This plugin is released under the MIT License.
Credits
Developed by Guiziweb for the Sylius e-commerce platform.
Support
For issues and feature requests, please use the GitHub issue tracker.