﻿---
name: payment-initiation-spi
description: >
  Instructs AI agents how to implement the Kyriba Payment Initiation Service SPI.
  This is an INBOUND interface - Kyriba calls YOUR service to initiate payments
  via a custom channel (direct bank API, payment gateway, etc.).
version: 1.0.0
scopes: []
authors:
  - kyriba
tags:
  - kyriba
  - payments
  - payment-initiation
  - spi
---

> **Auth** — POST {AUTH_BASE_URL}/oauth/token · Basic base64(CLIENT_ID:CLIENT_SECRET) · no scope.
> Use token_type verbatim — do not hardcode `Bearer`. On 401: retry once with the other scheme (`token` vs `Bearer`). On 429: wait Kyriba-Customer-Rate-Limit-Reset.

# Kyriba API Skill: Payment Initiation Service SPI

>  **This is NOT a standard API.** This is an SPI (Service Provider Interface).
> **Kyriba calls YOUR service.** You implement the server; Kyriba is the client.

---

## What is the Payment Initiation SPI?

The Payment Initiation SPI lets you plug a custom payment channel into Kyriba - for example, a direct bank API, a payment gateway, or a proprietary payment network. Kyriba routes approved payments to your service instead of (or alongside) SWIFT or file-based transmission.

---

## Integration Architecture

```
Payment approved in Kyriba
        ↓
Kyriba calls YOUR service -> POST /payment-orders
        ↓
YOUR service submits to bank/gateway
        ↓
Kyriba polls YOUR service -> GET /payment-orders/{id}
        ↓
Status flows back into Kyriba
```

---

## Endpoints YOUR Service Must Expose

| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/health` | Health check - Kyriba verifies your service is up |
| `POST` | `/payment-orders` | Initiate a payment |
| `GET` | `/payment-orders/{id}` | Get status of a previously initiated payment |

---

## Health Check

**Request from Kyriba:**
```
GET /health
```

**Expected response (`200 OK`):**
```json
{ "status": "UP" }
```

---

## Initiate Payment (Kyriba -> Your Service)

```http
POST /payment-orders
Content-Type: application/json
Authorization: Basic base64(clientId:clientSecret)

{
  "correlationId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "paymentOrder": {
    "amount": 5000.00,
    "currency": { "code": "EUR" },
    "valueDate": "2025-07-10",
    "debtor": {
      "bankAccount": {
        "iban": "FR7630006000011234567890189",
        "bic": "BNPAFRPP"
      },
      "name": "ACME Corp"
    },
    "creditor": {
      "bankAccount": {
        "iban": "DE89370400440532013000",
        "bic": "COBADEFFXXX"
      },
      "name": "Supplier GmbH"
    },
    "remittanceInfo": "INV-2025-001",
    "paymentFormat": "SEPA_CT"
  }
}
```

**Expected response (`201 Created`):**
```json
{
  "correlationId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "paymentOrderId": "your-internal-payment-id",
  "status": "ACCEPTED"
}
```

---

## Get Payment Status (Kyriba -> Your Service)

```http
GET /payment-orders/{paymentOrderId}
Authorization: Basic base64(clientId:clientSecret)
```

**Expected response (`200 OK`):**
```json
{
  "paymentOrderId": "your-internal-payment-id",
  "correlationId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "SETTLED",
  "statusDetails": "Payment confirmed by beneficiary bank",
  "settlementDate": "2025-07-10"
}
```

| `status` | Meaning |
|---|---|
| `ACCEPTED` | Payment received and queued |
| `PROCESSING` | Submitted to bank, awaiting confirmation |
| `SETTLED` | Bank confirmed successful settlement |
| `REJECTED` | Payment rejected by bank or gateway |
| `FAILED` | Technical failure |

---

## Critical Rules

1. **Echo back `correlationId`** - always return it in responses and status updates
2. **`paymentOrderId`** - your internal ID used by Kyriba to poll status
3. **Idempotency** - same `correlationId` may arrive more than once; return same `paymentOrderId`
4. **Always return 201 on accept** - return non-2xx only on actual server error or rejection
5. **Kyriba polls `/payment-orders/{id}`** - implement status caching to avoid redundant bank calls
6. **Authentication** - Kyriba sends `Basic` auth; validate it in your service

---

## Configuration in Kyriba

Register your SPI endpoint in the Kyriba UI under:
**Administration -> Connectivity -> Payment Channels -> Service Provider**

Required configuration:
- Service base URL
- Client ID / Client Secret
- Payment format(s) routed to this service
- Polling interval and max attempts

---

## Error Reference

| Your response | Effect |
|---|---|
| `201` + `paymentOrderId` | Payment accepted, Kyriba will poll for status |
| `4xx` | Kyriba marks payment as failed - check `statusDetails` |
| `5xx` / timeout | Kyriba retries per configuration, then marks as failed |

---

## OpenAPI Spec

- OpenAPI: `https://developer.kyriba.com/static/apis/payment-initiation-spi/payment-initiation-spi.yaml`
- Postman: `https://developer.kyriba.com/static/apis/payment-initiation-spi/payment-initiation-spi-postman-collection.json`