Changeset 3789673
- Timestamp:
- 11/07/2026 01:29:14 PM (less than one hour ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
storedispatcher-outbound-integration-for-woocommerce/trunk/readme.txt
r3789576 r3789673 47 47 Example: 48 48 49 ```text 50 WooCommerce Field API Field 51 ──────────────────────────────────────────── 52 Order ID order_id 53 Order Number order.reference 54 Order Status order.status 55 Currency order.currency 56 Order Total order.total 57 Billing Email customer.email 58 Billing First Name customer.first_name 59 Billing Last Name customer.last_name 60 ``` 49 WooCommerce Field API Field 50 ──────────────────────────────────────────── 51 Order ID order_id 52 Order Number order.reference 53 Order Status order.status 54 Currency order.currency 55 Order Total order.total 56 Billing Email customer.email 57 Billing First Name customer.first_name 58 Billing Last Name customer.last_name 59 61 60 62 61 The mapping engine supports nested destination structures such as: 63 62 64 ```text 65 customer.email 66 customer.address.city 67 order.shipping.postcode 68 ``` 63 customer.email 64 customer.address.city 65 order.shipping.postcode 66 69 67 70 68 Line items can also be mapped into arrays: 71 69 72 ```text 73 items[].sku 74 items[].name 75 items[].quantity 76 items[].price 77 ``` 70 items[].sku 71 items[].name 72 items[].quantity 73 items[].price 74 78 75 79 76 === Integration Logging === … … 111 108 The plugin follows a simple integration pipeline: 112 109 113 ```text 114 WooCommerce 115 │ 116 ▼ 117 Order Event 118 │ 119 ▼ 120 Integration Job 121 │ 122 ▼ 123 Mapping Engine 124 │ 125 ┌─────────┴─────────┐ 126 │ │ 127 Field Resolver Transformer 128 │ │ 129 └─────────┬─────────┘ 130 ▼ 131 JSON Payload 132 │ 133 ▼ 134 API Client 135 │ 136 ▼ 137 External REST API 138 │ 139 ▼ 140 Integration Log 141 ``` 110 WooCommerce 111 │ 112 ▼ 113 Order Event 114 │ 115 ▼ 116 Integration Job 117 │ 118 ▼ 119 Mapping Engine 120 │ 121 ┌─────────┴─────────┐ 122 │ │ 123 Field Resolver Transformer 124 │ │ 125 └─────────┬─────────┘ 126 ▼ 127 JSON Payload 128 │ 129 ▼ 130 API Client 131 │ 132 ▼ 133 External REST API 134 │ 135 ▼ 136 Integration Log 137 142 138 143 139 The integration is intentionally separated into independent components so the API client, mapping engine, event handling, and logging can evolve independently. … … 151 147 Clone the repository: 152 148 153 ```bash 154 git clone https://github.com/maryglo/api-connector-for-woocommerce.git 155 ``` 149 git clone https://github.com/maryglo/api-connector-for-woocommerce.git 150 156 151 157 152 The installable ZIP includes Composer's generated runtime autoloader; Composer is not required on the WordPress server. To build the ZIP from source, use PHP 8.1 or newer, run this from the repository root in PowerShell, then upload the ZIP under **Plugins → Add Plugin → Upload Plugin**: 158 153 159 ```powershell 160 .\scripts\build-plugin.ps1 161 ``` 154 .\scripts\build-plugin.ps1 155 162 156 163 157 The ZIP is written to `build/storedispatcher-outbound-integration-for-woocommerce.zip`. It includes `composer.json`, `composer.lock`, and the generated `vendor/` autoloader. The icon and screenshots remain in the source `assets/` folder and are excluded from the ZIP; the admin CSS and JavaScript are included. … … 165 159 After installing the ZIP, activate it from: 166 160 167 ```text 168 WordPress Admin 169 → Plugins 170 → Installed Plugins 171 → StoreDispatcher - Outbound Integration for WooCommerce 172 ``` 161 WordPress Admin 162 → Plugins 163 → Installed Plugins 164 → StoreDispatcher - Outbound Integration for WooCommerce 165 173 166 174 167 == Requirements == … … 195 188 After activating the plugin, open: 196 189 197 ```text 198 WordPress Admin 199 → WooCommerce 200 → API Connector 201 ``` 190 WordPress Admin 191 → WooCommerce 192 → API Connector 193 202 194 203 195 Configure: 204 196 205 ```text 206 API Connection 207 ├── API Name 208 ├── API Base URL 209 ├── Health Path 210 ├── Authentication method 211 ├── API credentials 212 └── Connection test 213 214 Order Events 215 ├── Order created 216 └── Order completed 217 218 Endpoints 219 └── Order endpoint 220 221 Field Mapping 222 ├── Order fields 223 └── Line-item fields 224 ``` 197 API Connection 198 ├── API Name 199 ├── API Base URL 200 ├── Health Path 201 ├── Authentication method 202 ├── API credentials 203 └── Connection test 204 205 Order Events 206 ├── Order created 207 └── Order completed 208 209 Endpoints 210 └── Order endpoint 211 212 Field Mapping 213 ├── Order fields 214 └── Line-item fields 215 225 216 226 217 Save the configuration and use the built-in connection test to verify communication with the external API. … … 234 225 Add: 235 226 236 ```php 237 define('WCAC_ENCRYPTION_KEY', 'YOUR_BASE64_ENCODED_32_BYTE_KEY'); 238 ``` 227 define('WCAC_ENCRYPTION_KEY', 'YOUR_BASE64_ENCODED_32_BYTE_KEY'); 228 239 229 240 230 Generate a secure 32-byte key with PHP: 241 231 242 ```bash 243 php -r "echo base64_encode(random_bytes(32)), PHP_EOL;" 244 ``` 232 php -r "echo base64_encode(random_bytes(32)), PHP_EOL;" 233 245 234 246 235 Copy the generated value into `wp-config.php`: 247 236 248 ```php 249 define('WCAC_ENCRYPTION_KEY', 'your-generated-base64-key'); 250 ``` 237 define('WCAC_ENCRYPTION_KEY', 'your-generated-base64-key'); 238 251 239 252 240 Place the constant before: 253 241 254 ```php 255 /* That's all, stop editing! Happy publishing. */ 256 ``` 242 /* That's all, stop editing! Happy publishing. */ 243 257 244 258 245 === Docker environments === … … 260 247 If WordPress is running in Docker, the key can be generated inside the WordPress container: 261 248 262 ```bash 263 docker compose exec wordpress php -r "echo base64_encode(random_bytes(32)), PHP_EOL;" 264 ``` 249 docker compose exec wordpress php -r "echo base64_encode(random_bytes(32)), PHP_EOL;" 250 265 251 266 252 The key can also be provided through the container environment. … … 268 254 For example, in `.env`: 269 255 270 ```env 271 WCAC_ENCRYPTION_KEY=your-generated-base64-key 272 ``` 256 WCAC_ENCRYPTION_KEY=your-generated-base64-key 257 273 258 274 259 Then expose it to the WordPress container and load it from `wp-config.php`: 275 260 276 ```php 277 if (getenv('WCAC_ENCRYPTION_KEY')) { 278 define('WCAC_ENCRYPTION_KEY', getenv('WCAC_ENCRYPTION_KEY')); 279 } 280 ``` 261 if (getenv('WCAC_ENCRYPTION_KEY')) { 262 define('WCAC_ENCRYPTION_KEY', getenv('WCAC_ENCRYPTION_KEY')); 263 } 264 281 265 282 266 Do not commit `.env` files containing the encryption key to source control. … … 305 289 Example: 306 290 307 ```http 308 Authorization: Bearer YOUR_TOKEN 309 ``` 291 Authorization: Bearer YOUR_TOKEN 292 310 293 311 294 === API Key === … … 313 296 Example: 314 297 315 ```http 316 X-API-Key: YOUR_API_KEY 317 ``` 298 X-API-Key: YOUR_API_KEY 299 318 300 319 301 The API credential is encrypted before being stored in the WordPress database. … … 329 311 Example: 330 312 331 ```php 332 define('WCAC_API_KEY', 'YOUR_API_CREDENTIAL'); 333 ``` 313 define('WCAC_API_KEY', 'YOUR_API_CREDENTIAL'); 314 334 315 335 316 When configured, this server-managed credential takes precedence over the credential stored by the plugin. … … 341 322 These are two different secrets: 342 323 343 ```text 344 WCAC_API_KEY 345 │ 346 └── External API credential 347 348 WCAC_ENCRYPTION_KEY 349 │ 350 └── Local encryption key used to protect 351 credentials stored by the plugin 352 ``` 324 WCAC_API_KEY 325 │ 326 └── External API credential 327 328 WCAC_ENCRYPTION_KEY 329 │ 330 └── Local encryption key used to protect 331 credentials stored by the plugin 332 353 333 354 334 The encryption key does not authenticate requests to the external API. … … 362 342 When a configured WooCommerce event occurs, the plugin creates an asynchronous integration job. 363 343 364 ```text 365 Order Event 366 │ 367 ▼ 368 Create Integration Job 369 │ 370 ▼ 371 Action Scheduler 372 │ 373 ▼ 374 Load WooCommerce Order 375 │ 376 ▼ 377 Apply Field Mapping 378 │ 379 ▼ 380 Generate JSON Payload 381 │ 382 ▼ 383 Send REST API Request 384 │ 385 ├── Success 386 │ ↓ 387 │ Log success 388 │ 389 └── Failure 390 ↓ 391 Retry 392 ↓ 393 Log failure 394 ``` 344 Order Event 345 │ 346 ▼ 347 Create Integration Job 348 │ 349 ▼ 350 Action Scheduler 351 │ 352 ▼ 353 Load WooCommerce Order 354 │ 355 ▼ 356 Apply Field Mapping 357 │ 358 ▼ 359 Generate JSON Payload 360 │ 361 ▼ 362 Send REST API Request 363 │ 364 ├── Success 365 │ ↓ 366 │ Log success 367 │ 368 └── Failure 369 ↓ 370 Retry 371 ↓ 372 Log failure 373 395 374 396 375 Using asynchronous processing prevents the external API request from unnecessarily blocking the WooCommerce order lifecycle. … … 412 391 A typical flow is: 413 392 414 ```text 415 Attempt 1 416 │ 417 └── Failed 418 ↓ 419 Retry 420 ↓ 421 Attempt 2 422 │ 423 └── Failed 424 ↓ 425 Retry 426 ↓ 427 Attempt 3 428 │ 429 ├── Success 430 │ 431 └── Failed → Mark as failed 432 ``` 393 Attempt 1 394 │ 395 └── Failed 396 ↓ 397 Retry 398 ↓ 399 Attempt 2 400 │ 401 └── Failed 402 ↓ 403 Retry 404 ↓ 405 Attempt 3 406 │ 407 ├── Success 408 │ 409 └── Failed → Mark as failed 410 433 411 434 412 --- … … 440 418 For example, a WooCommerce order might contain: 441 419 442 ```text 443 Order ID 444 Billing Email 445 Billing First Name 446 Billing Last Name 447 Order Total 448 Currency 449 Line Items 450 ``` 420 Order ID 421 Billing Email 422 Billing First Name 423 Billing Last Name 424 Order Total 425 Currency 426 Line Items 427 451 428 452 429 The external API may expect: 453 430 454 ```json 455 { 456 "externalOrderId": 12345, 457 "customer": { 458 "email": "customer@example.com", 459 "firstName": "John", 460 "lastName": "Doe" 461 }, 462 "amount": 199.99, 463 "currency": "USD", 464 "items": [] 465 } 466 ``` 431 { 432 "externalOrderId": 12345, 433 "customer": { 434 "email": "customer@example.com", 435 "firstName": "John", 436 "lastName": "Doe" 437 }, 438 "amount": 199.99, 439 "currency": "USD", 440 "items": [] 441 } 442 467 443 468 444 The mapping configuration determines how the WooCommerce data is transformed into the destination structure. … … 478 454 Run the test suite: 479 455 480 ```bash 481 composer test 482 ``` 456 composer test 457 483 458 484 459 Before deploying a new version, test the plugin against a real WooCommerce installation with: … … 529 504 == Project Structure == 530 505 531 ```text 532 api-connector-for-woocommerce/ 533 │ 534 ├── src/ 535 │ ├── Admin/ 536 │ ├── Api/ 537 │ ├── Mapping/ 538 │ ├── Orders/ 539 │ ├── Jobs/ 540 │ ├── Logging/ 541 │ ├── Settings/ 542 │ └── Install/ 543 │ 544 ├── assets/ (admin CSS and JavaScript, icon, and directory screenshots) 545 │ 546 ├── tests/ 547 │ 548 ├── languages/ 549 │ 550 ├── composer.json 551 ├── composer.lock 552 ├── readme.txt 553 ├── uninstall.php 554 └── storedispatcher-outbound-integration-for-woocommerce.php 555 ``` 506 api-connector-for-woocommerce/ 507 │ 508 ├── src/ 509 │ ├── Admin/ 510 │ ├── Api/ 511 │ ├── Mapping/ 512 │ ├── Orders/ 513 │ ├── Jobs/ 514 │ ├── Logging/ 515 │ ├── Settings/ 516 │ └── Install/ 517 │ 518 ├── assets/ (admin CSS and JavaScript, icon, and directory screenshots) 519 │ 520 ├── tests/ 521 │ 522 ├── languages/ 523 │ 524 ├── composer.json 525 ├── composer.lock 526 ├── readme.txt 527 ├── uninstall.php 528 └── storedispatcher-outbound-integration-for-woocommerce.php 529 556 530 557 531 The project uses a modular architecture to keep WordPress-specific functionality separate from API communication and mapping logic. … … 607 581 For example: 608 582 609 ```text 610 External API Schema 611 │ 612 ▼ 613 AI Mapping Assistant 614 │ 615 ▼ 616 Suggested WooCommerce Mappings 617 │ 618 ▼ 619 Administrator Review 620 │ 621 ▼ 622 Saved Mapping 623 │ 624 ▼ 625 Deterministic Production Integration 626 ``` 583 External API Schema 584 │ 585 ▼ 586 AI Mapping Assistant 587 │ 588 ▼ 589 Suggested WooCommerce Mappings 590 │ 591 ▼ 592 Administrator Review 593 │ 594 ▼ 595 Saved Mapping 596 │ 597 ▼ 598 Deterministic Production Integration 599 627 600 628 601 This approach keeps production integrations predictable while using AI to reduce the time required to configure complex API mappings.
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)