POST
/
api
/
v2.1
/
fintrans
/
{walletId}
/
payment-consents
/
types
/
{operationType}
{
  "consentId": "<string>",
  "data": {
    "consentId": "<string>",
    "status": "<string>",
    "validUntil": "<string>"
  }
}

Overview

The Payment Consent endpoint creates consent rules that govern financial operations. These consents:
  • Define allowed beneficiaries for transfers
  • Set transaction and time-based limits
  • Establish validity periods
  • Enable compliance controls
Payment consents are particularly important for ensuring that transfers only go to pre-approved beneficiaries.

Path Parameters

walletId
string
required
The wallet/account ID
operationType
string
required
Type of operation: transfer, withdraw, or topup

Headers

Authorization
string
required
Bearer token for authentication (admin privileges required)
X-Tenant-ID
string
required
Tenant identifier for multi-tenant operations
X-Session-Id
string
Session ID for tracking
Content-Type
string
required
Must be application/json

Request Body

paymentType
string
required
Payment type (should match operationType in uppercase)
title
string
required
Human-readable title for the consent
description
string
required
Detailed description of the consent purpose
parameters
object
required
Consent parameters and restrictions

Response

Unique consent identifier (various response formats supported)
data
object
Consent details (if wrapped in data object)

Example Request

curl --request POST \
  --url https://api.finhub.cloud/api/v2.1/fintrans/wal_abc123def456/payment-consents/types/transfer \
  --header 'Authorization: Bearer ADMIN_TOKEN' \
  --header 'X-Tenant-ID: fh_api_finsei_ltd_7f957f77' \
  --header 'Content-Type: application/json' \
  --data '{
    "paymentType": "TRANSFER",
    "title": "Payment Consent for transfer",
    "description": "Customer consent for transfer transaction processing",
    "parameters": {
      "validity": {
        "startDate": "2025-01-23",
        "endDate": "2025-01-24",
        "maxUsageCount": 100
      },
      "limits": {
        "maxAmountPerTransaction": {
          "amount": 1000,
          "currency": "EUR"
        },
        "maxAmountPerDay": {
          "amount": 5000,
          "currency": "EUR"
        },
        "maxAmountPerMonth": {
          "amount": 20000,
          "currency": "EUR"
        },
        "maxTransactionsPerDay": 10,
        "maxTransactionsPerWeek": 50
      },
      "beneficiaries": {
        "allowedAccounts": [
          "FR1420041010050500013M02606",
          "DE89370400440532013000",
          "ben_xyz789abc123",
          "ben_def456ghi789"
        ],
        "allowedTypes": ["INTERNAL", "SEPA", "SWIFT"],
        "allowNewBeneficiaries": false,
        "requireBeneficiaryName": true
      }
    }
  }'
```text`n## Example Response

```json
{
  "data": {
    "consentId": "consent-payment-abc123",
    "status": "ACTIVE",
    "validUntil": "2025-01-24T23:59:59.000Z"
  }
}
```text`n## Beneficiary Validation

The most critical feature of payment consents is beneficiary validation:

### Allowed Accounts Format

```javascript
const allowedAccounts = [
  // IBANs
  "FR1420041010050500013M02606",
  "DE89370400440532013000",
  
  // Beneficiary IDs (from create beneficiary)
  "ben_xyz789abc123",
  "ben_def456ghi789",
  
  // Internal account numbers
  "ACC456789",
  "ACC987654"
];
```text`n### Validation During Transfer

When a transfer is prepared with this consent:
1. The target IBAN is checked against `allowedAccounts`
2. If not found, the transfer is rejected
3. This prevents unauthorized recipients

## Common Use Cases

### 1. Restricted Business Payments

```json
{
  "title": "Supplier Payments Only",
  "beneficiaries": {
    "allowedAccounts": [
      "DE89370400440532013000",  // Supplier A
      "FR1420041010050500013M02606"  // Supplier B
    ],
    "allowNewBeneficiaries": false
  }
}
```text`n### 2. Family Member Transfers

```json
{
  "title": "Family Transfers",
  "beneficiaries": {
    "allowedAccounts": [
      "ben_family_member_1",
      "ben_family_member_2"
    ],
    "allowNewBeneficiaries": true
  }
}
```text`n### 3. High-Value Transaction Consent

