Configuration Payram

VérifiéSûr

Configure les variables d'environnement, explique le modèle d'authentification Payram (en-tête API-Key) et teste la connectivité via un script. Utile pour démarrer une intégration, valider une configuration ou résoudre des erreurs de connexion.

Spar Skills Guide Bot
DeveloppementDébutant
7002/06/2026
Claude Code
#payram#payment-integration#configuration#env-setup

Recommandé pour

Notre avis

Configure les variables d'environnement, présente le mécanisme d'authentification par en-tête de Payram et fournit des scripts de test pour valider la connexion à un serveur Payram auto-hébergé.

Points forts

  • Fournit des instructions étape par étape pour la configuration de l'environnement
  • Inclut des scripts de test prêts à l'emploi en Node.js et Python
  • Explique les pièges d'authentification courants (ex. utiliser l'en-tête 'API-Key' au lieu de 'Authorization')
  • Offre une gestion d'erreur détaillée dans les scripts de test

Limites

  • Suppose que le serveur Payram est déjà déployé et accessible
  • Le script de test crée un paiement minimal, ce qui peut ne pas être souhaitable dans tous les environnements
  • Ne couvre pas les fonctionnalités avancées de Payram au-delà de la connectivité
Quand l'utiliser

Lorsque vous devez configurer et vérifier rapidement une connexion à une instance Payram auto-hébergée pour un nouveau projet ou environnement.

Quand l'éviter

Lorsque vous avez déjà une intégration Payram fonctionnelle et que vous avez seulement besoin de gérer des points d'API spécifiques.

Analyse de sécurité

Sûr
Score qualité90/100

The skill provides clear, non-destructive instructions for setting up a project connection to Payram server, using standard environment variables and API client code. No security risks are present.

Aucun point d'attention détecté

Exemples

Setup Payram environment and test connection
I need to configure my backend to connect to my self-hosted Payram server. Help me set up the .env file and test the connectivity using Node.js.
Validate Payram authentication
I'm getting 401 errors when calling my Payram API. Can you guide me on the correct authentication header and test the connection?
Payram initial integration
I want to integrate Payram payments into my app. Start by setting up the environment and verifying the connection to my server.

name: setup-payram description: Configure and validate connectivity to a self-hosted Payram server

Setup Payram

Configure your backend to connect to a self-hosted Payram server and validate the connection.

Overview

This skill guides you through:

  1. Creating the required .env configuration
  2. Understanding Payram's authentication model
  3. Testing connectivity to your Payram instance
  4. Troubleshooting common connection issues

When to Use

  • Starting a new Payram integration
  • Validating existing Payram configuration
  • Troubleshooting connection errors
  • Setting up a new environment (staging, production)

Prerequisites

You must have:

  • A self-hosted Payram server deployed and accessible
  • Admin access to the Payram dashboard
  • An API key generated from the dashboard (Settings → Accounts → API Keys)

Instructions

Step 1: Create Environment Configuration

Create a .env file in your project root with the following variables:

# Payram REST base URL (include protocol, no trailing slash)
PAYRAM_BASE_URL=https://your-payram-server.example

# Payram API key (from dashboard Settings → Accounts → API Keys)
PAYRAM_API_KEY=pk_live_your_actual_key_here

Required Variables:

  • PAYRAM_BASE_URL: Full URL to your self-hosted Payram instance
  • PAYRAM_API_KEY: Project-scoped API key from the Payram dashboard

Important: Never commit .env files to version control. Add .env to your .gitignore.

Step 2: Understand Authentication

Payram uses header-based authentication:

API-Key: your_api_key_here

NOT Authorization: Bearer ... - this will fail with 401.

The API key must be:

  • Sent in the API-Key header (case-sensitive)
  • Generated for the specific project/workspace you're integrating
  • Kept secret and never exposed in client-side code

Step 3: Test Connectivity

Create a test script to validate your connection. The connection test creates a minimal payment request to verify:

  • Network reachability
  • API key validity
  • Correct authentication setup

