The **processor-core** service is the workflow engine powering PayLoops. It orchestrates payment processing, handles retries, manages state transitions, and ensures reliable webhook delivery—all with durability guarantees from [Temporal](https://temporal.
npm install @payloops/processor-coreThe processor-core service is the workflow engine powering PayLoops. It orchestrates payment processing, handles retries, manages state transitions, and ensures reliable webhook delivery—all with durability guarantees from Temporal.
```
┌─────────────────────────────────────────────────────────────────────────┐
│ │
│ Backend API │
│ │ │
│ │ Triggers workflows │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ ★ PROCESSOR-CORE (this repo) ★ │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────────┐ │ │
│ │ │ Temporal Workers │ │ │
│ │ │ │ │ │
│ │ │ PaymentWorkflow RefundWorkflow WebhookWorkflow │ │ │
│ │ │ │ │ │ │ │ │
│ │ │ ▼ ▼ ▼ │ │ │
│ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │
│ │ │ │Activities│ │Activities│ │Activities│ │ │ │
│ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │
│ │ └──────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ └───────────────────────────────┼──────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────┐ │
│ │ Payment Processors │ │
│ │ processor-stripe processor-razorpay │ │
│ └────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Payment processing requires durability and reliability:
- If the server crashes mid-payment, the workflow resumes exactly where it left off
- Long-running operations (like waiting for 3DS) don't block resources
- Automatic retries with configurable backoff
- Full audit trail of every state transition
- Easy to add timeouts, deadlines, and cancellation
Handles the complete lifecycle of a payment from order creation to completion.
``
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ pending │───▶│ routing │───▶│charging │───▶│ 3DS/SCA │───▶│completed│
└─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
│
▼
Wait for signal
(threeDSComplete)
States:
- pending - Order created, awaiting paymentprocessing
- - Routing to optimal processorauthorized
- - Payment authorized, awaiting capturerequires_action
- - Waiting for 3DS/SCA verificationcaptured
- - Payment successfully capturedfailed
- - Payment failed
Signals:
- threeDSComplete - Customer completed 3DS challenge
Ensures merchants receive webhook notifications reliably.
``
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ attempt │───▶│ retry │───▶│ retry │───▶│ final │
│ #1 │ │ #2 │ │ #3 │ │ status │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
1min 5min 30min
Retry Schedule:
1. Immediate
2. 1 minute
3. 5 minutes
4. 30 minutes
5. 2 hours
6. 24 hours (final attempt)
The core provides a plugin system for payment processors:
`typescript
// In processor-stripe or processor-razorpay
import { registerProcessor, PaymentProcessor } from '@payloops/processor-core';
class StripeProcessor implements PaymentProcessor {
name = 'stripe';
async createPayment(input, config) { / ... / }
async capturePayment(orderId, amount, config) { / ... / }
async refundPayment(transactionId, amount, config) { / ... / }
async getPaymentStatus(orderId, config) { / ... / }
}
registerProcessor(new StripeProcessor());
`
Workflows dynamically load the appropriate processor based on routing rules.
Activities are the building blocks that workflows orchestrate:
| Activity | Description |
|----------|-------------|
| getOrder | Fetch order details from database |updateOrderStatus
| | Update order status in database |getProcessorConfig
| | Get decrypted processor credentials |routePayment
| | Determine which processor to use |processPayment
| | Execute payment via processor |deliverWebhook
| | POST webhook to merchant endpoint |
- Node.js 22+
- npm
- Temporal server (via Docker)
- PostgreSQL (via Docker)
`bashInstall dependencies
npm install
$3
| Command | Description |
|---------|-------------|
|
npm dev | Start worker with hot reload |
| npm build | Build for production |
| npm start | Run production worker |
| npm typecheck | Run TypeScript compiler |
| npm lint | Run ESLint |Configuration
| Variable | Required | Description |
|----------|----------|-------------|
|
DATABASE_URL | Yes | PostgreSQL connection string |
| TEMPORAL_ADDRESS | Yes | Temporal server (default: localhost:7233) |
| TEMPORAL_NAMESPACE | Yes | Temporal namespace |
| ENCRYPTION_KEY | Yes | Key to decrypt processor credentials |
| OTEL_EXPORTER_OTLP_ENDPOINT | No | OpenTelemetry collector endpoint (default: http://localhost:4318) |
| OTEL_SERVICE_NAME | No | Service name for telemetry (default: loop-processor-core) |Adding a New Processor
1. Create a new repository (e.g.,
processor-paypal)
2. Implement the PaymentProcessor interface
3. Call registerProcessor() on module load
4. Import the processor in this repo's workerSee processor-stripe for a complete example.
Observability
The processor-core is fully instrumented with OpenTelemetry for distributed tracing, metrics, and structured logging.
$3
| Type | Description |
|------|-------------|
| Traces | Activity spans with workflow context, processor calls |
| Metrics | Activity execution counts, durations, error rates |
| Logs | Structured JSON logs with
trace_id, span_id, workflow context |$3
Every activity execution is automatically traced with:
`
activity.processPayment
├── temporal.activity.type: processPayment
├── temporal.workflow.id: payment-ord_abc123
├── temporal.task_queue: payment-queue
└── duration: 245ms
`$3
When the backend triggers a workflow, the correlation ID is propagated via:
- Search Attributes:
CorrelationId, MerchantId, OrderId
- Memo: traceContext, correlationIdThis enables end-to-end tracing from HTTP request → workflow → activities.
$3
1. Open http://localhost:5080 (login:
admin@loop.dev / admin123)
2. Logs: Filter by service: loop-processor-core or workflow ID
3. Traces: View activity spans linked to parent workflow
4. Metrics: Query activity execution metrics$3
Access at
http://localhost:8080 to:
- View running and completed workflows
- Inspect workflow history and state
- Search by CorrelationId search attribute
- Manually trigger signals
- Terminate stuck workflows$3
Workflows use predictable IDs for easy lookup:
- Payment:
payment-{orderId}
- Webhook: webhook-{eventId}`- backend - Triggers workflows via Temporal client
- processor-stripe - Stripe processor implementation
- processor-razorpay - Razorpay processor implementation
Copyright © 2025 PayLoops. All rights reserved.