```json
{
  "title": "High-Value Transfers",
  "limits": {
    "maxAmountPerTransaction": {
      "amount": 50000,
      "currency": "EUR"
    }
  },
  "beneficiaries": {
    "allowedAccounts": ["VERIFIED_HIGH_VALUE_ACCOUNTS"],
    "requireBeneficiaryName": true
  }
}
```text`n## Consent Lifecycle

1. **Creation** - Define restrictions and limits
2. **Activation** - Consent becomes usable
3. **Usage** - Validated during transfers
4. **Expiration** - Automatic deactivation
5. **Renewal** - Create new consent if needed

## Integration with Transfer Flow

```javascript
// 1. Create payment consent
const consent = await createPaymentConsent({
  paymentType: "TRANSFER",
  // ... parameters
});

// 2. Prepare transfer with consent
const preparedOrder = await prepareTransfer({
  consent: {
    consentReference: consent.consentId
  },
  target: {
    iban: "FR1420041010050500013M02606" // Must be in allowedAccounts
  }
});

// 3. Execute with consent confirmation
const result = await executeTransfer({
  preparedOrderId: preparedOrder.preparedOrderId,
  consentConfirmation: {
    consentId: consent.consentId,
    confirmed: true
  }
});
```text`n## Error Scenarios

| Error | Description | Resolution |
|-------|-------------|------------|
| Beneficiary not in allowed list | Target IBAN not found in allowedAccounts | Use approved beneficiary |
| Consent expired | Validity period ended | Create new consent |
| Limit exceeded | Transaction exceeds defined limits | Reduce amount or create new consent |
| Invalid beneficiary type | Network type not in allowedTypes | Use allowed network |

## PowerShell Script Example