Node.js/TypeScript (Using Payram SDK)

Install SDK:

npm install payram dotenv

Test Script:

import { Payram, isPayramSDKError } from 'payram';
import dotenv from 'dotenv';

dotenv.config();

const baseUrl = process.env.PAYRAM_BASE_URL;
const apiKey = process.env.PAYRAM_API_KEY;

if (!baseUrl || !apiKey) {
  console.error('❌ Missing PAYRAM_BASE_URL or PAYRAM_API_KEY in .env');
  process.exit(1);
}

async function testConnection() {
  try {
    // Initialize Payram SDK
    const payram = new Payram({
      apiKey,
      baseUrl,
      config: {
        timeoutMs: 10_000,
        maxRetries: 2,
      },
    });

    console.log('🔄 Testing connection to Payram...');
    console.log(`   Base URL: ${baseUrl}`);

    // Create a minimal test payment
    const checkout = await payram.payments.initiatePayment({
      customerEmail: 'test@example.com',
      customerId: 'connectivity-test',
      amountInUSD: 1,
    });

    console.log('✅ Connection successful!');
    console.log(`   Reference ID: ${checkout.reference_id}`);
    console.log(`   Checkout URL: ${checkout.url}`);

    return true;
  } catch (error) {
    console.error('❌ Connection failed');

    if (isPayramSDKError(error)) {
      console.error(`   Status: ${error.status}`);
      console.error(`   Error: ${error.error}`);
      console.error(`   Request ID: ${error.requestId}`);
      console.error(`   Retryable: ${error.isRetryable}`);
    } else {
      console.error(`   Error: ${error instanceof Error ? error.message : String(error)}`);
    }

    return false;
  }
}

testConnection();

Python (Using requests)

Install dependencies:

pip install requests python-dotenv

Test Script:

import os
import requests
from dotenv import load_dotenv

load_dotenv()

base_url = os.getenv('PAYRAM_BASE_URL')
api_key = os.getenv('PAYRAM_API_KEY')

if not base_url or not api_key:
    print('❌ Missing PAYRAM_BASE_URL or PAYRAM_API_KEY in .env')
    exit(1)

def test_connection():
    try:
        print('🔄 Testing connection to Payram...')
        print(f'   Base URL: {base_url}')

        endpoint = f"{base_url}/api/v1/payment"
        headers = {
            'API-Key': api_key,
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        }
        payload = {
            'customerEmail': 'test@example.com',
            'customerId': 'connectivity-test',
            'amountInUSD': 1,
        }

        response = requests.post(endpoint, json=payload, headers=headers, timeout=10)

        if response.status_code in [200, 201]:
            data = response.json()
            print('✅ Connection successful!')
            print(f"   Reference ID: {data.get('reference_id', 'N/A')}")
            print(f"   Checkout URL: {data.get('url', 'N/A')}")
            return True
        else:
            print('❌ Connection failed')
            print(f"   Status: {response.status_code}")
            print(f"   Response: {response.text}")
            return False

    except requests.exceptions.RequestException as e:
        print('❌ Connection failed')
        print(f"   Error: {str(e)}")
        return False

if __name__ == '__main__':
    test_connection()

Go (Using net/http)

Test Script:

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "os"
    "time"

    "github.com/joho/godotenv"
)

type PaymentRequest struct {
    CustomerEmail string  `json:"customerEmail"`
    CustomerID    string  `json:"customerId"`
    AmountInUSD   float64 `json:"amountInUSD"`
}

type PaymentResponse struct {
    ReferenceID string `json:"reference_id"`
    URL         string `json:"url"`
}

