Assist_Design/docs/SALESFORCE-ORDER-COMMUNICATION.md
T. Narantuya 0bf872e249 Refactor code formatting and improve documentation clarity
- Adjusted YAML and JSON files for consistent formatting, including healthcheck commands and package exports.
- Enhanced readability in various TypeScript files by standardizing string quotes and improving line breaks.
- Updated documentation across multiple files to improve clarity and consistency, including address system and logging levels.
- Removed unnecessary package-lock.json from shared package directory to streamline dependencies.
2025-09-09 18:19:54 +09:00

5.9 KiB

Salesforce-to-Portal Order Communication Guide

Note: 2025 update — Async-first via Salesforce Platform Events is now the recommended pattern. The legacy webhook path remains referenced only historically and should be phased out.

Overview

This guide focuses specifically on secure communication between Salesforce and your Portal for order provisioning. This is NOT about invoices or billing - it's about the order approval and provisioning workflow.

The Order Flow

1. Customer places order → Portal creates Salesforce Order (Status: "Pending Review")
2. Salesforce operator approves Order
3. Salesforce Flow publishes OrderProvisionRequested__e
4. Portal subscriber enqueues a job → provisions in WHMCS → updates Salesforce Order status
5. Customer sees updated status in Portal

1. Salesforce → Portal (Order Provisioning)

High-level flow

1. Operator marks Order Approved in Salesforce
2. Record-Triggered Flow publishes Order_Fulfilment_Requested__e
3. Portal subscribes via Pub/Sub API (gRPC) and enqueues a provisioning job
4. Portal provisions in WHMCS and updates Salesforce Order status
5. Portal UI polls BFF for status (unchanged)

Salesforce Setup

  • Create High-Volume Platform Event: Order_Fulfilment_Requested__e
    • Fields (example API names):
      • OrderId__c (Text 18) — required
      • IdemKey__c (Text 80) — optional (Idempotency key)
      • CorrelationId__c (Text 80) — optional
      • RequestedBy__c (Text 80) — optional
      • Version__c (Number) — optional
  • Flow: Record-Triggered on Order when Status changes to Approved
    • Actions:
      • Update Activation_Status__c = Activating
      • Create OrderProvisionRequested__e and set OrderId__c = $Record.Id
      • Optionally clear activation error fields

Portal Setup

  • Env
    • SF_EVENTS_ENABLED=true
    • SF_PROVISION_EVENT_CHANNEL=/event/OrderProvisionRequested__e
    • SF_EVENTS_REPLAY=LATEST (or ALL to start from earliest retained)
  • Subscriber (auto-start, durable replay): apps/bff/src/vendors/salesforce/events/pubsub.subscriber.ts
    • Subscribes to the channel and enqueues a job to the provisioning queue
  • Worker: apps/bff/src/orders/queue/provisioning.processor.ts
    • Guards on Activation_Status__c = Activating; provisions in WHMCS and then updates Salesforce

Why async: resilient (replay within retention), decoupled, no inbound allowlisting. No auto-retries from the portal; operators retry from Salesforce by flipping status to Activating.

Legacy Implementation (Webhook) — Removed

The old endpoint POST /orders/{sfOrderId}/fulfill has been removed. Provisioning is now triggered solely via Platform Events published from Salesforce.

Enhanced Security Implementation (Legacy Webhook)

All Quick Actions and Named Credentials previously used to call the portal should be retired.

Salesforce Apex Implementation (not needed)

No Apex callout to the portal is required. Use a Record-Triggered Flow to publish the Platform Event.

2. Security Configuration

Environment Variables

# Platform Events (BFF)
SF_EVENTS_ENABLED=true
SF_PROVISION_EVENT_CHANNEL=/event/OrderProvisionRequested__e
SF_EVENTS_REPLAY=LATEST  # or ALL

Salesforce Named Credential

Not required for the async path; the portal pulls events from Salesforce.

4. Customer Experience

Portal UI Polling

The portal should poll for order status updates:

// In your Portal UI
export function useOrderStatus(sfOrderId: string) {
  const [status, setStatus] = useState<OrderStatus>("Pending Review");

  useEffect(() => {
    const pollStatus = async () => {
      try {
        const response = await fetch(`/api/orders/${sfOrderId}`);
        const data = await response.json();
        setStatus(data.status);

        // Stop polling when order is complete
        if (["Provisioned", "Failed"].includes(data.status)) {
          clearInterval(interval);
        }
      } catch (error) {
        console.error("Failed to fetch order status:", error);
      }
    };

    const interval = setInterval(pollStatus, 5000); // Poll every 5 seconds
    pollStatus(); // Initial fetch

    return () => clearInterval(interval);
  }, [sfOrderId]);

  return status;
}

5. Monitoring and Alerting

Key Metrics to Monitor

  • Provisioning Success Rate: Track successful vs failed provisioning attempts
  • Provisioning Latency: Time from SF approval to completion
  • WHMCS API Errors: Monitor WHMCS integration health
  • Event Lag: Time between event publish and job enqueue/complete

Alert Conditions

// Example monitoring service
@Injectable()
export class OrderProvisioningMonitoringService {
  async recordProvisioningAttempt(sfOrderId: string, success: boolean, duration: number) {
    // Record metrics
    this.metricsService.increment("order.provisioning.attempts", {
      success: success.toString(),
    });

    this.metricsService.histogram("order.provisioning.duration", duration);

    // Alert on high failure rate
    const recentFailureRate = await this.getRecentFailureRate();
    if (recentFailureRate > 0.1) {
      // 10% failure rate
      await this.alertingService.sendAlert("High order provisioning failure rate");
    }
  }
}

6. Testing

Event Flow Testing

Validate that an OrderProvisionRequested__e event enqueues a job and runs the orchestrator. Check logs and /health/sf-events for status and cursor.

Summary

This focused approach ensures secure communication specifically for your order provisioning workflow:

  1. Salesforce Flow → Publishes Platform Event OrderProvisionRequested__e
  2. Portal BFF → Subscribes, queues job, provisions in WHMCS, updates Salesforce
  3. Customer → Sees real-time order status in Portal UI

The security relies on your existing JWT-based Salesforce API integration and ; no inbound webhooks are required.