```powershell
# Create payment consent with beneficiary restrictions
try {
    # Use fintrans API endpoint
    $consentUrl = "$baseUrl/api/v2.1/fintrans/$walletId/consents/payment"
    
    # Build consent body with beneficiary restrictions
    $consentBody = @{
        paymentType = "TRANSFER"
        limits = @{
            maxAmountPerTransaction = "5000.00"
            dailyLimit = "10000.00"
            weeklyLimit = "25000.00"
            monthlyLimit = "50000.00"
            currency = "EUR"
        }
        beneficiaryRestrictions = @{
            enabled = $true
            allowedBeneficiaries = $beneficiaryIds  # From previous beneficiary creation
            allowNewBeneficiaries = $false
        }
        validFrom = (Get-Date).ToString("yyyy-MM-dd")
        validUntil = (Get-Date).AddYears(1).ToString("yyyy-MM-dd")
        description = "Payment consent for EUR transfers with beneficiary restrictions"
        metadata = @{
            createdBy = "Customer Portal"
            purpose = "Business payments"
            ipAddress = "192.168.1.100"
        }
    } | ConvertTo-Json -Depth 3
    
    Write-Host "`nCreating payment consent..." -ForegroundColor Cyan
    Write-Host "  Type: TRANSFER" -ForegroundColor White
    Write-Host "  Max per transaction: €5,000" -ForegroundColor White
    Write-Host "  Daily limit: €10,000" -ForegroundColor White
    Write-Host "  Allowed beneficiaries: $($beneficiaryIds.Count)" -ForegroundColor White
    
    # Create headers with authentication
    $headers = @{
        "Authorization" = "Bearer $token"
        "Content-Type"  = "application/json"
        "Accept"        = "application/json"
        "X-Tenant-Id"   = $xTenantId
        "X-Session-Id"  = $sessionId
    }
    
    $consentResponse = Invoke-RestMethod -Uri $consentUrl -Method Post -Headers $headers -Body $consentBody
    
    if ($consentResponse.data) {
        $consentData = $consentResponse.data
        Write-Host "Payment consent created successfully!" -ForegroundColor Green
        Write-Host "  Consent ID: $($consentData.id)" -ForegroundColor White
        Write-Host "  Reference: $($consentData.consentReference)" -ForegroundColor White
        Write-Host "  Status: $($consentData.status)" -ForegroundColor White
        Write-Host "  Valid until: $($consentData.validUntil)" -ForegroundColor White
        
        # Save consent ID for later use
        $script:paymentConsentId = $consentData.consentReference
        
        # Display beneficiary restrictions
        if ($consentData.beneficiaryRestrictions -and $consentData.beneficiaryRestrictions.enabled) {
            Write-Host "  Beneficiary restrictions: ENABLED" -ForegroundColor Yellow
            Write-Host "    Allowed count: $($consentData.beneficiaryRestrictions.allowedBeneficiaries.Count)" -ForegroundColor White
            Write-Host "    New beneficiaries: $($consentData.beneficiaryRestrictions.allowNewBeneficiaries)" -ForegroundColor White
        }
        
        # Check if consent requires customer acceptance
        if ($consentData.requiresAcceptance) {
            Write-Host "`n  CUSTOMER ACCEPTANCE REQUIRED!" -ForegroundColor Red
            Write-Host "  Acceptance link: $($consentData.acceptanceUrl)" -ForegroundColor Yellow
            
            # Simulate customer acceptance
            Write-Host "`nAccepting consent as customer..." -ForegroundColor Cyan
            $acceptUrl = "$baseUrl/api/v2.1/fintrans/$walletId/consents/payment/$($consentData.id)/accept"
            $acceptBody = @{
                accepted = $true
                acceptedAt = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
                acceptanceChannel = "WEB"
                ipAddress = "192.168.1.100"
            } | ConvertTo-Json
            
            $acceptResponse = Invoke-RestMethod -Uri $acceptUrl -Method Post -Headers $headers -Body $acceptBody
            Write-Host "  Consent accepted successfully" -ForegroundColor Green
        }
        
        # Save consent details
        $consentFile = "./payment_consent_$(Get-Date -Format 'yyyyMMddHHmmss').json"
        $consentResponse | ConvertTo-Json -Depth 5 | Set-Content -Path $consentFile
        Write-Host "`nConsent details saved to: $consentFile" -ForegroundColor Green
    }
}
catch {
    Write-Host "Failed to create payment consent: $($_.Exception.Message)" -ForegroundColor Red
    
    # Handle specific errors
    $errorBody = $_.ErrorDetails.Message | ConvertFrom-Json -ErrorAction SilentlyContinue
    if ($errorBody) {
        switch ($errorBody.code) {
            "INVALID_BENEFICIARIES" {
                Write-Host "  One or more beneficiary IDs are invalid" -ForegroundColor Yellow
            }
            "LIMIT_TOO_HIGH" {
                Write-Host "  Requested limits exceed allowed maximum" -ForegroundColor Yellow
            }
            "DUPLICATE_CONSENT" {
                Write-Host "  Active consent already exists for this payment type" -ForegroundColor Yellow
            }
            default {
                Write-Host "  Error: $($errorBody.message)" -ForegroundColor Yellow
            }
        }
    }
}

# Alternative: Create consent without beneficiary restrictions
$openConsentBody = @{
    paymentType = "TRANSFER"
    limits = @{
        maxAmountPerTransaction = "1000.00"
        dailyLimit = "5000.00"
        currency = "EUR"
    }
    beneficiaryRestrictions = @{
        enabled = $false
    }
    validFrom = (Get-Date).ToString("yyyy-MM-dd")
    validUntil = (Get-Date).AddMonths(6).ToString("yyyy-MM-dd")
    description = "Open payment consent for small EUR transfers"
}

Write-Host "`nNote: For open consent (no beneficiary restrictions), set enabled = false" -ForegroundColor Cyan
```text`n## Related Endpoints

- [Get Payment Consents](/latest/api-reference/v2.1/fintrans/get-payment-consents) - List active consents
- [Update Payment Consent](/latest/api-reference/v2.1/fintrans/update-payment-consent) - Modify consent
- [Revoke Payment Consent](/latest/api-reference/v2.1/fintrans/revoke-payment-consent) - Cancel consent
- [Allowed Operations](/latest/api-reference/v2.1/fintrans/allowed-operations) - Check consent requirements