func testConnection() bool {
    godotenv.Load()

    baseURL := os.Getenv("PAYRAM_BASE_URL")
    apiKey := os.Getenv("PAYRAM_API_KEY")

    if baseURL == "" || apiKey == "" {
        fmt.Println("❌ Missing PAYRAM_BASE_URL or PAYRAM_API_KEY in .env")
        return false
    }

    fmt.Println("🔄 Testing connection to Payram...")
    fmt.Printf("   Base URL: %s\n", baseURL)

    payload := PaymentRequest{
        CustomerEmail: "test@example.com",
        CustomerID:    "connectivity-test",
        AmountInUSD:   1.0,
    }

    body, _ := json.Marshal(payload)

    client := &http.Client{Timeout: 10 * time.Second}
    req, err := http.NewRequest("POST", baseURL+"/api/v1/payment", bytes.NewBuffer(body))
    if err != nil {
        fmt.Printf("❌ Failed to create request: %v\n", err)
        return false
    }

    req.Header.Set("API-Key", apiKey)
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Accept", "application/json")

    resp, err := client.Do(req)
    if err != nil {
        fmt.Printf("❌ Connection failed: %v\n", err)
        return false
    }
    defer resp.Body.Close()

    if resp.StatusCode == 200 || resp.StatusCode == 201 {
        var result PaymentResponse
        bodyBytes, _ := io.ReadAll(resp.Body)
        json.Unmarshal(bodyBytes, &result)

        fmt.Println("✅ Connection successful!")
        fmt.Printf("   Reference ID: %s\n", result.ReferenceID)
        fmt.Printf("   Checkout URL: %s\n", result.URL)
        return true
    } else {
        fmt.Printf("❌ Connection failed: Status %d\n", resp.StatusCode)
        bodyBytes, _ := io.ReadAll(resp.Body)
        fmt.Printf("   Response: %s\n", string(bodyBytes))
        return false
    }
}

func main() {
    testConnection()
}

PHP (Using cURL)

Test Script:

<?php
require __DIR__ . '/vendor/autoload.php';

use Dotenv\Dotenv;

$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();

$baseUrl = $_ENV['PAYRAM_BASE_URL'] ?? null;
$apiKey = $_ENV['PAYRAM_API_KEY'] ?? null;

if (!$baseUrl || !$apiKey) {
    echo "❌ Missing PAYRAM_BASE_URL or PAYRAM_API_KEY in .env\n";
    exit(1);
}

function testConnection($baseUrl, $apiKey) {
    echo "🔄 Testing connection to Payram...\n";
    echo "   Base URL: $baseUrl\n";

    $payload = [
        'customerEmail' => 'test@example.com',
        'customerId' => 'connectivity-test',
        'amountInUSD' => 1,
    ];

    $ch = curl_init($baseUrl . '/api/v1/payment');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'API-Key: ' . $apiKey,
            'Content-Type: application/json',
            'Accept: application/json',
        ],
        CURLOPT_POSTFIELDS => json_encode($payload),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 10,
    ]);

    $response = curl_exec($ch);
    $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error = curl_error($ch);
    curl_close($ch);

    if ($error) {
        echo "❌ Connection failed: $error\n";
        return false;
    }

    if ($statusCode === 200 || $statusCode === 201) {
        $data = json_decode($response, true);
        echo "✅ Connection successful!\n";
        echo "   Reference ID: " . ($data['reference_id'] ?? 'N/A') . "\n";
        echo "   Checkout URL: " . ($data['url'] ?? 'N/A') . "\n";
        return true;
    } else {
        echo "❌ Connection failed: Status $statusCode\n";
        echo "   Response: $response\n";
        return false;
    }
}

testConnection($baseUrl, $apiKey);

Java (Using HttpClient)

Test Script:

package com.example.payram;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;

