# 11 — Third-Party Integration Plan

Every external service is hidden behind a TypeScript interface. Business code depends on the interface, not the vendor. The active implementation is selected by env vars at boot.

## Provider catalog

| Capability | Interface | Default (Phase 1) | Phase 3 candidates |
|---|---|---|---|
| Payment | `PaymentProvider` | `MockPaymentProvider` | Stripe, Checkout.com, Telr, Network International |
| Maps | `MapProvider` | `MockMapProvider` | Mapbox, Google Maps, HERE |
| SMS / OTP | `SmsProvider` | `ConsoleSmsProvider` (dev) | Twilio, Unifonic, Vonage |
| OCR | `OcrProvider` | `MockOcrProvider` | Google Vision, AWS Textract |
| Translation | `TranslationProvider` | `MockTranslationProvider` | DeepL, Google Translate, Azure |
| AI itinerary | `AiProvider` | `MockAiProvider` | OpenAI, Anthropic, Bedrock |
| Push | `PushProvider` | `ExpoPushProvider` | FCM, APNs |
| Email | `EmailProvider` | `ConsoleEmailProvider` | SES, Resend, Postmark |
| Storage | `StorageProvider` | `LocalStorageProvider` | S3, Cloudflare R2 |
| Analytics | `AnalyticsProvider` | `MockAnalyticsProvider` | PostHog, Amplitude |

## Common interface shape

```ts
export interface PaymentProvider {
  createIntent(input: CreatePaymentIntent): Promise<PaymentIntent>;
  confirm(input: ConfirmPayment): Promise<Payment>;
  refund(input: RefundInput): Promise<Refund>;
  parseWebhook(req: WebhookRequest): Promise<WebhookEvent>;
}
```

Each provider lives in `apps/api/src/providers/<capability>/` with `interface.ts`, `mock.ts`, `<vendor>.ts`, `module.ts`.

## Dependency injection

```ts
@Module({
  providers: [
    {
      provide: PAYMENT_PROVIDER,
      useFactory: (cfg: ConfigService) => buildPaymentProvider(cfg),
      inject: [ConfigService],
    },
  ],
})
```

`buildPaymentProvider` reads `PAYMENT_PROVIDER` env and returns the matching implementation.

## Rotation & secrets

Secrets only exist on the API host. Frontend apps receive only public keys (e.g. Stripe publishable key) via `/v1/config/public`. Secrets rotate via env updates without code changes.

## Webhook hardening

- Signed payloads validated with HMAC.
- Replay protection via `Idempotency-Key` and event timestamp tolerance.
- Failed handlers retried by BullMQ with exponential backoff and a DLQ.

## Documented assumptions

1. We can launch with mock providers everywhere; the platform is fully testable end-to-end without a vendor account.
2. PSP selection is deferred to Phase 3 pending UAE acquirer agreements.
3. Map provider for the website may differ from mobile (cost / SDK fit) — both go through `MapProvider`.