import io.github.cdimascio.dotenv.Dotenv;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class ConnectionTest {

    public static void main(String[] args) {
        Dotenv dotenv = Dotenv.load();

        String baseUrl = dotenv.get("PAYRAM_BASE_URL");
        String apiKey = dotenv.get("PAYRAM_API_KEY");

        if (baseUrl == null || apiKey == null) {
            System.out.println("❌ Missing PAYRAM_BASE_URL or PAYRAM_API_KEY in .env");
            System.exit(1);
        }

        testConnection(baseUrl, apiKey);
    }

    public static boolean testConnection(String baseUrl, String apiKey) {
        try {
            System.out.println("🔄 Testing connection to Payram...");
            System.out.println("   Base URL: " + baseUrl);

            // Create JSON payload
            ObjectMapper mapper = new ObjectMapper();
            ObjectNode payload = mapper.createObjectNode();
            payload.put("customerEmail", "test@example.com");
            payload.put("customerId", "connectivity-test");
            payload.put("amountInUSD", 1);

            // Build HTTP request
            HttpClient client = HttpClient.newBuilder()
                .connectTimeout(Duration.ofSeconds(10))
                .build();

            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(baseUrl + "/api/v1/payment"))
                .header("API-Key", apiKey)
                .header("Content-Type", "application/json")
                .header("Accept", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(payload)))
                .timeout(Duration.ofSeconds(10))
                .build();

            // Send request
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

            if (response.statusCode() == 200 || response.statusCode() == 201) {
                ObjectNode result = (ObjectNode) mapper.readTree(response.body());
                System.out.println("✅ Connection successful!");
                System.out.println("   Reference ID: " + result.get("reference_id").asText());
                System.out.println("   Checkout URL: " + result.get("url").asText());
                return true;
            } else {
                System.out.println("❌ Connection failed: Status " + response.statusCode());
                System.out.println("   Response: " + response.body());
                return false;
            }

        } catch (Exception e) {
            System.out.println("❌ Connection failed: " + e.getMessage());
            return false;
        }
    }
}

Step 4: Interpret Results

Success (200/201):

{
  "checkout": {
    "id": "...",
    "url": "https://...",
    ...
  }
}

Your configuration is correct and Payram is reachable.

401 Unauthorized:

  • Check that API-Key header is used (not Authorization)
  • Verify the API key is correct and hasn't been revoked
  • Ensure the key is for the correct project/workspace

404 Not Found:

  • Verify PAYRAM_BASE_URL is correct
  • Check for typos in the endpoint path
  • Confirm Payram is deployed and running

Network Errors:

  • Verify firewall rules allow outbound HTTPS
  • Check DNS resolution of your Payram domain
  • Confirm SSL certificates are valid

Best Practices

  1. Environment Separation

    • Use different API keys for staging vs production
    • Never share API keys between environments
    • Rotate keys regularly
  2. Security

    • Store API keys in secure secret management systems (AWS Secrets Manager, Vault, etc.)
    • Never log full API keys
    • Use environment-specific .env files (.env.staging, .env.production)
  3. Error Handling

    • Always check response status codes
    • Log failures with context but without sensitive data
    • Implement retry logic with exponential backoff for network errors
  4. Validation

    • Test connectivity before deploying to production
    • Run connectivity tests as part of CI/CD health checks
    • Monitor connection health in production with periodic pings

Troubleshooting

"Missing PAYRAM_BASE_URL or PAYRAM_API_KEY"

Cause: Environment variables not loaded.

Solution:

  • Ensure .env file exists in project root
  • Verify .env contains both variables
  • Check that your code loads .env (e.g., dotenv.config() in Node, load_dotenv() in Python)

"401 Unauthorized" or "Authentication Failed"

Cause: Invalid or missing API key.

Solution:

  • Confirm you're using API-Key header, not Authorization
  • Regenerate API key in Payram dashboard if needed
  • Check for extra whitespace in .env values

"Network error" or "Connection refused"

Cause: Payram server unreachable.

Solution:

  • Verify PAYRAM_BASE_URL includes protocol (https://)
  • Check firewall rules and network connectivity
  • Confirm Payram service is running (systemctl status payram)

"404 Not Found"

Cause: Wrong endpoint or base URL.

Solution:

  • Remove trailing slashes from PAYRAM_BASE_URL
  • Verify endpoint path is /api/v1/payment
  • Check Payram version compatibility

Related Skills

  • integrate-payments - After setup, implement payment flows
  • integrate-payouts - Configure outbound payment capabilities
  • handle-webhooks - Receive Payram event notifications
Skills similaires